$NetBSD: patch-aj,v 1.3 2000/06/16 23:40:17 wiz Exp $ --- glunix/src/idle/didle_sysinfo.cc.orig Thu Sep 18 21:04:55 1997 +++ glunix/src/idle/didle_sysinfo.cc Sat Jun 17 01:07:46 2000 @@ -95,14 +95,33 @@ #include #include #include + +#ifdef __NetBSD__ +#include +#include +#include +#include +#include +#if __NetBSD_Version__ < 104000200 +#include +#else /* moved to sys in 1.4.2 */ +#include +#endif +#include +#else #include #include #include #include #include +#endif + #include #include + +#ifndef __NetBSD__ #include // Contains defns for swap virtual memory info +#endif #include "clist.h" #include "cidle.h" @@ -120,12 +139,51 @@ #define LOADDOUBLE(la) ((double)(la) / FSCALE) #define HASH(x) ((x) >> 1) + +#ifdef __NetBSD__ +int getpsize() +{ + FILE *file; + char *buf; + + file = fopen("/kern/pagesize","r"); + fscanf(file,"%s",buf); + fclose(file); + return atoi(buf); +} +#define PAGETOK(size) (size) * getpsize() + +#else #define PAGETOK(size) (size) << 3 // 8K pages +#endif +#ifndef __NetBSD__ #define MAX(a, b) (((a) > (b)) ? (a) : (b)) - +#endif /*****************************************************************************/ +#ifdef __NetBSD__ +static struct nlist nlst[] = { +#define X_CCPU 0 + { "_ccpu" }, /* 0 */ +#define X_CP_TIME 1 + { "_cp_time" }, /* 1 */ +#define X_HZ 2 + { "_hz" }, /* 2 */ +#define X_STATHZ 3 + { "_stathz" }, /* 3 */ +#define X_AVENRUN 4 + { "_averunnable" }, /* 4 */ +#define X_CNT 5 + { "_cnt" }, + + { 0 } +}; + +static ulong cp_time_offset,cnt_offset; + +#else + /* definitions for indices in the nlist array */ #define X_AVENRUN 0 #define X_MPID 1 @@ -165,11 +223,11 @@ // These are offsets into kmem for the stats we need static ulong avenrunOffset, availrmemOffset, anoninfoOffset, swapfsOffset; - +#endif /*****************************************************************************/ /* These two declarations are no longer necessary */ -#ifdef 0 +#if 0 static int cpuStates[NUM_CPUSTATES]; static int memoryStats[5]; static char *cpuStateNames[] = @@ -237,6 +295,45 @@ * * Side effects: *****************************************************************************/ +#ifdef __NetBSD__ +Bool +Idle_InitializeSysinfo(void) +{ + int notFound; + int i; + + if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) { + kd = NULL; + perror("(dile)Idle_InitializeSysinfo: kvm_open"); + return -1; + } + /* get the list of symbols we want to access in the kernel */ + if ((notFound = kvm_nlist(kd, nlst)) < 0) { + fprintf(stderr, "res: nlist failed\n"); + return False; + } + numCpus=1; + cp_time_offset = nlst[X_CP_TIME].n_value; + cnt_offset = nlst[X_CNT].n_value; + + if (!(procdir = opendir(PROCFS))) { + (void) fprintf(stderr, "Unable to open %s\n", PROCFS); + return False; + } + /* handy for later on when we're reading it */ + if (chdir(PROCFS)) { + (void) fprintf(stderr, "Unable to chdir to %s\n", PROCFS); + return False; + } + + for (i = 0; i < USAGE_TABLE_SIZE; i++) { + procUsageTable[i].pid = -1; + procUsageTable[i].cpuUsage = 0.0; + } + + return True; +} +#else Bool Idle_InitializeSysinfo(void) { @@ -301,7 +398,7 @@ return True; } - +#endif /****************************************************************************** * Idle_CleanupSysinfo -- * Description of purpose and function of the procedure @@ -333,18 +430,30 @@ * * Side effects: *****************************************************************************/ +#ifdef __NetBSD__ +static ProcUsage * +FindEntry(pid_t pid, double usage) +#else static ProcUsage * FindEntry(struct prpsinfo *targProc, double usage) +#endif { int index, start; ProcUsage *candidate; +#ifdef __NetBSD__ + index = HASH(pid); +#else ASSERT(targProc != NULL); - index = HASH(targProc->pr_pid); +#endif start = index; while (1) { candidate = &(procUsageTable[index]); +#ifdef __NetBSD__ + if (candidate->pid == pid) { +#else if (candidate->pid == targProc->pr_pid) { +#endif /* Has this pid been recycled? Are we hitting a very old process? If so, then reset the entry */ if (usage < candidate->cpuUsage) { @@ -353,7 +462,11 @@ return candidate; } if (candidate->pid == -1) { +#ifdef __NetBSD__ + candidate->pid = pid; +#else candidate->pid = targProc->pr_pid; +#endif candidate->cpuUsage = 0; return candidate; } @@ -379,10 +492,17 @@ * * Side effects: *****************************************************************************/ + +#ifdef __NetBSD__ +static void +UpdateEntry(ProcUsage *entry, double usage) +{ +#else static void UpdateEntry(ProcUsage *entry, struct prpsinfo *proc, double usage) { UNUSED_PARAM(proc); +#endif ASSERT(entry != NULL); entry->cpuUsage = usage; } @@ -408,12 +528,24 @@ void Idle_GetSysInfo(Idle_Load *total, Idle_Load *seq, List_List *glunixProcs) { + +#ifndef __NetBSD__ struct prpsinfo currproc; /* pointer to current proc structure */ +#else + struct kinfo_proc *procs; + int mib[3],i; + size_t size; +#endif + +#ifndef __NetBSD__ int fd; +#endif int activeMemory[2]; int vmInUse[2]; int cpuUsage[2]; +#ifndef __NetBSD__ struct dirent *direntp; +#endif static struct timeval lastTime = {0, 0}; struct timeval currTime; double alpha, beta; @@ -459,6 +591,33 @@ vmInUse[TOTAL] = 0; vmInUse[SEQUENTIAL] = 0; cpuUsage[TOTAL] = 0; cpuUsage[SEQUENTIAL] = 0; numProcs = 0; + +#ifdef __NetBSD__ + size = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_ALL; + + sysctl(mib, 3, NULL, &size, NULL, 0); + procs = (struct kinfo_proc *)malloc(size); + sysctl(mib, 3, procs, &size, NULL, 0); + numProcs = size / sizeof(struct kinfo_proc); + + for (i=0; icpuUsage) / timeDiff; + UpdateEntry(oldProc, currUsage); + cpuUsage[TOTAL] += (int) (percentCpu * 10.0); + if (glunixProcs->KeySearch(procs[i].kp_proc.p_pid) == NULL) { + activeMemory[SEQUENTIAL] += procs[i].kp_eproc.e_xrssize; + vmInUse[SEQUENTIAL] += procs[i].kp_eproc.e_xsize; + cpuUsage[SEQUENTIAL] += (int) (percentCpu * 10.0); + } + } +#else rewinddir(procdir); while ((direntp = readdir(procdir)) != 0) { @@ -493,6 +652,7 @@ (void) close(fd); numProcs++; } +#endif total->mem = activeMemory[TOTAL]; total->cpu = cpuUsage[TOTAL]; seq->mem = activeMemory[SEQUENTIAL]; @@ -503,10 +663,21 @@ void Idle_GetSystemInfo(Idle_SystemLoad *sysLoad) { - struct anoninfo anoninfo; +#ifndef __NetBSD__ + int i; long avenrun[3]; + struct anoninfo anoninfo; int ani_max, ani_resv, availrmem, swapfs_minfree; - int i; +#else + int i; + double avenrun[3]; + int mib[2]; + struct vmtotal total; + int sizeofvmtotal; + struct swapent *sep; + int totalsize, size, totalinuse, inuse, ncounted; + int rnswap, nswap; +#endif if (kd == NULL) { sysLoad->loadAvg[0] = 0; @@ -515,7 +686,48 @@ sysLoad->memory = 0; return; } +#ifdef __NetBSD__ + getloadavg(avenrun,3); + for (i = 0; i < 3; i++) { + sysLoad->loadAvg[i] = avenrun[i]; + } + + sep = NULL; + do { + nswap = swapctl(SWAP_NSWAP, 0, 0); + if (nswap < 1) + break; + sep = (struct swapent *)malloc(nswap * sizeof(*sep)); + if (sep == NULL) + break; + rnswap = swapctl(SWAP_STATS, (void *)sep, nswap); + if (nswap != rnswap) + break; + + totalsize = totalinuse = ncounted = 0; + for (; rnswap-- > 0; sep++) { + ncounted++; + size = sep->se_nblks; + inuse = sep->se_inuse; + totalsize += size; + totalinuse += inuse; + } + + } while (0); + if (sep) + free(sep); + + sizeofvmtotal = sizeof(total); + mib[0] = CTL_VM; + mib[1] = VM_METER; + if (sysctl(mib, 2, &total, &sizeofvmtotal, NULL, 0) < 0) { + printf("Can't get vmtotals: %s\n", + strerror(errno)); + memset(&total, 0, sizeof(total)); + } + sysLoad->memory = PAGETOK(dbtob(totalsize) - dbtob(totalinuse) + total.t_free); +#else /* get load average array */ ReadKernelData(avenrunOffset, (char *) avenrun, sizeof (avenrun)); // @@ -539,6 +751,7 @@ sysLoad->memory = PAGETOK(MAX(ani_max - ani_resv, 0) + availrmem - swapfs_minfree); +#endif return; }