PatchworkOS  28a9544
A non-POSIX operating system.
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
15
18
25
27
28static void terminal_size_get(void)
29{
30 uint32_t terminalWidth = 80;
31 uint32_t terminalHeight = 24;
32
33 printf("\033[s\033[999;999H\033[6n");
35
36 char buffer[MAX_NAME] = {0};
37 for (uint32_t i = 0; i < sizeof(buffer) - 1; i++)
38 {
39 read(STDIN_FILENO, &buffer[i], 1);
40 if (buffer[i] == 'R')
41 {
42 break;
43 }
44 }
45
46 int rows, cols;
47 sscanf(buffer, "\033[%d;%dR", &rows, &cols);
48
49 if (cols != 0)
50 {
51 terminalWidth = (uint32_t)cols;
52 }
53 if (rows != 0)
54 {
55 terminalHeight = (uint32_t)rows;
56 }
57
58 printf("\033[H\033[u");
60
61 terminalColumns = terminalWidth;
62 terminalRows = terminalHeight;
63}
64
72
79
91
102
104{
105 FILE* file = fopen("/dev/perf/cpu", "r");
106 if (file == NULL)
107 {
108 return ERR;
109 }
110
111 uint64_t cpuCount = 0;
112 char line[256];
113 while (fgets(line, sizeof(line), file) != NULL)
114 {
115 cpuCount++;
116 }
117
118 fclose(file);
119 return cpuCount - 1;
120}
121
123{
124 FILE* file = fopen("/dev/perf/cpu", "r");
125 if (file == NULL)
126 {
127 return ERR;
128 }
129
130 char line[1024];
131 fgets(line, sizeof(line), file);
132
133 for (uint64_t i = 0; i < cpuAmount; i++)
134 {
135 if (fgets(line, sizeof(line), file) == NULL)
136 {
137 break;
138 }
139
140 if (sscanf(line, "%lu %lu %lu %lu", &cpuPerfs[i].id, &cpuPerfs[i].idleClocks, &cpuPerfs[i].activeClocks,
141 &cpuPerfs[i].interruptClocks) != 4)
142 {
143 cpuPerfs[i].id = 0;
144 cpuPerfs[i].idleClocks = 0;
145 cpuPerfs[i].activeClocks = 0;
146 cpuPerfs[i].interruptClocks = 0;
147 }
148 }
149
150 fclose(file);
151 return 0;
152}
153
155{
156 FILE* file = fopen("/dev/perf/mem", "r");
157 if (file == NULL)
158 {
159 return ERR;
160 }
161
162 uint64_t totalPages = 0;
163 uint64_t freePages = 0;
164 uint64_t usedPages = 0;
165 if (fscanf(file, "total_pages %lu\nfree_pages %lu\nused_pages %lu", &totalPages, &freePages, &usedPages) == 3)
166 {
167 memPerfs->totalKiB = totalPages * (PAGE_SIZE / 1024);
168 memPerfs->freeKiB = freePages * (PAGE_SIZE / 1024);
169 memPerfs->usedKiB = usedPages * (PAGE_SIZE / 1024);
170 }
171 else
172 {
173 memPerfs->totalKiB = 0;
174 memPerfs->freeKiB = 0;
175 memPerfs->usedKiB = 0;
176 }
177
178 fclose(file);
179 return 0;
180}
181
183{
184 fd_t procDir = open("/proc:dir");
185 if (procDir == ERR)
186 {
187 return NULL;
188 }
189
190 proc_perfs_t* procPerfs = NULL;
191 *procAmount = 0;
192 dirent_t buffer[128];
193 while (1)
194 {
195 uint64_t readAmount = getdents(procDir, (dirent_t*)buffer, sizeof(buffer));
196 if (readAmount == ERR)
197 {
198 free(procPerfs);
199 close(procDir);
200 return NULL;
201 }
202 if (readAmount == 0)
203 {
204 break;
205 }
206
207 for (uint64_t i = 0; i < readAmount / sizeof(dirent_t); i++)
208 {
209 if (buffer[i].path[0] == '.' || strcmp(buffer[i].path, "self") == 0)
210 {
211 continue;
212 }
213
214 pid_t pid = (pid_t)atoi(buffer[i].path);
215 if (pid == 0)
216 {
217 continue;
218 }
219
220 char path[MAX_PATH];
221 snprintf(path, sizeof(path), "/proc/%d/perf", pid);
222 FILE* perfFile = fopen(path, "r");
223 if (perfFile == NULL)
224 {
225 continue;
226 }
227
228 uint64_t userPages;
229 proc_perfs_t procPerf;
230 if (fscanf(perfFile,
231 "user_clocks %lu\nkernel_clocks %lu\nstart_clocks %lu\nuser_pages %lu\nthread_count %lu",
232 &procPerf.userClocks, &procPerf.kernelClocks, &procPerf.startClocks, &userPages,
233 &procPerf.threadCount) != 5)
234 {
235 fclose(perfFile);
236 continue;
237 }
238 procPerf.pid = pid;
239 procPerf.userKiB = userPages * (PAGE_SIZE / 1024);
240 procPerf.cpuPercent = 0.0;
241 fclose(perfFile);
242
243 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
244 FILE* cmdlineFile = fopen(path, "r");
245 if (cmdlineFile == NULL)
246 {
247 free(procPerfs);
248 close(procDir);
249 return NULL;
250 }
251
252 char c;
253 uint64_t index = 0;
254 while (fread(&c, 1, 1, cmdlineFile) == 1 && index < sizeof(procPerf.cmdline) - 1)
255 {
256 if (c == '\0')
257 {
258 procPerf.cmdline[index] = ' ';
259 }
260 else
261 {
262 procPerf.cmdline[index] = c;
263 }
264 index++;
265 }
266 procPerf.cmdline[index] = '\0';
267 fclose(cmdlineFile);
268
269 procPerfs = realloc(procPerfs, sizeof(proc_perfs_t) * (*procAmount + 1));
270 if (procPerfs == NULL)
271 {
272 close(procDir);
273 return NULL;
274 }
275 procPerfs[(*procAmount)++] = procPerf;
276 }
277 }
278
279 close(procDir);
280 return procPerfs;
281}
282
284{
285 for (uint64_t i = 0; i < perfs->procAmount; i++)
286 {
287 perfs->procPerfs[i].cpuPercent = 0.0;
288
289 for (uint64_t j = 0; j < perfs->prevProcAmount; j++)
290 {
291 if (perfs->procPerfs[i].pid == perfs->prevProcPerfs[j].pid)
292 {
293 clock_t userDelta = perfs->procPerfs[i].userClocks - perfs->prevProcPerfs[j].userClocks;
294 clock_t kernelDelta = perfs->procPerfs[i].kernelClocks - perfs->prevProcPerfs[j].kernelClocks;
295 clock_t totalDelta = userDelta + kernelDelta;
296
297 perfs->procPerfs[i].cpuPercent = (totalDelta * 100.0) / SAMPLE_INTERVAL;
298 break;
299 }
300 }
301 }
302}
303
304static int compare_by_pid(const void* a, const void* b)
305{
306 const proc_perfs_t* pa = (const proc_perfs_t*)a;
307 const proc_perfs_t* pb = (const proc_perfs_t*)b;
308 return (pa->pid > pb->pid) - (pa->pid < pb->pid);
309}
310
311static int compare_by_memory(const void* a, const void* b)
312{
313 const proc_perfs_t* pa = (const proc_perfs_t*)a;
314 const proc_perfs_t* pb = (const proc_perfs_t*)b;
315 return (pb->userKiB > pa->userKiB) - (pb->userKiB < pa->userKiB);
316}
317
318static int compare_by_cpu(const void* a, const void* b)
319{
320 const proc_perfs_t* pa = (const proc_perfs_t*)a;
321 const proc_perfs_t* pb = (const proc_perfs_t*)b;
322 if (pb->cpuPercent > pa->cpuPercent)
323 return 1;
324 if (pb->cpuPercent < pa->cpuPercent)
325 return -1;
326 return 0;
327}
328
329static void sort_processes(perfs_t* perfs)
330{
331 switch (currentSortMode)
332 {
333 case SORT_PID:
334 qsort(perfs->procPerfs, perfs->procAmount, sizeof(proc_perfs_t), compare_by_pid);
335 break;
336 case SORT_MEMORY:
337 qsort(perfs->procPerfs, perfs->procAmount, sizeof(proc_perfs_t), compare_by_memory);
338 break;
339 case SORT_CPU:
340 qsort(perfs->procPerfs, perfs->procAmount, sizeof(proc_perfs_t), compare_by_cpu);
341 break;
342 }
343}
344
345static void perfs_update(perfs_t* perfs)
346{
347 clock_t currentTime = clock();
348 while (currentTime - lastSampleTime < SAMPLE_INTERVAL)
349 {
350 clock_t remaining = SAMPLE_INTERVAL - (currentTime - lastSampleTime);
351 if (!(poll1(STDIN_FILENO, POLLIN, remaining) & POLLIN))
352 {
353 break;
354 }
355
356 bool keyPressed = true;
357 sort_mode_t previousSortMode = currentSortMode;
358 uint64_t previousScrollOffset = processScrollOffset;
359
360 char c;
361 read(STDIN_FILENO, &c, 1);
362 switch (c)
363 {
364 case 'p':
365 case 'P':
368 break;
369 case 'm':
370 case 'M':
373 break;
374 case 'c':
375 case 'C':
378 break;
379 case 'j':
380 case 'J':
381 if (processScrollOffset + 1 < perfs->procAmount)
382 {
384 }
385 break;
386 case 'k':
387 case 'K':
388 if (processScrollOffset > 0)
389 {
391 }
392 break;
393 case 'q':
394 case 'Q':
395 printf("\033[?25h\033[H\033[J");
396 exit(0);
397 break;
398 default:
399 keyPressed = false;
400 break;
401 }
402
403 if (keyPressed && (previousSortMode != currentSortMode || previousScrollOffset != processScrollOffset))
404 {
405 sort_processes(perfs);
406 break;
407 }
408
409 currentTime = clock();
410 }
411
412 if (currentTime - lastSampleTime < SAMPLE_INTERVAL)
413 {
414 return;
415 }
416
417 if (perfs->cpuPerfs != NULL)
418 {
419 memcpy(perfs->prevCpuPerfs, perfs->cpuPerfs, sizeof(cpu_perfs_t) * cpuAmount);
420 }
421 free(perfs->prevProcPerfs);
422 perfs->prevProcPerfs = perfs->procPerfs;
423 perfs->prevProcAmount = perfs->procAmount;
424
425 if (cpu_perf_read(perfs->cpuPerfs) == ERR)
426 {
427 printf("Failed to read CPU performance data\n");
428 abort();
429 }
430
431 if (mem_perf_read(&perfs->memPerfs) == ERR)
432 {
433 printf("Failed to read memory performance data\n");
434 abort();
435 }
436
437 perfs->procPerfs = proc_perfs_read(&perfs->procAmount);
438 if (perfs->procPerfs == NULL)
439 {
440 printf("Failed to read process performance data\n");
441 abort();
442 }
443
445 sort_processes(perfs);
446
447 lastSampleTime = currentTime;
448}
449
450static void perf_percentage(clock_t part, clock_t total, uint64_t* whole, uint64_t* thousandths)
451{
452 if (total == 0)
453 {
454 *whole = 0;
455 *thousandths = 0;
456 return;
457 }
458
459 uint64_t scaledPart = part * 100000;
460 uint64_t percent = scaledPart / total;
461 *whole = percent / 1000;
462 *thousandths = percent % 1000;
463}
464
465static void perfs_print(perfs_t* perfs)
466{
467 printf("\033[H\n");
468
469 uint64_t cpuPrefixWidth = 20;
470 uint64_t singleColumnWidth = (terminalColumns + 1) / 2;
471 uint64_t cpuBarWidth = singleColumnWidth - cpuPrefixWidth;
472
473 uint64_t memPrefixWidth = 4;
474 uint64_t memBarWidth = terminalColumns - memPrefixWidth - 2;
475
476 printf("\033[1;33m CPU Usage:\033[0m\033[K\n");
477
478 uint64_t cpusPerColumn = (cpuAmount + 1) / 2;
479 for (uint64_t row = 0; row < cpusPerColumn; row++)
480 {
481 uint64_t i = row;
482 clock_t prevTotal = perfs->prevCpuPerfs[i].idleClocks + perfs->prevCpuPerfs[i].activeClocks +
484 clock_t currTotal =
485 perfs->cpuPerfs[i].idleClocks + perfs->cpuPerfs[i].activeClocks + perfs->cpuPerfs[i].interruptClocks;
486
487 clock_t totalDelta = currTotal - prevTotal;
488 clock_t activeDelta = (perfs->cpuPerfs[i].activeClocks - perfs->prevCpuPerfs[i].activeClocks) +
490
491 uint64_t whole, thousandths;
492 perf_percentage(activeDelta, totalDelta, &whole, &thousandths);
493
494 const char* color;
495 if (whole < 30)
496 {
497 color = "\033[32m";
498 }
499 else if (whole < 70)
500 {
501 color = "\033[33m";
502 }
503 else
504 {
505 color = "\033[31m";
506 }
507
508 printf(" \033[90mCPU%-2llu\033[0m %s%3llu.%03llu%%\033[0m [", i, color, whole, thousandths);
509
510 uint64_t barLength = (whole * cpuBarWidth) / 100;
511 for (uint64_t j = 0; j < cpuBarWidth; j++)
512 {
513 if (j < barLength)
514 {
515 printf("%s#\033[0m", color);
516 }
517 else
518 {
519 printf("\033[90m \033[0m");
520 }
521 }
522 printf("]");
523
524 uint64_t rightIdx = row + cpusPerColumn;
525 if (rightIdx < cpuAmount)
526 {
527 prevTotal = perfs->prevCpuPerfs[rightIdx].idleClocks + perfs->prevCpuPerfs[rightIdx].activeClocks +
528 perfs->prevCpuPerfs[rightIdx].interruptClocks;
529 currTotal = perfs->cpuPerfs[rightIdx].idleClocks + perfs->cpuPerfs[rightIdx].activeClocks +
530 perfs->cpuPerfs[rightIdx].interruptClocks;
531
532 totalDelta = currTotal - prevTotal;
533 activeDelta = (perfs->cpuPerfs[rightIdx].activeClocks - perfs->prevCpuPerfs[rightIdx].activeClocks) +
534 (perfs->cpuPerfs[rightIdx].interruptClocks - perfs->prevCpuPerfs[rightIdx].interruptClocks);
535
536 perf_percentage(activeDelta, totalDelta, &whole, &thousandths);
537
538 if (whole < 30)
539 {
540 color = "\033[32m";
541 }
542 else if (whole < 70)
543 {
544 color = "\033[33m";
545 }
546 else
547 {
548 color = "\033[31m";
549 }
550
551 printf(" \033[90mCPU%-2llu\033[0m %s%3llu.%03llu%%\033[0m [", rightIdx, color, whole, thousandths);
552
553 barLength = (whole * cpuBarWidth) / 100;
554 for (uint64_t j = 0; j < cpuBarWidth; j++)
555 {
556 if (j < barLength)
557 {
558 printf("%s#\033[0m", color);
559 }
560 else
561 {
562 printf("\033[90m \033[0m");
563 }
564 }
565 printf("]");
566 }
567
568 printf("\033[K\n");
569 }
570
571 printf("\033[K\n");
572
573 printf("\033[1;33m Memory:\033[0m\033[K\n");
574 uint64_t usedKiB = perfs->memPerfs.totalKiB - perfs->memPerfs.freeKiB;
575 uint64_t whole, thousandths;
576 perf_percentage(usedKiB, perfs->memPerfs.totalKiB, &whole, &thousandths);
577
578 const char* color;
579 if (whole < 50)
580 {
581 color = "\033[32m";
582 }
583 else if (whole < 80)
584 {
585 color = "\033[33m";
586 }
587 else
588 {
589 color = "\033[31m";
590 }
591
592 printf(" \033[90mUsed:\033[0m %s%5llu MiB\033[0m / %5llu MiB "
593 "\033[90m(%s%3llu.%03llu%%\033[0m\033[90m)\033[0m\033[K\n",
594 color, usedKiB / 1024, perfs->memPerfs.totalKiB / 1024, color, whole, thousandths);
595 printf(" \033[90mFree:\033[0m \033[32m%5llu MiB\033[0m\033[K\n", perfs->memPerfs.freeKiB / 1024);
596
597 printf(" [");
598 uint64_t barLength = (whole * memBarWidth) / 100;
599 for (uint64_t j = 0; j < memBarWidth; j++)
600 {
601 if (j < barLength)
602 {
603 printf("%s#\033[0m", color);
604 }
605 else
606 {
607 printf("\033[90m \033[0m");
608 }
609 }
610 printf("]\033[K\n");
611
612 printf("\033[K\n");
613
614 const char* sortIndicator = "";
615 switch (currentSortMode)
616 {
617 case SORT_PID:
618 sortIndicator = " \033[36m[PID]\033[0m";
619 break;
620 case SORT_MEMORY:
621 sortIndicator = " \033[36m[MEM]\033[0m";
622 break;
623 case SORT_CPU:
624 sortIndicator = " \033[36m[CPU]\033[0m";
625 break;
626 }
627
628 printf(" Processes:\033[0m%s \033[90m(p=PID, m=Mem, c=CPU, j/k=scroll)\033[0m\033[K\n", sortIndicator);
629 printf(" \033[90mPID CPU%% KiB Threads Command\033[0m\033[K\n");
630 printf(" \033[90m");
631 for (uint64_t i = 0; i < terminalColumns - 4; i++)
632 {
633 printf("-");
634 }
635 printf("\n\033[0m");
636
637 uint64_t headerLines = 4 + cpusPerColumn + 7;
638 uint64_t availableLines = (terminalRows - 1 > headerLines + 1) ? (terminalRows - 1 - headerLines - 1) : 10;
639
640 if (processScrollOffset > perfs->procAmount)
641 {
643 }
644 if (perfs->procAmount > availableLines && processScrollOffset > perfs->procAmount - availableLines)
645 {
646 processScrollOffset = perfs->procAmount - availableLines;
647 }
648
649 uint64_t displayCount = availableLines;
650 if (processScrollOffset + displayCount > perfs->procAmount)
651 {
652 displayCount = perfs->procAmount - processScrollOffset;
653 }
654
655 for (uint64_t i = 0; i < displayCount; i++)
656 {
657 uint64_t procIdx = processScrollOffset + i;
658 const char* cpuColor;
659 if (perfs->procPerfs[procIdx].cpuPercent < 10.0)
660 {
661 cpuColor = "\033[32m";
662 }
663 else if (perfs->procPerfs[procIdx].cpuPercent < 50.0)
664 {
665 cpuColor = "\033[33m";
666 }
667 else
668 {
669 cpuColor = "\033[31m";
670 }
671
672 const char* memColor;
673 if (perfs->procPerfs[procIdx].userKiB < 1024 * 50)
674 {
675 memColor = "\033[32m";
676 }
677 else if (perfs->procPerfs[procIdx].userKiB < 1024 * 200)
678 {
679 memColor = "\033[33m";
680 }
681 else
682 {
683 memColor = "\033[31m";
684 }
685
686 uint64_t cpuWhole = (uint64_t)perfs->procPerfs[procIdx].cpuPercent;
687 uint64_t cpuThousandths = (uint64_t)((perfs->procPerfs[procIdx].cpuPercent - cpuWhole) * 1000);
688
689 char displayCmdline[terminalColumns - 40 + 1];
690 if (strlen(perfs->procPerfs[procIdx].cmdline) > terminalColumns - 40)
691 {
692 strncpy(displayCmdline, perfs->procPerfs[procIdx].cmdline, terminalColumns - 43);
693 displayCmdline[terminalColumns - 43] = '\0';
694 strcat(displayCmdline, "...");
695 }
696 else
697 {
698 strcpy(displayCmdline, perfs->procPerfs[procIdx].cmdline);
699 }
700
701 printf(" \033[90m%-8d\033[0m %s%4llu.%03llu%%\033[0m %s%7llu\033[0m %7llu %s\033[K\n",
702 perfs->procPerfs[procIdx].pid, cpuColor, cpuWhole, cpuThousandths, memColor,
703 perfs->procPerfs[procIdx].userKiB, perfs->procPerfs[procIdx].threadCount, displayCmdline);
704 }
705
706 for (uint64_t i = displayCount; i < availableLines; i++)
707 {
708 printf("\033[K\n");
709 }
710
711 fflush(stdout);
712}
713
714int main(void)
715{
717 if (cpuAmount == ERR)
718 {
719 printf("Failed to read CPU amount\n");
720 abort();
721 }
722
723 perfs_t perfs = {0};
724 perfs.prevCpuPerfs = calloc(cpuAmount, sizeof(cpu_perfs_t));
725 if (perfs.prevCpuPerfs == NULL)
726 {
727 printf("Failed to allocate memory for previous CPU performance data\n");
728 return EXIT_FAILURE;
729 }
730 perfs.cpuPerfs = calloc(cpuAmount, sizeof(cpu_perfs_t));
731 if (perfs.cpuPerfs == NULL)
732 {
733 printf("Failed to allocate memory for CPU performance data\n");
734 free(perfs.prevCpuPerfs);
735 return EXIT_FAILURE;
736 }
737 perfs.prevProcPerfs = NULL;
738 perfs.procPerfs = NULL;
739 perfs.memPerfs = (mem_perfs_t){0};
740
742
743 bool pleaseWaitShown = true;
744 const char* waitMessage = "[Please Wait]";
745 uint64_t waitMessageLength = strlen(waitMessage);
746 printf("\033[H\033[J\033[?25l\033[%lluC%s\n", (terminalColumns - waitMessageLength) / 2, waitMessage);
747
748 while (1)
749 {
750 perfs_print(&perfs);
751 perfs_update(&perfs);
752 if (pleaseWaitShown)
753 {
754 printf("\033[s\033[H\033[K\033[u");
755 pleaseWaitShown = false;
756 }
757 }
758
759 printf("\033[?25h");
760 return 0;
761}
#define MAX_NAME
Maximum length of names.
Definition MAX_NAME.h:11
#define MAX_PATH
Maximum length of filepaths.
Definition MAX_PATH.h:11
uint64_t getdents(fd_t fd, dirent_t *buffer, uint64_t count)
System call for reading directory entires.
Definition getdents.c:9
fd_t open(const char *path)
System call for opening files.
Definition open.c:9
poll_events_t poll1(fd_t fd, poll_events_t events, clock_t timeout)
Wrapper for polling one file.
Definition poll1.c:9
uint64_t close(fd_t fd)
System call for closing files.
Definition close.c:9
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
@ POLLIN
File descriptor is ready to read.
Definition io.h:300
#define PAGE_SIZE
Memory page size.
Definition proc.h:140
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ fd_t
A file descriptor.
Definition fd_t.h:12
__UINT64_TYPE__ pid_t
Process Identifier.
Definition pid_t.h:11
__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
int main(void)
Definition main.c:5
static proc_perfs_t * proc_perfs_read(uint64_t *procAmount)
Definition main.c:182
static uint64_t terminalRows
Definition main.c:13
static sort_mode_t currentSortMode
Definition main.c:26
static int compare_by_pid(const void *a, const void *b)
Definition main.c:304
static void perf_percentage(clock_t part, clock_t total, uint64_t *whole, uint64_t *thousandths)
Definition main.c:450
static void perfs_update(perfs_t *perfs)
Definition main.c:345
#define SAMPLE_INTERVAL
Definition main.c:10
static int compare_by_memory(const void *a, const void *b)
Definition main.c:311
static uint64_t cpu_perf_count_cpus(void)
Definition main.c:103
static uint64_t cpuAmount
Definition main.c:17
static uint64_t terminalColumns
Definition main.c:12
static void sort_processes(perfs_t *perfs)
Definition main.c:329
static int compare_by_cpu(const void *a, const void *b)
Definition main.c:318
static void perfs_print(perfs_t *perfs)
Definition main.c:465
static uint64_t mem_perf_read(mem_perfs_t *memPerfs)
Definition main.c:154
static void terminal_size_get(void)
Definition main.c:28
static uint64_t processScrollOffset
Definition main.c:14
static clock_t lastSampleTime
Definition main.c:16
static uint64_t cpu_perf_read(cpu_perfs_t *cpuPerfs)
Definition main.c:122
sort_mode_t
Definition main.c:20
@ SORT_MEMORY
Definition main.c:22
@ SORT_CPU
Definition main.c:23
@ SORT_PID
Definition main.c:21
static void calculate_cpu_percentages(perfs_t *perfs)
Definition main.c:283
__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 size_t fread(void *_RESTRICT ptr, size_t size, size_t nmemb, FILE *_RESTRICT stream)
Definition fread.c:7
_PUBLIC int fclose(FILE *stream)
Definition fclose.c:7
FILE * stdout
Definition std_streams.c:17
_PUBLIC int snprintf(char *_RESTRICT s, size_t n, const char *_RESTRICT format,...)
Definition snprintf.c:3
_PUBLIC _NORETURN void exit(int status)
Definition exit.c:7
_PUBLIC void * realloc(void *ptr, size_t size)
Definition realloc.c:13
_PUBLIC void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))
Definition qsort.c:47
#define EXIT_FAILURE
Definition stdlib.h:47
#define atoi(nptr)
Definition stdlib.h:34
_PUBLIC void * calloc(size_t nmemb, size_t size)
Definition calloc.c:6
_PUBLIC _NORETURN void abort(void)
Definition abort.c:7
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
Definition strncpy.c:3
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:61
_PUBLIC size_t strlen(const char *s)
Definition strlen.c:3
_PUBLIC char * strcat(char *_RESTRICT s1, const char *_RESTRICT s2)
Definition strcat.c:3
_PUBLIC char * strcpy(char *_RESTRICT s1, const char *_RESTRICT s2)
Definition strcpy.c:3
_PUBLIC int strcmp(const char *s1, const char *s2)
Definition strcmp.c:3
Definition file.h:34
uint64_t id
Definition main.c:67
clock_t interruptClocks
Definition main.c:70
clock_t idleClocks
Definition main.c:68
clock_t activeClocks
Definition main.c:69
Directory entry struct.
Definition io.h:434
uint64_t usedKiB
Definition main.c:77
uint64_t freeKiB
Definition main.c:76
uint64_t totalKiB
Definition main.c:75
Definition main.c:93
proc_perfs_t * prevProcPerfs
Definition main.c:97
cpu_perfs_t * cpuPerfs
Definition main.c:95
uint64_t procAmount
Definition main.c:98
mem_perfs_t memPerfs
Definition main.c:100
proc_perfs_t * procPerfs
Definition main.c:99
cpu_perfs_t * prevCpuPerfs
Definition main.c:94
uint64_t prevProcAmount
Definition main.c:96
char cmdline[256]
Definition main.c:89
uint64_t threadCount
Definition main.c:87
pid_t pid
Definition main.c:82
clock_t startClocks
Definition main.c:85
uint64_t userKiB
Definition main.c:86
clock_t kernelClocks
Definition main.c:84
clock_t userClocks
Definition main.c:83
double cpuPercent
Definition main.c:88
_PUBLIC clock_t clock(void)
Definition clock.c:5