2 * cpu_linux.c - module to get cpu usage, for GNU/Linux
4 * Copyright (C) 2001, 2002 Seiichi SATO <ssato@sh.rim.or.jp>
6 * licensed under the GPL
20 #include <sys/types.h>
22 #include <linux/limits.h>
25 #include <linux/threads.h>
28 static void set_pidlist_from_namelist(int names
, char **name_list
);
29 static int get_cpuusage_bypid(pid_t pid
);
36 /* You don't need initialization under GNU/Linux */
40 /* returns current cpu usage in percent */
42 cpu_get_usage(cpu_options
*opts
)
44 static int pre_used
, pre_total
;
45 static int pre_ig_used
;
47 int cpu
, nice
, system
, idle
;
48 int used
= 0, total
= 0;
53 if (!(fp
= fopen("/proc/stat", "r"))) {
54 perror("can't open /proc/stat");
58 fscanf(fp
, "%*s %d %d %d %d", &cpu
, &nice
, &system
, &idle
);
61 if (opts
->cpu_number
>= 0) {
63 if (opts
->cpu_number
> NR_CPUS
- 1) {
64 fprintf (stderr
, "MAX CPU number that can be running in SMP is %d\n", NR_CPUS
- 1);
68 for (i
= 0; i
<= opts
->cpu_number
; i
++) {
69 fscanf(fp
, "%s %d %d %d %d", cpu_name
, &cpu
, &nice
, &system
, &idle
);
70 if (strncmp(cpu_name
, "cpu", 3)){
71 fprintf (stderr
, "can't find cpu%d!\n", opts
->cpu_number
);
80 if (!opts
->ignore_nice
)
82 total
= cpu
+ nice
+ system
+ idle
;
84 /* get CPU usage of processes which specified by name with '-p' option */
85 if (opts
->ignore_procs
) {
87 if (!(pid_list
= malloc(sizeof(pid_t
)))) {
91 set_pidlist_from_namelist(opts
->ignore_procs
, opts
->ignore_proc_list
);
92 for (i
= 0; i
< pids
; i
++)
93 ig_used
+= get_cpuusage_bypid(pid_list
[i
]);
98 if ((pre_total
== 0) || !(total
- pre_total
> 0)) {
100 } else if (ig_used
- pre_ig_used
> 0) {
101 usage
= (100 * (double)(used
- pre_used
- ig_used
+ pre_ig_used
)) /
102 (double)(total
- pre_total
);
104 usage
= (100 * (double)(used
- pre_used
)) / (double)(total
- pre_total
);
107 /* save current values for next calculation */
108 pre_ig_used
= ig_used
;
115 /* set pid list table from command names */
117 set_pidlist_from_namelist(int names
, char **name_list
)
122 char path
[PATH_MAX
+ 1];
127 if (!(dir
= opendir("/proc"))) {
128 perror("can't open /proc");
132 /* search specified process from all processes */
134 while ((de
= readdir(dir
)) != NULL
) {
135 if ((de
->d_name
[0] != '.') &&
136 ((de
->d_name
[0] >= '0') && (de
->d_name
[0] <= '9'))) {
137 pid
= (pid_t
) atoi(de
->d_name
);
138 sprintf(path
, "%d/stat", pid
);
139 if ((fp
= fopen(path
, "r")) != NULL
) {
140 fscanf(fp
, "%*d (%[^)]", comm
);
141 for (i
= 0; i
< names
; i
++) {
142 if (strcmp(comm
, name_list
[i
]) == 0) {
143 /* add process id to list */
145 if (!(pid_list
=realloc(pid_list
, pids
*sizeof(pid_t
)))){
146 perror("realloc() failed");
149 pid_list
[pids
- 1] = pid
;
160 get_cpuusage_bypid(pid_t pid
)
164 int utime
= 0, stime
= 0;
167 sprintf(path
, "/proc/%d/stat", pid
);
168 if ((fp
= fopen(path
, "r")) != NULL
) {
169 fscanf(fp
, "%*d %*s %*s %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d ",