Skip to content

Commit 12167ba

Browse files
committed
Add more information to /proc/stat
Now it's compatible with Linux's implementation
1 parent a2c9ab9 commit 12167ba

File tree

4 files changed

+89
-5
lines changed

4 files changed

+89
-5
lines changed

fs/proc/root.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,30 @@ static int proc_show_version(struct proc_entry *UNUSED(entry), struct proc_data
1515
}
1616

1717
static int proc_show_stat(struct proc_entry *UNUSED(entry), struct proc_data *buf) {
18-
struct cpu_usage usage = get_cpu_usage();
19-
proc_printf(buf, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64"\n", usage.user_ticks, usage.nice_ticks, usage.system_ticks, usage.idle_ticks);
18+
int ncpus = get_cpu_count();
19+
struct cpu_usage total_usage = get_total_cpu_usage();
20+
struct cpu_usage* per_cpu_usage = 0;
21+
struct uptime_info uptime_info = get_uptime();
22+
unsigned uptime = uptime_info.uptime_ticks;
23+
24+
proc_printf(buf, "cpu %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" 0 0 0 0\n", total_usage.user_ticks, total_usage.nice_ticks, total_usage.system_ticks, total_usage.idle_ticks);
25+
26+
int err = get_per_cpu_usage(&per_cpu_usage);
27+
if (!err) {
28+
for (int i = 0; i < ncpus; i++) {
29+
proc_printf(buf, "cpu%d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64" 0 0 0 0\n", i, per_cpu_usage[i].user_ticks, per_cpu_usage[i].nice_ticks, per_cpu_usage[i].system_ticks, per_cpu_usage[i].idle_ticks);
30+
}
31+
free(per_cpu_usage);
32+
}
33+
34+
int blocked_task_count = get_count_of_blocked_tasks();
35+
int alive_task_count = get_count_of_alive_tasks();
36+
proc_printf(buf, "ctxt 0\n");
37+
proc_printf(buf, "btime %u\n", uptime);
38+
proc_printf(buf, "processes %d\n", alive_task_count);
39+
proc_printf(buf, "procs_running %d\n", alive_task_count - blocked_task_count);
40+
proc_printf(buf, "procs_blocked %d\n", blocked_task_count);
41+
2042
return 0;
2143
}
2244

platform/darwin.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
#include <errno.h>
12
#include <mach/mach.h>
23
#include <sys/sysctl.h>
34
#include <sys/time.h>
5+
#include <sys/mman.h>
46
#include "platform/platform.h"
7+
#include "debug.h"
58

6-
struct cpu_usage get_cpu_usage() {
9+
struct cpu_usage get_total_cpu_usage() {
710
host_cpu_load_info_data_t load;
811
mach_msg_type_number_t fuck = HOST_CPU_LOAD_INFO_COUNT;
912
host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t) &load, &fuck);
@@ -68,3 +71,35 @@ int get_cpu_count() {
6871
sysctlbyname("hw.ncpu", &ncpu, &size, NULL, 0);
6972
return ncpu;
7073
}
74+
75+
int get_per_cpu_usage(struct cpu_usage** cpus_usage) {
76+
mach_msg_type_number_t info_size = sizeof(processor_cpu_load_info_t);
77+
processor_cpu_load_info_t sys_load_data = 0;
78+
natural_t ncpu;
79+
80+
int err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &ncpu, (processor_info_array_t*)&sys_load_data, &info_size);
81+
if (err) {
82+
STRACE("Unable to get per cpu usage");
83+
return err;
84+
}
85+
86+
struct cpu_usage* cpus_load_data = (struct cpu_usage*)calloc(ncpu, sizeof(struct cpu_usage));
87+
if (!cpus_load_data) {
88+
return -ENOMEM;
89+
}
90+
91+
for (natural_t i = 0; i < ncpu; i++) {
92+
cpus_load_data[i].user_ticks = sys_load_data[i].cpu_ticks[CPU_STATE_USER];
93+
cpus_load_data[i].system_ticks = sys_load_data[i].cpu_ticks[CPU_STATE_SYSTEM];
94+
cpus_load_data[i].idle_ticks = sys_load_data[i].cpu_ticks[CPU_STATE_IDLE];
95+
cpus_load_data[i].nice_ticks = sys_load_data[i].cpu_ticks[CPU_STATE_NICE];
96+
}
97+
*cpus_usage = cpus_load_data;
98+
99+
// Freeing cpu load information
100+
if (sys_load_data) {
101+
munmap(sys_load_data, vm_page_size);
102+
}
103+
104+
return 0;
105+
}

platform/linux.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
#include <errno.h>
12
#include <sys/sysinfo.h>
23
#include <inttypes.h>
34
#include <stdio.h>
5+
#include <stdlib.h>
46
#include <string.h>
57
#include "platform/platform.h"
68
#include "debug.h"
@@ -16,7 +18,7 @@ static void read_proc_line(const char *file, const char *name, char *buf) {
1618
fclose(f);
1719
}
1820

19-
struct cpu_usage get_cpu_usage() {
21+
struct cpu_usage get_total_cpu_usage() {
2022
struct cpu_usage usage = {};
2123
char buf[1234];
2224
read_proc_line("/proc/stat", "cpu", buf);
@@ -55,3 +57,27 @@ struct uptime_info get_uptime() {
5557
int get_cpu_count() {
5658
return get_nprocs();
5759
}
60+
61+
int get_per_cpu_usage(struct cpu_usage** cpus_usage) {
62+
char buf[1234];
63+
char cpu_title[8];
64+
int ncpu = get_cpu_count();
65+
struct cpu_usage* cpus_load_data = (struct cpu_usage*)calloc(ncpu, sizeof(struct cpu_usage));
66+
if (!cpus_load_data) {
67+
return -ENOMEM;
68+
}
69+
70+
for (int i = 0; i < ncpu; i++) {
71+
int cpu_num;
72+
int title_len = snprintf(cpu_title, 8, "cpu%d", i);
73+
if (title_len > 8 || title_len < 0) {
74+
STRACE("Can't load info of cpu %d (>10000)", i);
75+
free(cpus_load_data);
76+
return -ENOMEM;
77+
}
78+
read_proc_line("/proc/stat", cpu_title, buf);
79+
sscanf(buf, "cpu%d %"SCNu64" %"SCNu64" %"SCNu64" %"SCNu64"\n", &cpu_num, &cpus_load_data[i].user_ticks, &cpus_load_data[i].system_ticks, &cpus_load_data[i].idle_ticks, &cpus_load_data[i].nice_ticks);
80+
}
81+
*cpus_usage = cpus_load_data;
82+
return 0;
83+
}

platform/platform.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ struct cpu_usage {
99
uint64_t idle_ticks;
1010
uint64_t nice_ticks;
1111
};
12-
struct cpu_usage get_cpu_usage(void);
12+
struct cpu_usage get_total_cpu_usage(void);
13+
int get_per_cpu_usage(struct cpu_usage** cpus_usage);
1314

1415
struct mem_usage {
1516
uint64_t total;

0 commit comments

Comments
 (0)