]> granicus.if.org Git - procps-ng/commitdiff
sorted threads might work
authoralbert <>
Sun, 19 Oct 2003 23:37:47 +0000 (23:37 +0000)
committeralbert <>
Sun, 19 Oct 2003 23:37:47 +0000 (23:37 +0000)
proc/readproc.c
proc/readproc.h
ps/display.c
ps/sortformat.c

index 85b75804cbe22868a8d2392c4d486c9fe1daed83..2dd46da9eac1ecd6071d9d5b0bc021765583213b 100644 (file)
@@ -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;
 }
index 21a4964abc83c948d81208a14071720db504864d..e1ad75bd8a5f2b08ea173ff306f35493cd528013 100644 (file)
@@ -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.
index d4892463e74b2d0ca74290270d82b1c1eb2a671b..47fd4270a5726cbeeda7462515acf24704d3184c 100644 (file)
@@ -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);
 }
 
 
index 010f70a35acde795e63f4754749d1d872bac14a6..11d65a3c2982f558b672ed6b01fac045a22d8646 100644 (file)
@@ -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);