-
Notifications
You must be signed in to change notification settings - Fork 66
/
stat.c
132 lines (120 loc) · 2.89 KB
/
stat.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "stat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct cpu_stat_value_t {
long int idle;
long int total;
};
struct cpu_stat_full_t {
struct cpu_stat_t parent;
int cpu_count;
struct cpu_stat_value_t * values;
};
static void read_eol(FILE * file) {
int c;
while ((c = fgetc(file)) != EOF && c != '\n');
}
struct cpu_stat_t * cpu_stat_init() {
FILE * file;
char buf[80];
int cpu_count = 0;
int index;
file = fopen("/proc/stat", "r");
if (file) {
while (fscanf(file, "%s", buf) == 1 && strstr(buf, "cpu") == buf) {
read_eol(file);
if (strlen(buf) > 3) {
index = atoi(&buf[3]) + 1;
cpu_count = cpu_count >= index ? cpu_count : index;
}
}
fclose(file);
}
if (cpu_count > 0) {
struct cpu_stat_full_t * full = malloc(sizeof(struct cpu_stat_full_t));
struct cpu_stat_value_t * values = malloc(cpu_count *
sizeof(struct cpu_stat_value_t));
if (!full || !values) {
if (full) {
free(full);
}
if (values) {
free(values);
}
fprintf(stderr, "No enough memory\n");
return NULL;
}
memset(values, 0, cpu_count * sizeof(struct cpu_stat_value_t));
full->parent.single_core = 0;
full->parent.multi_core = 0;
full->cpu_count = cpu_count;
full->values = values;
return &full->parent;
} else {
fprintf(stderr, "Failed to read /proc/stat\n");
return NULL;
}
}
void cpu_stat_measure(struct cpu_stat_t * cpu_stat) {
if (cpu_stat) {
struct cpu_stat_full_t * full = (struct cpu_stat_full_t *) cpu_stat;
int index;
int count;
long int idle;
long int total;
long int value;
float single_core = 0;
float multi_core = 0;
double load;
FILE * file;
char buf[80];
file = fopen("/proc/stat", "r");
if (file) {
while (fscanf(file, "%s", buf) == 1 && strstr(buf, "cpu") == buf) {
if (strlen(buf) > 3) {
index = atoi(&buf[3]);
if (index >= 0 && index < full->cpu_count) {
count = 0;
idle = 0;
total = 0;
while (fscanf(file, "%ld", &value) == 1) {
count++;
total += value;
if (count == 4) {
idle = value;
}
}
if (count >= 4) {
if (full->values[index].idle > 0 &&
full->values[index].total > 0) {
load = (double) (total -
full->values[index].total -
idle + full->values[index].idle) /
(total - full->values[index].total);
single_core = load > single_core
? load : single_core;
multi_core = multi_core > 0
? multi_core + load : load;
}
full->values[index].idle = idle;
full->values[index].total = total;
}
}
} else {
read_eol(file);
}
}
fclose(file);
}
full->parent.single_core = single_core;
full->parent.multi_core = multi_core;
}
}
void cpu_stat_free(struct cpu_stat_t * cpu_stat) {
if (cpu_stat) {
struct cpu_stat_full_t * full = (struct cpu_stat_full_t *) cpu_stat;
free(full->values);
free(full);
}
}