Polyfill sysinfo() a ilttle bit on BSDs

This commit is contained in:
Justine Tunney 2022-08-18 15:43:03 -07:00
parent 897e33ccc4
commit 75832f7379
6 changed files with 103 additions and 12 deletions

View file

@ -0,0 +1,23 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/timeval.h"
struct timeval _timespec_totimeval(struct timespec ts) {
return (struct timeval){ts.tv_sec, ts.tv_nsec / 1000};
}

View file

@ -0,0 +1,23 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/timeval.h"
struct timespec _timeval_totimespec(struct timeval tv) {
return (struct timespec){tv.tv_sec, tv.tv_usec * 1000};
}

View file

@ -185,6 +185,7 @@ o//libc/calls/getcwd-xnu.greg.o: private \
# division is expensive if not optimized
o/$(MODE)/libc/calls/_timespec_tomillis.o \
o/$(MODE)/libc/calls/_timespec_tomicros.o \
o/$(MODE)/libc/calls/_timespec_totimeval.o \
o/$(MODE)/libc/calls/_timespec_frommillis.o \
o/$(MODE)/libc/calls/_timespec_frommicros.o: private \
OVERRIDE_CFLAGS += \

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_
#include "libc/calls/struct/timespec.h"
#include "libc/time/struct/timezone.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -16,6 +17,8 @@ int lutimes(const char *, const struct timeval[2]);
int utimes(const char *, const struct timeval[2]);
struct timeval _timeval_add(struct timeval, struct timeval);
struct timeval _timespec_totimeval(struct timespec);
struct timespec _timeval_totimespec(struct timeval);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

View file

@ -16,36 +16,77 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/sysinfo.h"
#include "libc/calls/struct/sysinfo.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/calls/struct/vmmeter-meta.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/macros.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
#define CTL_KERN 1
#define CTL_HW 6
#define KERN_BOOTTIME 21
#define HW_PHYSMEM 5
static int64_t GetUptime(void) {
if (IsNetbsd()) return 0; // TODO(jart): Why?
struct timeval x;
size_t n = sizeof(x);
int mib[] = {CTL_KERN, KERN_BOOTTIME};
if (sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1) return 0;
return _timespec_real().tv_sec - x.tv_sec;
}
static int64_t GetPhysmem(void) {
uint64_t x;
size_t n = sizeof(x);
int mib[] = {CTL_HW, HW_PHYSMEM};
if (sysctl(mib, ARRAYLEN(mib), &x, &n, 0, 0) == -1) return 0;
return x;
}
static int sys_sysinfo_bsd(struct sysinfo *info) {
info->uptime = GetUptime();
info->totalram = GetPhysmem();
return 0;
}
/**
* Returns amount of system ram, cores, etc.
*
* Only the `totalram` field is supported on all platforms right now.
* Support is best on Linux. Fields will be set to zero when they're not
* known.
*
* @return 0 on success or -1 w/ errno
* @error ENOSYS, EFAULT
* @error EFAULT
*/
int sysinfo(struct sysinfo *info) {
int rc;
if (IsAsan()) {
if (info && !__asan_is_valid(info, sizeof(*info))) {
return efault();
struct sysinfo x = {0};
if (IsAsan() && info && !__asan_is_valid(info, sizeof(*info))) {
rc = efault();
} else if (!IsWindows()) {
if (IsLinux()) {
rc = sys_sysinfo(&x);
} else {
rc = sys_sysinfo_bsd(&x);
}
}
bzero(info, sizeof(*info));
if (!IsWindows()) {
rc = sys_sysinfo(info);
} else {
rc = sys_sysinfo_nt(info);
rc = sys_sysinfo_nt(&x);
}
if (rc != -1) {
info->procs = MAX(1, info->procs);
info->mem_unit = MAX(1, info->mem_unit);
info->totalram = MAX((8 * 1024 * 1024) / info->mem_unit, info->totalram);
x.procs = MAX(1, x.procs);
x.mem_unit = MAX(1, x.mem_unit);
x.totalram = MAX((8 * 1024 * 1024) / x.mem_unit, x.totalram);
memcpy(info, &x, sizeof(x));
}
STRACE("sysinfo(%p) → %d% m", info, rc);
return rc;
}