src/hack_forked/utils/sys/sysinfo.c (77 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #define CAML_NAME_SPACE #include <caml/memory.h> #include <caml/mlvalues.h> #include <caml/unixsupport.h> #include <assert.h> #include <errno.h> #ifdef __linux__ #include <sys/sysinfo.h> #endif #ifdef __APPLE__ #include <sys/sysctl.h> #endif #ifdef _WIN32 #include <windows.h> #endif CAMLprim value hh_sysinfo_totalram(value unit) { CAMLparam1(unit); #if defined(__linux__) struct sysinfo info; if (-1 == sysinfo(&info)) { uerror("sysinfo", Nothing); } CAMLreturn(Val_long(info.totalram)); #elif defined(__APPLE__) int mib[] = {CTL_HW, HW_MEMSIZE}; int64_t memsize = 0; size_t len = sizeof(memsize); if (-1 == sysctl(mib, 2, &memsize, &len, NULL, 0)) { uerror("sysctl", Nothing); } CAMLreturn(Val_long(memsize)); #else /* Not implemented */ CAMLreturn(Val_long(0)); #endif } /** * Whether we're running under Rosetta on Apple Silicon */ CAMLprim value hh_is_rosetta(value unit) { CAMLparam1(unit); int ret = 0; #ifdef __APPLE__ size_t size = sizeof(ret); if (-1 == sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0)) { if (errno == ENOENT) { // e.g. Intel ret = 0; } else { uerror("sysctl", Nothing); } } #endif CAMLreturn(Val_bool(ret)); } CAMLprim value hh_sysinfo_uptime(value unit) { CAMLparam1(unit); #ifdef __linux__ struct sysinfo info; int success = sysinfo(&info); assert(success == 0 && "sysinfo() failed"); CAMLreturn(Val_long(info.uptime)); #else /* Not implemented */ CAMLreturn(Val_long(0)); #endif } /** * There are a bunch of functions that you expect to return a pid, * like Unix.getpid() and Unix.create_process(). However, on * Windows, instead of returning the process ID, they return a * process handle. * * Process handles seem act like pointers to a process. You can have * more than one handle that points to a single process (unlike * pids, where there is a single pid for a process). * * This isn't a problem normally, since functons like Unix.waitpid() * will take the process handle on Windows. But if you want to print * or log the pid, then you need to dereference the handle and get * the pid. And that's what this function does. */ value pid_of_handle(value handle) { CAMLparam1(handle); #ifdef _WIN32 CAMLreturn(Val_int(GetProcessId((HANDLE)Long_val(handle)))); #else CAMLreturn(handle); #endif } value handle_of_pid_for_termination(value pid) { CAMLparam1(pid); #ifdef _WIN32 CAMLreturn(Val_int(OpenProcess(PROCESS_TERMINATE, FALSE, Int_val(pid)))); #else CAMLreturn(pid); #endif }