diff --git a/fs/proc/root.c b/fs/proc/root.c index c907e8435f..5779861a16 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -41,6 +41,14 @@ static ssize_t proc_show_meminfo(struct proc_entry *UNUSED(entry), char *buf) { return n; } +static ssize_t proc_show_uptime(struct proc_entry *UNUSED(entry), char *buf) { + struct uptime_info uptime_info = get_uptime(); + unsigned uptime = uptime_info.uptime_ticks; + size_t n = 0; + n += sprintf(buf + n, "%u.%u %u.%u\n", uptime / 100, uptime % 100, uptime / 100, uptime % 100); + return n; +} + static int proc_readlink_self(struct proc_entry *UNUSED(entry), char *buf) { sprintf(buf, "%d/", current->pid); return 0; @@ -51,6 +59,7 @@ struct proc_dir_entry proc_root_entries[] = { {"version", .show = proc_show_version}, {"stat", .show = proc_show_stat}, {"meminfo", .show = proc_show_meminfo}, + {"uptime", .show = proc_show_uptime}, {"self", S_IFLNK, .readlink = proc_readlink_self}, }; #define PROC_ROOT_LEN sizeof(proc_root_entries)/sizeof(proc_root_entries[0]) diff --git a/kernel/uname.c b/kernel/uname.c index 4a789b4263..0e11d41258 100644 --- a/kernel/uname.c +++ b/kernel/uname.c @@ -1,11 +1,13 @@ #include #include +#include "kernel/calls.h" +#include "platform/platform.h" + #if __APPLE__ #include #elif __linux__ #include #endif -#include "kernel/calls.h" void do_uname(struct uname *uts) { struct utsname real_uname; @@ -38,25 +40,14 @@ static uint64_t get_total_ram() { sysctl((int []) {CTL_DEBUG, HW_PHYSMEM}, 2, &total_ram, NULL, NULL, 0); return total_ram; } -static uint64_t get_uptime() { - uint64_t value[2]; - size_t size = sizeof(value); - sysctlbyname("kern.boottime", &value, &size, NULL, 0); - struct timeval now; - gettimeofday(&now, NULL); - return now.tv_sec - value[0]; -} static void sysinfo_specific(struct sys_info *info) { info->totalram = get_total_ram(); - info->uptime = get_uptime(); // TODO: everything else } #elif __linux__ static void sysinfo_specific(struct sys_info *info) { struct sysinfo host_info; sysinfo(&host_info); - memcpy(info->loads, host_info.loads, sizeof(host_info.loads)); - info->uptime = host_info.uptime; info->totalram = host_info.totalram; info->freeram = host_info.freeram; info->sharedram = host_info.sharedram; @@ -71,6 +62,11 @@ static void sysinfo_specific(struct sys_info *info) { dword_t sys_sysinfo(addr_t info_addr) { struct sys_info info = {0}; + struct uptime_info uptime = get_uptime(); + info.uptime = uptime.uptime_ticks; + info.loads[0] = uptime.load_1m; + info.loads[1] = uptime.load_5m; + info.loads[2] = uptime.load_15m; sysinfo_specific(&info); if (user_put(info_addr, info)) diff --git a/platform/darwin.c b/platform/darwin.c index d1971afd6f..1ce6b32b0e 100644 --- a/platform/darwin.c +++ b/platform/darwin.c @@ -1,4 +1,6 @@ #include +#include +#include #include "platform/platform.h" struct cpu_usage get_cpu_usage() { @@ -28,3 +30,34 @@ struct mem_usage get_mem_usage() { usage.inactive = vm.inactive_count * vm_page_size; return usage; } + +struct uptime_info get_uptime() { + uint64_t kern_boottime[2]; + size_t size = sizeof(kern_boottime); + sysctlbyname("kern.boottime", &kern_boottime, &size, NULL, 0); + struct timeval now; + gettimeofday(&now, NULL); + + struct { + uint32_t ldavg[3]; + long scale; + } vm_loadavg; + size = sizeof(vm_loadavg); + sysctlbyname("vm.loadavg", &vm_loadavg, &size, NULL, 0); + + // linux wants the scale to be 16 bits + for (int i = 0; i < 3; i++) { + if (FSHIFT < 16) + vm_loadavg.ldavg[i] <<= 16 - FSHIFT; + else + vm_loadavg.ldavg[i] >>= FSHIFT - 16; + } + + struct uptime_info uptime = { + .uptime_ticks = now.tv_sec - kern_boottime[0], + .load_1m = vm_loadavg.ldavg[0], + .load_5m = vm_loadavg.ldavg[1], + .load_15m = vm_loadavg.ldavg[2], + }; + return uptime; +} diff --git a/platform/linux.c b/platform/linux.c index b3282c9225..e4d958304d 100644 --- a/platform/linux.c +++ b/platform/linux.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -38,3 +39,15 @@ struct mem_usage get_mem_usage() { return usage; } + +struct uptime_info get_uptime() { + struct sysinfo info; + sysinfo(&info); + struct uptime_info uptime = { + .uptime_ticks = info.uptime, + .load_1m = info.loads[0], + .load_5m = info.loads[1], + .load_15m = info.loads[2], + }; + return uptime; +} diff --git a/platform/platform.h b/platform/platform.h index b9897549a3..c265fdc866 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -19,4 +19,10 @@ struct mem_usage { }; struct mem_usage get_mem_usage(void); +struct uptime_info { + uint64_t uptime_ticks; + uint64_t load_1m, load_5m, load_15m; +}; +struct uptime_info get_uptime(void); + #endif