update process info primitive api

This commit is contained in:
Daan Leijen 2023-03-19 19:11:43 -07:00
parent eca98ac056
commit 8fbe7aae50
6 changed files with 59 additions and 59 deletions

View file

@ -12,7 +12,7 @@ terms of the MIT license. A copy of the license can be found in the file
#include "windows/prim.c" // VirtualAlloc (Windows) #include "windows/prim.c" // VirtualAlloc (Windows)
#elif defined(__wasi__) #elif defined(__wasi__)
#define MI_USE_SBRK #define MI_USE_SBRK
#include "wasi/prim.h" // memory-grow or sbrk (Wasm) #include "wasi/prim.c" // memory-grow or sbrk (Wasm)
#else #else
#include "unix/prim.c" // mmap() (Linux, macOSX, BSD, Illumnos, Haiku, DragonFly, etc.) #include "unix/prim.c" // mmap() (Linux, macOSX, BSD, Illumnos, Haiku, DragonFly, etc.)
#endif #endif

View file

@ -59,9 +59,18 @@ size_t _mi_prim_numa_node_count(void);
mi_msecs_t _mi_prim_clock_now(void); mi_msecs_t _mi_prim_clock_now(void);
// Return process information (only for statistics) // Return process information (only for statistics)
void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, typedef struct mi_process_info_s {
size_t* current_rss, size_t* peak_rss, mi_msecs_t elapsed;
size_t* current_commit, size_t* peak_commit, size_t* page_faults); mi_msecs_t utime;
mi_msecs_t stime;
size_t current_rss;
size_t peak_rss;
size_t current_commit;
size_t peak_commit;
size_t page_faults;
} mi_process_info_t;
void _mi_prim_process_info(mi_process_info_t* pinfo);
// Default stderr output. (only for warnings etc. with verbose enabled) // Default stderr output. (only for warnings etc. with verbose enabled)
// msg != NULL && _mi_strlen(msg) > 0 // msg != NULL && _mi_strlen(msg) > 0
@ -202,6 +211,7 @@ This is inlined here as it is on the fast path for allocation functions.
On most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a On most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a
__thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures __thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures
that the storage will always be available (allocated on the thread stacks). that the storage will always be available (allocated on the thread stacks).
On some platforms though we cannot use that when overriding `malloc` since the underlying On some platforms though we cannot use that when overriding `malloc` since the underlying
TLS implementation (or the loader) will call itself `malloc` on a first access and recurse. TLS implementation (or the loader) will call itself `malloc` on a first access and recurse.
We try to circumvent this in an efficient way: We try to circumvent this in an efficient way:

View file

@ -541,19 +541,15 @@ static mi_msecs_t timeval_secs(const struct timeval* tv) {
return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L); return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L);
} }
void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) void _mi_prim_process_info(mi_process_info_t* pinfo)
{ {
struct rusage rusage; struct rusage rusage;
getrusage(RUSAGE_SELF, &rusage); getrusage(RUSAGE_SELF, &rusage);
*utime = timeval_secs(&rusage.ru_utime); pinfo->utime = timeval_secs(&rusage.ru_utime);
*stime = timeval_secs(&rusage.ru_stime); pinfo->stime = timeval_secs(&rusage.ru_stime);
#if !defined(__HAIKU__) #if !defined(__HAIKU__)
*page_faults = rusage.ru_majflt; pinfo->page_faults = rusage.ru_majflt;
#endif #endif
// estimate commit using our stats
*peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak));
*current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current));
*current_rss = *current_commit; // estimate
#if defined(__HAIKU__) #if defined(__HAIKU__)
// Haiku does not have (yet?) a way to // Haiku does not have (yet?) a way to
// get these stats per process // get these stats per process
@ -562,19 +558,20 @@ void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* current
ssize_t c; ssize_t c;
get_thread_info(find_thread(0), &tid); get_thread_info(find_thread(0), &tid);
while (get_next_area_info(tid.team, &c, &mem) == B_OK) { while (get_next_area_info(tid.team, &c, &mem) == B_OK) {
*peak_rss += mem.ram_size; pinfo->peak_rss += mem.ram_size;
} }
*page_faults = 0; pinfo->page_faults = 0;
#elif defined(__APPLE__) #elif defined(__APPLE__)
*peak_rss = rusage.ru_maxrss; // BSD reports in bytes pinfo->peak_rss = rusage.ru_maxrss; // BSD reports in bytes
struct mach_task_basic_info info; struct mach_task_basic_info info;
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) { if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) {
*current_rss = (size_t)info.resident_size; pinfo->current_rss = (size_t)info.resident_size;
} }
#else #else
*peak_rss = rusage.ru_maxrss * 1024; // Linux reports in KiB pinfo->peak_rss = rusage.ru_maxrss * 1024; // Linux reports in KiB
#endif #endif
// use defaults for commit
} }
#else #else
@ -584,15 +581,10 @@ void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* current
#pragma message("define a way to get process info") #pragma message("define a way to get process info")
#endif #endif
void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) void _mi_prim_process_info(mi_process_info_t* pinfo)
{ {
*peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak)); // use defaults
*current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current)); MI_UNUSED(pinfo);
*peak_rss = *peak_commit;
*current_rss = *current_commit;
*page_faults = 0;
*utime = 0;
*stime = 0;
} }
#endif #endif

View file

@ -194,17 +194,13 @@ mi_msecs_t _mi_prim_clock_now(void) {
// Process info // Process info
//---------------------------------------------------------------- //----------------------------------------------------------------
void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) void _mi_prim_process_info(mi_process_info_t* pinfo)
{ {
*peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak)); // use defaults
*current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current)); MI_UNUSED(pinfo);
*peak_rss = *peak_commit;
*current_rss = *current_commit;
*page_faults = 0;
*utime = 0;
*stime = 0;
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
// Output // Output
//---------------------------------------------------------------- //----------------------------------------------------------------

View file

@ -428,15 +428,15 @@ static mi_msecs_t filetime_msecs(const FILETIME* ftime) {
typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD); typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
static PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL; static PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL;
void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) void _mi_prim_process_info(mi_process_info_t* pinfo)
{ {
FILETIME ct; FILETIME ct;
FILETIME ut; FILETIME ut;
FILETIME st; FILETIME st;
FILETIME et; FILETIME et;
GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut); GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);
*utime = filetime_msecs(&ut); pinfo->utime = filetime_msecs(&ut);
*stime = filetime_msecs(&st); pinfo->stime = filetime_msecs(&st);
// load psapi on demand // load psapi on demand
if (pGetProcessMemoryInfo == NULL) { if (pGetProcessMemoryInfo == NULL) {
@ -452,11 +452,11 @@ void _mi_prim_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* current
if (pGetProcessMemoryInfo != NULL) { if (pGetProcessMemoryInfo != NULL) {
pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
} }
*current_rss = (size_t)info.WorkingSetSize; pinfo->current_rss = (size_t)info.WorkingSetSize;
*peak_rss = (size_t)info.PeakWorkingSetSize; pinfo->peak_rss = (size_t)info.PeakWorkingSetSize;
*current_commit = (size_t)info.PagefileUsage; pinfo->current_commit = (size_t)info.PagefileUsage;
*peak_commit = (size_t)info.PeakPagefileUsage; pinfo->peak_commit = (size_t)info.PeakPagefileUsage;
*page_faults = (size_t)info.PageFaultCount; pinfo->page_faults = (size_t)info.PageFaultCount;
} }
//---------------------------------------------------------------- //----------------------------------------------------------------

View file

@ -430,21 +430,23 @@ mi_msecs_t _mi_clock_end(mi_msecs_t start) {
mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept
{ {
mi_msecs_t elapsed = _mi_clock_end(mi_process_start); mi_process_info_t pinfo = { 0 };
mi_msecs_t utime = 0; pinfo.elapsed = _mi_clock_end(mi_process_start);
mi_msecs_t stime = 0; pinfo.utime = 0;
size_t current_rss0 = 0; pinfo.stime = 0;
size_t peak_rss0 = 0; pinfo.current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current));
size_t current_commit0 = 0; pinfo.peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak));
size_t peak_commit0 = 0; pinfo.current_rss = pinfo.current_commit;
size_t page_faults0 = 0; pinfo.peak_rss = pinfo.peak_commit;
_mi_prim_process_info(&utime, &stime, &current_rss0, &peak_rss0, &current_commit0, &peak_commit0, &page_faults0); pinfo.page_faults = 0;
if (elapsed_msecs!=NULL) *elapsed_msecs = (elapsed < 0 ? 0 : (elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)elapsed : PTRDIFF_MAX));
if (user_msecs!=NULL) *user_msecs = (utime < 0 ? 0 : (utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)utime : PTRDIFF_MAX)); _mi_prim_process_info(&pinfo);
if (system_msecs!=NULL) *system_msecs = (stime < 0 ? 0 : (stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)stime : PTRDIFF_MAX)); if (elapsed_msecs!=NULL) *elapsed_msecs = (pinfo.elapsed < 0 ? 0 : (pinfo.elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.elapsed : PTRDIFF_MAX));
if (current_rss!=NULL) *current_rss = current_rss0; if (user_msecs!=NULL) *user_msecs = (pinfo.utime < 0 ? 0 : (pinfo.utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.utime : PTRDIFF_MAX));
if (peak_rss!=NULL) *peak_rss = peak_rss0; if (system_msecs!=NULL) *system_msecs = (pinfo.stime < 0 ? 0 : (pinfo.stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.stime : PTRDIFF_MAX));
if (current_commit!=NULL) *current_commit = current_commit0; if (current_rss!=NULL) *current_rss = pinfo.current_rss;
if (peak_commit!=NULL) *peak_commit = peak_commit0; if (peak_rss!=NULL) *peak_rss = pinfo.peak_rss;
if (page_faults!=NULL) *page_faults = page_faults0; if (current_commit!=NULL) *current_commit = pinfo.current_commit;
if (peak_commit!=NULL) *peak_commit = pinfo.peak_commit;
if (page_faults!=NULL) *page_faults = pinfo.page_faults;
} }