From: albert <> Date: Sun, 19 Oct 2003 23:37:47 +0000 (+0000) Subject: sorted threads might work X-Git-Tag: v3.3.0~212 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7dfe80961ab9a9921785f454efb4f263b725c38a;p=procps-ng sorted threads might work --- diff --git a/proc/readproc.c b/proc/readproc.c index 85b75804..2dd46da9 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -558,6 +558,7 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric static char sbuf[1024]; // buffer for stat,statm unsigned flags = PT->flags; +//printf("hhh\n"); if (unlikely(stat(path, &sb) == -1)) /* no such dirent (anymore) */ goto next_task; @@ -567,6 +568,7 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric t->euid = sb.st_uid; /* need a way to get real uid */ t->egid = sb.st_gid; /* need a way to get real gid */ +//printf("iii\n"); if (flags & PROC_FILLSTAT) { /* read, parse /proc/#/stat */ if (unlikely( file2str(path, "stat", sbuf, sizeof sbuf) == -1 )) goto next_task; /* error reading /proc/#/stat */ @@ -659,12 +661,15 @@ static int simple_nextpid(PROCTAB *restrict const PT, proc_t *restrict const p) // Return non-zero on success. static int simple_nexttid(PROCTAB *restrict const PT, const proc_t *restrict const p, proc_t *restrict const t, char *restrict const path) { static struct direct *ent; /* dirent handle */ - (void)p; - if(!PT->taskdir){ + if(PT->taskdir_user != p->tgid){ + if(PT->taskdir){ + closedir(PT->taskdir); + } // use "path" as some tmp space snprintf(path, PROCPATHLEN, "%s/task", PT->path); PT->taskdir = opendir(path); if(!PT->taskdir) return 0; + PT->taskdir_user = p->tgid; } for (;;) { ent = readdir(PT->taskdir); @@ -761,10 +766,11 @@ proc_t* readproc(PROCTAB *restrict const PT, proc_t *restrict p) { proc_t *saved_p; if (PT->did_fake) PT->did_fake=0; - if (PT->taskdir) { - closedir(PT->taskdir); - PT->taskdir = NULL; - } +// if (PT->taskdir) { +// closedir(PT->taskdir); +// PT->taskdir = NULL; +// PT->taskdir_user = -1; +// } saved_p = p; if(!p) p = xcalloc(p, sizeof *p); /* passed buf or alloced mem */ @@ -868,6 +874,7 @@ PROCTAB* openproc(int flags, ...) { did_stat = 1; } PT->taskdir = NULL; + PT->taskdir_user = -1; PT->taskfinder = simple_nexttid; PT->taskreader = simple_readtask; @@ -910,6 +917,7 @@ void closeproc(PROCTAB* PT) { if (PT){ if (PT->procfs) closedir(PT->procfs); if (PT->taskdir) closedir(PT->taskdir); + memset(PT,'#',sizeof(PROCTAB)); free(PT); } } @@ -979,36 +987,20 @@ proc_t** readproctab(int flags, ...) { } // Try again, this time with threads and selection. -proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), int flags, ...) { - PROCTAB* PT = NULL; +proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), PROCTAB *restrict const PT) { proc_t** ptab = NULL; - proc_t** ttab = NULL; - proc_t* data = NULL; - unsigned n_alloc = 0; - unsigned n_used = 0; unsigned n_proc_alloc = 0; unsigned n_proc = 0; - unsigned n_task = 0; + + proc_t** ttab = NULL; unsigned n_task_alloc = 0; - va_list ap; - proc_data_t *pd; + unsigned n_task = 0; - va_start(ap, flags); - if (flags & PROC_UID) { - // temporary variables ensure that va_arg() instances - // are called in the right order - uid_t* u; - int i; + proc_t* data = NULL; + unsigned n_alloc = 0; + unsigned long n_used = 0; - u = va_arg(ap, uid_t*); - i = va_arg(ap, int); - PT = openproc(flags, u, i); - } - else if (flags & PROC_PID) - PT = openproc(flags, va_arg(ap, void*)); - else - PT = openproc(flags); - va_end(ap); + proc_data_t *pd; for(;;){ proc_t *tmp; @@ -1027,8 +1019,7 @@ proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t * tmp = readproc_direct(PT, data+n_used); if(!tmp) break; if(!want_proc(tmp)) continue; - ptab[n_proc++] = tmp; - n_used++; + ptab[n_proc++] = (proc_t*)(n_used++); if(!( PT->flags & PROC_LOOSE_TASKS )) continue; for(;;){ proc_t *t; @@ -1047,25 +1038,25 @@ proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t * t = readtask_direct(PT, tmp, data+n_used); if(!t) break; if(!want_task(t)) continue; - ttab[n_task++] = t; - n_used++; + ttab[n_task++] = (proc_t*)(n_used++); } } - closeproc(PT); - pd = malloc(sizeof(proc_data_t)); pd->proc = ptab; pd->task = ttab; pd->nproc = n_proc; pd->ntask = n_task; - if(flags & PROC_LOOSE_TASKS){ + if(PT->flags & PROC_LOOSE_TASKS){ pd->tab = ttab; pd->n = n_task; }else{ pd->tab = ptab; pd->n = n_proc; } + // change array indexes to pointers + while(n_proc--) ptab[n_proc] = data+(long)(ptab[n_proc]); + while(n_task--) ttab[n_task] = data+(long)(ttab[n_task]); return pd; } diff --git a/proc/readproc.h b/proc/readproc.h index 21a4964a..e1ad75bd 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -152,7 +152,10 @@ typedef struct proc_t { typedef struct PROCTAB { DIR* procfs; +// char deBug0[64]; DIR* taskdir; // for threads +// char deBug1[64]; + pid_t taskdir_user; // for threads int did_fake; // used when taskdir is missing int(*finder)(struct PROCTAB *restrict const, proc_t *restrict const); proc_t*(*reader)(struct PROCTAB *restrict const, proc_t *restrict const); @@ -181,7 +184,7 @@ typedef struct proc_data_t { int ntask; } proc_data_t; -extern proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), int flags, ... /* same as openproc */ ); +extern proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t *buf), PROCTAB *restrict const PT); // Convenient wrapper around openproc and readproc to slurp in the whole process // table subset satisfying the constraints of flags and the optional PID list. diff --git a/ps/display.c b/ps/display.c index d4892463..47fd4270 100644 --- a/ps/display.c +++ b/ps/display.c @@ -302,11 +302,13 @@ static void lists_and_needs(void){ /***** fill in %CPU; not in libproc because of include_dead_children */ /* Note: for sorting, not display, so 0..0x7fffffff would be OK */ -static void fill_pcpu(proc_t *buf){ +static int want_this_proc_pcpu(proc_t *buf){ unsigned long long used_jiffies; unsigned long pcpu = 0; unsigned long long avail_jiffies; + if(!want_this_proc(buf)) return 0; + used_jiffies = buf->utime + buf->stime; if(include_dead_children) used_jiffies += (buf->cutime + buf->cstime); @@ -314,6 +316,8 @@ static void fill_pcpu(proc_t *buf){ if(avail_jiffies) pcpu = (used_jiffies << 24) / avail_jiffies; buf->pcpu = pcpu; // fits in an int, summing children on 128 CPUs + + return 1; } /***** just display */ @@ -469,6 +473,11 @@ not_root: /* don't free the array because it takes time and ps will exit anyway */ } +static int want_this_proc_nop(proc_t *dummy){ + (void)dummy; + return 1; +} + /***** sorted or forest */ static void fancy_spew(void){ proc_t *retbuf = NULL; @@ -480,23 +489,27 @@ static void fancy_spew(void){ fprintf(stderr, "can't have threads with sorting or forest output\n"); exit(49); } +#endif ptp = openproc(needs_for_format | needs_for_sort | needs_for_select | needs_for_threads); if(!ptp) { fprintf(stderr, "Error: can not access /proc.\n"); exit(1); } +#if 0 while((retbuf = readproc(ptp,retbuf))){ - if(want_this_proc(retbuf)){ - fill_pcpu(retbuf); // in case we might sort by %cpu + if(want_this_proc_pcpu(retbuf)){ +// fill_pcpu(retbuf); // in case we might sort by %cpu processes[n++] = retbuf; retbuf = NULL; // NULL asks readproc to allocate } } if(retbuf) free(retbuf); - closeproc(ptp); #else - // FIXME: need pcpu - pd = readproctab2(want_this_proc, want_this_proc, needs_for_format | needs_for_sort | needs_for_select | needs_for_threads); + if(thread_flags & TF_loose_tasks){ + pd = readproctab2(want_this_proc_nop, want_this_proc_pcpu, ptp); + }else{ + pd = readproctab2(want_this_proc_pcpu, (void*)0xdeadbeaful, ptp); + } n = pd->n; processes = pd->tab; #endif @@ -505,6 +518,7 @@ static void fancy_spew(void){ qsort(processes, n, sizeof(proc_t*), compare_two_procs); if(forest_type) show_forest(n); else show_proc_array(ptp,n); + closeproc(ptp); } diff --git a/ps/sortformat.c b/ps/sortformat.c index 010f70a3..11d65a3c 100644 --- a/ps/sortformat.c +++ b/ps/sortformat.c @@ -800,11 +800,11 @@ const char *process_sf_options(int localbroken){ // If nothing else, try to use $PS_FORMAT before the default. if(!format_flags && !format_modifiers && !format_list){ char *tmp; - if(thread_flags&TF_must_use) return "Tell procps-feedback@sf.net what you want. (-L/-T, -m/m/H, and $PS_FORMAT)"; tmp = getenv("PS_FORMAT"); /* user override kills default */ if(tmp && *tmp){ const char *err; sf_node sfn; + if(thread_flags&TF_must_use) return "Tell procps-feedback@sf.net what you want. (-L/-T, -m/m/H, and $PS_FORMAT)"; sfn.sf = tmp; sfn.f_cooked = NULL; err = format_parse(&sfn);