10195501441 3 лет назад
Родитель
Сommit
beee872cb1
2 измененных файлов: 58 добавлений и 73 удалений
  1. +37
    -56
      yeeshell.c
  2. +21
    -17
      yeeshell.h

+ 37
- 56
yeeshell.c Просмотреть файл

@ -36,7 +36,10 @@ char *history[CMDLINE_HISTORY_MAX_QUANTITY];
int cmdline_amount = 0;
struct proc *proc = NULL, *prev_proc = NULL;
int order = ORDER_CPU;
int blockedverbose = 0;
int nr_total = 0;
int slot = 1;
unsigned int nr_procs, nr_tasks;
int main()
@ -462,7 +465,7 @@ void parse_dir()
DIR *p_dir;
struct dirent *p_ent;
pid_t pid;
char *end;
char *end; //end是指向第一个不可转换的字符位置的指针
if ((p_dir = opendir("/proc")) == NULL)
{
@ -472,12 +475,10 @@ void parse_dir()
for (p_ent = readdir(p_dir); p_ent != NULL; p_ent = readdir(p_dir))
{
pid = strtol(p_ent->d_name, &end, 10);
pid = strtol(p_ent->d_name, &end, 10); //long strtol(char *str, char **endptr, int base)将串转换为长整数,base是基数,表示要转换的是几进制的数
if (!end[0] && pid != 0)
{
parse_file(pid);
}
}
closedir(p_dir);
@ -486,14 +487,15 @@ void parse_dir()
void parse_file(pid_t pid)
{
char path[PATH_MAX], name[256], type, state;
int version, endpt, effuid;
unsigned long cycles_hi, cycles_lo;
int version, endpt, effuid; //版本,端点,有效用户ID
unsigned long cycles_hi, cycles_lo; //高周期,低周期
FILE *fp;
struct proc *p;
int slot;
//int slot; //插槽?
int i;
//printf("parse_file\n");
sprintf(path, "%d/psinfo", pid);
sprintf(path, "/proc/%d/psinfo", pid);
if ((fp = fopen(path, "r")) == NULL)
return;
@ -505,7 +507,7 @@ void parse_file(pid_t pid)
}
if (version != PSINFO_VERSION)
{
{ //0
fputs("procfs version mismatch!\n", stderr);
exit(1);
}
@ -516,11 +518,12 @@ void parse_file(pid_t pid)
return;
}
slot = SLOT_NR(endpt);
slot++;
//slot = SLOT_NR(endpt);
if (slot < 0 || slot >= nr_total)
{
//fprintf(stderr, "top: unreasonable endpoint number %d\n", endpt);
fprintf(stderr, "top: unreasonable endpoint number %d\n", endpt);
fclose(fp);
return;
}
@ -528,18 +531,16 @@ void parse_file(pid_t pid)
p = &proc[slot];
if (type == TYPE_TASK)
{
p->p_flags |= IS_TASK;
}
else if (type == TYPE_SYSTEM)
{
p->p_flags |= IS_SYSTEM;
}
p->p_endpoint = endpt;
p->p_pid = pid;
if (fscanf(fp, " %255s %c %d %d %lu %*u %lu %lu", name, &state, &p->p_blocked, &p->p_priority, &p->p_user_time, &cycles_hi, &cycles_lo) != 7)
if (fscanf(fp, " %255s %c %d %d %lu %*u %lu %lu",
name, &state, &p->p_blocked, &p->p_priority,
&p->p_user_time, &cycles_hi, &cycles_lo) != 7)
{
fclose(fp);
@ -550,16 +551,15 @@ void parse_file(pid_t pid)
p->p_name[sizeof(p->p_name) - 1] = 0;
if (state != STATE_RUN)
{
p->p_flags |= BLOCKED;
}
p->p_cpucycles[0] = make64(cycles_lo, cycles_hi);
p->p_memory = 0L;
if (!(p->p_flags & IS_TASK))
{
int j;
if ((j = fscanf(fp, " %lu %*u %*u %*c %*d %*u %u %*u %d %*c %*d %*u", &p->p_memory, &effuid, &p->p_nice)) != 3)
if ((j = fscanf(fp, " %lu %*u %*u %*c %*d %*u %u %*u %d %*c %*d %*u",
&p->p_memory, &effuid, &p->p_nice)) != 3)
{
fclose(fp);
@ -569,13 +569,12 @@ void parse_file(pid_t pid)
p->p_effuid = effuid;
}
else
{
p->p_effuid = 0;
}
for (i = 1; i < CPUTIMENAMES; i++)
{
if (fscanf(fp, " %lu %lu", &cycles_hi, &cycles_lo) == 2)
if (fscanf(fp, " %lu %lu",
&cycles_hi, &cycles_lo) == 2)
{
p->p_cpucycles[i] = make64(cycles_lo, cycles_hi);
}
@ -622,11 +621,14 @@ void getkinfo()
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 tp *tick_procs = NULL;
static struct tp *tick_procs = NULL; //tp结构体的数组tick_procs,对所有的进程和任务(即上面读出来的nr_total)计算ticks
if (tick_procs == NULL)
{
tick_procs = malloc(nr_total * sizeof(tick_procs[0]));
@ -642,58 +644,37 @@ void print_procs(struct proc *proc1, struct proc *proc2, int cputimemode)
{
u64_t uticks;
if (!(proc2[p].p_flags & USED))
{
continue;
}
tick_procs[nprocs].p = proc2 + p;
tick_procs[nprocs].ticks = cputicks(&proc1[p], &proc2[p], cputimemode);
uticks = cputicks(&proc1[p], &proc2[p], 1);
total_ticks = total_ticks + uticks;
//printf("total_ticks:%llu\n",total_ticks);
/*if(p-NR_TASKS == IDLE) {
idleticks = uticks;
continue;
}
if(p-NR_TASKS == KERNEL) {
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%% user, ", 100.0 * userticks / total_ticks);
printf("%6.2f%% system", 100.0 * systemticks / total_ticks);
printf("%6.2f%% in total\n", 100.0 * (systemticks + userticks) / total_ticks);
}
u64_t cputicks(struct proc *p1, struct proc *p2, int timemode)
{
int i;
u64_t t = 0;
for (i = 0; i < CPUTIMENAMES; i++)
{
if (!CPUTIME(timemode, i))
{
continue;
}
if (p1->p_endpoint == p2->p_endpoint)
{
{
t = t + p2->p_cpucycles[i] - p1->p_cpucycles[i];
}
}
else
{
t = t + p2->p_cpucycles[i];
}
}
return t;
//printf("%6.2f%% kernel, ", 100.0 * kernelticks/ total_ticks);
//printf("%6.2f%% idle", 100.0 * idleticks / total_ticks);
}

+ 21
- 17
yeeshell.h Просмотреть файл

@ -15,28 +15,33 @@
#define REDIRECT_OUT 1 /* redirect output */
#define REDIRECT_IN 2 /* redirect input */
typedef int endpoint_t;
typedef uint64_t u64_t;
typedef long unsigned int vir_bytes;
#define _PATH_PROC "/proc/"
#define PSINFO_VERSION 0
#define TYPE_TASK 'T'
#define TYPE_SYSTEM 'S'
#define TYPE_USER 'U'
#define STATE_RUN 'R'
#define TIMECYCLEKEY 't'
#define ORDERKEY 'o'
#define USED 0x1
#define IS_TASK 0x2
#define IS_SYSTEM 0x4
#define BLOCKED 0x8
#define TYPE_TASK 'T'
#define TYPE_SYSTEM 'S'
#define STATE_RUN 'R'
#define MAX_NR_TASKS 1023
#define SELF ((endpoint_t)0x8ace)
#define _MAX_MAGIC_PROC (SELF)
#define _ENDPOINT_GENERATION_SIZE (MAX_NR_TASKS + _MAX_MAGIC_PROC + 1)
#define _ENDPOINT_P(e) \
((((e) + MAX_NR_TASKS) % _ENDPOINT_GENERATION_SIZE) - MAX_NR_TASKS)
#define SLOT_NR(e) (_ENDPOINT_P(e) + 5)
#define _PATH_PROC "/proc"
#define CPUTIME(m, i) (m & (1L << (i)))
#define ORDER_CPU 0
#define ORDER_MEMORY 1
#define ORDER_HIGHEST ORDER_MEMORY
#define TC_BUFFER 1024 /* Size of termcap(3) buffer */
#define TC_STRINGS 200 /* Enough room for cm,cl,so,se */
/* name of cpu cycle types, in the order they appear in /psinfo. */
const char *cputimenames[] = {"user", "ipc", "kernelcall"};
#define CPUTIMENAMES (sizeof(cputimenames) / sizeof(cputimenames[0]))
#define CPUTIME(m, i) (m & (1L << (i)))
struct proc
{
int p_flags;
@ -95,5 +100,4 @@ void get_procs();
void parse_dir();
void parse_file(pid_t pid);
void getkinfo();
void print_procs(struct proc *proc1, struct proc *proc2, int cputimemode);
u64_t cputicks(struct proc *p1, struct proc *p2, int timemode);
void print_procs(struct proc *proc1, struct proc *proc2, int cputimemode);

Загрузка…
Отмена
Сохранить