代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "machine.h"
#include "top.h"
#include "os.h"
#include "utils.h"
//#define HASH_SIZE 1024
#define NR_TASKS 1024;
#define PROCFS "/proc"
extern char *myname;
extern uid_t proc_owner(pid_t pid);
/*=STATE IDENT STRINGS==================================================*/
#define NPROCSTATES 7
static char *state_abbrev[NPROCSTATES+1] =
{
"", "run", "sleep", "disk", "zomb", "stop", "swap",
NULL
};
static char *procstatenames[NPROCSTATES+1] =
{
"", " running, ", " sleeping, ", " uninterruptable, ",
" zombie, ", " stopped, ", " swapping, ",
NULL
};
#define NCPUSTATES 4
static char *cpustatenames[NCPUSTATES+1] =
{
"user", "nice", "system", "idle",
NULL
};
#define NMEMSTATS 6
static char *memorynames[NMEMSTATS+1] =
{
"K used, ", "K free, ", "K shd, ", "K buf Swap: ",
"K used, ", "K free",
NULL
};
static char fmt_header[] =
" PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND";
/*=SYSTEM STATE INFO====================================================*/
/* these are for calculating cpu state percentages */
static long cp_time[NCPUSTATES];
static long cp_old[NCPUSTATES];
static long cp_diff[NCPUSTATES];
/* these are for keeping track of processes */
#define HASH_SIZE (NR_TASKS * 3 / 2)
static struct top_proc **nextactive;
/* these are for passing data back to the machine independant portion */
static int cpu_states[NCPUSTATES];
static int memory_stats[NMEMSTATS];
/* usefull macros */
#define bytetok(x) (((x) + 512) >> 10)
#define pagetok(x) ((x) << (PAGE_SHIFT - 10))
#define HASH(x) (((x) * 1686629713U) % HASH_SIZE)
/*======================================================================*/
/*
* percentages(cnt, out, new, old, diffs) - calculate percentage change
* between array "old" and "new", putting the percentages i "out".
* "cnt" is size of each array and "diffs" is used for scratch space.
* The array "old" is updated on each call.
* The routine assumes modulo arithmetic. This function is especially
* useful on BSD mchines for calculating cpu state percentages.
*/
long percentages(cnt, out, new, old, diffs)
int cnt;
int *out;
register long *new;
register long *old;
long *diffs;
{
register int i;
register long change;
register long total_change;
register long *dp;
long half_total;
/* initialization */
total_change = 0;
dp = diffs;
/* calculate changes for each state and the overall change */
for (i = 0; i < cnt; i++)
{
if ((change = *new - *old) < 0)
{
/* this only happens when the counter wraps */
change = (int)
((unsigned long)*new-(unsigned long)*old);
}
total_change += (*dp++ = change);
*old++ = *new++;
}
/* avoid divide by zero potential */
if (total_change == 0)
{
total_change = 1;
}
/* calculate percentages based on overall change, rounding up */
half_total = total_change / 2l;
for (i = 0; i < cnt; i++)
{
*out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
}
/* return the total in case the caller wants to use it */
return(total_change);
}
static inline char *
skip_token(const char *p)
{
while (isspace(*p)) p++;
while (*p && !isspace(*p)) p++;
return (char *)p;
}
static inline char *
skip_ws(const char *p)
{
while (isspace(*p)) p++;
return (char *)p;
}
void get_system_info(info)
struct system_info *info;
{
char buffer[4096+1];
int fd, len;
char *p;
int i;
/* get load averages */
{
fd = open("/proc/loadavg", O_RDONLY);
len = read(fd, buffer, sizeof(buffer)-1);
close(fd);
buffer[len] = '/0';
info->load_avg[0] = strtod(buffer, &p);
info->load_avg[1] = strtod(p, &p);
info->load_avg[2] = strtod(p, &p);
p = skip_token(p); /* skip running/tasks */
p = skip_ws(p);
if (*p)
info->last_pid = atoi(p);
else
info->last_pid = -1;
}
/* get the cpu time info */
{
fd = open("/proc/stat", O_RDONLY);
len = read(fd, buffer, sizeof(buffer)-1);
close(fd);
buffer[len] = '/0';
p = skip_token(buffer); /* "cpu" */
cp_time[0] = strtoul(p, &p, 0);
cp_time[1] = strtoul(p, &p, 0);
cp_time[2] = strtoul(p, &p, 0);
cp_time[3] = strtoul(p, &p, 0);
/* convert cp_time counts to percentages
after this funcation, cpu_states[0] stores the percentage of used cpu
*/
percentages(4, cpu_states, cp_time, cp_old, cp_diff);
}
/* get system wide memory usage */
{
char *p;
fd = open("/proc/meminfo", O_RDONLY);
len = read(fd, buffer, sizeof(buffer)-1);
close(fd);
buffer[len] = '/0';
/* be prepared for extra columns to appear be seeking
to ends of lines */
p = buffer;
p = skip_token(p);
memory_stats[0] = strtoul(p, &p, 10); /* total memory */
p = strchr(p, '/n');
p = skip_token(p);
memory_stats[1] = strtoul(p, &p, 10); /* free memory */
p = strchr(p, '/n');
p = skip_token(p);
memory_stats[2] = strtoul(p, &p, 10); /* buffer memory */
p = strchr(p, '/n');
p = skip_token(p);
memory_stats[3] = strtoul(p, &p, 10); /* cached memory */
for(i = 0; i< 8 ;i++) {
p++;
p = strchr(p, '/n');
}
p = skip_token(p);
memory_stats[4] = strtoul(p, &p, 10); /* total swap */
p = strchr(p, '/n');
p = skip_token(p);
memory_stats[5] = strtoul(p, &p, 10); /* free swap */
}
/* set arrays and strings */
info->cpustates = cpu_states;
info->memory = memory_stats;
}
int main_old()
{
int i;
struct system_info info;
get_system_info(&info);
for(i=0;i<3;i++){
if(i==2){
printf("Used CPU:%.1f%%/n",(float)info.cpustates[0]/10);
printf("Nice CPU:%.1f%%/n",(float)info.cpustates[1]/10);
printf("System CPU:%.1f%%/n",(float)info.cpustates[2]/10);
printf("Idle CPU:%.1f%%/n",(float)info.cpustates[3]/10);
printf("total memroy:%d/n", info.memory[0]);
printf("free memroy:%d/n", info.memory[1]);
printf("buffers:%d/n", info.memory[2]);
printf("cached:%d/n", info.memory[3]);
printf("total swap:%d/n", info.memory[4]);
printf("free swap:%d/n", info.memory[5]);
printf("................................../n");
}
sleep(2);
get_system_info(&info);
}
return 0;
}
int main()
{
int i;
struct system_info info;
get_system_info(&info);
for(i=0;i<3;i++){
if(i==2){
/*
printf("Used CPU:%.1f%%/n",(float)info.cpustates[0]/10);
printf("Nice CPU:%.1f%%/n",(float)info.cpustates[1]/10);
printf("System CPU:%.1f%%/n",(float)info.cpustates[2]/10);
printf("Idle CPU:%.1f%%/n",(float)info.cpustates[3]/10);
printf("total memroy:%d/n", info.memory[0]);
printf("free memroy:%d/n", info.memory[1]);
printf("buffers:%d/n", info.memory[2]);
printf("cached:%d/n", info.memory[3]);
printf("total swap:%d/n", info.memory[4]);
printf("free swap:%d/n", info.memory[5]);
printf("................................../n");
printf("Used CPU:%.1f%%/n",(float)info.cpustates[0]/10);
printf("Used CPU:%.1f%%/n",(float)info.cpustates[0]);
printf("Used CPU:%.1f%%/n",(float)info.cpustates[0]/10);
*/
printf("%d/n",(int)info.cpustates[0]); //
return 0;
}
sleep(2);
get_system_info(&info);
}
return (float)0;
}