Add memory statistics to struct psctl_stat.
This is an incompatible ABI change.
This commit is contained in:
parent
2cd7361294
commit
8a4548db7d
2
Makefile
2
Makefile
|
@ -225,7 +225,7 @@ sysroot-system: sysroot-fsh sysroot-base-headers
|
|||
echo 'ID=sortix' && \
|
||||
echo 'VERSION_ID="$(VERSION)"' && \
|
||||
echo 'PRETTY_NAME="Sortix $(VERSION)"' && \
|
||||
echo 'SORTIX_ABI=1.4' && \
|
||||
echo 'SORTIX_ABI=2.0' && \
|
||||
true) > "$(SYSROOT)/etc/sortix-release"
|
||||
echo /etc/sortix-release >> "$(SYSROOT)/tix/manifest/system"
|
||||
ln -sf sortix-release "$(SYSROOT)/etc/os-release"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2022 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -88,6 +88,10 @@ struct psctl_stat
|
|||
int status;
|
||||
int nice;
|
||||
struct tmns tmns;
|
||||
size_t pss;
|
||||
size_t rss;
|
||||
size_t uss;
|
||||
size_t vms;
|
||||
};
|
||||
|
||||
#define PSCTL_PROGRAM_PATH __PSCTL(psctl_program_path, 4)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2022 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -127,6 +127,17 @@ int sys_psctl(pid_t pid, int request, void* ptr)
|
|||
kthread_mutex_lock(&process->nicelock);
|
||||
psst.nice = process->nice;
|
||||
kthread_mutex_unlock(&process->nicelock);
|
||||
kthread_mutex_lock(&process->segment_lock);
|
||||
// TODO: Cache these.
|
||||
for ( size_t i = 0; i < process->segments_used; i++ )
|
||||
{
|
||||
const struct segment* segment = &process->segments[i];
|
||||
psst.pss += segment->size;
|
||||
psst.rss += segment->size;
|
||||
psst.uss += segment->size;
|
||||
psst.vms += segment->size;
|
||||
}
|
||||
kthread_mutex_unlock(&process->segment_lock);
|
||||
// Note: It is safe to access the clocks in this manner as each of them
|
||||
// are locked by disabling interrupts. This is perhaps not
|
||||
// SMP-ready, but it will do for now.
|
||||
|
|
|
@ -69,6 +69,19 @@ releasing Sortix x.y, foo." to allow the maintainer to easily
|
|||
.Xr grep 1
|
||||
for it after a release.
|
||||
.Sh CHANGES
|
||||
.Ss Add memory statistics to struct psctl_stat
|
||||
The
|
||||
.Xr psctl 2
|
||||
now provides per-process memory statistics in
|
||||
.Vt struct psctl_stat
|
||||
via the new members
|
||||
.Fa pss ,
|
||||
.Fa rss ,
|
||||
.Fa uss ,
|
||||
and
|
||||
.Fa vms .
|
||||
.Pp
|
||||
This is an incompatible ABI change.
|
||||
.Ss Add memusage(2)
|
||||
The
|
||||
.Xr memusage 2
|
||||
|
|
53
utils/ps.c
53
utils/ps.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016 Jonas 'Sortie' Termansen.
|
||||
* Copyright (c) 2015, 2016, 2022, 2023 Jonas 'Sortie' Termansen.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <memusage.h>
|
||||
#include <psctl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -30,6 +31,30 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static char* format_bytes_amount(uintmax_t num_bytes, int unit, bool raw)
|
||||
{
|
||||
uintmax_t value = num_bytes;
|
||||
uintmax_t value_fraction = 0;
|
||||
uintmax_t exponent = 1024;
|
||||
char suffixes[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
|
||||
size_t num_suffixes = sizeof(suffixes) / sizeof(suffixes[0]);
|
||||
size_t suffix_index = 0;
|
||||
while ( (unit < 0 ? exponent <= value : (int) suffix_index < unit) &&
|
||||
suffix_index + 1 < num_suffixes )
|
||||
{
|
||||
value_fraction = value % exponent;
|
||||
value /= exponent;
|
||||
suffix_index++;
|
||||
}
|
||||
char suffix_char = raw ? 0 : suffixes[suffix_index];
|
||||
char value_fraction_char = '0' + (value_fraction / (1024 / 10 + 1)) % 10;
|
||||
char decimals[3] = {suffix_index ? '.' : 0, value_fraction_char, 0};
|
||||
char* result;
|
||||
if ( asprintf(&result, "%ju%s%c", value, decimals, suffix_char) < 0 )
|
||||
return NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
static char* get_program_path_of_pid(pid_t pid)
|
||||
{
|
||||
struct psctl_program_path ctl;
|
||||
|
@ -103,6 +128,7 @@ int main(int argc, char* argv[])
|
|||
bool select_all = false;
|
||||
bool show_full = false;
|
||||
bool show_long = false;
|
||||
bool show_memory = false;
|
||||
|
||||
const char* argv0 = argv[0];
|
||||
for ( int i = 1; i < argc; i++ )
|
||||
|
@ -126,12 +152,15 @@ int main(int argc, char* argv[])
|
|||
//case 'g': break;
|
||||
//case 'G': break;
|
||||
case 'l': show_long = true; break;
|
||||
case 'm': show_long = true; break;
|
||||
//case 'n': break;
|
||||
//case 'o': break;
|
||||
//case 'p': break;
|
||||
//case 't': break;
|
||||
//case 'u': break;
|
||||
//case 'U': break;
|
||||
// TODO: -o or some better more standard design for this.
|
||||
case 'v': show_memory = true; break;
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c);
|
||||
help(stderr, argv0);
|
||||
|
@ -155,6 +184,11 @@ int main(int argc, char* argv[])
|
|||
if ( 1 < argc )
|
||||
errx(1, "extra operand: %s", argv[1]);
|
||||
|
||||
size_t total_counter = MEMUSAGE_TOTAL;
|
||||
size_t total_memory;
|
||||
if ( show_memory && memusage(&total_counter, &total_memory, 1) < 0 )
|
||||
err(1, "memusage");
|
||||
|
||||
if ( show_full || show_long )
|
||||
printf("UID\t");
|
||||
printf("PID\t");
|
||||
|
@ -167,7 +201,12 @@ int main(int argc, char* argv[])
|
|||
if ( show_long )
|
||||
printf("NI\t");
|
||||
printf("TTY\t");
|
||||
printf("TIME\t ");
|
||||
printf("TIME\t ");
|
||||
if ( show_memory )
|
||||
{
|
||||
printf("%%MEM\t");
|
||||
printf("VMS\t");
|
||||
}
|
||||
printf("CMD\n");
|
||||
pid_t pid = 0;
|
||||
while ( true )
|
||||
|
@ -215,6 +254,16 @@ int main(int argc, char* argv[])
|
|||
int minutes = (time / 60) % 60;
|
||||
int seconds = (time / 1) % 60;
|
||||
printf("%02i:%02i:%02i ", hours, minutes, seconds);
|
||||
if ( show_memory )
|
||||
{
|
||||
unsigned percent = ((uintmax_t) psst.vms * 100) / total_memory;
|
||||
printf("%3u%%\t", percent);
|
||||
char* usage = format_bytes_amount(psst.vms, -1, false);
|
||||
if ( !usage )
|
||||
err(1, "malloc");
|
||||
printf("%s\t", usage);
|
||||
free(usage);
|
||||
}
|
||||
char* program_path = get_program_path_of_pid(pid);
|
||||
// TODO: Strip special characters from the process name lest an attacker
|
||||
// do things to the user's terminal.
|
||||
|
|
Loading…
Reference in New Issue