case_Pid:
P->tid = strtol(S,&S,10);
continue;
+ case_Threads:
+ P->nlwp = strtol(S,&S,10);
+ continue;
case_ShdPnd:
memcpy(ShdPnd, S, 16);
"%d %d %d %d %d "
"%lu %lu %lu %lu %lu "
"%Lu %Lu %Lu %Lu " /* utime stime cutime cstime */
- "%ld %ld %ld %ld "
+ "%ld %ld "
+ "%d "
+ "%ld "
"%Lu " /* start_time */
"%lu "
"%ld "
&P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid,
&P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt,
&P->utime, &P->stime, &P->cutime, &P->cstime,
- &P->priority, &P->nice, &P->timeout, &P->it_real_value,
+ &P->priority, &P->nice,
+ &P->nlwp,
+ &P->it_real_value,
&P->start_time,
&P->vsize,
&P->rss,
}
HIDDEN_ALIAS(readproc);
+HIDDEN_ALIAS(readtask);
/* Convenient wrapper around openproc and readproc to slurp in the whole process
* table subset satisfying the constraints of flags and the optional PID list.
closeproc(PT);
return tab;
}
+
+// 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_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;
+ unsigned n_task_alloc = 0;
+ va_list ap;
+ proc_data_t *pd;
+
+ 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;
+
+ 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);
+
+ for(;;){
+ proc_t *tmp;
+ if(n_alloc == n_used){
+ //proc_t *old = data;
+ n_alloc = n_alloc*5/4+30; // grow by over 25%
+ data = realloc(data,sizeof(proc_t)*n_alloc);
+ //if(!data) return NULL;
+ }
+ if(n_proc_alloc == n_proc){
+ //proc_t **old = ptab;
+ n_proc_alloc = n_proc_alloc*5/4+30; // grow by over 25%
+ ptab = realloc(ptab,sizeof(proc_t*)*n_proc_alloc);
+ //if(!ptab) return NULL;
+ }
+ tmp = readproc_direct(PT, data+n_used);
+ if(!tmp) break;
+ if(!want_proc(tmp)) continue;
+ ptab[n_proc++] = tmp;
+ n_used++;
+ if(!( PT->flags & PROC_LOOSE_TASKS )) continue;
+ for(;;){
+ proc_t *t;
+ if(n_alloc == n_used){
+ //proc_t *old = data;
+ n_alloc = n_alloc*5/4+30; // grow by over 25%
+ data = realloc(data,sizeof(proc_t)*n_alloc);
+ //if(!data) return NULL;
+ }
+ if(n_task_alloc == n_task){
+ //proc_t **old = ttab;
+ n_task_alloc = n_task_alloc*5/4+1; // grow by over 25%
+ ttab = realloc(ttab,sizeof(proc_t*)*n_task_alloc);
+ //if(!ttab) return NULL;
+ }
+ t = readtask_direct(PT, tmp, data+n_used);
+ if(!t) break;
+ if(!want_task(t)) continue;
+ ttab[n_task++] = 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){
+ pd->tab = ttab;
+ pd->n = n_task;
+ }else{
+ pd->tab = ptab;
+ pd->n = n_proc;
+ }
+
+ return pd;
+}
+
#endif
long
priority, // stat kernel scheduling priority
- timeout, // stat ?
nice, // stat standard unix nice level of process
rss, // stat resident set size from /proc/#/stat (pages)
it_real_value, // stat ?
int
pgrp, // stat process group id
session, // stat session id
+ nlwp, // stat,status number of threads, or 0 if no clue
tgid, // (special) task group ID, the POSIX PID (see also: tid)
tty, // stat full device number of controlling terminal
euid, egid, // stat(),status effective
// initialize a PROCTAB structure holding needed call-to-call persistent data
extern PROCTAB* openproc(int flags, ... /* pid_t*|uid_t*|dev_t*|char* [, int n] */ );
+typedef struct proc_data_t {
+ proc_t **tab;
+ proc_t **proc;
+ proc_t **task;
+ int n;
+ int nproc;
+ 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 */ );
// Convenient wrapper around openproc and readproc to slurp in the whole process
// table subset satisfying the constraints of flags and the optional PID list.
CMP_INT(cutime)
CMP_INT(cstime)
CMP_SMALL(priority) /* nice */
-CMP_INT(timeout)
+CMP_SMALL(nlwp)
CMP_SMALL(nice) /* priority */
CMP_INT(rss) /* resident set size from stat file */ /* vm_rss, resident */
CMP_INT(it_real_value)
return 6;
}
-static int pr_timeout(char *restrict const outbuf, const proc_t *restrict const pp){
- return old_time_helper(outbuf, pp->timeout, seconds_since_boot*Hertz);
-}
-
static int pr_alarm(char *restrict const outbuf, const proc_t *restrict const pp){
return old_time_helper(outbuf, pp->it_real_value, 0ULL);
}
return snprintf(outbuf, width, "%s", pp->suser);
}
-
-static int pr_thread(char *restrict const outbuf, const proc_t *restrict const pp){ /* TID tid LWP lwp SPID spid */
+// TID tid LWP lwp SPID spid
+static int pr_thread(char *restrict const outbuf, const proc_t *restrict const pp){
return snprintf(outbuf, COLWID, "%u", pp->tid);
}
-static int pr_nlwp(char *restrict const outbuf, const proc_t *restrict const pp){ /* THCNT thcount NLWP nlwp */
- (void)pp; // FIXME
- return snprintf(outbuf, COLWID, "-"); /* for now... FIXME */
+// thcount THCNT
+static int pr_nlwp(char *restrict const outbuf, const proc_t *restrict const pp){
+ return snprintf(outbuf, COLWID, "%d", pp->nlwp);
}
static int pr_sess(char *restrict const outbuf, const proc_t *restrict const pp){
{"ni", "NI", pr_nice, sr_nice, 3, 0, BSD, TO|RIGHT}, /*nice*/
{"nice", "NI", pr_nice, sr_nice, 3, 0, U98, TO|RIGHT}, /*ni*/
{"nivcsw", "IVCSW", pr_nop, sr_nop, 5, 0, XXX, AN|RIGHT},
-{"nlwp", "NLWP", pr_nlwp, sr_nop, 4, 0, SUN, AN|RIGHT},
+{"nlwp", "NLWP", pr_nlwp, sr_nlwp, 4, 0, SUN, AN|RIGHT},
{"nsignals", "NSIGS", pr_nop, sr_nop, 5, 0, DEC, AN|RIGHT}, /*nsigs*/
{"nsigs", "NSIGS", pr_nop, sr_nop, 5, 0, BSD, AN|RIGHT}, /*nsignals*/
{"nswap", "NSWAP", pr_nop, sr_nswap, 5, 0, XXX, AN|RIGHT},
{"systime", "SYSTEM", pr_nop, sr_nop, 6, 0, DEC, ET|RIGHT},
{"sz", "SZ", pr_sz, sr_nop, 5, 0, HPU, PO|RIGHT},
{"tdev", "TDEV", pr_nop, sr_nop, 4, 0, XXX, AN|RIGHT},
-{"thcount", "THCNT", pr_nlwp, sr_nop, 5, 0, AIX, AN|RIGHT},
+{"thcount", "THCNT", pr_nlwp, sr_nlwp, 5, 0, AIX, AN|RIGHT},
{"tid", "TID", pr_thread, sr_tid, 5, 0, AIX, TO|PIDMAX|RIGHT},
{"time", "TIME", pr_time, sr_nop, 8, 0, U98, ET|CUMUL|RIGHT}, /*cputime*/ /* was 6 wide */
-{"timeout", "TMOUT", pr_timeout, sr_timeout, 5, 0, LNX, AN|RIGHT},
-{"tmout", "TMOUT", pr_timeout, sr_timeout, 5, 0, LNX, AN|RIGHT},
+{"timeout", "TMOUT", pr_nop, sr_nop, 5, 0, LNX, AN|RIGHT}, // 2.0.xx era
+{"tmout", "TMOUT", pr_nop, sr_nop, 5, 0, LNX, AN|RIGHT}, // 2.0.xx era
{"tname", "TTY", pr_tty8, sr_tty, 8, 0, DEC, PO|LEFT},
{"tpgid", "TPGID", pr_tpgid, sr_tpgid, 5, 0, XXX, PO|PIDMAX|RIGHT},
{"trs", "TRS", pr_trs, sr_trs, 4, MEM, AIX, PO|RIGHT},