static int get_load() { static int old_load = 0; int u = 0, n = 0, s = 0, i, load; four_cpu_numbers( &u, &n, &s, &i ); load = u + n + s; old_load = (load + load + load + old_load) >> 2; return old_load >> 10; }
/* * Calculates the number of tasks in each state (running, sleeping, etc.). * Calculates the CPU time in each state (system, user, nice, etc). * Calculates percent cpu usage for each task. */ void do_stats(proc_t** p, float elapsed_time, int pass) { proc_t *this; int index, total_time, cpumap, i, n = 0; int sleeping = 0, stopped = 0, zombie = 0, running = 0; unsigned long system_ticks = 0, user_ticks = 0, nice_ticks = 0, idle_ticks; static int prev_count = 0; int stime, utime; /* start with one 4K page as a reasonable allocate size */ static int save_history_size = sizeof(struct save_hist) * 204; static struct save_hist *save_history; struct save_hist *New_save_hist; static int *s_ticks_o = NULL, *u_ticks_o = NULL, *n_ticks_o = NULL, *i_ticks_o = NULL; int s_ticks, u_ticks, n_ticks, i_ticks, t_ticks; char str[128]; FILE *file; if (!save_history) save_history = xcalloc(NULL, save_history_size); New_save_hist = xcalloc(NULL, save_history_size); if(s_ticks_o == NULL) { s_ticks_o = (int *)malloc(nr_cpu * sizeof(int)); u_ticks_o = (int *)malloc(nr_cpu * sizeof(int)); n_ticks_o = (int *)malloc(nr_cpu * sizeof(int)); i_ticks_o = (int *)malloc(nr_cpu * sizeof(int)); } idle_ticks = 1000 * nr_cpu; /* * Make a pass through the data to get stats. */ index = 0; while (p[n]->pid != -1) { this = p[n]; switch (this->state) { case 'S': case 'D': sleeping++; break; case 'T': stopped++; break; case 'Z': zombie++; break; case 'R': running++; break; default: /* Don't know how to handle this one. */ break; } /* * Calculate time in this process. Time is sum of user time * (utime) plus system time (stime). */ total_time = this->utime + this->stime; if (index * sizeof(struct save_hist) >= save_history_size) { save_history_size *= 2; save_history = xrealloc(save_history, save_history_size); New_save_hist = xrealloc(New_save_hist, save_history_size); } New_save_hist[index].ticks = total_time; New_save_hist[index].pid = this->pid; stime = this->stime; utime = this->utime; New_save_hist[index].stime = stime; New_save_hist[index].utime = utime; /* find matching entry from previous pass */ for (i = 0; i < prev_count; i++) { if (save_history[i].pid == this->pid) { total_time -= save_history[i].ticks; stime -= save_history[i].stime; utime -= save_history[i].utime; i = prev_count; } } /* * Calculate percent cpu time for this task. */ this->pcpu = (total_time * 10 * 100/Hertz) / elapsed_time; if (this->pcpu > 999) this->pcpu = 999; /* * Calculate time in idle, system, user and niced tasks. */ idle_ticks -= this->pcpu; system_ticks += stime; user_ticks += utime; if (this->nice > 0) nice_ticks += this->pcpu; /* * If in Sun-mode, adjust cpu percentage not only for * the cpu the process is running on, but for all cpu together. */ if(!Irixmode) { this->pcpu /= nr_cpu; } index++; n++; } if (idle_ticks < 0) idle_ticks = 0; system_ticks = (system_ticks * 10 * 100/Hertz) / elapsed_time; user_ticks = (user_ticks * 10 * 100/Hertz) / elapsed_time; /* * Display stats. */ if (pass > 0 && show_stats) { printf("%d processes: %d sleeping, %d running, %d zombie, " "%d stopped", n, sleeping, running, zombie, stopped); PUTP(top_clrtoeol); putchar('\n'); if (nr_cpu == 1 || CPU_states) { /* BEGIN EXPERIMENTAL CODE */ /* Throw out the calculation above... TODO: remove calculation. */ four_cpu_numbers(&user_ticks,&nice_ticks,&system_ticks,&idle_ticks); do{ unsigned long sum; sum = user_ticks+nice_ticks+system_ticks+idle_ticks; user_ticks = (user_ticks * 1000) / sum; system_ticks = (system_ticks * 1000) / sum; nice_ticks = (nice_ticks * 1000) / sum; idle_ticks = (idle_ticks * 1000) / sum; }while(0); /* END EXPERIMENTAL CODE */ if (Irixmode) { user_ticks *= nr_cpu; system_ticks *= nr_cpu; nice_ticks *= nr_cpu; idle_ticks *= nr_cpu; } printf("CPU states:" " %2ld.%ld%% user, %2ld.%ld%% system," " %2ld.%ld%% nice, %2ld.%ld%% idle", user_ticks / 10UL, user_ticks % 10UL, system_ticks / 10UL, system_ticks % 10UL, nice_ticks / 10UL, nice_ticks % 10UL, idle_ticks / 10UL, idle_ticks % 10UL); PUTP(top_clrtoeol); putchar('\n'); } /* * Calculate stats for all cpus */ if(nr_cpu > 1) { file = fopen("/proc/stat", "r"); if(file == NULL) { fprintf(stderr, "fopen failed on /proc/stat\n"); } else { /* Skip the total CPU states. */ if(fgets(str, 128, file) == NULL) { fprintf(stderr, "fgets failed on /proc/stat\n"); } else { for(i = 0; i < nr_cpu; i++) { if(fscanf(file, "cpu%*d %d %d %d %d\n", &u_ticks, &n_ticks, &s_ticks, &i_ticks) != 4) { fprintf(stderr, "fscanf failed on /proc/stat for cpu %d\n", i); break; } else { t_ticks = (u_ticks + s_ticks + i_ticks + n_ticks) - (u_ticks_o[i] + s_ticks_o[i] + i_ticks_o[i] + n_ticks_o[i]); if (Irixmode) cpumap=i; else cpumap=cpu_mapping[i]; printf ("CPU%d states: %2d.%-d%% user, %2d.%-d%% system," " %2d.%-d%% nice, %2d.%-d%% idle", cpumap, (u_ticks - u_ticks_o[i] + n_ticks - n_ticks_o[i]) * 100 / t_ticks, (u_ticks - u_ticks_o[i]) * 100 % t_ticks / 100, (s_ticks - s_ticks_o[i]) * 100 / t_ticks, (s_ticks - s_ticks_o[i]) * 100 % t_ticks / 100, (n_ticks - n_ticks_o[i]) * 100 / t_ticks, (n_ticks - n_ticks_o[i]) * 100 % t_ticks / 100, (i_ticks - i_ticks_o[i]) * 100 / t_ticks, (i_ticks - i_ticks_o[i]) * 100 % t_ticks / 100); s_ticks_o[i] = s_ticks; u_ticks_o[i] = u_ticks; n_ticks_o[i] = n_ticks; i_ticks_o[i] = i_ticks; PUTP (top_clrtoeol); putchar ('\n'); } } } fclose(file); } } } else { /* * During the first pass, get the information for the * different CPUs. */ if(nr_cpu > 1) { file = fopen("/proc/stat", "r"); if(file == NULL) { puts("open"); } if(fgets(str, 128, file) == NULL) { fprintf(stderr, "fgets failed on /proc/stat\n"); } for(i = 0; i < nr_cpu; i++) { if(fscanf(file, "cpu%*d %d %d %d %d\n", &u_ticks_o[i], &n_ticks_o[i], &s_ticks_o[i], &i_ticks_o[i]) != 4) { fprintf(stderr, "fscanf failed on /proc/stat for cpu %d\n", i); } } fclose(file); } } /* * Save this frame's information. */ for (i = 0; i < n; i++) { /* copy the relevant info for the next pass */ save_history[i].pid = New_save_hist[i].pid; save_history[i].ticks = New_save_hist[i].ticks; save_history[i].stime = New_save_hist[i].stime; save_history[i].utime = New_save_hist[i].utime; } free(New_save_hist); prev_count = n; qsort(p, n, sizeof(proc_t*), (void*)mult_lvl_cmp); }