/* ========================================================================= */ struct cpustats *ParseCPUStats(struct cpustats *cpus, void *statbuf) { char line[256]; struct bufhandle bh; int cpulncnt = 0; if ( cpus == NULL ) { bh.buf = statbuf; bh.readptr = statbuf; while(get_cpu_line(line, 256, &bh)) { cpulncnt++; } cpus = alloc_cpustats(cpulncnt); } /* Now start reading in data */ bh.buf = statbuf; bh.readptr = statbuf; while(get_cpu_line(line, 256, &bh)) { parse_cpu_line(cpus, line); } return(cpus); }
/* Name: GetCPUStats (Externally exposed function - see header file) * Description: - * Parameters: - * Returns: - * Side effects: - * Notes: This code has a STUB in it. */ struct cpustats *GetCPUStats(struct cpustats *cpus) { char line[256]; struct bufhandle bh; void *readbuf; unsigned long bufsize; int cpulncnt = 0; int index_cpus = 0; /* Should we index the CPUs (or not) */ //STUB fprintf(stderr, "GetCPUStats("); //STUB fprintf(stderr, "1"); /* Check for NULL input - and handle the buffer part ONLY */ if ( NULL == cpus ) { /* Determine how big the buffer needs to be */ if ( 0 == (bufsize = read_proc_stat(NULL, 0)) ) return(NULL); /* Allocate some memory for it based on what we just found */ if ( NULL == (readbuf = malloc(bufsize)) ) return(NULL); } else { readbuf = cpus->buf; /* Get the already allocated buffer */ bufsize = cpus->bufsize; /* Get the size of the buffer */ cpus->isvalid = 0; /* Consider invalid until done */ } //STUBfprintf(stderr, "2"); /* So now readbuf is good, and the bufsize is good, read in actual data */ if ( 0 == read_proc_stat(readbuf, bufsize) ) return(cpus); /* If cpus struct is null - then allocate it */ if ( cpus == NULL ) { /* Set up our buffer pointers */ bh.buf = readbuf; bh.readptr = readbuf; /* Make a note to index the CPU list */ index_cpus = 1; /* Read data out of the buffer - just to count CPU lines */ while(get_cpu_line(line, 256, &bh)) { cpulncnt++; } /* Allocate the cpustats structure */ if ( NULL == (cpus = alloc_cpustats(cpulncnt)) ) { free(readbuf); /* Do this because we know it does not belong to a cpustats struct */ return(NULL); } /* Add-in our previously allocated read buffer */ cpus->buf = readbuf; cpus->bufsize = bufsize; /* Mark this read as invalid - as we are not done at this time */ cpus->isvalid = 0; } /* Now start reading data into the cpustats struct */ bh.buf = readbuf; bh.readptr = readbuf; while(get_cpu_line(line, 256, &bh)) { parse_cpu_line(cpus, line); } /* STUB: Probably should be validating against the results of parse_cpu_line() */ cpus->isvalid = 0; #ifdef STUB_DEBUG if ( index_cpus ) { if (build_cpu_index(cpus)) { /* This will be our first time through. All memory has been successfully allocated, so it must all be freed. */ /* STUB: Call free_all_cpus() - after you write it */ return(NULL); } } #endif //STUB fprintf(stderr, ");\n"); return(cpus); }
int cpu(int argc, char **argv) { FILE *f; char buff[256]; int ncpu = 0, extinfo = 0, ret; bool scaleto100 = false; if (argc > 1) { if (!strcmp(argv[1], "config")) { char *s = getenv("scaleto100"); if (s && !strcmp(s, "yes")) scaleto100 = true; if (!(f = fopen(PROC_STAT, "r"))) return fail("cannot open " PROC_STAT); while (fgets(buff, 256, f)) { if (!strncmp(buff, "cpu", 3)) { if (xisdigit(buff[3])) ncpu++; if (buff[3] == ' ' && 0 == extinfo) { strtok(buff + 4, " \t"); for (extinfo = 1; strtok(NULL, " \t"); extinfo++); } } } fclose(f); if (ncpu < 1 || extinfo < 4) return fail("cannot parse " PROC_STAT); puts("graph_title CPU usage"); if (extinfo >= 7) puts("graph_order system user nice idle iowait irq softirq"); else puts("graph_order system user nice idle"); if (scaleto100) puts("graph_args --base 1000 -r --lower-limit 0 --upper-limit 100"); else printf ("graph_args --base 1000 -r --lower-limit 0 --upper-limit %d\n", 110 * ncpu); puts("graph_vlabel %\n" "graph_scale no\n" "graph_info This graph shows how CPU time is spent.\n" "graph_category system\n" "graph_period second\n" "system.label system\n" "system.draw AREA"); printf("system.max %d\n", 110 * ncpu); puts("system.min 0\n" "system.type DERIVE"); printf("system.warning %d\n", SYSWARNING * ncpu); printf("system.critical %d\n", SYSCRITICAL * ncpu); puts("system.info CPU time spent by the kernel in system activities\n" "user.label user\n" "user.draw STACK\n" "user.min 0"); printf("user.max %d\n", 110 * ncpu); printf("user.warning %d\n", USRWARNING * ncpu); puts("user.type DERIVE\n" "user.info CPU time spent by normal programs and daemons\n" "nice.label nice\n" "nice.draw STACK\n" "nice.min 0"); printf("nice.max %d\n", 110 * ncpu); puts("nice.type DERIVE\n" "nice.info CPU time spent by nice(1)d programs\n" "idle.label idle\n" "idle.draw STACK\n" "idle.min 0"); printf("idle.max %d\n", 110 * ncpu); puts("idle.type DERIVE\n" "idle.info Idle CPU time"); if (scaleto100) printf("system.cdef system,%d,/\n" "user.cdef user,%d,/\n" "nice.cdef nice,%d,/\n" "idle.cdef idle,%d,/\n", ncpu, ncpu, ncpu, ncpu); if (extinfo >= 7) { puts("iowait.label iowait\n" "iowait.draw STACK\n" "iowait.min 0"); printf("iowait.max %d\n", 110 * ncpu); puts("iowait.type DERIVE\n" "iowait.info CPU time spent waiting for I/O operations to finish\n" "irq.label irq\n" "irq.draw STACK\n" "irq.min 0"); printf("irq.max %d\n", 110 * ncpu); puts("irq.type DERIVE\n" "irq.info CPU time spent handling interrupts\n" "softirq.label softirq\n" "softirq.draw STACK\n" "softirq.min 0"); printf("softirq.max %d\n", 110 * ncpu); puts("softirq.type DERIVE\n" "softirq.info CPU time spent handling \"batched\" interrupts"); if (scaleto100) printf("iowait.cdef iowait,%d,/\n" "irq.cdef irq,%d,/\n" "softirq.cdef softirq,%d,/\n", ncpu, ncpu, ncpu); } if (extinfo >= 8) { puts("steal.label steal\n" "steal.draw STACK\n" "steal.min 0"); printf("steal.max %d\n", 110 * ncpu); puts("steal.type DERIVE\n" "steal.info The time that a virtual CPU had runnable tasks, but the virtual CPU itself was not running"); if (scaleto100) printf("steal.cdef steal,%d,/\n", ncpu); } if (extinfo >= 9) { puts("guest.label guest\n" "guest.draw STACK\n" "guest.min 0"); printf("guest.max %d\n", 110 * ncpu); puts("guest.type DERIVE\n" "guest.info The time spent running a virtual CPU for guest operating systems under the control of the Linux kernel."); if (scaleto100) printf("guest.cdef guest,%d,/\n", ncpu); } return 0; } if (!strcmp(argv[1], "autoconf")) return autoconf_check_readable(PROC_STAT); } if (!(f = fopen(PROC_STAT, "r"))) return fail("cannot open " PROC_STAT); while (fgets(buff, 256, f)) { if (!strncmp(buff, "cpu ", 4)) { ret = parse_cpu_line(buff); goto OK; } } /* We didn't find anyting */ ret = fail("no cpu line found in " PROC_STAT); OK: fclose(f); return ret; }