diff --git a/kernel/syscall/processctl.c b/kernel/syscall/processctl.c index 049d5ec..112af20 100644 --- a/kernel/syscall/processctl.c +++ b/kernel/syscall/processctl.c @@ -142,6 +142,12 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) { hal_strcpy(stat->name, p->name); stat->state = p->state; stat->kern = p->kern; + + VasRange *range = p->vas; + while (range) { + stat->usemem += range->size; + range = range->next; + } break; } diff --git a/user/pctl/ls.c b/user/pctl/ls.c index 6ec9013..8664a7b 100644 --- a/user/pctl/ls.c +++ b/user/pctl/ls.c @@ -6,18 +6,69 @@ #include #include #include +#include +const char *human_size(uint64_t bytes, char *buf, size_t bufsize) { + static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" }; + int unit = 0; + + // Scale down until value fits nicely + uint64_t rem = 0; + while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) { + rem = bytes % 1024; + bytes /= 1024; + unit++; + } + + if (unit == 0) { + // Just bytes + usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]); + } else { + // Show one decimal place without using floats + // Multiply remainder by 10 to get first decimal digit + uint64_t frac = (rem * 10 + 512) / 1024; // rounded + if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0 + bytes++; + frac = 0; + } + + if (frac > 0) usnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]); + else usnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]); + } + + return buf; +} + + void pctl_ls(void) { + static const char *states[] = {"embryo", "ready", "zombie", "waiting", "died"}; + uint64_t procslen = processctl(-1, PCTL_PLS_SZ, 0, 0, 0); - uprintf("%-30s %s %-6s\n", "NAME", "PID", "TYPE"); + + char *namebuf = dlmalloc(34); + char *membuf = dlmalloc(20); + + uprintf("%-30s %s %-6s %-15s %-8s\n", "NAME", "PID", "TYPE", "MEMORY", "STATE"); for (size_t i = 0; i < procslen; i++) { ProcStat stat = ZERO(&stat); - char namebuf[34] = {0}; + + string_memset(namebuf, 0, 34); + string_memset(membuf, 0, 20); + int32_t r = processctl(-1, PCTL_PLS_STAT, i, (uint64_t)&stat, 0); if (r == E_OK) { string_memcpy(namebuf, stat.name, 30); namebuf[31] = namebuf[32] = namebuf[33] = '.'; - uprintf("%-30s %3lu %-6s\n", namebuf, stat.pid, stat.kern ? "KERNEL" : "USER"); + + // Too big format string causes a stack overflow. This is an issue with printf ;( + uprintf("%-30s %-3lu %-6s %-15s ", + namebuf, + stat.pid, + stat.kern ? "KERNEL" : "USER", + human_size(stat.usemem, membuf, 20) + ); + uprintf("%-8s", states[stat.state]); + uprintf("\n"); } } }