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

Blair Zajac blair at orcaware.com
Thu Nov 18 09:26:49 PST 2004


Dmitry Berezin wrote:
> Blair,
> 
> You are right; this is the same copy from 3.3.1. As far as I know, this file
> is only being used by original workload_class.se and our workinfo_class.se,
> so it should be fine to use the same version. I don't think I have 3.2.1,
> but I should be able to find 3.3 to test this against. I am about to commit
> the actual bug fix, so I will mention the version info in the comments.
> 
>   -Dmitry.

Dmitry,

Turns out that the 3.3 and the 3.3.1 versions are identical.  The 3.2.1 
is significantly different in terms of a cursory examination of a diff, 
so it's probably best to replace the 3.2.1 process_class.se with the one 
I'm attaching and then apply your patches to that.

Regarding the commit log, it's better to change the commit log for that 
revision than put the info in another commit.  A new developer wondering 
where these files come from won't notice that a following commit message 
has the info.  Commands like this will do the trick to modify a commit log.

svn propget --revprop -r 403 svn:log > log.txt
vi log.txt
svn propset --revprop -r 403 svn:log -F log.txt
rm log.txt

BTW, changing commit log messages is pretty common.

Regards,
Blair

-- 
Blair Zajac <blair at orcaware.com>
Plots of your system's performance - http://www.orcaware.com/orca/
-------------- next part --------------

// 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
*/

#include <se_trees.se>
#if MINOR_VERSION >= 60
#define	PCSET    16	/* set modes from long argument */
#define PCUNSET  17 

long msaccton[2] = { PCSET, PR_MSACCT | PR_MSFORK };
long msacctoff[2] = { PCUNSET, PR_MSACCT };
#else
printf(" OS Version < 2.6 not supported \n ");
exit(1);
#endif

/* 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 */
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) {
    printf("\n%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);
}

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 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));
		}
		/* printf("returning from init \n"); */
		return;
	  }

	  /* printf("index = %d PID = %d \n",index$, pid$);  */

	  if (index$ == -1) {	/* update the data from /proc */
	    /* printf("update the data from /proc  \n"); */
            /* debug_on(); */
	    /* 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;
	    for (; 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);
	      /* printf("looking at %d \n" , process_number ); */
              }
#if MINOR_VERSION < 60
		printf(" OS Version < 2.6 not supported \n ");
		exit(1);
#else
              procname = sprintf("/proc/%d/usage", process_number);
#endif
	      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 */
                    /* printf (" size of lwp_prusage = %d, size from pr header = %d \n", sizeof(lwp_info), prh.size_of_entries ); */
                    /* 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++;
		  /* printf("process_number %d  being deleted \n",process_number);  */
	      	  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 */
          /* printf("process number = %d \n", process_number); */
	  /* printf("retreiving process_number %d  , PID$ %d \n",process_number, pid$); */
          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$, fname, args);
#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);
                user_lock_time = timestruc(NU.pr_ltime);
                stoptime = timestruc(NU.pr_stoptime);
                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;
                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 */
/* End if valid pp */ 
}else {
	      process_number = -1;
	      index$ = -1;
	      pid$ = -1;
	      /* printf(" ran out of data NEXT PID \n"); */
       }
}
};
     
     


More information about the Orca-dev mailing list