PatchworkOS
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <sys/io.h>
6#include <sys/proc.h>
7#include <threads.h>
8#include <time.h>
9
10#define SAMPLE_INTERVAL (CLOCKS_PER_SEC)
11
12#define PLOT_WIDTH 20
13
15
17{
18 uint32_t terminalWidth = 80;
19 printf("\033[999C\033[6n");
21 char buffer[MAX_NAME] = {0};
22 for (uint32_t i = 0; i < sizeof(buffer) - 1; i++)
23 {
24 read(STDIN_FILENO, &buffer[i], 1);
25 if (buffer[i] == 'R')
26 {
27 break;
28 }
29 }
30 int row;
31 int cols;
32 sscanf(buffer, "\033[%d;%dR", &row, &cols);
33
34 if (cols != 0)
35 {
36 terminalWidth = (uint32_t)cols;
37 }
38
39 printf("\r");
41 return terminalWidth;
42}
43
51
58
66
68{
69 FILE* file = fopen("/dev/stat/cpu", "r");
70 if (file == NULL)
71 {
72 return ERR;
73 }
74
75 uint64_t cpuCount = 0;
76 char line[256];
77 while (fgets(line, sizeof(line), file) != NULL)
78 {
79 cpuCount++;
80 }
81
82 fclose(file);
83 return cpuCount - 1; // -1 due to header
84}
85
86static uint64_t cpu_stat_read(cpu_stats_t* cpuStats, uint64_t cpuAmount)
87{
88 FILE* file = fopen("/dev/stat/cpu", "r");
89 if (file == NULL)
90 {
91 return ERR;
92 }
93
94 char line[256];
95 fgets(line, sizeof(line), file); // Skip header line
96
97 for (uint64_t i = 0; i < cpuAmount; i++)
98 {
99 if (fgets(line, sizeof(line), file) == NULL)
100 {
101 break;
102 }
103
104 if (sscanf(line, "cpu%d %llu %llu %llu", &cpuStats[i].id, &cpuStats[i].idleClocks, &cpuStats[i].activeClocks,
105 &cpuStats[i].interruptClocks) != 4)
106 {
107 cpuStats[i].id = 0;
108 cpuStats[i].idleClocks = 0;
109 cpuStats[i].activeClocks = 0;
110 cpuStats[i].interruptClocks = 0;
111 }
112 }
113
114 fclose(file);
115 return 0;
116}
117
119{
120 FILE* file = fopen("/dev/stat/mem", "r");
121 if (file == NULL)
122 {
123 return ERR;
124 }
125
126 if (fscanf(file, "value kib\ntotal %llu\nfree %llu\nreserved %llu", &memStats->totalKiB, &memStats->freeKiB,
127 &memStats->reservedKiB) != 3)
128 {
129 memStats->totalKiB = 0;
130 memStats->freeKiB = 0;
131 memStats->reservedKiB = 0;
132 }
133
134 fclose(file);
135 return 0;
136}
137
138static void stats_update(stats_t* stats)
139{
140 if (cpu_stat_read(stats->prevCpuStats, stats->cpuAmount) == ERR)
141 {
142 printf("Failed to read prev CPU statistics\n");
143 }
144
146
147 if (cpu_stat_read(stats->cpuStats, stats->cpuAmount) == ERR)
148 {
149 printf("Failed to read CPU statistics\n");
150 }
151
152 if (mem_stat_read(&stats->memStats) == ERR)
153 {
154 printf("Failed to read memory statistics\n");
155 }
156}
157
158static void stat_percentage(clock_t part, clock_t total, uint64_t* whole, uint64_t* thousandths)
159{
160 if (total == 0)
161 {
162 *whole = 0;
163 *thousandths = 0;
164 return;
165 }
166
167 uint64_t scaledPart = part * 100000;
168 uint64_t percent = scaledPart / total;
169 *whole = percent / 1000;
170 *thousandths = percent % 1000;
171}
172
173static void stats_print(stats_t* stats)
174{
175 printf("\033[H\033[K\n");
176
177 uint64_t cpuPrefixWidth = 20;
178 uint64_t cpuBarWidth = (terminalColumns > cpuPrefixWidth + 1) ? (terminalColumns - cpuPrefixWidth - 1) : PLOT_WIDTH;
179
180 uint64_t memPrefixWidth = 4;
181 uint64_t memBarWidth =
182 (terminalColumns > memPrefixWidth + 2) ? (terminalColumns - memPrefixWidth - 2) : (PLOT_WIDTH * 2);
183
184 printf("\033[1;33m CPU Usage:\033[0m\033[K\n");
185 for (uint64_t i = 0; i < stats->cpuAmount; i++)
186 {
187 clock_t prevTotal = stats->prevCpuStats[i].idleClocks + stats->prevCpuStats[i].activeClocks +
189 clock_t currTotal =
190 stats->cpuStats[i].idleClocks + stats->cpuStats[i].activeClocks + stats->cpuStats[i].interruptClocks;
191
192 clock_t totalDelta = currTotal - prevTotal;
193 clock_t activeDelta = (stats->cpuStats[i].activeClocks - stats->prevCpuStats[i].activeClocks) +
195
196 uint64_t whole, thousandths;
197 stat_percentage(activeDelta, totalDelta, &whole, &thousandths);
198
199 const char* color;
200 if (whole < 30)
201 {
202 color = "\033[32m";
203 }
204 else if (whole < 70)
205 {
206 color = "\033[33m";
207 }
208 else
209 {
210 color = "\033[31m";
211 }
212
213 printf(" \033[90mCPU%-2llu\033[0m %s%3llu.%03llu%%\033[0m [", i, color, whole, thousandths);
214
215 uint64_t barLength = (whole * cpuBarWidth) / 100;
216 for (uint64_t j = 0; j < cpuBarWidth; j++)
217 {
218 if (j < barLength)
219 {
220 printf("%s#\033[0m", color);
221 }
222 else
223 {
224 printf("\033[90m \033[0m");
225 }
226 }
227 printf("]\033[K\n");
228 }
229
230 printf("\033[K\n");
231
232 printf("\033[1;33m Memory:\033[0m\033[K\n");
233 uint64_t usedKiB = stats->memStats.totalKiB - stats->memStats.freeKiB;
234 uint64_t whole, thousandths;
235 stat_percentage(usedKiB, stats->memStats.totalKiB, &whole, &thousandths);
236
237 const char* color;
238 if (whole < 50)
239 {
240 color = "\033[32m";
241 }
242 else if (whole < 80)
243 {
244 color = "\033[33m";
245 }
246 else
247 {
248 color = "\033[31m";
249 }
250
251 printf(" \033[90mUsed:\033[0m %s%5llu MiB\033[0m / %5llu MiB "
252 "\033[90m(%s%3llu.%03llu%%\033[0m\033[90m)\033[0m\033[K\n",
253 color, usedKiB / 1024, stats->memStats.totalKiB / 1024, color, whole, thousandths);
254 printf(" \033[90mFree:\033[0m \033[32m%5llu MiB\033[0m\033[K\n", stats->memStats.freeKiB / 1024);
255
256 printf(" [");
257 uint64_t barLength = (whole * memBarWidth) / 100;
258 for (uint64_t j = 0; j < memBarWidth; j++)
259 {
260 if (j < barLength)
261 {
262 printf("%s#\033[0m", color);
263 }
264 else
265 {
266 printf("\033[90m \033[0m");
267 }
268 }
269 printf("]\033[K\n");
270
271 printf("\033[K\n");
272 fflush(stdout);
273}
274
275int main(void)
276{
277 printf("\033[H\033[J");
278
279 stats_t stats = {0};
281 if (stats.cpuAmount == ERR)
282 {
283 printf("Failed to read CPU statistics\n");
284 return EXIT_FAILURE;
285 }
286 stats.prevCpuStats = calloc(stats.cpuAmount, sizeof(cpu_stats_t));
287 if (stats.prevCpuStats == NULL)
288 {
289 printf("Failed to allocate memory for previous CPU statistics\n");
290 return EXIT_FAILURE;
291 }
292 stats.cpuStats = calloc(stats.cpuAmount, sizeof(cpu_stats_t));
293 if (stats.cpuStats == NULL)
294 {
295 printf("Failed to allocate memory for CPU statistics\n");
296 free(stats.prevCpuStats);
297 return EXIT_FAILURE;
298 }
299 stats.memStats = (mem_stats_t){0};
300
302
303 printf("Please wait...\n");
304 stats_update(&stats);
305
306 while (1)
307 {
308 stats_print(&stats);
309
310 stats_update(&stats);
311 }
312
313 return 0;
314}
#define MAX_NAME
Maximum length of names.
Definition MAX_NAME.h:11
uint64_t read(fd_t fd, void *buffer, uint64_t count)
System call for reading from files.
Definition read.c:9
#define STDIN_FILENO
Definition io.h:44
uint64_t nanosleep(clock_t timeout)
System call for sleeping.
Definition nanosleep.c:6
#define NULL
Pointer error value.
Definition NULL.h:23
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
static dentry_t * file
Definition log_file.c:17
EFI_PHYSICAL_ADDRESS buffer
Definition mem.c:15
#define ERR
Definition main.c:44
int main()
Definition main.c:97
static uint64_t terminal_columns_get(void)
Definition main.c:10
#define PLOT_WIDTH
Definition main.c:12
static uint64_t cpu_stat_count_cpus(void)
Definition main.c:67
static void stats_update(stats_t *stats)
Definition main.c:138
static uint64_t mem_stat_read(mem_stats_t *memStats)
Definition main.c:118
static void stats_print(stats_t *stats)
Definition main.c:173
#define SAMPLE_INTERVAL
Definition main.c:10
static uint64_t terminalColumns
Definition main.c:14
static void stat_percentage(clock_t part, clock_t total, uint64_t *whole, uint64_t *thousandths)
Definition main.c:158
static uint64_t cpu_stat_read(cpu_stats_t *cpuStats, uint64_t cpuAmount)
Definition main.c:86
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC int sscanf(const char *_RESTRICT s, const char *_RESTRICT format,...)
Definition sscanf.c:4
_PUBLIC char * fgets(char *_RESTRICT s, int n, FILE *_RESTRICT stream)
Definition fgets.c:5
_PUBLIC int fflush(FILE *stream)
Definition fflush.c:6
_PUBLIC int printf(const char *_RESTRICT format,...)
Definition printf.c:5
_PUBLIC int fscanf(FILE *_RESTRICT stream, const char *_RESTRICT format,...)
Definition fscanf.c:4
_PUBLIC FILE * fopen(const char *_RESTRICT filename, const char *_RESTRICT mode)
Definition fopen.c:27
_PUBLIC int fclose(FILE *stream)
Definition fclose.c:7
FILE * stdout
Definition std_streams.c:17
#define EXIT_FAILURE
Definition stdlib.h:47
_PUBLIC void * calloc(size_t nmemb, size_t size)
Definition calloc.c:6
_PUBLIC void free(void *ptr)
Definition free.c:11
Definition file.h:34
clock_t idleClocks
Definition main.c:47
uint64_t id
Definition main.c:46
clock_t activeClocks
Definition main.c:48
clock_t interruptClocks
Definition main.c:49
uint64_t reservedKiB
Definition main.c:56
uint64_t freeKiB
Definition main.c:55
uint64_t totalKiB
Definition main.c:54
Definition main.c:60
cpu_stats_t * cpuStats
Definition main.c:63
uint64_t cpuAmount
Definition main.c:61
cpu_stats_t * prevCpuStats
Definition main.c:62
mem_stats_t memStats
Definition main.c:64