10#define SAMPLE_INTERVAL (CLOCKS_PER_SEC)
33 printf(
"\033[s\033[999;999H\033[6n");
140 if (
sscanf(line,
"%lu %lu %lu %lu", &cpuPerfs[i].
id, &cpuPerfs[i].idleClocks, &cpuPerfs[i].activeClocks,
141 &cpuPerfs[i].interruptClocks) != 4)
165 if (
fscanf(
file,
"total_pages %lu\nfree_pages %lu\nused_pages %lu", &totalPages, &freePages, &usedPages) == 3)
196 if (readAmount ==
ERR)
221 snprintf(path,
sizeof(path),
"/proc/%d/perf", pid);
223 if (perfFile ==
NULL)
231 "user_clocks %lu\nkernel_clocks %lu\nstart_clocks %lu\nuser_pages %lu\nthread_count %lu",
243 snprintf(path,
sizeof(path),
"/proc/%d/cmdline", pid);
245 if (cmdlineFile ==
NULL)
254 while (
fread(&c, 1, 1, cmdlineFile) == 1 && index <
sizeof(procPerf.
cmdline) - 1)
266 procPerf.
cmdline[index] =
'\0';
270 if (procPerfs ==
NULL)
275 procPerfs[(*procAmount)++] = procPerf;
295 clock_t totalDelta = userDelta + kernelDelta;
356 bool keyPressed =
true;
395 printf(
"\033[?25h\033[H\033[J");
409 currentTime =
clock();
427 printf(
"Failed to read CPU performance data\n");
433 printf(
"Failed to read memory performance data\n");
440 printf(
"Failed to read process performance data\n");
459 uint64_t scaledPart = part * 100000;
460 uint64_t percent = scaledPart / total;
461 *whole = percent / 1000;
462 *thousandths = percent % 1000;
471 uint64_t cpuBarWidth = singleColumnWidth - cpuPrefixWidth;
476 printf(
"\033[1;33m CPU Usage:\033[0m\033[K\n");
479 for (
uint64_t row = 0; row < cpusPerColumn; row++)
487 clock_t totalDelta = currTotal - prevTotal;
508 printf(
" \033[90mCPU%-2llu\033[0m %s%3llu.%03llu%%\033[0m [", i, color, whole, thousandths);
510 uint64_t barLength = (whole * cpuBarWidth) / 100;
511 for (
uint64_t j = 0; j < cpuBarWidth; j++)
515 printf(
"%s#\033[0m", color);
519 printf(
"\033[90m \033[0m");
524 uint64_t rightIdx = row + cpusPerColumn;
532 totalDelta = currTotal - prevTotal;
551 printf(
" \033[90mCPU%-2llu\033[0m %s%3llu.%03llu%%\033[0m [", rightIdx, color, whole, thousandths);
553 barLength = (whole * cpuBarWidth) / 100;
554 for (
uint64_t j = 0; j < cpuBarWidth; j++)
558 printf(
"%s#\033[0m", color);
562 printf(
"\033[90m \033[0m");
573 printf(
"\033[1;33m Memory:\033[0m\033[K\n");
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);
598 uint64_t barLength = (whole * memBarWidth) / 100;
599 for (
uint64_t j = 0; j < memBarWidth; j++)
603 printf(
"%s#\033[0m", color);
607 printf(
"\033[90m \033[0m");
614 const char* sortIndicator =
"";
618 sortIndicator =
" \033[36m[PID]\033[0m";
621 sortIndicator =
" \033[36m[MEM]\033[0m";
624 sortIndicator =
" \033[36m[CPU]\033[0m";
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");
637 uint64_t headerLines = 4 + cpusPerColumn + 7;
649 uint64_t displayCount = availableLines;
655 for (
uint64_t i = 0; i < displayCount; i++)
658 const char* cpuColor;
661 cpuColor =
"\033[32m";
665 cpuColor =
"\033[33m";
669 cpuColor =
"\033[31m";
672 const char* memColor;
675 memColor =
"\033[32m";
679 memColor =
"\033[33m";
683 memColor =
"\033[31m";
694 strcat(displayCmdline,
"...");
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,
706 for (
uint64_t i = displayCount; i < availableLines; i++)
719 printf(
"Failed to read CPU amount\n");
727 printf(
"Failed to allocate memory for previous CPU performance data\n");
733 printf(
"Failed to allocate memory for CPU performance data\n");
743 bool pleaseWaitShown =
true;
744 const char* waitMessage =
"[Please Wait]";
746 printf(
"\033[H\033[J\033[?25l\033[%lluC%s\n", (
terminalColumns - waitMessageLength) / 2, waitMessage);
754 printf(
"\033[s\033[H\033[K\033[u");
755 pleaseWaitShown =
false;
#define MAX_NAME
Maximum length of names.
#define MAX_PATH
Maximum length of filepaths.
uint64_t getdents(fd_t fd, dirent_t *buffer, uint64_t count)
System call for reading directory entires.
fd_t open(const char *path)
System call for opening files.
poll_events_t poll1(fd_t fd, poll_events_t events, clock_t timeout)
Wrapper for polling one file.
uint64_t close(fd_t fd)
System call for closing files.
uint64_t read(fd_t fd, void *buffer, uint64_t count)
System call for reading from files.
@ POLLIN
File descriptor is ready to read.
#define PAGE_SIZE
Memory page size.
#define NULL
Pointer error value.
#define ERR
Integer error value.
__UINT64_TYPE__ fd_t
A file descriptor.
__UINT64_TYPE__ pid_t
Process Identifier.
__UINT64_TYPE__ clock_t
A nanosecond time.
EFI_PHYSICAL_ADDRESS buffer
static proc_perfs_t * proc_perfs_read(uint64_t *procAmount)
static uint64_t terminalRows
static sort_mode_t currentSortMode
static int compare_by_pid(const void *a, const void *b)
static void perf_percentage(clock_t part, clock_t total, uint64_t *whole, uint64_t *thousandths)
static void perfs_update(perfs_t *perfs)
static int compare_by_memory(const void *a, const void *b)
static uint64_t cpu_perf_count_cpus(void)
static uint64_t cpuAmount
static uint64_t terminalColumns
static void sort_processes(perfs_t *perfs)
static int compare_by_cpu(const void *a, const void *b)
static void perfs_print(perfs_t *perfs)
static uint64_t mem_perf_read(mem_perfs_t *memPerfs)
static void terminal_size_get(void)
static uint64_t processScrollOffset
static clock_t lastSampleTime
static uint64_t cpu_perf_read(cpu_perfs_t *cpuPerfs)
static void calculate_cpu_percentages(perfs_t *perfs)
_PUBLIC int sscanf(const char *_RESTRICT s, const char *_RESTRICT format,...)
_PUBLIC char * fgets(char *_RESTRICT s, int n, FILE *_RESTRICT stream)
_PUBLIC int fflush(FILE *stream)
_PUBLIC int printf(const char *_RESTRICT format,...)
_PUBLIC int fscanf(FILE *_RESTRICT stream, const char *_RESTRICT format,...)
_PUBLIC FILE * fopen(const char *_RESTRICT filename, const char *_RESTRICT mode)
_PUBLIC size_t fread(void *_RESTRICT ptr, size_t size, size_t nmemb, FILE *_RESTRICT stream)
_PUBLIC int fclose(FILE *stream)
_PUBLIC int snprintf(char *_RESTRICT s, size_t n, const char *_RESTRICT format,...)
_PUBLIC _NORETURN void exit(int status)
_PUBLIC void * realloc(void *ptr, size_t size)
_PUBLIC void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))
_PUBLIC void * calloc(size_t nmemb, size_t size)
_PUBLIC _NORETURN void abort(void)
_PUBLIC void free(void *ptr)
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC size_t strlen(const char *s)
_PUBLIC char * strcat(char *_RESTRICT s1, const char *_RESTRICT s2)
_PUBLIC char * strcpy(char *_RESTRICT s1, const char *_RESTRICT s2)
_PUBLIC int strcmp(const char *s1, const char *s2)
proc_perfs_t * prevProcPerfs
cpu_perfs_t * prevCpuPerfs
_PUBLIC clock_t clock(void)