[Orca-checkins] r403 - in trunk/orca/lib/SE: 3.2.1 3.3 3.3.1

dmberezin at hotmail.com dmberezin at hotmail.com
Wed Nov 17 14:56:14 PST 2004


Author: dmberezin at hotmail.com
Date: Wed Nov 17 14:52:09 2004
New Revision: 403

Added:
   trunk/orca/lib/SE/3.2.1/orca_process_class.se
   trunk/orca/lib/SE/3.3.1/orca_process_class.se
   trunk/orca/lib/SE/3.3/orca_process_class.se
Log:
Add process_class.se from SE Toolkit to orca distribution

* lib/SE/3.2.1/orca_process_class.se
* lib/SE/3.3.1/orca_process_class.se
* lib/SE/3.3/orca_process_class.se
  Add a copy of process_class.se as orca_process_class.se for future bug fixing.


Added: trunk/orca/lib/SE/3.2.1/orca_process_class.se
==============================================================================
--- (empty file)
+++ trunk/orca/lib/SE/3.2.1/orca_process_class.se	Wed Nov 17 14:52:09 2004
@@ -0,0 +1,909 @@
+//
+//    Copyright (c) 1995-1998, by Sun Microsystems, Inc. 
+//      All Rights Reserved
+//
+
+#ifndef _PROCESS_CLASS_SE_
+#define _PROCESS_CLASS_SE_
+
+// 16 Oct 01 richp - more clean ups, some fields not being computed
+// 19 Sep 01 richp - replaced struct_fill and changed long to pointer_t
+// process class 19 Feb 98 Adrian - 2.6 extras added
+// measured and sampled cpu comparison version 18/5/98
+// vmem_delta added for process_rules 27 Nov 98
+// added processor set info 16 Apr 99
+// merged rules version 22 Apri 99
+// added lwp info 5-27-99 Rick Weisner
+// added PCUNSET 11-05-99 Rick Weisner
+// added se_trees 08-2000 Rick Weisner
+// patched linked list login Jul 2001 Rick Weisner
+
+// Obtain data averaged over the interval between updates
+// return one process at a time, snapshot all good stuff
+// in one update then provide index$, pid$ methods to extract groups
+// of processes.
+// Store data in raw form taken from psinfo and pusage ioctls, and
+// process it when called up by class. Feeds data to workload_class.se
+
+
+#if MINOR_VERSION < 60
+# error "process_class only works on 2.6 or newer"
+#endif
+
+#include <se_trees.se>
+
+long msaccton[2]  = { PCSET, PR_MSACCT | PR_MSFORK };
+long msacctoff[2] = { PCUNSET, PR_MSACCT };
+
+// codes for action$
+#define PROC_ACTION_INIT        0       // starting point -> next index
+#define PROC_ACTION_PID         1       // get the specified pid
+                                        // do not sample all PIDS
+#define PROC_ACTION_NEXT_INDEX  2       // index order is based on /proc
+#define PROC_ACTION_NEXT_PID    3       // search for pid and return data
+                                        // do sample all PIDS
+#define PROC_ACTION_NEXT_LWP    4       // search for lwp and return data
+
+// index$ returns -1 if no more data
+// proc data updates if index$ is -1
+
+struct pr_header_t {
+  long number_lwps;
+  size_t size_of_entries;
+};
+
+struct lwp_prusage {
+  prusage_t lwp_pru;
+  long next_lwp_pru;
+};
+
+struct raw_proc_info_t {       // all the per process info
+  pointer_t       orp;         // old prusage_t pointer
+  pointer_t       nrp;         // new prusage_t pointer
+  long            nextpid;     // next pid in list
+  long            gencnt;      // update generation counter
+  // stuff from prpsinfo_t
+  long            pr_flag;     // process flags
+  long            pr_size;     // size of process image in pages
+  long            pr_oldsize;  // previous size of process image
+  long            pr_rssize;   // resident set size in pages
+  long            pr_pri;      // priority, high value is high priority
+  char            pr_nice;     // nice for cpu usage
+  char            pr_sname;    // printable character representing pr_state
+  timestruc_t     o_pr_time;   // old sampled user+system CPU time
+  timestruc_t     n_pr_time;   // sampled user+system CPU time
+  timestruc_t     o_pr_ctime;  // old usr+sys cpu time for reaped children
+  timestruc_t     n_pr_ctime;  // new usr+sys cpu time for reaped children
+  long            pr_uid;      // real user id
+  long            pr_ppid;     // process id of parent
+  int             pr_bindpset; // processor set binding
+#define PRCLSZ 8
+  char            pr_clname[PRCLSZ]; // scheduling class name
+#define PRFNSZ 16
+  char            pr_fname[PRFNSZ];  // last component of execed pathname
+#define PRARGSZ 80
+  char            pr_psargs[PRARGSZ];// initial characters of arg list
+  int             lwp_count;
+  pointer_t       olwp;  // pointers to prev. lwp prusage linked list
+  pointer_t       nlwp;  // pointers to current lwp prusage linked list
+};
+
+struct  lwp_pr_info {
+  int     lwp_id;         // always contains  lwp_id
+  double  timestamp;      // last time lwp was measured
+  double  creation;       // lwp start time
+  double  termination;    // lwp termination time stamp
+  double  user_time;      // user time in this interval
+  double  system_time;    // system call time in this interval
+  double  trap_time;      // system trap time in interval
+  double  text_pf_time;   // text page fault wait in interval
+  double  data_pf_time;   // data page fault wait in interval
+  double  kernel_pf_time; // kernel page fault wait in interval
+  double  user_lock_time; // user lock wait in interval
+  double  sleep_time;     // all other sleep time
+  double  cpu_wait_time;  // time on runqueue waiting for CPU
+  double  stoptime;       // time stopped from ^Z
+  ulong   syscalls;       // syscall/interval for this process
+  ulong   maj_faults;     // majf/interval
+  ulong   min_faults;     // minf/interval
+  ulong   total_swaps;    // swapout count
+  ulong   inblocks;       // input blocks/interval
+  ulong   outblocks;      // output blocks/interval
+  ulong   messages;       // msgin+msgout/interval
+  ulong   signals;        // signals/interval
+  ulong   vcontexts;      // voluntary context switches/interval
+  ulong   icontexts;      // in-ditto
+  ulong   charios;        // characters in and out/interval
+  ulong   next_class;
+};
+// the process class that does all the real work
+
+// get both types of hires timestamp into a common more useful form
+#define timestruc(t) (t.tv_sec + (t.tv_nsec / 1000000000.0))
+#define timeval(t) (t.tv_sec + (t.tv_usec / 1000000.0))
+#define hr_min_sec(t) sprintf("%.3f", timestruc(t))
+
+// double timestruc(timestruc_t ts_time) {
+//   return ts_time.tv_sec + (ts_time.tv_nsec / 1000000000.0);
+// }
+
+// double timeval(timeval_t tv_time) {
+//   return tv_time.tv_sec + (tv_time.tv_usec / 1000000.0);
+// }
+
+// string hr_min_sec(timestruc_t ts) {
+//   char buf[80];
+//   double tmp;
+//   tmp = timestruc(ts);
+//   buf = sprintf("%.3f", tmp);
+//   return buf;
+// }
+
+msprint(prusage_t pru, int pid, string cmd, string arg) {
+    puts("\n--------------- BEGIN ----------------");
+    printf("%d %s %s\n", pid, cmd, arg);
+    printf("Elapsed time        %12s  ", hr_min_sec(pru.pr_rtime));
+    printf("Create time %s Timestamp %s\n", hr_min_sec(pru.pr_create),
+            hr_min_sec(pru.pr_tstamp));
+    printf("User CPU time       %12s  ", hr_min_sec(pru.pr_utime));
+    printf("System call time    %12s\n", hr_min_sec(pru.pr_stime));
+    printf("System trap time    %12s  ", hr_min_sec(pru.pr_ttime));
+    printf("Text pfault sleep   %12s\n", hr_min_sec(pru.pr_tftime));
+    printf("Data pfault sleep   %12s  ", hr_min_sec(pru.pr_dftime));
+    printf("Kernel pfault sleep %12s\n", hr_min_sec(pru.pr_kftime));
+    printf("User lock sleep     %12s  ", hr_min_sec(pru.pr_ltime));
+    printf("Other sleep time    %12s\n", hr_min_sec(pru.pr_slptime));
+    printf("Wait for CPU time   %12s  ", hr_min_sec(pru.pr_wtime));
+    printf("Stopped time        %12s\n", hr_min_sec(pru.pr_stoptime));
+    printf("pf %d mf %d sw %d inb %d oub %d ms %d mr %d\n",
+            pru.pr_minf, pru.pr_majf, pru.pr_nswap, pru.pr_inblk, pru.pr_oublk,
+            pru.pr_msnd, pru.pr_mrcv);
+    printf("sig %d vctx %d ictx %d sysc %d ioch %d\n",
+            pru.pr_sigs, pru.pr_vctx, pru.pr_ictx, pru.pr_sysc, pru.pr_ioch);
+    puts("---------------- END -----------------");
+}
+
+class proc_class_t {
+  // input controls
+  int     index$;         // always contains current index or -1
+  int     pid$;           // always contains current pid
+  // for ACTION_PID mode set pid$ and set index$ to -1 to get new data
+  int     action$;
+  int     off$;
+  int     wantlwp$;       // 0 = do not want lwps, 1 = want lsps
+  // summary totals
+  double  lasttime;       // timestamp for the end of the last update
+  int     nproc;          // current number of processes
+  int     newproc;
+  int     deadproc;
+  int     missedproc;     // number of fork+vfork - newproc
+  // output data for specified process
+  long    flags;          // latest pr_flag for the process
+  double  interval;       // measured time interval for averages
+  double  timestamp;      // last time process was measured
+  double  creation;       // process start time
+  double  termination;    // process termination time stamp
+  double  elapsed;        // elapsed time for all lwps in process
+  double  total_user;     // current totals in seconds
+  double  total_system;
+  double  total_sampled_cpu;
+  double  total_child;
+  double  user_time;      // user time in this interval
+  double  system_time;    // system call time in this interval
+  double  sampled_cpu;    // total sampled cpu time
+  double  trap_time;      // system trap time in interval
+  double  child_time;     // child CPU in this interval
+  double  text_pf_time;   // text page fault wait in interval
+  double  data_pf_time;   // data page fault wait in interval
+  double  kernel_pf_time; // kernel page fault wait in interval
+  double  user_lock_time; // user lock wait in interval
+  double  sleep_time;     // all other sleep time
+  double  cpu_wait_time;  // time on runqueue waiting for CPU
+  double  stoptime;       // time stopped from ^Z
+  ulong   syscalls;       // syscall/interval for this process
+  ulong   inblocks;       // input blocks/interval
+  ulong   outblocks;      // output blocks/interval
+  ulong   vmem_size;      // size in KB
+  long    vmem_delta;     // size change in KB
+  ulong   rmem_size;      // RSS in KB
+#ifdef XMAP
+  ulong   pmem_size;      // private mem in KB
+  ulong   smem_size;      // shared mem in KB
+#endif
+  ulong   maj_faults;     // majf/interval
+  ulong   min_faults;     // minf/interval
+  ulong   total_swaps;    // swapout count
+  long    priority;       // current sched priority
+  long    niceness;       // current nice value
+  char    sched_class[PRCLSZ];    // name of class
+  ulong   messages;       // msgin+msgout/interval
+  ulong   signals;        // signals/interval
+  ulong   vcontexts;      // voluntary context switches/interval
+  ulong   icontexts;      // in-ditto
+  ulong   charios;        // characters in and out/interval
+  ulong   lwp_count;      // number of lwps for the process
+  int     uid;            // current uid
+  long    ppid;           // parent pid
+  int     bindpset;       // processor set binding
+  char    fname[PRFNSZ];  // last components of exec'd pathname
+  char    args[PRARGSZ];  // initial part of arg list
+  ulong   lwp_class_ptr;  // head of linked list of lwp_class_ptrs
+
+  proc$() {
+    ulong_t MAX_PID;
+    ulong_t pp;             // pointer to malloc for raw proc info
+    ulong_t pp_tmp;         // temp pointer to malloc for raw proc info
+    ulong_t pp_ret;         // temp pointer to malloc for raw proc info
+                            // chained using nextpid
+    ulong_t pp_tree;
+    raw_proc_info_t rpi;
+    raw_proc_info_t t_rpi;
+    prusage_t   ou;         // old and new usage data
+#define NU      nu[0]
+    prusage_t   nu[1];      // array of one for read and ioctl
+#define PS      ps[0]
+    psinfo_t    ps[1];      // format changes when read used
+    pr_header_t prh;
+    prusage_t   plwp;
+    ulong pnu;
+    ulong pps;
+    int   i;
+    dirent_t directory_data;
+    ulong directory_pointer;
+    ulong directory_entry;
+    ulong_t tag;
+    int process_number;   // current link in chain
+    int first_process;    // fixed first link in search chain
+    int previous_process; // last one used to build chain
+    int next_process;     // next pid
+    int broken_chain;     // flag that chain changed this time
+    int cleaning_chain;   // flag that we are in cleanup mode
+    int pfd;
+    int lfd; // file descriptor for /prod/PID/lusage
+    char procname[64];
+    char lwpname[64];     // String for /prod/PID/lusage
+    long gen;             // number of generations of update
+    int err;
+    int new_entry;
+    ulong tmp;
+    double dtmp;
+    timeval_t tmp_tval[1];
+    int pg_to_kb;
+
+    // lwp working storage
+    prusage_t lwp_info;
+    pointer_t lwp_t_ptr;
+    pointer_t olwp_t_ptr;
+    lwp_prusage lwp_t_struct;
+    lwp_prusage olwp_t_struct;
+    lwp_pr_info lwp_t_class;
+    long lwp_t_class_ptr;
+    int ircw;
+
+// **********************************************************
+
+    if (action$ == PROC_ACTION_INIT) {
+      action$ = PROC_ACTION_NEXT_INDEX;
+      // open the directory containing the process data
+      directory_pointer = opendir("/proc");
+      index$ = -1;
+      off$ = 0 ;
+      gen = -1;
+      wantlwp$ = 0;
+      first_process=-1;
+      gettimeofday(tmp_tval,0);
+      lasttime = timeval(tmp_tval[0]);
+      pg_to_kb = sysconf(_SC_PAGESIZE) / 1024;
+      pp_tree= int2int_init();
+      if (pnu == 0 || pps == 0) {
+        pnu = malloc(sizeof(nu));
+        pps = malloc(sizeof(ps));
+      }
+      return;
+    }
+
+    if (index$ == -1) {   // update the data from /proc
+      // read the first entry in the directory
+      rewinddir(directory_pointer);
+      directory_entry = readdir(directory_pointer); // read .
+      directory_entry = readdir(directory_pointer); // read ..
+      directory_entry = readdir(directory_pointer);
+      MAX_PID=0;
+      nproc = 0;
+      newproc = 0;
+      deadproc = 0;
+      gen++;
+      previous_process = -1;
+      broken_chain = 0;
+      cleaning_chain = 0;
+      while(directory_entry != NULL) {
+        directory_data = *((dirent_t *) directory_entry);
+        // get the process number and open the data file
+        // only look at specified process
+        if (action$ == PROC_ACTION_PID) {
+          process_number = pid$;
+          directory_entry = NULL;
+        } else {
+          process_number = atoi(directory_data.d_name);
+        }
+        procname = sprintf("/proc/%d/usage", process_number);
+        pfd = open(procname, O_RDONLY, 0);
+        // file cannot be accessed if pfd = -1; ignore this process
+        // may be that there is no permission or just died
+        if (pfd != -1) { // start of good pfd
+          if ( process_number > MAX_PID ) {
+            MAX_PID = process_number ;
+          }
+          tag = process_number;
+          pp_tmp = NULL ;
+          pp_ret = int2int_get(pp_tree, tag);
+          if ( pp_ret != NULL) {
+            pp_tmp = ((ulong_t) *((ulong_t *) pp_ret));
+            // Process Found
+          }
+          if (pp_tmp == NULL) {
+            // load the tree , new process
+            pp = malloc(sizeof(rpi));
+            memset(pp, 0, sizeof(rpi));
+            new_entry = 1;
+            broken_chain = 1;
+            pp_ret= int2int_put(pp_tree, tag, pp);
+            if ( pp_ret < 0 ) {
+              printf(" Error unable to insert into tree %d, %d , %x\n",
+                       pp_ret, tag, pp);
+              exit(1);
+            }
+            pp_ret = int2int_get(pp_tree, tag);
+            pp_tmp = ((ulong_t) *((ulong_t *) pp_ret));
+            if ( pp != pp_tmp) {
+              printf(" Error pointers do not match %x, %x \n",
+                       pp, pp_tmp);
+              exit(1);
+            }
+          } else {
+            new_entry = 0;
+            // Process Found
+          }
+
+          // get the existing or blank data
+          tag = process_number;
+          pp_ret = int2int_get(pp_tree, tag);
+          if ( pp_ret== NULL) {
+            printf(" Error pointer not found for process_number %d\n",
+                     tag);
+            exit(1);
+          }
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+          if ( pp == NULL) {
+            printf("process_number %d  invalid2 \n", process_number);
+            exit(1);
+          }
+          rpi = *((raw_proc_info_t *) pp);
+
+          // read usage info directly
+          // 2.6 specific, can read usage and psinfo without needing
+          // ownership or permissions on /proc entry but can't read
+          // directly into SE structure so go via malloc buffers
+
+          err = read(pfd, pnu, sizeof(nu));
+          close(pfd);
+
+          // turn on msacct
+
+          procname = sprintf("/proc/%d/ctl", process_number);
+          pfd = open(procname, O_WRONLY, 0);
+          if (pfd != -1) {
+            if ( off$ == 0 ) {
+              write(pfd, &msaccton, sizeof(msaccton));
+            } else {
+              printf("%d ms accounting off \n", process_number );
+              write(pfd, &msacctoff, sizeof(msaccton));
+            }
+            close(pfd);
+          }
+
+          // get usage
+          procname = sprintf("/proc/%d/psinfo", process_number);
+          pfd = open(procname, O_RDONLY, 0);
+          err += read(pfd, pps, sizeof(ps));
+          NU = *((prusage_t *) pnu);
+          PS = *((psinfo_t *) pps);
+          close(pfd);
+          if (err == 0) {
+            // process went away since directory was opened
+            // unlikely but still need to tidy up mallocs
+            // when it is a new entry
+            if ( new_entry == 1 ) {
+              deadproc++;
+              free(pp);
+              tag = process_number;
+              pp_ret=int2int_put(pp_tree, tag, NULL);
+              if ( pp_ret < 0 ) {
+                printf("unable to free tag = %d \n",tag);
+                exit(1);
+              }
+            }
+            if (action$ == PROC_ACTION_PID) {
+              directory_entry = NULL;
+            } else {
+              directory_entry = readdir(directory_pointer);
+            }
+            continue;
+          } else { // good pfd
+
+// ***************************************************************
+
+            if ( wantlwp$ == 1 ) {
+              // read the lwp info
+              lwpname = sprintf("/proc/%d/lusage", process_number);
+              lfd = open(lwpname, O_RDONLY, 0);
+              if ( lfd > 0 ) {
+                lwp_t_ptr = malloc(sizeof(prh));
+                err = read(lfd, lwp_t_ptr, sizeof(prh));
+                prh = *((pr_header_t *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                if (err <= 0) {
+                  printf("Error reading pr_header %s error code = %d \n",
+                          lwpname, err);
+                } else { // good read of pr_head
+                  // if there is an old lwp linked list free it
+                  lwp_t_ptr = rpi.olwp ;
+                  while ( lwp_t_ptr != NULL ) {
+                    lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                    free(lwp_t_ptr);
+                    lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+                  }
+                  rpi.olwp = rpi.nlwp;
+                  rpi.nlwp = NULL;
+                  // create new lwp linked list
+                  for (ircw=0; ircw<prh.number_lwps; ircw++) {
+                    lwp_t_ptr = malloc(prh.size_of_entries);
+                    err = read(lfd, lwp_t_ptr, prh.size_of_entries);
+                    if (err <= 0 ) {
+                      printf("Error reading pr lwp %d/n", i);
+                      free(lwp_t_ptr);
+                    } else {
+                      if ( ircw != -1 ) {
+                        lwp_info = *((prusage_t *) lwp_t_ptr);
+                        free(lwp_t_ptr);
+                        lwp_t_ptr=malloc(sizeof(lwp_t_struct));
+                        memset(lwp_t_ptr, NULL, sizeof(lwp_t_struct));
+                        struct_empty(lwp_info, lwp_t_ptr);
+                        lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                        lwp_t_struct.next_lwp_pru = rpi.nlwp;
+                        struct_empty(lwp_t_struct, lwp_t_ptr);
+                        rpi.nlwp = lwp_t_ptr;
+                      } else {
+                        free(lwp_t_ptr);
+                      }
+                    }
+                  } // end for
+
+                  close(lfd);
+
+                } // end else on bad pr header read
+              } // good open on lfd
+            } // end of wantlwp
+// ********** lwp info read **************************************
+          } // good read on pfd
+
+          if (new_entry == 1 ) {
+            rpi.nextpid = first_process;
+            first_process = process_number;
+          }
+
+          // check to see if we are still dealing with the same process
+          //  we had before, and update and
+          if (new_entry == 1 || timestruc(PS.pr_start) > lasttime) {
+            newproc++;
+            if (new_entry == 0) {
+              // leftover from an old process at same pid
+              if (rpi.orp != NULL) {
+                free(rpi.orp);
+                rpi.orp = NULL;   // dump old rp, and overwrite new
+              }
+// ***************** delete old lwp info *********************
+              if ( wantlwp$ == 1 ) {
+                lwp_t_ptr = rpi.olwp ;
+                rpi.olwp = NULL;
+                while ( lwp_t_ptr != NULL ) {
+                  lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                  free(lwp_t_ptr);
+                  lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+                }
+              }
+// ***************** end delete old lwp info *********************
+            }
+            // static psinfo needs updating
+            rpi.pr_uid = PS.pr_uid;
+            rpi.pr_ppid = PS.pr_ppid;
+            rpi.pr_bindpset = PS.pr_lwp.pr_bindpset;
+            rpi.pr_clname = PS.pr_lwp.pr_clname;
+            rpi.pr_fname = PS.pr_fname;
+            rpi.pr_psargs = PS.pr_psargs;
+          }
+          // update usage data
+          tmp = rpi.orp;  // hang on to malloced data
+          rpi.orp = rpi.nrp;      // switch new to old
+          if (tmp == NULL) {
+            rpi.nrp = malloc(sizeof(ou));
+          } else {
+            rpi.nrp = tmp;
+          }
+          struct_empty(NU, rpi.nrp);      // save whole block
+          // update dynamic psinfo data
+          rpi.pr_oldsize = rpi.pr_size;
+          rpi.pr_size = PS.pr_size;
+          rpi.pr_rssize = PS.pr_rssize;
+          rpi.pr_pri = PS.pr_lwp.pr_pri;
+          rpi.pr_nice = PS.pr_lwp.pr_nice;
+          rpi.pr_sname = PS.pr_lwp.pr_sname;
+          rpi.pr_flag = PS.pr_flag;
+          rpi.o_pr_time = rpi.n_pr_time;
+          rpi.n_pr_time = PS.pr_time;
+          rpi.o_pr_ctime = rpi.n_pr_ctime;
+          rpi.n_pr_ctime = PS.pr_ctime;
+          rpi.gencnt = gen;
+          struct_empty(rpi, pp);
+          nproc++;
+          // printf("processed %d \n" , process_number );
+        } // end of good pfd
+        // step through the files in the directory ...
+        if (action$ == PROC_ACTION_PID) {
+          directory_entry = NULL;
+        } else {
+          directory_entry = readdir(directory_pointer);
+        }
+      } // end of directory
+// **************************************************************
+      // go through list and remove deadwood
+      // printf("first process_number %d  \n",first_process);
+      process_number = first_process;
+      next_process = -1;
+      previous_process = -1;
+      while ( process_number > 0 ) {
+        // printf("processing %d  \n",process_number);
+        if (process_number > 0 ) {
+          pp_ret = int2int_get(pp_tree, process_number);
+          if ( pp_ret == NULL) {
+            printf("unable to get process_number  %d \n", process_number);
+            exit(1);
+          }
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+          if ( pp == NULL) {
+            printf("process_number %d  invalid4 \n",process_number);
+            exit(1);
+          }
+          rpi = *((raw_proc_info_t *) pp); // rpi <- pp
+          next_process = rpi.nextpid;
+          // printf("next process %d  \n",next_process);
+          // unhook dead processes
+          if (rpi.gencnt != gen) {
+            deadproc++;
+            if (rpi.orp != NULL) {
+              free(rpi.orp);
+              rpi.orp = NULL;
+            }
+            if (rpi.nrp != NULL) {
+              free(rpi.nrp);
+              rpi.nrp = NULL;
+            }
+            if ( wantlwp$ == 1 ) {
+              lwp_t_ptr = rpi.olwp ;
+              while ( lwp_t_ptr != NULL ) {
+                lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+              }
+              lwp_t_ptr = t_rpi.nlwp ;
+              while ( lwp_t_ptr != NULL ) {
+                lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+              }
+            }
+            free(pp);
+            pp_ret = int2int_put(pp_tree, process_number , NULL);
+            if ( pp_ret < 0 ) {
+              printf("unable to free process_number \n");
+              exit(1);
+            }
+            if ( previous_process > 0 ) { // there was a previous process
+              pp_tmp = int2int_get(pp_tree, previous_process);
+              if ( pp_tmp == NULL) {
+                printf("unable to get process_number %d \n",
+                          previous_process);
+                exit(1);
+              }
+              pp = ((ulong_t) *((ulong_t *) pp_tmp));
+              if ( pp == NULL) {
+                 printf("process_number %d invalid5 \n",
+                         previous_process);
+                 exit(1);
+              }
+              rpi = *((raw_proc_info_t *) pp); // rpi <- pp
+              // printf("previous process %d  \n",previous_process);
+              rpi.nextpid = next_process;
+              struct_empty(rpi, pp);
+            } else {
+              first_process = next_process;
+            }
+          } else {
+            // update previous process ptr
+            previous_process = process_number;
+          }
+        }
+        process_number = next_process;
+      }
+      // printf(" end of deadwood removal \n");
+      gettimeofday(tmp_tval,0);
+      lasttime = timeval(tmp_tval[0]);
+      process_number = first_process;
+      index$ = -1;
+    }
+    // printf("done updating \n");
+    // printf("MAX_PID = %d \n", MAX_PID);
+// ****************************** end of update section *******************
+
+    if (action$ == PROC_ACTION_NEXT_INDEX ) {
+      // printf("PROC_ACTION_NEXT_INDEX \n");
+      if (index$ == -1) {
+        process_number = first_process;
+      } else {
+        process_number = rpi.nextpid;
+      }
+      if (process_number < 0 || process_number > MAX_PID) {
+        // ran out of data
+        process_number = -1;
+        index$ = -1;
+        pid$ = -1;
+        // printf(" thats all there is \n");
+        return;
+      }
+      index$++;
+    }
+
+    if (action$ == PROC_ACTION_NEXT_PID) {
+      // printf("PROC_ACTION_NEXT_PID \n");
+      if (index$ == -1) {
+        process_number = 0;
+      } else {
+        process_number++;
+      }
+      index$++;
+      // look for the next data
+      pp = NULL;
+      pp_ret=int2int_get(pp_tree,process_number);
+      if ( pp_ret != NULL ) {
+        pp = ((ulong_t) *((ulong_t *) pp_ret));
+      }
+      while (process_number < MAX_PID && pp == NULL) {
+        process_number++;
+        pp = NULL;
+        pp_ret=int2int_get(pp_tree,process_number);
+        if ( pp_ret != NULL ) {
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+        }
+      }
+      if (process_number < 0 || process_number > MAX_PID) {
+        // ran out of data
+        process_number = -1;
+        index$ = -1;
+        pid$ = -1;
+        // printf(" ran out of data NEXT PID \n");
+        return;
+      }
+    }
+
+    if (action$ == PROC_ACTION_PID) {
+      process_number = pid$;
+      index$ = 0;
+    }
+
+    // common code to update class once process has been chosen
+
+    pp_ret=int2int_get(pp_tree,process_number);
+    pp = NULL;
+    if (pp_ret != NULL) {
+      pp = ((ulong_t) *((ulong_t *) pp_ret));
+    }
+    if ( pp != NULL) {
+      rpi = *((raw_proc_info_t *) pp);
+      // make sure that all class data is updated
+      // index$ is already set
+      pid$ = process_number;
+      uid = rpi.pr_uid;
+      // nproc, , are already set
+      missedproc = rpi.nextpid; // for debug until fork counting
+
+      // nrp will always be set
+      NU = *((prusage_t *) rpi.nrp);
+      creation = timestruc(NU.pr_create);
+      timestamp = timestruc(NU.pr_tstamp);
+      termination = 0.0; // set later if process is dead
+      elapsed = timestruc(NU.pr_rtime);
+      total_user = timestruc(NU.pr_utime);
+      total_system = timestruc(NU.pr_stime);
+      total_child = timestruc(rpi.n_pr_ctime);
+      total_sampled_cpu = timestruc(rpi.n_pr_time);
+      flags = rpi.pr_flag;
+#ifdef PDEBUG
+      msprint(NU, pid$, rpi.pr_fname, rpi.pr_psargs);
+#endif
+      if (rpi.orp != NULL) {
+        ou = *((prusage_t *) rpi.orp);
+        interval = timestamp - timestruc(ou.pr_tstamp);
+        // interval should never be zero
+        if (interval == 0.0) {
+          printf("zero interval on pid %d state %c\n", pid$, rpi.pr_sname);
+          msprint(ou, pid$, fname, args);
+          interval = 1.0;
+        }
+        user_time = total_user - timestruc(ou.pr_utime);
+        system_time = total_system - timestruc(ou.pr_stime);
+        sampled_cpu = total_sampled_cpu - timestruc(rpi.o_pr_time);
+        trap_time = timestruc(NU.pr_ttime) - timestruc(ou.pr_ttime);
+        child_time = total_child - timestruc(rpi.o_pr_ctime);
+        text_pf_time = timestruc(NU.pr_tftime) - timestruc(ou.pr_tftime);
+        data_pf_time = timestruc(NU.pr_dftime) - timestruc(ou.pr_dftime);
+        kernel_pf_time = timestruc(NU.pr_kftime) - timestruc(ou.pr_kftime);
+        user_lock_time = timestruc(NU.pr_ltime) - timestruc(ou.pr_ltime);
+        sleep_time = timestruc(NU.pr_slptime) - timestruc(ou.pr_slptime);
+        cpu_wait_time = timestruc(NU.pr_wtime) - timestruc(ou.pr_wtime);
+        stoptime = timestruc(NU.pr_stoptime) - timestruc(ou.pr_stoptime);
+        syscalls = NU.pr_sysc - ou.pr_sysc;
+        inblocks = NU.pr_inblk - ou.pr_inblk;
+        outblocks = NU.pr_oublk - ou.pr_oublk;
+        maj_faults = NU.pr_majf - ou.pr_majf;
+        min_faults = NU.pr_minf - ou.pr_minf;
+        messages = (NU.pr_msnd + NU.pr_mrcv) - (ou.pr_msnd + ou.pr_mrcv);
+        signals = NU.pr_sigs - ou.pr_sigs;
+        vcontexts = NU.pr_vctx - ou.pr_vctx;
+        icontexts = NU.pr_ictx - ou.pr_ictx;
+        charios = NU.pr_ioch - ou.pr_ioch;
+      } else {
+        // new process will only have rpi.nrp set
+        interval = timestamp - creation; // elapsed time so far
+        if (interval == 0.0) {
+          printf("zero interval on pid %d state %c\n", pid$, rpi.pr_sname);
+          msprint(NU, pid$, fname, args);
+          interval = 1.0;
+        }
+        user_time = total_user;
+        system_time = total_system;
+        sampled_cpu = total_sampled_cpu;
+        trap_time = timestruc(NU.pr_ttime);
+        child_time = total_child;
+        text_pf_time = timestruc(NU.pr_tftime);
+        data_pf_time = timestruc(NU.pr_dftime);
+        kernel_pf_time = timestruc(NU.pr_kftime);
+        user_lock_time = timestruc(NU.pr_ltime);
+        sleep_time = timestruc(NU.pr_slptime);
+        cpu_wait_time = timestruc(NU.pr_wtime);
+        stoptime = timestruc(NU.pr_stoptime);
+        syscalls = NU.pr_sysc;
+        inblocks = NU.pr_inblk;
+        outblocks = NU.pr_oublk;
+        maj_faults = NU.pr_majf;
+        min_faults = NU.pr_minf;
+        messages = NU.pr_msnd + NU.pr_mrcv;
+        signals = NU.pr_sigs;
+        vcontexts = NU.pr_vctx;
+        icontexts = NU.pr_ictx;
+        charios = NU.pr_ioch;
+      }
+      vmem_size = rpi.pr_size;
+      vmem_delta = rpi.pr_size - rpi.pr_oldsize;
+      rmem_size = rpi.pr_rssize;
+      total_swaps = NU.pr_nswap;
+      priority = rpi.pr_pri;
+      niceness = rpi.pr_nice;
+      sched_class = rpi.pr_clname;
+      lwp_count = NU.pr_count;
+      ppid = rpi.pr_ppid;
+      bindpset = rpi.pr_bindpset;
+      fname = rpi.pr_fname;
+      if (fname == "" && rpi.pr_sname == 'Z') {
+        fname = "Zombie";
+        bindpset = -1;        // no pset, but Zomb defaults to 0
+      }
+      args = rpi.pr_psargs;
+      // bug in sched pid 0 gives 100% system time
+      if (pid$ == 0) {
+        total_system = 0.0;
+        system_time = 0.0;
+      }
+#ifdef PDEBUG
+      printf("interval %.5f\n", interval);
+#endif
+// *******************************************************
+      if ( wantlwp$ == 1 ) {
+        // process lwp info
+        lwp_t_ptr = lwp_class_ptr;
+        lwp_class_ptr = NULL;
+        // if there is an old lwp class linked list free it
+        while ( lwp_t_ptr != NULL ) {
+          lwp_t_class = *((lwp_pr_info *) lwp_t_ptr);
+          free(lwp_t_ptr);
+          lwp_t_ptr = lwp_t_class.next_class ;
+        }
+        // Process lwp information
+        if ( rpi.nlwp != NULL ) {
+          lwp_t_ptr = rpi.nlwp ;
+          while ( lwp_t_ptr != NULL) {
+            lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+            lwp_t_class.lwp_id = lwp_t_struct.lwp_pru.pr_lwpid;
+            lwp_t_class.timestamp = timestruc(lwp_t_struct.lwp_pru.pr_tstamp);
+            lwp_t_class.creation = timestruc(lwp_t_struct.lwp_pru.pr_create);
+            lwp_t_class.termination = timestruc(lwp_t_struct.lwp_pru.pr_term);
+            lwp_t_class.user_time = timestruc(lwp_t_struct.lwp_pru.pr_utime);
+            lwp_t_class.system_time = timestruc(lwp_t_struct.lwp_pru.pr_stime) + timestruc(lwp_t_struct.lwp_pru.pr_ttime);
+            lwp_t_class.text_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_tftime) ;
+            lwp_t_class.data_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_dftime) ;
+            lwp_t_class.kernel_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_kftime) ;
+            lwp_t_class.user_lock_time = timestruc(lwp_t_struct.lwp_pru.pr_ltime) ;
+            lwp_t_class.sleep_time = timestruc(lwp_t_struct.lwp_pru.pr_slptime) ;
+            lwp_t_class.cpu_wait_time = timestruc(lwp_t_struct.lwp_pru.pr_wtime) ;
+            lwp_t_class.stoptime = timestruc(lwp_t_struct.lwp_pru.pr_stoptime) ;
+            lwp_t_class.min_faults = lwp_t_struct.lwp_pru.pr_minf ;
+            lwp_t_class.maj_faults = lwp_t_struct.lwp_pru.pr_majf ;
+            lwp_t_class.total_swaps = lwp_t_struct.lwp_pru.pr_nswap;
+            lwp_t_class.inblocks = lwp_t_struct.lwp_pru.pr_inblk ;
+            lwp_t_class.outblocks = lwp_t_struct.lwp_pru.pr_oublk ;
+            lwp_t_class.messages = lwp_t_struct.lwp_pru.pr_msnd + lwp_t_struct.lwp_pru.pr_mrcv;
+            lwp_t_class.signals = lwp_t_struct.lwp_pru.pr_sigs;
+            lwp_t_class.vcontexts = lwp_t_struct.lwp_pru.pr_vctx;
+            lwp_t_class.icontexts = lwp_t_struct.lwp_pru.pr_ictx;
+            lwp_t_class.syscalls = lwp_t_struct.lwp_pru.pr_sysc;
+            lwp_t_class.charios = lwp_t_struct.lwp_pru.pr_ioch;
+
+            olwp_t_ptr = rpi.olwp;
+            while ( olwp_t_ptr != NULL ) {
+              olwp_t_struct = *((lwp_prusage *) olwp_t_ptr);
+              if ( olwp_t_struct.lwp_pru.pr_lwpid ==
+                    lwp_t_struct.lwp_pru.pr_lwpid) {
+                break;
+              }
+              olwp_t_ptr = olwp_t_struct.next_lwp_pru ;
+            }
+            if ( olwp_t_ptr != NULL) {
+              lwp_t_class.user_time =  lwp_t_class.user_time - timestruc(olwp_t_struct.lwp_pru.pr_utime);
+              lwp_t_class.system_time = lwp_t_class.system_time - timestruc(olwp_t_struct.lwp_pru.pr_stime) - timestruc(olwp_t_struct.lwp_pru.pr_ttime);
+              lwp_t_class.text_pf_time = lwp_t_class.text_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_tftime) ;
+              lwp_t_class.data_pf_time = lwp_t_class.data_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_dftime) ;
+              lwp_t_class.kernel_pf_time = lwp_t_class.kernel_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_kftime) ;
+              lwp_t_class.user_lock_time = lwp_t_class.user_lock_time  - timestruc(olwp_t_struct.lwp_pru.pr_ltime) ;
+              lwp_t_class.sleep_time = lwp_t_class.sleep_time - timestruc(olwp_t_struct.lwp_pru.pr_slptime) ;
+              lwp_t_class.cpu_wait_time = lwp_t_class.cpu_wait_time - timestruc(olwp_t_struct.lwp_pru.pr_wtime) ;
+              lwp_t_class.stoptime = lwp_t_class.stoptime - timestruc(olwp_t_struct.lwp_pru.pr_stoptime) ;
+              lwp_t_class.min_faults = lwp_t_class.min_faults  - olwp_t_struct.lwp_pru.pr_minf ;
+              lwp_t_class.maj_faults = lwp_t_class.maj_faults - olwp_t_struct.lwp_pru.pr_majf ;
+              lwp_t_class.total_swaps = lwp_t_class.total_swaps  - olwp_t_struct.lwp_pru.pr_nswap;
+              lwp_t_class.inblocks = lwp_t_class.inblocks  - olwp_t_struct.lwp_pru.pr_inblk ;
+              lwp_t_class.outblocks = lwp_t_class.outblocks - olwp_t_struct.lwp_pru.pr_oublk ;
+              lwp_t_class.messages = lwp_t_class.messages - olwp_t_struct.lwp_pru.pr_msnd + lwp_t_struct.lwp_pru.pr_mrcv;
+              lwp_t_class.signals = lwp_t_class.signals - olwp_t_struct.lwp_pru.pr_sigs;
+              lwp_t_class.vcontexts = lwp_t_class.vcontexts  - olwp_t_struct.lwp_pru.pr_vctx;
+              lwp_t_class.icontexts = lwp_t_class.icontexts - olwp_t_struct.lwp_pru.pr_ictx;
+              lwp_t_class.syscalls = lwp_t_class.syscalls - olwp_t_struct.lwp_pru.pr_sysc;
+              lwp_t_class.charios = lwp_t_class.charios - olwp_t_struct.lwp_pru.pr_ioch;
+
+            } // end of if old pointer
+            lwp_t_class_ptr = malloc(sizeof(lwp_t_class));
+            memset(lwp_t_class_ptr, NULL, sizeof(lwp_t_class));
+            lwp_t_class.next_class = lwp_class_ptr;
+            lwp_class_ptr = lwp_t_class_ptr;
+            struct_empty(lwp_t_class, lwp_t_class_ptr);
+            lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+          } // end of while
+        } // end of if we have lwps
+      } // end of we want lwps
+    } else { // End if valid pp
+      process_number = -1;
+      index$ = -1;
+      pid$ = -1;
+    }
+  }
+};
+
+#endif

Added: trunk/orca/lib/SE/3.3.1/orca_process_class.se
==============================================================================
--- (empty file)
+++ trunk/orca/lib/SE/3.3.1/orca_process_class.se	Wed Nov 17 14:52:09 2004
@@ -0,0 +1,909 @@
+//
+//    Copyright (c) 1995-1998, by Sun Microsystems, Inc. 
+//      All Rights Reserved
+//
+
+#ifndef _PROCESS_CLASS_SE_
+#define _PROCESS_CLASS_SE_
+
+// 16 Oct 01 richp - more clean ups, some fields not being computed
+// 19 Sep 01 richp - replaced struct_fill and changed long to pointer_t
+// process class 19 Feb 98 Adrian - 2.6 extras added
+// measured and sampled cpu comparison version 18/5/98
+// vmem_delta added for process_rules 27 Nov 98
+// added processor set info 16 Apr 99
+// merged rules version 22 Apri 99
+// added lwp info 5-27-99 Rick Weisner
+// added PCUNSET 11-05-99 Rick Weisner
+// added se_trees 08-2000 Rick Weisner
+// patched linked list login Jul 2001 Rick Weisner
+
+// Obtain data averaged over the interval between updates
+// return one process at a time, snapshot all good stuff
+// in one update then provide index$, pid$ methods to extract groups
+// of processes.
+// Store data in raw form taken from psinfo and pusage ioctls, and
+// process it when called up by class. Feeds data to workload_class.se
+
+
+#if MINOR_VERSION < 60
+# error "process_class only works on 2.6 or newer"
+#endif
+
+#include <se_trees.se>
+
+long msaccton[2]  = { PCSET, PR_MSACCT | PR_MSFORK };
+long msacctoff[2] = { PCUNSET, PR_MSACCT };
+
+// codes for action$
+#define PROC_ACTION_INIT        0       // starting point -> next index
+#define PROC_ACTION_PID         1       // get the specified pid
+                                        // do not sample all PIDS
+#define PROC_ACTION_NEXT_INDEX  2       // index order is based on /proc
+#define PROC_ACTION_NEXT_PID    3       // search for pid and return data
+                                        // do sample all PIDS
+#define PROC_ACTION_NEXT_LWP    4       // search for lwp and return data
+
+// index$ returns -1 if no more data
+// proc data updates if index$ is -1
+
+struct pr_header_t {
+  long number_lwps;
+  size_t size_of_entries;
+};
+
+struct lwp_prusage {
+  prusage_t lwp_pru;
+  long next_lwp_pru;
+};
+
+struct raw_proc_info_t {       // all the per process info
+  pointer_t       orp;         // old prusage_t pointer
+  pointer_t       nrp;         // new prusage_t pointer
+  long            nextpid;     // next pid in list
+  long            gencnt;      // update generation counter
+  // stuff from prpsinfo_t
+  long            pr_flag;     // process flags
+  long            pr_size;     // size of process image in pages
+  long            pr_oldsize;  // previous size of process image
+  long            pr_rssize;   // resident set size in pages
+  long            pr_pri;      // priority, high value is high priority
+  char            pr_nice;     // nice for cpu usage
+  char            pr_sname;    // printable character representing pr_state
+  timestruc_t     o_pr_time;   // old sampled user+system CPU time
+  timestruc_t     n_pr_time;   // sampled user+system CPU time
+  timestruc_t     o_pr_ctime;  // old usr+sys cpu time for reaped children
+  timestruc_t     n_pr_ctime;  // new usr+sys cpu time for reaped children
+  long            pr_uid;      // real user id
+  long            pr_ppid;     // process id of parent
+  int             pr_bindpset; // processor set binding
+#define PRCLSZ 8
+  char            pr_clname[PRCLSZ]; // scheduling class name
+#define PRFNSZ 16
+  char            pr_fname[PRFNSZ];  // last component of execed pathname
+#define PRARGSZ 80
+  char            pr_psargs[PRARGSZ];// initial characters of arg list
+  int             lwp_count;
+  pointer_t       olwp;  // pointers to prev. lwp prusage linked list
+  pointer_t       nlwp;  // pointers to current lwp prusage linked list
+};
+
+struct  lwp_pr_info {
+  int     lwp_id;         // always contains  lwp_id
+  double  timestamp;      // last time lwp was measured
+  double  creation;       // lwp start time
+  double  termination;    // lwp termination time stamp
+  double  user_time;      // user time in this interval
+  double  system_time;    // system call time in this interval
+  double  trap_time;      // system trap time in interval
+  double  text_pf_time;   // text page fault wait in interval
+  double  data_pf_time;   // data page fault wait in interval
+  double  kernel_pf_time; // kernel page fault wait in interval
+  double  user_lock_time; // user lock wait in interval
+  double  sleep_time;     // all other sleep time
+  double  cpu_wait_time;  // time on runqueue waiting for CPU
+  double  stoptime;       // time stopped from ^Z
+  ulong   syscalls;       // syscall/interval for this process
+  ulong   maj_faults;     // majf/interval
+  ulong   min_faults;     // minf/interval
+  ulong   total_swaps;    // swapout count
+  ulong   inblocks;       // input blocks/interval
+  ulong   outblocks;      // output blocks/interval
+  ulong   messages;       // msgin+msgout/interval
+  ulong   signals;        // signals/interval
+  ulong   vcontexts;      // voluntary context switches/interval
+  ulong   icontexts;      // in-ditto
+  ulong   charios;        // characters in and out/interval
+  ulong   next_class;
+};
+// the process class that does all the real work
+
+// get both types of hires timestamp into a common more useful form
+#define timestruc(t) (t.tv_sec + (t.tv_nsec / 1000000000.0))
+#define timeval(t) (t.tv_sec + (t.tv_usec / 1000000.0))
+#define hr_min_sec(t) sprintf("%.3f", timestruc(t))
+
+// double timestruc(timestruc_t ts_time) {
+//   return ts_time.tv_sec + (ts_time.tv_nsec / 1000000000.0);
+// }
+
+// double timeval(timeval_t tv_time) {
+//   return tv_time.tv_sec + (tv_time.tv_usec / 1000000.0);
+// }
+
+// string hr_min_sec(timestruc_t ts) {
+//   char buf[80];
+//   double tmp;
+//   tmp = timestruc(ts);
+//   buf = sprintf("%.3f", tmp);
+//   return buf;
+// }
+
+msprint(prusage_t pru, int pid, string cmd, string arg) {
+    puts("\n--------------- BEGIN ----------------");
+    printf("%d %s %s\n", pid, cmd, arg);
+    printf("Elapsed time        %12s  ", hr_min_sec(pru.pr_rtime));
+    printf("Create time %s Timestamp %s\n", hr_min_sec(pru.pr_create),
+            hr_min_sec(pru.pr_tstamp));
+    printf("User CPU time       %12s  ", hr_min_sec(pru.pr_utime));
+    printf("System call time    %12s\n", hr_min_sec(pru.pr_stime));
+    printf("System trap time    %12s  ", hr_min_sec(pru.pr_ttime));
+    printf("Text pfault sleep   %12s\n", hr_min_sec(pru.pr_tftime));
+    printf("Data pfault sleep   %12s  ", hr_min_sec(pru.pr_dftime));
+    printf("Kernel pfault sleep %12s\n", hr_min_sec(pru.pr_kftime));
+    printf("User lock sleep     %12s  ", hr_min_sec(pru.pr_ltime));
+    printf("Other sleep time    %12s\n", hr_min_sec(pru.pr_slptime));
+    printf("Wait for CPU time   %12s  ", hr_min_sec(pru.pr_wtime));
+    printf("Stopped time        %12s\n", hr_min_sec(pru.pr_stoptime));
+    printf("pf %d mf %d sw %d inb %d oub %d ms %d mr %d\n",
+            pru.pr_minf, pru.pr_majf, pru.pr_nswap, pru.pr_inblk, pru.pr_oublk,
+            pru.pr_msnd, pru.pr_mrcv);
+    printf("sig %d vctx %d ictx %d sysc %d ioch %d\n",
+            pru.pr_sigs, pru.pr_vctx, pru.pr_ictx, pru.pr_sysc, pru.pr_ioch);
+    puts("---------------- END -----------------");
+}
+
+class proc_class_t {
+  // input controls
+  int     index$;         // always contains current index or -1
+  int     pid$;           // always contains current pid
+  // for ACTION_PID mode set pid$ and set index$ to -1 to get new data
+  int     action$;
+  int     off$;
+  int     wantlwp$;       // 0 = do not want lwps, 1 = want lsps
+  // summary totals
+  double  lasttime;       // timestamp for the end of the last update
+  int     nproc;          // current number of processes
+  int     newproc;
+  int     deadproc;
+  int     missedproc;     // number of fork+vfork - newproc
+  // output data for specified process
+  long    flags;          // latest pr_flag for the process
+  double  interval;       // measured time interval for averages
+  double  timestamp;      // last time process was measured
+  double  creation;       // process start time
+  double  termination;    // process termination time stamp
+  double  elapsed;        // elapsed time for all lwps in process
+  double  total_user;     // current totals in seconds
+  double  total_system;
+  double  total_sampled_cpu;
+  double  total_child;
+  double  user_time;      // user time in this interval
+  double  system_time;    // system call time in this interval
+  double  sampled_cpu;    // total sampled cpu time
+  double  trap_time;      // system trap time in interval
+  double  child_time;     // child CPU in this interval
+  double  text_pf_time;   // text page fault wait in interval
+  double  data_pf_time;   // data page fault wait in interval
+  double  kernel_pf_time; // kernel page fault wait in interval
+  double  user_lock_time; // user lock wait in interval
+  double  sleep_time;     // all other sleep time
+  double  cpu_wait_time;  // time on runqueue waiting for CPU
+  double  stoptime;       // time stopped from ^Z
+  ulong   syscalls;       // syscall/interval for this process
+  ulong   inblocks;       // input blocks/interval
+  ulong   outblocks;      // output blocks/interval
+  ulong   vmem_size;      // size in KB
+  long    vmem_delta;     // size change in KB
+  ulong   rmem_size;      // RSS in KB
+#ifdef XMAP
+  ulong   pmem_size;      // private mem in KB
+  ulong   smem_size;      // shared mem in KB
+#endif
+  ulong   maj_faults;     // majf/interval
+  ulong   min_faults;     // minf/interval
+  ulong   total_swaps;    // swapout count
+  long    priority;       // current sched priority
+  long    niceness;       // current nice value
+  char    sched_class[PRCLSZ];    // name of class
+  ulong   messages;       // msgin+msgout/interval
+  ulong   signals;        // signals/interval
+  ulong   vcontexts;      // voluntary context switches/interval
+  ulong   icontexts;      // in-ditto
+  ulong   charios;        // characters in and out/interval
+  ulong   lwp_count;      // number of lwps for the process
+  int     uid;            // current uid
+  long    ppid;           // parent pid
+  int     bindpset;       // processor set binding
+  char    fname[PRFNSZ];  // last components of exec'd pathname
+  char    args[PRARGSZ];  // initial part of arg list
+  ulong   lwp_class_ptr;  // head of linked list of lwp_class_ptrs
+
+  proc$() {
+    ulong_t MAX_PID;
+    ulong_t pp;             // pointer to malloc for raw proc info
+    ulong_t pp_tmp;         // temp pointer to malloc for raw proc info
+    ulong_t pp_ret;         // temp pointer to malloc for raw proc info
+                            // chained using nextpid
+    ulong_t pp_tree;
+    raw_proc_info_t rpi;
+    raw_proc_info_t t_rpi;
+    prusage_t   ou;         // old and new usage data
+#define NU      nu[0]
+    prusage_t   nu[1];      // array of one for read and ioctl
+#define PS      ps[0]
+    psinfo_t    ps[1];      // format changes when read used
+    pr_header_t prh;
+    prusage_t   plwp;
+    ulong pnu;
+    ulong pps;
+    int   i;
+    dirent_t directory_data;
+    ulong directory_pointer;
+    ulong directory_entry;
+    ulong_t tag;
+    int process_number;   // current link in chain
+    int first_process;    // fixed first link in search chain
+    int previous_process; // last one used to build chain
+    int next_process;     // next pid
+    int broken_chain;     // flag that chain changed this time
+    int cleaning_chain;   // flag that we are in cleanup mode
+    int pfd;
+    int lfd; // file descriptor for /prod/PID/lusage
+    char procname[64];
+    char lwpname[64];     // String for /prod/PID/lusage
+    long gen;             // number of generations of update
+    int err;
+    int new_entry;
+    ulong tmp;
+    double dtmp;
+    timeval_t tmp_tval[1];
+    int pg_to_kb;
+
+    // lwp working storage
+    prusage_t lwp_info;
+    pointer_t lwp_t_ptr;
+    pointer_t olwp_t_ptr;
+    lwp_prusage lwp_t_struct;
+    lwp_prusage olwp_t_struct;
+    lwp_pr_info lwp_t_class;
+    long lwp_t_class_ptr;
+    int ircw;
+
+// **********************************************************
+
+    if (action$ == PROC_ACTION_INIT) {
+      action$ = PROC_ACTION_NEXT_INDEX;
+      // open the directory containing the process data
+      directory_pointer = opendir("/proc");
+      index$ = -1;
+      off$ = 0 ;
+      gen = -1;
+      wantlwp$ = 0;
+      first_process=-1;
+      gettimeofday(tmp_tval,0);
+      lasttime = timeval(tmp_tval[0]);
+      pg_to_kb = sysconf(_SC_PAGESIZE) / 1024;
+      pp_tree= int2int_init();
+      if (pnu == 0 || pps == 0) {
+        pnu = malloc(sizeof(nu));
+        pps = malloc(sizeof(ps));
+      }
+      return;
+    }
+
+    if (index$ == -1) {   // update the data from /proc
+      // read the first entry in the directory
+      rewinddir(directory_pointer);
+      directory_entry = readdir(directory_pointer); // read .
+      directory_entry = readdir(directory_pointer); // read ..
+      directory_entry = readdir(directory_pointer);
+      MAX_PID=0;
+      nproc = 0;
+      newproc = 0;
+      deadproc = 0;
+      gen++;
+      previous_process = -1;
+      broken_chain = 0;
+      cleaning_chain = 0;
+      while(directory_entry != NULL) {
+        directory_data = *((dirent_t *) directory_entry);
+        // get the process number and open the data file
+        // only look at specified process
+        if (action$ == PROC_ACTION_PID) {
+          process_number = pid$;
+          directory_entry = NULL;
+        } else {
+          process_number = atoi(directory_data.d_name);
+        }
+        procname = sprintf("/proc/%d/usage", process_number);
+        pfd = open(procname, O_RDONLY, 0);
+        // file cannot be accessed if pfd = -1; ignore this process
+        // may be that there is no permission or just died
+        if (pfd != -1) { // start of good pfd
+          if ( process_number > MAX_PID ) {
+            MAX_PID = process_number ;
+          }
+          tag = process_number;
+          pp_tmp = NULL ;
+          pp_ret = int2int_get(pp_tree, tag);
+          if ( pp_ret != NULL) {
+            pp_tmp = ((ulong_t) *((ulong_t *) pp_ret));
+            // Process Found
+          }
+          if (pp_tmp == NULL) {
+            // load the tree , new process
+            pp = malloc(sizeof(rpi));
+            memset(pp, 0, sizeof(rpi));
+            new_entry = 1;
+            broken_chain = 1;
+            pp_ret= int2int_put(pp_tree, tag, pp);
+            if ( pp_ret < 0 ) {
+              printf(" Error unable to insert into tree %d, %d , %x\n",
+                       pp_ret, tag, pp);
+              exit(1);
+            }
+            pp_ret = int2int_get(pp_tree, tag);
+            pp_tmp = ((ulong_t) *((ulong_t *) pp_ret));
+            if ( pp != pp_tmp) {
+              printf(" Error pointers do not match %x, %x \n",
+                       pp, pp_tmp);
+              exit(1);
+            }
+          } else {
+            new_entry = 0;
+            // Process Found
+          }
+
+          // get the existing or blank data
+          tag = process_number;
+          pp_ret = int2int_get(pp_tree, tag);
+          if ( pp_ret== NULL) {
+            printf(" Error pointer not found for process_number %d\n",
+                     tag);
+            exit(1);
+          }
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+          if ( pp == NULL) {
+            printf("process_number %d  invalid2 \n", process_number);
+            exit(1);
+          }
+          rpi = *((raw_proc_info_t *) pp);
+
+          // read usage info directly
+          // 2.6 specific, can read usage and psinfo without needing
+          // ownership or permissions on /proc entry but can't read
+          // directly into SE structure so go via malloc buffers
+
+          err = read(pfd, pnu, sizeof(nu));
+          close(pfd);
+
+          // turn on msacct
+
+          procname = sprintf("/proc/%d/ctl", process_number);
+          pfd = open(procname, O_WRONLY, 0);
+          if (pfd != -1) {
+            if ( off$ == 0 ) {
+              write(pfd, &msaccton, sizeof(msaccton));
+            } else {
+              printf("%d ms accounting off \n", process_number );
+              write(pfd, &msacctoff, sizeof(msaccton));
+            }
+            close(pfd);
+          }
+
+          // get usage
+          procname = sprintf("/proc/%d/psinfo", process_number);
+          pfd = open(procname, O_RDONLY, 0);
+          err += read(pfd, pps, sizeof(ps));
+          NU = *((prusage_t *) pnu);
+          PS = *((psinfo_t *) pps);
+          close(pfd);
+          if (err == 0) {
+            // process went away since directory was opened
+            // unlikely but still need to tidy up mallocs
+            // when it is a new entry
+            if ( new_entry == 1 ) {
+              deadproc++;
+              free(pp);
+              tag = process_number;
+              pp_ret=int2int_put(pp_tree, tag, NULL);
+              if ( pp_ret < 0 ) {
+                printf("unable to free tag = %d \n",tag);
+                exit(1);
+              }
+            }
+            if (action$ == PROC_ACTION_PID) {
+              directory_entry = NULL;
+            } else {
+              directory_entry = readdir(directory_pointer);
+            }
+            continue;
+          } else { // good pfd
+
+// ***************************************************************
+
+            if ( wantlwp$ == 1 ) {
+              // read the lwp info
+              lwpname = sprintf("/proc/%d/lusage", process_number);
+              lfd = open(lwpname, O_RDONLY, 0);
+              if ( lfd > 0 ) {
+                lwp_t_ptr = malloc(sizeof(prh));
+                err = read(lfd, lwp_t_ptr, sizeof(prh));
+                prh = *((pr_header_t *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                if (err <= 0) {
+                  printf("Error reading pr_header %s error code = %d \n",
+                          lwpname, err);
+                } else { // good read of pr_head
+                  // if there is an old lwp linked list free it
+                  lwp_t_ptr = rpi.olwp ;
+                  while ( lwp_t_ptr != NULL ) {
+                    lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                    free(lwp_t_ptr);
+                    lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+                  }
+                  rpi.olwp = rpi.nlwp;
+                  rpi.nlwp = NULL;
+                  // create new lwp linked list
+                  for (ircw=0; ircw<prh.number_lwps; ircw++) {
+                    lwp_t_ptr = malloc(prh.size_of_entries);
+                    err = read(lfd, lwp_t_ptr, prh.size_of_entries);
+                    if (err <= 0 ) {
+                      printf("Error reading pr lwp %d/n", i);
+                      free(lwp_t_ptr);
+                    } else {
+                      if ( ircw != -1 ) {
+                        lwp_info = *((prusage_t *) lwp_t_ptr);
+                        free(lwp_t_ptr);
+                        lwp_t_ptr=malloc(sizeof(lwp_t_struct));
+                        memset(lwp_t_ptr, NULL, sizeof(lwp_t_struct));
+                        struct_empty(lwp_info, lwp_t_ptr);
+                        lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                        lwp_t_struct.next_lwp_pru = rpi.nlwp;
+                        struct_empty(lwp_t_struct, lwp_t_ptr);
+                        rpi.nlwp = lwp_t_ptr;
+                      } else {
+                        free(lwp_t_ptr);
+                      }
+                    }
+                  } // end for
+
+                  close(lfd);
+
+                } // end else on bad pr header read
+              } // good open on lfd
+            } // end of wantlwp
+// ********** lwp info read **************************************
+          } // good read on pfd
+
+          if (new_entry == 1 ) {
+            rpi.nextpid = first_process;
+            first_process = process_number;
+          }
+
+          // check to see if we are still dealing with the same process
+          //  we had before, and update and
+          if (new_entry == 1 || timestruc(PS.pr_start) > lasttime) {
+            newproc++;
+            if (new_entry == 0) {
+              // leftover from an old process at same pid
+              if (rpi.orp != NULL) {
+                free(rpi.orp);
+                rpi.orp = NULL;   // dump old rp, and overwrite new
+              }
+// ***************** delete old lwp info *********************
+              if ( wantlwp$ == 1 ) {
+                lwp_t_ptr = rpi.olwp ;
+                rpi.olwp = NULL;
+                while ( lwp_t_ptr != NULL ) {
+                  lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                  free(lwp_t_ptr);
+                  lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+                }
+              }
+// ***************** end delete old lwp info *********************
+            }
+            // static psinfo needs updating
+            rpi.pr_uid = PS.pr_uid;
+            rpi.pr_ppid = PS.pr_ppid;
+            rpi.pr_bindpset = PS.pr_lwp.pr_bindpset;
+            rpi.pr_clname = PS.pr_lwp.pr_clname;
+            rpi.pr_fname = PS.pr_fname;
+            rpi.pr_psargs = PS.pr_psargs;
+          }
+          // update usage data
+          tmp = rpi.orp;  // hang on to malloced data
+          rpi.orp = rpi.nrp;      // switch new to old
+          if (tmp == NULL) {
+            rpi.nrp = malloc(sizeof(ou));
+          } else {
+            rpi.nrp = tmp;
+          }
+          struct_empty(NU, rpi.nrp);      // save whole block
+          // update dynamic psinfo data
+          rpi.pr_oldsize = rpi.pr_size;
+          rpi.pr_size = PS.pr_size;
+          rpi.pr_rssize = PS.pr_rssize;
+          rpi.pr_pri = PS.pr_lwp.pr_pri;
+          rpi.pr_nice = PS.pr_lwp.pr_nice;
+          rpi.pr_sname = PS.pr_lwp.pr_sname;
+          rpi.pr_flag = PS.pr_flag;
+          rpi.o_pr_time = rpi.n_pr_time;
+          rpi.n_pr_time = PS.pr_time;
+          rpi.o_pr_ctime = rpi.n_pr_ctime;
+          rpi.n_pr_ctime = PS.pr_ctime;
+          rpi.gencnt = gen;
+          struct_empty(rpi, pp);
+          nproc++;
+          // printf("processed %d \n" , process_number );
+        } // end of good pfd
+        // step through the files in the directory ...
+        if (action$ == PROC_ACTION_PID) {
+          directory_entry = NULL;
+        } else {
+          directory_entry = readdir(directory_pointer);
+        }
+      } // end of directory
+// **************************************************************
+      // go through list and remove deadwood
+      // printf("first process_number %d  \n",first_process);
+      process_number = first_process;
+      next_process = -1;
+      previous_process = -1;
+      while ( process_number > 0 ) {
+        // printf("processing %d  \n",process_number);
+        if (process_number > 0 ) {
+          pp_ret = int2int_get(pp_tree, process_number);
+          if ( pp_ret == NULL) {
+            printf("unable to get process_number  %d \n", process_number);
+            exit(1);
+          }
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+          if ( pp == NULL) {
+            printf("process_number %d  invalid4 \n",process_number);
+            exit(1);
+          }
+          rpi = *((raw_proc_info_t *) pp); // rpi <- pp
+          next_process = rpi.nextpid;
+          // printf("next process %d  \n",next_process);
+          // unhook dead processes
+          if (rpi.gencnt != gen) {
+            deadproc++;
+            if (rpi.orp != NULL) {
+              free(rpi.orp);
+              rpi.orp = NULL;
+            }
+            if (rpi.nrp != NULL) {
+              free(rpi.nrp);
+              rpi.nrp = NULL;
+            }
+            if ( wantlwp$ == 1 ) {
+              lwp_t_ptr = rpi.olwp ;
+              while ( lwp_t_ptr != NULL ) {
+                lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+              }
+              lwp_t_ptr = t_rpi.nlwp ;
+              while ( lwp_t_ptr != NULL ) {
+                lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+              }
+            }
+            free(pp);
+            pp_ret = int2int_put(pp_tree, process_number , NULL);
+            if ( pp_ret < 0 ) {
+              printf("unable to free process_number \n");
+              exit(1);
+            }
+            if ( previous_process > 0 ) { // there was a previous process
+              pp_tmp = int2int_get(pp_tree, previous_process);
+              if ( pp_tmp == NULL) {
+                printf("unable to get process_number %d \n",
+                          previous_process);
+                exit(1);
+              }
+              pp = ((ulong_t) *((ulong_t *) pp_tmp));
+              if ( pp == NULL) {
+                 printf("process_number %d invalid5 \n",
+                         previous_process);
+                 exit(1);
+              }
+              rpi = *((raw_proc_info_t *) pp); // rpi <- pp
+              // printf("previous process %d  \n",previous_process);
+              rpi.nextpid = next_process;
+              struct_empty(rpi, pp);
+            } else {
+              first_process = next_process;
+            }
+          } else {
+            // update previous process ptr
+            previous_process = process_number;
+          }
+        }
+        process_number = next_process;
+      }
+      // printf(" end of deadwood removal \n");
+      gettimeofday(tmp_tval,0);
+      lasttime = timeval(tmp_tval[0]);
+      process_number = first_process;
+      index$ = -1;
+    }
+    // printf("done updating \n");
+    // printf("MAX_PID = %d \n", MAX_PID);
+// ****************************** end of update section *******************
+
+    if (action$ == PROC_ACTION_NEXT_INDEX ) {
+      // printf("PROC_ACTION_NEXT_INDEX \n");
+      if (index$ == -1) {
+        process_number = first_process;
+      } else {
+        process_number = rpi.nextpid;
+      }
+      if (process_number < 0 || process_number > MAX_PID) {
+        // ran out of data
+        process_number = -1;
+        index$ = -1;
+        pid$ = -1;
+        // printf(" thats all there is \n");
+        return;
+      }
+      index$++;
+    }
+
+    if (action$ == PROC_ACTION_NEXT_PID) {
+      // printf("PROC_ACTION_NEXT_PID \n");
+      if (index$ == -1) {
+        process_number = 0;
+      } else {
+        process_number++;
+      }
+      index$++;
+      // look for the next data
+      pp = NULL;
+      pp_ret=int2int_get(pp_tree,process_number);
+      if ( pp_ret != NULL ) {
+        pp = ((ulong_t) *((ulong_t *) pp_ret));
+      }
+      while (process_number < MAX_PID && pp == NULL) {
+        process_number++;
+        pp = NULL;
+        pp_ret=int2int_get(pp_tree,process_number);
+        if ( pp_ret != NULL ) {
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+        }
+      }
+      if (process_number < 0 || process_number > MAX_PID) {
+        // ran out of data
+        process_number = -1;
+        index$ = -1;
+        pid$ = -1;
+        // printf(" ran out of data NEXT PID \n");
+        return;
+      }
+    }
+
+    if (action$ == PROC_ACTION_PID) {
+      process_number = pid$;
+      index$ = 0;
+    }
+
+    // common code to update class once process has been chosen
+
+    pp_ret=int2int_get(pp_tree,process_number);
+    pp = NULL;
+    if (pp_ret != NULL) {
+      pp = ((ulong_t) *((ulong_t *) pp_ret));
+    }
+    if ( pp != NULL) {
+      rpi = *((raw_proc_info_t *) pp);
+      // make sure that all class data is updated
+      // index$ is already set
+      pid$ = process_number;
+      uid = rpi.pr_uid;
+      // nproc, , are already set
+      missedproc = rpi.nextpid; // for debug until fork counting
+
+      // nrp will always be set
+      NU = *((prusage_t *) rpi.nrp);
+      creation = timestruc(NU.pr_create);
+      timestamp = timestruc(NU.pr_tstamp);
+      termination = 0.0; // set later if process is dead
+      elapsed = timestruc(NU.pr_rtime);
+      total_user = timestruc(NU.pr_utime);
+      total_system = timestruc(NU.pr_stime);
+      total_child = timestruc(rpi.n_pr_ctime);
+      total_sampled_cpu = timestruc(rpi.n_pr_time);
+      flags = rpi.pr_flag;
+#ifdef PDEBUG
+      msprint(NU, pid$, rpi.pr_fname, rpi.pr_psargs);
+#endif
+      if (rpi.orp != NULL) {
+        ou = *((prusage_t *) rpi.orp);
+        interval = timestamp - timestruc(ou.pr_tstamp);
+        // interval should never be zero
+        if (interval == 0.0) {
+          printf("zero interval on pid %d state %c\n", pid$, rpi.pr_sname);
+          msprint(ou, pid$, fname, args);
+          interval = 1.0;
+        }
+        user_time = total_user - timestruc(ou.pr_utime);
+        system_time = total_system - timestruc(ou.pr_stime);
+        sampled_cpu = total_sampled_cpu - timestruc(rpi.o_pr_time);
+        trap_time = timestruc(NU.pr_ttime) - timestruc(ou.pr_ttime);
+        child_time = total_child - timestruc(rpi.o_pr_ctime);
+        text_pf_time = timestruc(NU.pr_tftime) - timestruc(ou.pr_tftime);
+        data_pf_time = timestruc(NU.pr_dftime) - timestruc(ou.pr_dftime);
+        kernel_pf_time = timestruc(NU.pr_kftime) - timestruc(ou.pr_kftime);
+        user_lock_time = timestruc(NU.pr_ltime) - timestruc(ou.pr_ltime);
+        sleep_time = timestruc(NU.pr_slptime) - timestruc(ou.pr_slptime);
+        cpu_wait_time = timestruc(NU.pr_wtime) - timestruc(ou.pr_wtime);
+        stoptime = timestruc(NU.pr_stoptime) - timestruc(ou.pr_stoptime);
+        syscalls = NU.pr_sysc - ou.pr_sysc;
+        inblocks = NU.pr_inblk - ou.pr_inblk;
+        outblocks = NU.pr_oublk - ou.pr_oublk;
+        maj_faults = NU.pr_majf - ou.pr_majf;
+        min_faults = NU.pr_minf - ou.pr_minf;
+        messages = (NU.pr_msnd + NU.pr_mrcv) - (ou.pr_msnd + ou.pr_mrcv);
+        signals = NU.pr_sigs - ou.pr_sigs;
+        vcontexts = NU.pr_vctx - ou.pr_vctx;
+        icontexts = NU.pr_ictx - ou.pr_ictx;
+        charios = NU.pr_ioch - ou.pr_ioch;
+      } else {
+        // new process will only have rpi.nrp set
+        interval = timestamp - creation; // elapsed time so far
+        if (interval == 0.0) {
+          printf("zero interval on pid %d state %c\n", pid$, rpi.pr_sname);
+          msprint(NU, pid$, fname, args);
+          interval = 1.0;
+        }
+        user_time = total_user;
+        system_time = total_system;
+        sampled_cpu = total_sampled_cpu;
+        trap_time = timestruc(NU.pr_ttime);
+        child_time = total_child;
+        text_pf_time = timestruc(NU.pr_tftime);
+        data_pf_time = timestruc(NU.pr_dftime);
+        kernel_pf_time = timestruc(NU.pr_kftime);
+        user_lock_time = timestruc(NU.pr_ltime);
+        sleep_time = timestruc(NU.pr_slptime);
+        cpu_wait_time = timestruc(NU.pr_wtime);
+        stoptime = timestruc(NU.pr_stoptime);
+        syscalls = NU.pr_sysc;
+        inblocks = NU.pr_inblk;
+        outblocks = NU.pr_oublk;
+        maj_faults = NU.pr_majf;
+        min_faults = NU.pr_minf;
+        messages = NU.pr_msnd + NU.pr_mrcv;
+        signals = NU.pr_sigs;
+        vcontexts = NU.pr_vctx;
+        icontexts = NU.pr_ictx;
+        charios = NU.pr_ioch;
+      }
+      vmem_size = rpi.pr_size;
+      vmem_delta = rpi.pr_size - rpi.pr_oldsize;
+      rmem_size = rpi.pr_rssize;
+      total_swaps = NU.pr_nswap;
+      priority = rpi.pr_pri;
+      niceness = rpi.pr_nice;
+      sched_class = rpi.pr_clname;
+      lwp_count = NU.pr_count;
+      ppid = rpi.pr_ppid;
+      bindpset = rpi.pr_bindpset;
+      fname = rpi.pr_fname;
+      if (fname == "" && rpi.pr_sname == 'Z') {
+        fname = "Zombie";
+        bindpset = -1;        // no pset, but Zomb defaults to 0
+      }
+      args = rpi.pr_psargs;
+      // bug in sched pid 0 gives 100% system time
+      if (pid$ == 0) {
+        total_system = 0.0;
+        system_time = 0.0;
+      }
+#ifdef PDEBUG
+      printf("interval %.5f\n", interval);
+#endif
+// *******************************************************
+      if ( wantlwp$ == 1 ) {
+        // process lwp info
+        lwp_t_ptr = lwp_class_ptr;
+        lwp_class_ptr = NULL;
+        // if there is an old lwp class linked list free it
+        while ( lwp_t_ptr != NULL ) {
+          lwp_t_class = *((lwp_pr_info *) lwp_t_ptr);
+          free(lwp_t_ptr);
+          lwp_t_ptr = lwp_t_class.next_class ;
+        }
+        // Process lwp information
+        if ( rpi.nlwp != NULL ) {
+          lwp_t_ptr = rpi.nlwp ;
+          while ( lwp_t_ptr != NULL) {
+            lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+            lwp_t_class.lwp_id = lwp_t_struct.lwp_pru.pr_lwpid;
+            lwp_t_class.timestamp = timestruc(lwp_t_struct.lwp_pru.pr_tstamp);
+            lwp_t_class.creation = timestruc(lwp_t_struct.lwp_pru.pr_create);
+            lwp_t_class.termination = timestruc(lwp_t_struct.lwp_pru.pr_term);
+            lwp_t_class.user_time = timestruc(lwp_t_struct.lwp_pru.pr_utime);
+            lwp_t_class.system_time = timestruc(lwp_t_struct.lwp_pru.pr_stime) + timestruc(lwp_t_struct.lwp_pru.pr_ttime);
+            lwp_t_class.text_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_tftime) ;
+            lwp_t_class.data_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_dftime) ;
+            lwp_t_class.kernel_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_kftime) ;
+            lwp_t_class.user_lock_time = timestruc(lwp_t_struct.lwp_pru.pr_ltime) ;
+            lwp_t_class.sleep_time = timestruc(lwp_t_struct.lwp_pru.pr_slptime) ;
+            lwp_t_class.cpu_wait_time = timestruc(lwp_t_struct.lwp_pru.pr_wtime) ;
+            lwp_t_class.stoptime = timestruc(lwp_t_struct.lwp_pru.pr_stoptime) ;
+            lwp_t_class.min_faults = lwp_t_struct.lwp_pru.pr_minf ;
+            lwp_t_class.maj_faults = lwp_t_struct.lwp_pru.pr_majf ;
+            lwp_t_class.total_swaps = lwp_t_struct.lwp_pru.pr_nswap;
+            lwp_t_class.inblocks = lwp_t_struct.lwp_pru.pr_inblk ;
+            lwp_t_class.outblocks = lwp_t_struct.lwp_pru.pr_oublk ;
+            lwp_t_class.messages = lwp_t_struct.lwp_pru.pr_msnd + lwp_t_struct.lwp_pru.pr_mrcv;
+            lwp_t_class.signals = lwp_t_struct.lwp_pru.pr_sigs;
+            lwp_t_class.vcontexts = lwp_t_struct.lwp_pru.pr_vctx;
+            lwp_t_class.icontexts = lwp_t_struct.lwp_pru.pr_ictx;
+            lwp_t_class.syscalls = lwp_t_struct.lwp_pru.pr_sysc;
+            lwp_t_class.charios = lwp_t_struct.lwp_pru.pr_ioch;
+
+            olwp_t_ptr = rpi.olwp;
+            while ( olwp_t_ptr != NULL ) {
+              olwp_t_struct = *((lwp_prusage *) olwp_t_ptr);
+              if ( olwp_t_struct.lwp_pru.pr_lwpid ==
+                    lwp_t_struct.lwp_pru.pr_lwpid) {
+                break;
+              }
+              olwp_t_ptr = olwp_t_struct.next_lwp_pru ;
+            }
+            if ( olwp_t_ptr != NULL) {
+              lwp_t_class.user_time =  lwp_t_class.user_time - timestruc(olwp_t_struct.lwp_pru.pr_utime);
+              lwp_t_class.system_time = lwp_t_class.system_time - timestruc(olwp_t_struct.lwp_pru.pr_stime) - timestruc(olwp_t_struct.lwp_pru.pr_ttime);
+              lwp_t_class.text_pf_time = lwp_t_class.text_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_tftime) ;
+              lwp_t_class.data_pf_time = lwp_t_class.data_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_dftime) ;
+              lwp_t_class.kernel_pf_time = lwp_t_class.kernel_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_kftime) ;
+              lwp_t_class.user_lock_time = lwp_t_class.user_lock_time  - timestruc(olwp_t_struct.lwp_pru.pr_ltime) ;
+              lwp_t_class.sleep_time = lwp_t_class.sleep_time - timestruc(olwp_t_struct.lwp_pru.pr_slptime) ;
+              lwp_t_class.cpu_wait_time = lwp_t_class.cpu_wait_time - timestruc(olwp_t_struct.lwp_pru.pr_wtime) ;
+              lwp_t_class.stoptime = lwp_t_class.stoptime - timestruc(olwp_t_struct.lwp_pru.pr_stoptime) ;
+              lwp_t_class.min_faults = lwp_t_class.min_faults  - olwp_t_struct.lwp_pru.pr_minf ;
+              lwp_t_class.maj_faults = lwp_t_class.maj_faults - olwp_t_struct.lwp_pru.pr_majf ;
+              lwp_t_class.total_swaps = lwp_t_class.total_swaps  - olwp_t_struct.lwp_pru.pr_nswap;
+              lwp_t_class.inblocks = lwp_t_class.inblocks  - olwp_t_struct.lwp_pru.pr_inblk ;
+              lwp_t_class.outblocks = lwp_t_class.outblocks - olwp_t_struct.lwp_pru.pr_oublk ;
+              lwp_t_class.messages = lwp_t_class.messages - olwp_t_struct.lwp_pru.pr_msnd + lwp_t_struct.lwp_pru.pr_mrcv;
+              lwp_t_class.signals = lwp_t_class.signals - olwp_t_struct.lwp_pru.pr_sigs;
+              lwp_t_class.vcontexts = lwp_t_class.vcontexts  - olwp_t_struct.lwp_pru.pr_vctx;
+              lwp_t_class.icontexts = lwp_t_class.icontexts - olwp_t_struct.lwp_pru.pr_ictx;
+              lwp_t_class.syscalls = lwp_t_class.syscalls - olwp_t_struct.lwp_pru.pr_sysc;
+              lwp_t_class.charios = lwp_t_class.charios - olwp_t_struct.lwp_pru.pr_ioch;
+
+            } // end of if old pointer
+            lwp_t_class_ptr = malloc(sizeof(lwp_t_class));
+            memset(lwp_t_class_ptr, NULL, sizeof(lwp_t_class));
+            lwp_t_class.next_class = lwp_class_ptr;
+            lwp_class_ptr = lwp_t_class_ptr;
+            struct_empty(lwp_t_class, lwp_t_class_ptr);
+            lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+          } // end of while
+        } // end of if we have lwps
+      } // end of we want lwps
+    } else { // End if valid pp
+      process_number = -1;
+      index$ = -1;
+      pid$ = -1;
+    }
+  }
+};
+
+#endif

Added: trunk/orca/lib/SE/3.3/orca_process_class.se
==============================================================================
--- (empty file)
+++ trunk/orca/lib/SE/3.3/orca_process_class.se	Wed Nov 17 14:52:09 2004
@@ -0,0 +1,909 @@
+//
+//    Copyright (c) 1995-1998, by Sun Microsystems, Inc. 
+//      All Rights Reserved
+//
+
+#ifndef _PROCESS_CLASS_SE_
+#define _PROCESS_CLASS_SE_
+
+// 16 Oct 01 richp - more clean ups, some fields not being computed
+// 19 Sep 01 richp - replaced struct_fill and changed long to pointer_t
+// process class 19 Feb 98 Adrian - 2.6 extras added
+// measured and sampled cpu comparison version 18/5/98
+// vmem_delta added for process_rules 27 Nov 98
+// added processor set info 16 Apr 99
+// merged rules version 22 Apri 99
+// added lwp info 5-27-99 Rick Weisner
+// added PCUNSET 11-05-99 Rick Weisner
+// added se_trees 08-2000 Rick Weisner
+// patched linked list login Jul 2001 Rick Weisner
+
+// Obtain data averaged over the interval between updates
+// return one process at a time, snapshot all good stuff
+// in one update then provide index$, pid$ methods to extract groups
+// of processes.
+// Store data in raw form taken from psinfo and pusage ioctls, and
+// process it when called up by class. Feeds data to workload_class.se
+
+
+#if MINOR_VERSION < 60
+# error "process_class only works on 2.6 or newer"
+#endif
+
+#include <se_trees.se>
+
+long msaccton[2]  = { PCSET, PR_MSACCT | PR_MSFORK };
+long msacctoff[2] = { PCUNSET, PR_MSACCT };
+
+// codes for action$
+#define PROC_ACTION_INIT        0       // starting point -> next index
+#define PROC_ACTION_PID         1       // get the specified pid
+                                        // do not sample all PIDS
+#define PROC_ACTION_NEXT_INDEX  2       // index order is based on /proc
+#define PROC_ACTION_NEXT_PID    3       // search for pid and return data
+                                        // do sample all PIDS
+#define PROC_ACTION_NEXT_LWP    4       // search for lwp and return data
+
+// index$ returns -1 if no more data
+// proc data updates if index$ is -1
+
+struct pr_header_t {
+  long number_lwps;
+  size_t size_of_entries;
+};
+
+struct lwp_prusage {
+  prusage_t lwp_pru;
+  long next_lwp_pru;
+};
+
+struct raw_proc_info_t {       // all the per process info
+  pointer_t       orp;         // old prusage_t pointer
+  pointer_t       nrp;         // new prusage_t pointer
+  long            nextpid;     // next pid in list
+  long            gencnt;      // update generation counter
+  // stuff from prpsinfo_t
+  long            pr_flag;     // process flags
+  long            pr_size;     // size of process image in pages
+  long            pr_oldsize;  // previous size of process image
+  long            pr_rssize;   // resident set size in pages
+  long            pr_pri;      // priority, high value is high priority
+  char            pr_nice;     // nice for cpu usage
+  char            pr_sname;    // printable character representing pr_state
+  timestruc_t     o_pr_time;   // old sampled user+system CPU time
+  timestruc_t     n_pr_time;   // sampled user+system CPU time
+  timestruc_t     o_pr_ctime;  // old usr+sys cpu time for reaped children
+  timestruc_t     n_pr_ctime;  // new usr+sys cpu time for reaped children
+  long            pr_uid;      // real user id
+  long            pr_ppid;     // process id of parent
+  int             pr_bindpset; // processor set binding
+#define PRCLSZ 8
+  char            pr_clname[PRCLSZ]; // scheduling class name
+#define PRFNSZ 16
+  char            pr_fname[PRFNSZ];  // last component of execed pathname
+#define PRARGSZ 80
+  char            pr_psargs[PRARGSZ];// initial characters of arg list
+  int             lwp_count;
+  pointer_t       olwp;  // pointers to prev. lwp prusage linked list
+  pointer_t       nlwp;  // pointers to current lwp prusage linked list
+};
+
+struct  lwp_pr_info {
+  int     lwp_id;         // always contains  lwp_id
+  double  timestamp;      // last time lwp was measured
+  double  creation;       // lwp start time
+  double  termination;    // lwp termination time stamp
+  double  user_time;      // user time in this interval
+  double  system_time;    // system call time in this interval
+  double  trap_time;      // system trap time in interval
+  double  text_pf_time;   // text page fault wait in interval
+  double  data_pf_time;   // data page fault wait in interval
+  double  kernel_pf_time; // kernel page fault wait in interval
+  double  user_lock_time; // user lock wait in interval
+  double  sleep_time;     // all other sleep time
+  double  cpu_wait_time;  // time on runqueue waiting for CPU
+  double  stoptime;       // time stopped from ^Z
+  ulong   syscalls;       // syscall/interval for this process
+  ulong   maj_faults;     // majf/interval
+  ulong   min_faults;     // minf/interval
+  ulong   total_swaps;    // swapout count
+  ulong   inblocks;       // input blocks/interval
+  ulong   outblocks;      // output blocks/interval
+  ulong   messages;       // msgin+msgout/interval
+  ulong   signals;        // signals/interval
+  ulong   vcontexts;      // voluntary context switches/interval
+  ulong   icontexts;      // in-ditto
+  ulong   charios;        // characters in and out/interval
+  ulong   next_class;
+};
+// the process class that does all the real work
+
+// get both types of hires timestamp into a common more useful form
+#define timestruc(t) (t.tv_sec + (t.tv_nsec / 1000000000.0))
+#define timeval(t) (t.tv_sec + (t.tv_usec / 1000000.0))
+#define hr_min_sec(t) sprintf("%.3f", timestruc(t))
+
+// double timestruc(timestruc_t ts_time) {
+//   return ts_time.tv_sec + (ts_time.tv_nsec / 1000000000.0);
+// }
+
+// double timeval(timeval_t tv_time) {
+//   return tv_time.tv_sec + (tv_time.tv_usec / 1000000.0);
+// }
+
+// string hr_min_sec(timestruc_t ts) {
+//   char buf[80];
+//   double tmp;
+//   tmp = timestruc(ts);
+//   buf = sprintf("%.3f", tmp);
+//   return buf;
+// }
+
+msprint(prusage_t pru, int pid, string cmd, string arg) {
+    puts("\n--------------- BEGIN ----------------");
+    printf("%d %s %s\n", pid, cmd, arg);
+    printf("Elapsed time        %12s  ", hr_min_sec(pru.pr_rtime));
+    printf("Create time %s Timestamp %s\n", hr_min_sec(pru.pr_create),
+            hr_min_sec(pru.pr_tstamp));
+    printf("User CPU time       %12s  ", hr_min_sec(pru.pr_utime));
+    printf("System call time    %12s\n", hr_min_sec(pru.pr_stime));
+    printf("System trap time    %12s  ", hr_min_sec(pru.pr_ttime));
+    printf("Text pfault sleep   %12s\n", hr_min_sec(pru.pr_tftime));
+    printf("Data pfault sleep   %12s  ", hr_min_sec(pru.pr_dftime));
+    printf("Kernel pfault sleep %12s\n", hr_min_sec(pru.pr_kftime));
+    printf("User lock sleep     %12s  ", hr_min_sec(pru.pr_ltime));
+    printf("Other sleep time    %12s\n", hr_min_sec(pru.pr_slptime));
+    printf("Wait for CPU time   %12s  ", hr_min_sec(pru.pr_wtime));
+    printf("Stopped time        %12s\n", hr_min_sec(pru.pr_stoptime));
+    printf("pf %d mf %d sw %d inb %d oub %d ms %d mr %d\n",
+            pru.pr_minf, pru.pr_majf, pru.pr_nswap, pru.pr_inblk, pru.pr_oublk,
+            pru.pr_msnd, pru.pr_mrcv);
+    printf("sig %d vctx %d ictx %d sysc %d ioch %d\n",
+            pru.pr_sigs, pru.pr_vctx, pru.pr_ictx, pru.pr_sysc, pru.pr_ioch);
+    puts("---------------- END -----------------");
+}
+
+class proc_class_t {
+  // input controls
+  int     index$;         // always contains current index or -1
+  int     pid$;           // always contains current pid
+  // for ACTION_PID mode set pid$ and set index$ to -1 to get new data
+  int     action$;
+  int     off$;
+  int     wantlwp$;       // 0 = do not want lwps, 1 = want lsps
+  // summary totals
+  double  lasttime;       // timestamp for the end of the last update
+  int     nproc;          // current number of processes
+  int     newproc;
+  int     deadproc;
+  int     missedproc;     // number of fork+vfork - newproc
+  // output data for specified process
+  long    flags;          // latest pr_flag for the process
+  double  interval;       // measured time interval for averages
+  double  timestamp;      // last time process was measured
+  double  creation;       // process start time
+  double  termination;    // process termination time stamp
+  double  elapsed;        // elapsed time for all lwps in process
+  double  total_user;     // current totals in seconds
+  double  total_system;
+  double  total_sampled_cpu;
+  double  total_child;
+  double  user_time;      // user time in this interval
+  double  system_time;    // system call time in this interval
+  double  sampled_cpu;    // total sampled cpu time
+  double  trap_time;      // system trap time in interval
+  double  child_time;     // child CPU in this interval
+  double  text_pf_time;   // text page fault wait in interval
+  double  data_pf_time;   // data page fault wait in interval
+  double  kernel_pf_time; // kernel page fault wait in interval
+  double  user_lock_time; // user lock wait in interval
+  double  sleep_time;     // all other sleep time
+  double  cpu_wait_time;  // time on runqueue waiting for CPU
+  double  stoptime;       // time stopped from ^Z
+  ulong   syscalls;       // syscall/interval for this process
+  ulong   inblocks;       // input blocks/interval
+  ulong   outblocks;      // output blocks/interval
+  ulong   vmem_size;      // size in KB
+  long    vmem_delta;     // size change in KB
+  ulong   rmem_size;      // RSS in KB
+#ifdef XMAP
+  ulong   pmem_size;      // private mem in KB
+  ulong   smem_size;      // shared mem in KB
+#endif
+  ulong   maj_faults;     // majf/interval
+  ulong   min_faults;     // minf/interval
+  ulong   total_swaps;    // swapout count
+  long    priority;       // current sched priority
+  long    niceness;       // current nice value
+  char    sched_class[PRCLSZ];    // name of class
+  ulong   messages;       // msgin+msgout/interval
+  ulong   signals;        // signals/interval
+  ulong   vcontexts;      // voluntary context switches/interval
+  ulong   icontexts;      // in-ditto
+  ulong   charios;        // characters in and out/interval
+  ulong   lwp_count;      // number of lwps for the process
+  int     uid;            // current uid
+  long    ppid;           // parent pid
+  int     bindpset;       // processor set binding
+  char    fname[PRFNSZ];  // last components of exec'd pathname
+  char    args[PRARGSZ];  // initial part of arg list
+  ulong   lwp_class_ptr;  // head of linked list of lwp_class_ptrs
+
+  proc$() {
+    ulong_t MAX_PID;
+    ulong_t pp;             // pointer to malloc for raw proc info
+    ulong_t pp_tmp;         // temp pointer to malloc for raw proc info
+    ulong_t pp_ret;         // temp pointer to malloc for raw proc info
+                            // chained using nextpid
+    ulong_t pp_tree;
+    raw_proc_info_t rpi;
+    raw_proc_info_t t_rpi;
+    prusage_t   ou;         // old and new usage data
+#define NU      nu[0]
+    prusage_t   nu[1];      // array of one for read and ioctl
+#define PS      ps[0]
+    psinfo_t    ps[1];      // format changes when read used
+    pr_header_t prh;
+    prusage_t   plwp;
+    ulong pnu;
+    ulong pps;
+    int   i;
+    dirent_t directory_data;
+    ulong directory_pointer;
+    ulong directory_entry;
+    ulong_t tag;
+    int process_number;   // current link in chain
+    int first_process;    // fixed first link in search chain
+    int previous_process; // last one used to build chain
+    int next_process;     // next pid
+    int broken_chain;     // flag that chain changed this time
+    int cleaning_chain;   // flag that we are in cleanup mode
+    int pfd;
+    int lfd; // file descriptor for /prod/PID/lusage
+    char procname[64];
+    char lwpname[64];     // String for /prod/PID/lusage
+    long gen;             // number of generations of update
+    int err;
+    int new_entry;
+    ulong tmp;
+    double dtmp;
+    timeval_t tmp_tval[1];
+    int pg_to_kb;
+
+    // lwp working storage
+    prusage_t lwp_info;
+    pointer_t lwp_t_ptr;
+    pointer_t olwp_t_ptr;
+    lwp_prusage lwp_t_struct;
+    lwp_prusage olwp_t_struct;
+    lwp_pr_info lwp_t_class;
+    long lwp_t_class_ptr;
+    int ircw;
+
+// **********************************************************
+
+    if (action$ == PROC_ACTION_INIT) {
+      action$ = PROC_ACTION_NEXT_INDEX;
+      // open the directory containing the process data
+      directory_pointer = opendir("/proc");
+      index$ = -1;
+      off$ = 0 ;
+      gen = -1;
+      wantlwp$ = 0;
+      first_process=-1;
+      gettimeofday(tmp_tval,0);
+      lasttime = timeval(tmp_tval[0]);
+      pg_to_kb = sysconf(_SC_PAGESIZE) / 1024;
+      pp_tree= int2int_init();
+      if (pnu == 0 || pps == 0) {
+        pnu = malloc(sizeof(nu));
+        pps = malloc(sizeof(ps));
+      }
+      return;
+    }
+
+    if (index$ == -1) {   // update the data from /proc
+      // read the first entry in the directory
+      rewinddir(directory_pointer);
+      directory_entry = readdir(directory_pointer); // read .
+      directory_entry = readdir(directory_pointer); // read ..
+      directory_entry = readdir(directory_pointer);
+      MAX_PID=0;
+      nproc = 0;
+      newproc = 0;
+      deadproc = 0;
+      gen++;
+      previous_process = -1;
+      broken_chain = 0;
+      cleaning_chain = 0;
+      while(directory_entry != NULL) {
+        directory_data = *((dirent_t *) directory_entry);
+        // get the process number and open the data file
+        // only look at specified process
+        if (action$ == PROC_ACTION_PID) {
+          process_number = pid$;
+          directory_entry = NULL;
+        } else {
+          process_number = atoi(directory_data.d_name);
+        }
+        procname = sprintf("/proc/%d/usage", process_number);
+        pfd = open(procname, O_RDONLY, 0);
+        // file cannot be accessed if pfd = -1; ignore this process
+        // may be that there is no permission or just died
+        if (pfd != -1) { // start of good pfd
+          if ( process_number > MAX_PID ) {
+            MAX_PID = process_number ;
+          }
+          tag = process_number;
+          pp_tmp = NULL ;
+          pp_ret = int2int_get(pp_tree, tag);
+          if ( pp_ret != NULL) {
+            pp_tmp = ((ulong_t) *((ulong_t *) pp_ret));
+            // Process Found
+          }
+          if (pp_tmp == NULL) {
+            // load the tree , new process
+            pp = malloc(sizeof(rpi));
+            memset(pp, 0, sizeof(rpi));
+            new_entry = 1;
+            broken_chain = 1;
+            pp_ret= int2int_put(pp_tree, tag, pp);
+            if ( pp_ret < 0 ) {
+              printf(" Error unable to insert into tree %d, %d , %x\n",
+                       pp_ret, tag, pp);
+              exit(1);
+            }
+            pp_ret = int2int_get(pp_tree, tag);
+            pp_tmp = ((ulong_t) *((ulong_t *) pp_ret));
+            if ( pp != pp_tmp) {
+              printf(" Error pointers do not match %x, %x \n",
+                       pp, pp_tmp);
+              exit(1);
+            }
+          } else {
+            new_entry = 0;
+            // Process Found
+          }
+
+          // get the existing or blank data
+          tag = process_number;
+          pp_ret = int2int_get(pp_tree, tag);
+          if ( pp_ret== NULL) {
+            printf(" Error pointer not found for process_number %d\n",
+                     tag);
+            exit(1);
+          }
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+          if ( pp == NULL) {
+            printf("process_number %d  invalid2 \n", process_number);
+            exit(1);
+          }
+          rpi = *((raw_proc_info_t *) pp);
+
+          // read usage info directly
+          // 2.6 specific, can read usage and psinfo without needing
+          // ownership or permissions on /proc entry but can't read
+          // directly into SE structure so go via malloc buffers
+
+          err = read(pfd, pnu, sizeof(nu));
+          close(pfd);
+
+          // turn on msacct
+
+          procname = sprintf("/proc/%d/ctl", process_number);
+          pfd = open(procname, O_WRONLY, 0);
+          if (pfd != -1) {
+            if ( off$ == 0 ) {
+              write(pfd, &msaccton, sizeof(msaccton));
+            } else {
+              printf("%d ms accounting off \n", process_number );
+              write(pfd, &msacctoff, sizeof(msaccton));
+            }
+            close(pfd);
+          }
+
+          // get usage
+          procname = sprintf("/proc/%d/psinfo", process_number);
+          pfd = open(procname, O_RDONLY, 0);
+          err += read(pfd, pps, sizeof(ps));
+          NU = *((prusage_t *) pnu);
+          PS = *((psinfo_t *) pps);
+          close(pfd);
+          if (err == 0) {
+            // process went away since directory was opened
+            // unlikely but still need to tidy up mallocs
+            // when it is a new entry
+            if ( new_entry == 1 ) {
+              deadproc++;
+              free(pp);
+              tag = process_number;
+              pp_ret=int2int_put(pp_tree, tag, NULL);
+              if ( pp_ret < 0 ) {
+                printf("unable to free tag = %d \n",tag);
+                exit(1);
+              }
+            }
+            if (action$ == PROC_ACTION_PID) {
+              directory_entry = NULL;
+            } else {
+              directory_entry = readdir(directory_pointer);
+            }
+            continue;
+          } else { // good pfd
+
+// ***************************************************************
+
+            if ( wantlwp$ == 1 ) {
+              // read the lwp info
+              lwpname = sprintf("/proc/%d/lusage", process_number);
+              lfd = open(lwpname, O_RDONLY, 0);
+              if ( lfd > 0 ) {
+                lwp_t_ptr = malloc(sizeof(prh));
+                err = read(lfd, lwp_t_ptr, sizeof(prh));
+                prh = *((pr_header_t *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                if (err <= 0) {
+                  printf("Error reading pr_header %s error code = %d \n",
+                          lwpname, err);
+                } else { // good read of pr_head
+                  // if there is an old lwp linked list free it
+                  lwp_t_ptr = rpi.olwp ;
+                  while ( lwp_t_ptr != NULL ) {
+                    lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                    free(lwp_t_ptr);
+                    lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+                  }
+                  rpi.olwp = rpi.nlwp;
+                  rpi.nlwp = NULL;
+                  // create new lwp linked list
+                  for (ircw=0; ircw<prh.number_lwps; ircw++) {
+                    lwp_t_ptr = malloc(prh.size_of_entries);
+                    err = read(lfd, lwp_t_ptr, prh.size_of_entries);
+                    if (err <= 0 ) {
+                      printf("Error reading pr lwp %d/n", i);
+                      free(lwp_t_ptr);
+                    } else {
+                      if ( ircw != -1 ) {
+                        lwp_info = *((prusage_t *) lwp_t_ptr);
+                        free(lwp_t_ptr);
+                        lwp_t_ptr=malloc(sizeof(lwp_t_struct));
+                        memset(lwp_t_ptr, NULL, sizeof(lwp_t_struct));
+                        struct_empty(lwp_info, lwp_t_ptr);
+                        lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                        lwp_t_struct.next_lwp_pru = rpi.nlwp;
+                        struct_empty(lwp_t_struct, lwp_t_ptr);
+                        rpi.nlwp = lwp_t_ptr;
+                      } else {
+                        free(lwp_t_ptr);
+                      }
+                    }
+                  } // end for
+
+                  close(lfd);
+
+                } // end else on bad pr header read
+              } // good open on lfd
+            } // end of wantlwp
+// ********** lwp info read **************************************
+          } // good read on pfd
+
+          if (new_entry == 1 ) {
+            rpi.nextpid = first_process;
+            first_process = process_number;
+          }
+
+          // check to see if we are still dealing with the same process
+          //  we had before, and update and
+          if (new_entry == 1 || timestruc(PS.pr_start) > lasttime) {
+            newproc++;
+            if (new_entry == 0) {
+              // leftover from an old process at same pid
+              if (rpi.orp != NULL) {
+                free(rpi.orp);
+                rpi.orp = NULL;   // dump old rp, and overwrite new
+              }
+// ***************** delete old lwp info *********************
+              if ( wantlwp$ == 1 ) {
+                lwp_t_ptr = rpi.olwp ;
+                rpi.olwp = NULL;
+                while ( lwp_t_ptr != NULL ) {
+                  lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                  free(lwp_t_ptr);
+                  lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+                }
+              }
+// ***************** end delete old lwp info *********************
+            }
+            // static psinfo needs updating
+            rpi.pr_uid = PS.pr_uid;
+            rpi.pr_ppid = PS.pr_ppid;
+            rpi.pr_bindpset = PS.pr_lwp.pr_bindpset;
+            rpi.pr_clname = PS.pr_lwp.pr_clname;
+            rpi.pr_fname = PS.pr_fname;
+            rpi.pr_psargs = PS.pr_psargs;
+          }
+          // update usage data
+          tmp = rpi.orp;  // hang on to malloced data
+          rpi.orp = rpi.nrp;      // switch new to old
+          if (tmp == NULL) {
+            rpi.nrp = malloc(sizeof(ou));
+          } else {
+            rpi.nrp = tmp;
+          }
+          struct_empty(NU, rpi.nrp);      // save whole block
+          // update dynamic psinfo data
+          rpi.pr_oldsize = rpi.pr_size;
+          rpi.pr_size = PS.pr_size;
+          rpi.pr_rssize = PS.pr_rssize;
+          rpi.pr_pri = PS.pr_lwp.pr_pri;
+          rpi.pr_nice = PS.pr_lwp.pr_nice;
+          rpi.pr_sname = PS.pr_lwp.pr_sname;
+          rpi.pr_flag = PS.pr_flag;
+          rpi.o_pr_time = rpi.n_pr_time;
+          rpi.n_pr_time = PS.pr_time;
+          rpi.o_pr_ctime = rpi.n_pr_ctime;
+          rpi.n_pr_ctime = PS.pr_ctime;
+          rpi.gencnt = gen;
+          struct_empty(rpi, pp);
+          nproc++;
+          // printf("processed %d \n" , process_number );
+        } // end of good pfd
+        // step through the files in the directory ...
+        if (action$ == PROC_ACTION_PID) {
+          directory_entry = NULL;
+        } else {
+          directory_entry = readdir(directory_pointer);
+        }
+      } // end of directory
+// **************************************************************
+      // go through list and remove deadwood
+      // printf("first process_number %d  \n",first_process);
+      process_number = first_process;
+      next_process = -1;
+      previous_process = -1;
+      while ( process_number > 0 ) {
+        // printf("processing %d  \n",process_number);
+        if (process_number > 0 ) {
+          pp_ret = int2int_get(pp_tree, process_number);
+          if ( pp_ret == NULL) {
+            printf("unable to get process_number  %d \n", process_number);
+            exit(1);
+          }
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+          if ( pp == NULL) {
+            printf("process_number %d  invalid4 \n",process_number);
+            exit(1);
+          }
+          rpi = *((raw_proc_info_t *) pp); // rpi <- pp
+          next_process = rpi.nextpid;
+          // printf("next process %d  \n",next_process);
+          // unhook dead processes
+          if (rpi.gencnt != gen) {
+            deadproc++;
+            if (rpi.orp != NULL) {
+              free(rpi.orp);
+              rpi.orp = NULL;
+            }
+            if (rpi.nrp != NULL) {
+              free(rpi.nrp);
+              rpi.nrp = NULL;
+            }
+            if ( wantlwp$ == 1 ) {
+              lwp_t_ptr = rpi.olwp ;
+              while ( lwp_t_ptr != NULL ) {
+                lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+              }
+              lwp_t_ptr = t_rpi.nlwp ;
+              while ( lwp_t_ptr != NULL ) {
+                lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+                free(lwp_t_ptr);
+                lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+              }
+            }
+            free(pp);
+            pp_ret = int2int_put(pp_tree, process_number , NULL);
+            if ( pp_ret < 0 ) {
+              printf("unable to free process_number \n");
+              exit(1);
+            }
+            if ( previous_process > 0 ) { // there was a previous process
+              pp_tmp = int2int_get(pp_tree, previous_process);
+              if ( pp_tmp == NULL) {
+                printf("unable to get process_number %d \n",
+                          previous_process);
+                exit(1);
+              }
+              pp = ((ulong_t) *((ulong_t *) pp_tmp));
+              if ( pp == NULL) {
+                 printf("process_number %d invalid5 \n",
+                         previous_process);
+                 exit(1);
+              }
+              rpi = *((raw_proc_info_t *) pp); // rpi <- pp
+              // printf("previous process %d  \n",previous_process);
+              rpi.nextpid = next_process;
+              struct_empty(rpi, pp);
+            } else {
+              first_process = next_process;
+            }
+          } else {
+            // update previous process ptr
+            previous_process = process_number;
+          }
+        }
+        process_number = next_process;
+      }
+      // printf(" end of deadwood removal \n");
+      gettimeofday(tmp_tval,0);
+      lasttime = timeval(tmp_tval[0]);
+      process_number = first_process;
+      index$ = -1;
+    }
+    // printf("done updating \n");
+    // printf("MAX_PID = %d \n", MAX_PID);
+// ****************************** end of update section *******************
+
+    if (action$ == PROC_ACTION_NEXT_INDEX ) {
+      // printf("PROC_ACTION_NEXT_INDEX \n");
+      if (index$ == -1) {
+        process_number = first_process;
+      } else {
+        process_number = rpi.nextpid;
+      }
+      if (process_number < 0 || process_number > MAX_PID) {
+        // ran out of data
+        process_number = -1;
+        index$ = -1;
+        pid$ = -1;
+        // printf(" thats all there is \n");
+        return;
+      }
+      index$++;
+    }
+
+    if (action$ == PROC_ACTION_NEXT_PID) {
+      // printf("PROC_ACTION_NEXT_PID \n");
+      if (index$ == -1) {
+        process_number = 0;
+      } else {
+        process_number++;
+      }
+      index$++;
+      // look for the next data
+      pp = NULL;
+      pp_ret=int2int_get(pp_tree,process_number);
+      if ( pp_ret != NULL ) {
+        pp = ((ulong_t) *((ulong_t *) pp_ret));
+      }
+      while (process_number < MAX_PID && pp == NULL) {
+        process_number++;
+        pp = NULL;
+        pp_ret=int2int_get(pp_tree,process_number);
+        if ( pp_ret != NULL ) {
+          pp = ((ulong_t) *((ulong_t *) pp_ret));
+        }
+      }
+      if (process_number < 0 || process_number > MAX_PID) {
+        // ran out of data
+        process_number = -1;
+        index$ = -1;
+        pid$ = -1;
+        // printf(" ran out of data NEXT PID \n");
+        return;
+      }
+    }
+
+    if (action$ == PROC_ACTION_PID) {
+      process_number = pid$;
+      index$ = 0;
+    }
+
+    // common code to update class once process has been chosen
+
+    pp_ret=int2int_get(pp_tree,process_number);
+    pp = NULL;
+    if (pp_ret != NULL) {
+      pp = ((ulong_t) *((ulong_t *) pp_ret));
+    }
+    if ( pp != NULL) {
+      rpi = *((raw_proc_info_t *) pp);
+      // make sure that all class data is updated
+      // index$ is already set
+      pid$ = process_number;
+      uid = rpi.pr_uid;
+      // nproc, , are already set
+      missedproc = rpi.nextpid; // for debug until fork counting
+
+      // nrp will always be set
+      NU = *((prusage_t *) rpi.nrp);
+      creation = timestruc(NU.pr_create);
+      timestamp = timestruc(NU.pr_tstamp);
+      termination = 0.0; // set later if process is dead
+      elapsed = timestruc(NU.pr_rtime);
+      total_user = timestruc(NU.pr_utime);
+      total_system = timestruc(NU.pr_stime);
+      total_child = timestruc(rpi.n_pr_ctime);
+      total_sampled_cpu = timestruc(rpi.n_pr_time);
+      flags = rpi.pr_flag;
+#ifdef PDEBUG
+      msprint(NU, pid$, rpi.pr_fname, rpi.pr_psargs);
+#endif
+      if (rpi.orp != NULL) {
+        ou = *((prusage_t *) rpi.orp);
+        interval = timestamp - timestruc(ou.pr_tstamp);
+        // interval should never be zero
+        if (interval == 0.0) {
+          printf("zero interval on pid %d state %c\n", pid$, rpi.pr_sname);
+          msprint(ou, pid$, fname, args);
+          interval = 1.0;
+        }
+        user_time = total_user - timestruc(ou.pr_utime);
+        system_time = total_system - timestruc(ou.pr_stime);
+        sampled_cpu = total_sampled_cpu - timestruc(rpi.o_pr_time);
+        trap_time = timestruc(NU.pr_ttime) - timestruc(ou.pr_ttime);
+        child_time = total_child - timestruc(rpi.o_pr_ctime);
+        text_pf_time = timestruc(NU.pr_tftime) - timestruc(ou.pr_tftime);
+        data_pf_time = timestruc(NU.pr_dftime) - timestruc(ou.pr_dftime);
+        kernel_pf_time = timestruc(NU.pr_kftime) - timestruc(ou.pr_kftime);
+        user_lock_time = timestruc(NU.pr_ltime) - timestruc(ou.pr_ltime);
+        sleep_time = timestruc(NU.pr_slptime) - timestruc(ou.pr_slptime);
+        cpu_wait_time = timestruc(NU.pr_wtime) - timestruc(ou.pr_wtime);
+        stoptime = timestruc(NU.pr_stoptime) - timestruc(ou.pr_stoptime);
+        syscalls = NU.pr_sysc - ou.pr_sysc;
+        inblocks = NU.pr_inblk - ou.pr_inblk;
+        outblocks = NU.pr_oublk - ou.pr_oublk;
+        maj_faults = NU.pr_majf - ou.pr_majf;
+        min_faults = NU.pr_minf - ou.pr_minf;
+        messages = (NU.pr_msnd + NU.pr_mrcv) - (ou.pr_msnd + ou.pr_mrcv);
+        signals = NU.pr_sigs - ou.pr_sigs;
+        vcontexts = NU.pr_vctx - ou.pr_vctx;
+        icontexts = NU.pr_ictx - ou.pr_ictx;
+        charios = NU.pr_ioch - ou.pr_ioch;
+      } else {
+        // new process will only have rpi.nrp set
+        interval = timestamp - creation; // elapsed time so far
+        if (interval == 0.0) {
+          printf("zero interval on pid %d state %c\n", pid$, rpi.pr_sname);
+          msprint(NU, pid$, fname, args);
+          interval = 1.0;
+        }
+        user_time = total_user;
+        system_time = total_system;
+        sampled_cpu = total_sampled_cpu;
+        trap_time = timestruc(NU.pr_ttime);
+        child_time = total_child;
+        text_pf_time = timestruc(NU.pr_tftime);
+        data_pf_time = timestruc(NU.pr_dftime);
+        kernel_pf_time = timestruc(NU.pr_kftime);
+        user_lock_time = timestruc(NU.pr_ltime);
+        sleep_time = timestruc(NU.pr_slptime);
+        cpu_wait_time = timestruc(NU.pr_wtime);
+        stoptime = timestruc(NU.pr_stoptime);
+        syscalls = NU.pr_sysc;
+        inblocks = NU.pr_inblk;
+        outblocks = NU.pr_oublk;
+        maj_faults = NU.pr_majf;
+        min_faults = NU.pr_minf;
+        messages = NU.pr_msnd + NU.pr_mrcv;
+        signals = NU.pr_sigs;
+        vcontexts = NU.pr_vctx;
+        icontexts = NU.pr_ictx;
+        charios = NU.pr_ioch;
+      }
+      vmem_size = rpi.pr_size;
+      vmem_delta = rpi.pr_size - rpi.pr_oldsize;
+      rmem_size = rpi.pr_rssize;
+      total_swaps = NU.pr_nswap;
+      priority = rpi.pr_pri;
+      niceness = rpi.pr_nice;
+      sched_class = rpi.pr_clname;
+      lwp_count = NU.pr_count;
+      ppid = rpi.pr_ppid;
+      bindpset = rpi.pr_bindpset;
+      fname = rpi.pr_fname;
+      if (fname == "" && rpi.pr_sname == 'Z') {
+        fname = "Zombie";
+        bindpset = -1;        // no pset, but Zomb defaults to 0
+      }
+      args = rpi.pr_psargs;
+      // bug in sched pid 0 gives 100% system time
+      if (pid$ == 0) {
+        total_system = 0.0;
+        system_time = 0.0;
+      }
+#ifdef PDEBUG
+      printf("interval %.5f\n", interval);
+#endif
+// *******************************************************
+      if ( wantlwp$ == 1 ) {
+        // process lwp info
+        lwp_t_ptr = lwp_class_ptr;
+        lwp_class_ptr = NULL;
+        // if there is an old lwp class linked list free it
+        while ( lwp_t_ptr != NULL ) {
+          lwp_t_class = *((lwp_pr_info *) lwp_t_ptr);
+          free(lwp_t_ptr);
+          lwp_t_ptr = lwp_t_class.next_class ;
+        }
+        // Process lwp information
+        if ( rpi.nlwp != NULL ) {
+          lwp_t_ptr = rpi.nlwp ;
+          while ( lwp_t_ptr != NULL) {
+            lwp_t_struct = *((lwp_prusage *) lwp_t_ptr);
+            lwp_t_class.lwp_id = lwp_t_struct.lwp_pru.pr_lwpid;
+            lwp_t_class.timestamp = timestruc(lwp_t_struct.lwp_pru.pr_tstamp);
+            lwp_t_class.creation = timestruc(lwp_t_struct.lwp_pru.pr_create);
+            lwp_t_class.termination = timestruc(lwp_t_struct.lwp_pru.pr_term);
+            lwp_t_class.user_time = timestruc(lwp_t_struct.lwp_pru.pr_utime);
+            lwp_t_class.system_time = timestruc(lwp_t_struct.lwp_pru.pr_stime) + timestruc(lwp_t_struct.lwp_pru.pr_ttime);
+            lwp_t_class.text_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_tftime) ;
+            lwp_t_class.data_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_dftime) ;
+            lwp_t_class.kernel_pf_time = timestruc(lwp_t_struct.lwp_pru.pr_kftime) ;
+            lwp_t_class.user_lock_time = timestruc(lwp_t_struct.lwp_pru.pr_ltime) ;
+            lwp_t_class.sleep_time = timestruc(lwp_t_struct.lwp_pru.pr_slptime) ;
+            lwp_t_class.cpu_wait_time = timestruc(lwp_t_struct.lwp_pru.pr_wtime) ;
+            lwp_t_class.stoptime = timestruc(lwp_t_struct.lwp_pru.pr_stoptime) ;
+            lwp_t_class.min_faults = lwp_t_struct.lwp_pru.pr_minf ;
+            lwp_t_class.maj_faults = lwp_t_struct.lwp_pru.pr_majf ;
+            lwp_t_class.total_swaps = lwp_t_struct.lwp_pru.pr_nswap;
+            lwp_t_class.inblocks = lwp_t_struct.lwp_pru.pr_inblk ;
+            lwp_t_class.outblocks = lwp_t_struct.lwp_pru.pr_oublk ;
+            lwp_t_class.messages = lwp_t_struct.lwp_pru.pr_msnd + lwp_t_struct.lwp_pru.pr_mrcv;
+            lwp_t_class.signals = lwp_t_struct.lwp_pru.pr_sigs;
+            lwp_t_class.vcontexts = lwp_t_struct.lwp_pru.pr_vctx;
+            lwp_t_class.icontexts = lwp_t_struct.lwp_pru.pr_ictx;
+            lwp_t_class.syscalls = lwp_t_struct.lwp_pru.pr_sysc;
+            lwp_t_class.charios = lwp_t_struct.lwp_pru.pr_ioch;
+
+            olwp_t_ptr = rpi.olwp;
+            while ( olwp_t_ptr != NULL ) {
+              olwp_t_struct = *((lwp_prusage *) olwp_t_ptr);
+              if ( olwp_t_struct.lwp_pru.pr_lwpid ==
+                    lwp_t_struct.lwp_pru.pr_lwpid) {
+                break;
+              }
+              olwp_t_ptr = olwp_t_struct.next_lwp_pru ;
+            }
+            if ( olwp_t_ptr != NULL) {
+              lwp_t_class.user_time =  lwp_t_class.user_time - timestruc(olwp_t_struct.lwp_pru.pr_utime);
+              lwp_t_class.system_time = lwp_t_class.system_time - timestruc(olwp_t_struct.lwp_pru.pr_stime) - timestruc(olwp_t_struct.lwp_pru.pr_ttime);
+              lwp_t_class.text_pf_time = lwp_t_class.text_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_tftime) ;
+              lwp_t_class.data_pf_time = lwp_t_class.data_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_dftime) ;
+              lwp_t_class.kernel_pf_time = lwp_t_class.kernel_pf_time - timestruc(olwp_t_struct.lwp_pru.pr_kftime) ;
+              lwp_t_class.user_lock_time = lwp_t_class.user_lock_time  - timestruc(olwp_t_struct.lwp_pru.pr_ltime) ;
+              lwp_t_class.sleep_time = lwp_t_class.sleep_time - timestruc(olwp_t_struct.lwp_pru.pr_slptime) ;
+              lwp_t_class.cpu_wait_time = lwp_t_class.cpu_wait_time - timestruc(olwp_t_struct.lwp_pru.pr_wtime) ;
+              lwp_t_class.stoptime = lwp_t_class.stoptime - timestruc(olwp_t_struct.lwp_pru.pr_stoptime) ;
+              lwp_t_class.min_faults = lwp_t_class.min_faults  - olwp_t_struct.lwp_pru.pr_minf ;
+              lwp_t_class.maj_faults = lwp_t_class.maj_faults - olwp_t_struct.lwp_pru.pr_majf ;
+              lwp_t_class.total_swaps = lwp_t_class.total_swaps  - olwp_t_struct.lwp_pru.pr_nswap;
+              lwp_t_class.inblocks = lwp_t_class.inblocks  - olwp_t_struct.lwp_pru.pr_inblk ;
+              lwp_t_class.outblocks = lwp_t_class.outblocks - olwp_t_struct.lwp_pru.pr_oublk ;
+              lwp_t_class.messages = lwp_t_class.messages - olwp_t_struct.lwp_pru.pr_msnd + lwp_t_struct.lwp_pru.pr_mrcv;
+              lwp_t_class.signals = lwp_t_class.signals - olwp_t_struct.lwp_pru.pr_sigs;
+              lwp_t_class.vcontexts = lwp_t_class.vcontexts  - olwp_t_struct.lwp_pru.pr_vctx;
+              lwp_t_class.icontexts = lwp_t_class.icontexts - olwp_t_struct.lwp_pru.pr_ictx;
+              lwp_t_class.syscalls = lwp_t_class.syscalls - olwp_t_struct.lwp_pru.pr_sysc;
+              lwp_t_class.charios = lwp_t_class.charios - olwp_t_struct.lwp_pru.pr_ioch;
+
+            } // end of if old pointer
+            lwp_t_class_ptr = malloc(sizeof(lwp_t_class));
+            memset(lwp_t_class_ptr, NULL, sizeof(lwp_t_class));
+            lwp_t_class.next_class = lwp_class_ptr;
+            lwp_class_ptr = lwp_t_class_ptr;
+            struct_empty(lwp_t_class, lwp_t_class_ptr);
+            lwp_t_ptr = lwp_t_struct.next_lwp_pru ;
+          } // end of while
+        } // end of if we have lwps
+      } // end of we want lwps
+    } else { // End if valid pp
+      process_number = -1;
+      index$ = -1;
+      pid$ = -1;
+    }
+  }
+};
+
+#endif



More information about the Orca-checkins mailing list