lkml.org 
[lkml]   [2002]   [Dec]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[pidhash] [5/4] make get_pid_list() scan the PID bitmap
Make get_pid_list() walk the PID bitmap instead of the tasklist.
This is not quite as good as it could be, because the PID search
structures are not appropriately arranged for range queries.

fs/proc/base.c | 22 +---------------------
kernel/pid.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 21 deletions(-)


diff -urpN wli-2.5.50-5/fs/proc/base.c wli-2.5.50-6/fs/proc/base.c
--- wli-2.5.50-5/fs/proc/base.c 2002-11-27 14:36:06.000000000 -0800
+++ wli-2.5.50-6/fs/proc/base.c 2002-12-04 19:15:00.000000000 -0800
@@ -1153,28 +1153,8 @@ out:
* tasklist lock while doing this, and we must release it before
* we actually do the filldir itself, so we use a temp buffer..
*/
-static int get_pid_list(int index, unsigned int *pids)
-{
- struct task_struct *p;
- int nr_pids = 0;
-
- index--;
- read_lock(&tasklist_lock);
- for_each_process(p) {
- int pid = p->pid;
- if (!pid)
- continue;
- if (--index >= 0)
- continue;
- pids[nr_pids] = pid;
- nr_pids++;
- if (nr_pids >= PROC_MAXPIDS)
- break;
- }
- read_unlock(&tasklist_lock);
- return nr_pids;
-}

+int get_pid_list(int ordinal_of_pid, unsigned int *pid_buf);
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
unsigned int pid_array[PROC_MAXPIDS];
diff -urpN wli-2.5.50-5/kernel/pid.c wli-2.5.50-6/kernel/pid.c
--- wli-2.5.50-5/kernel/pid.c 2002-11-27 14:36:03.000000000 -0800
+++ wli-2.5.50-6/kernel/pid.c 2002-12-04 19:15:59.000000000 -0800
@@ -258,6 +258,59 @@ void switch_exec_pids(task_t *leader, ta
attach_pid(leader, PIDTYPE_SID, leader->session);
}

+int get_pid_list(int ordinal, unsigned int *pid_buf)
+{
+ pidmap_t *map = pidmap_array;
+ int count = 0, k = 0, pos = 0;
+
+ BUG_ON(ordinal <= 0);
+ ordinal--;
+
+ while (pos + BITS_PER_PAGE < ordinal && map - pidmap_array < PIDMAP_ENTRIES) {
+ pos += BITS_PER_PAGE - atomic_read(&map->nr_free);
+ ++map;
+ }
+
+ if (map - pidmap_array >= PIDMAP_ENTRIES || !map->page)
+ return 0;
+
+ while (pos < ordinal && k < BITS_PER_PAGE) {
+ task_t *task;
+ if (test_bit(k, map->page)
+ && (map - pidmap_array)*BITS_PER_PAGE + k) {
+ int pid = (map-pidmap_array)*BITS_PER_PAGE + k;
+ read_lock(&tasklist_lock);
+ task = find_task_by_pid(pid);
+ if (task && thread_group_leader(task))
+ ++pos;
+ read_unlock(&tasklist_lock);
+ }
+ ++k;
+ }
+
+ while (map - pidmap_array < PIDMAP_ENTRIES && map->page && count < 20) {
+ while (k < BITS_PER_PAGE && count < 20) {
+ task_t *task;
+
+ if (test_bit(k, map->page)
+ && (map - pidmap_array)*BITS_PER_PAGE + k) {
+ int pid = (map-pidmap_array)*BITS_PER_PAGE + k;
+ read_lock(&tasklist_lock);
+ task = find_task_by_pid(pid);
+ if (task && thread_group_leader(task)) {
+ pid_buf[count] = task->pid;
+ ++count;
+ }
+ read_unlock(&tasklist_lock);
+ }
+ ++k;
+ }
+ ++map;
+ k = 0;
+ }
+ return count;
+}
+
void __init pidhash_init(void)
{
int i, j;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 13:31    [W:0.077 / U:1.248 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site