|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <pwd.h>
|
|
#include <curses.h>
|
|
#include <stdlib.h>
|
|
#include <limits.h>
|
|
#include <termcap.h>
|
|
#include <termios.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <dirent.h>
|
|
#include <assert.h>
|
|
|
|
struct proc {
|
|
pid_t pid;
|
|
int tick;
|
|
};
|
|
|
|
void print_procs(
|
|
struct proc *proc1, struct proc *proc2, int cputimemode)
|
|
{
|
|
int p, nprocs;
|
|
u64_t idleticks = 0;
|
|
u64_t kernelticks = 0;
|
|
u64_t systemticks = 0;
|
|
u64_t userticks = 0;
|
|
u64_t total_ticks = 0;
|
|
int blockedseen = 0;
|
|
static struct proc *tick_procs = NULL;
|
|
tick_procs = malloc(nr_total * sizeof(struct proc));
|
|
|
|
|
|
for(p = nprocs = 0; p < nr_total; p++) {
|
|
u64_t uticks;
|
|
//如果当前进程标志不是used就continue 看下一个进程。
|
|
if(!(proc2[p].p_flags & USED))
|
|
continue;
|
|
tick_procs[nprocs].p = proc2 + p;
|
|
tick_procs[nprocs].ticks = cputicks(&proc1[p], &proc2[p], cputimemode);
|
|
//更新实时uticks
|
|
uticks = cputicks(&proc1[p], &proc2[p], 1);
|
|
//算出总的ticks
|
|
total_ticks = total_ticks + uticks;
|
|
//判断是否为idletick
|
|
//为0一直continue 不用计算
|
|
if(p-5 == 317) {
|
|
idleticks = uticks;
|
|
continue;
|
|
}
|
|
//判断是否为kerneltick
|
|
if(p-5 == ((endpoint_t) -1)) {
|
|
kernelticks = uticks;
|
|
}
|
|
if(!(proc2[p].p_flags & IS_TASK)) {
|
|
if(proc2[p].p_flags & IS_SYSTEM)
|
|
systemticks = systemticks + tick_procs[nprocs].ticks;
|
|
else
|
|
userticks = userticks + tick_procs[nprocs].ticks;
|
|
}
|
|
|
|
nprocs++;
|
|
}
|
|
|
|
if (total_ticks == 0)
|
|
return;
|
|
printf("CPU states: %6.2f%%", 100.0 * usedticks / total_ticks);
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
|
|
int print_memory(void)
|
|
{
|
|
FILE *fp;
|
|
unsigned int pagesize;
|
|
unsigned long total, free, largest, cached;
|
|
if ((fp = fopen("/proc/meminfo", "r")) == NULL)
|
|
return 0;
|
|
if (fscanf(fp, "%u %lu %lu %lu %lu", &pagesize, &total, &free,
|
|
&largest, &cached) != 5) {
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
fclose(fp);
|
|
printf("main memory: %ldK total, %ldK free, %ldK contig free, "
|
|
"%ldK cached\n",
|
|
(pagesize * total)/1024, (pagesize * free)/1024,
|
|
(pagesize * largest)/1024, (pagesize * cached)/1024);
|
|
return 1;
|
|
}
|
|
|
|
int nr_procs, nr_tasks, nr_total;
|
|
void getkinfo(void)
|
|
{
|
|
FILE *fp;
|
|
if ((fp = fopen("/proc/kinfo", "r")) == NULL) {
|
|
|
|
exit(1);
|
|
}
|
|
if (fscanf(fp, "%u %u", &nr_procs, &nr_tasks) != 2) {
|
|
|
|
exit(1);
|
|
}
|
|
fclose(fp);
|
|
nr_total = (int) (nr_procs + nr_tasks);
|
|
}
|
|
|
|
void parse_psinfo(pid_t pid, struct proc pro)
|
|
{
|
|
char path[PATH_MAX];
|
|
char name[256], type, state;
|
|
int version, endpt, blocked, priority, tick;
|
|
FILE *fp;
|
|
sprintf(path, "/proc/%d/psinfo", pid);
|
|
if ((fp = fopen(path, "r")) == NULL)
|
|
return;
|
|
if (fscanf(fp, "%d %c %d %s %c %d %d", &version, &type, &endpt, name, &state, &blocked, &priority) != 7)
|
|
{
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
//读入 滴答
|
|
if (fscanf(fp, "%d", &tick) < 0)
|
|
{
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
//存入进程结构体
|
|
pro.pid = pid;
|
|
pro.tick = tick;
|
|
fclose(fp);
|
|
}
|
|
|
|
void parse_dir(process)
|
|
{
|
|
DIR *p_dir;
|
|
struct dirent *p_ent;
|
|
pid_t pid;
|
|
char *end;
|
|
p_dir = opendir("/proc/");
|
|
//readdir(),/proc/pid/psinfo,/proc/内文件名为PID
|
|
p_ent=readdir(p_dir);
|
|
int i=0;
|
|
while(p_ent != NULL)
|
|
{
|
|
pid=strtol(p_ent->d_name,&end,10);
|
|
if(pid!=0 && !end[0])
|
|
{
|
|
parse_psinfo(pid, process[i]);
|
|
i++;
|
|
}
|
|
p_ent=readdir(p_dir);
|
|
}
|
|
closedir(p_dir);
|
|
}
|
|
|
|
void get_procs()
|
|
{
|
|
//struct proc *process;
|
|
//process = malloc(nr_total * sizeof(struct proc);
|
|
struct proc process[nr_total];
|
|
parse_dir(process);
|
|
print_procs(process);
|
|
}
|
|
|
|
int mytop()
|
|
{
|
|
if (chdir("/proc") != 0)
|
|
{
|
|
perror("chdir to /proc" );
|
|
return 1;
|
|
}
|
|
print_memory();
|
|
getkinfo();
|
|
get_procs();
|
|
}
|