mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-06 07:29:30 +03:00
move process info into primitives
This commit is contained in:
parent
08a01d26dc
commit
69cb30a874
5 changed files with 248 additions and 169 deletions
|
@ -481,3 +481,111 @@ size_t _mi_prim_numa_node_count(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
// Clock
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)
|
||||||
|
|
||||||
|
mi_msecs_t _mi_prim_clock_now(void) {
|
||||||
|
struct timespec t;
|
||||||
|
#ifdef CLOCK_MONOTONIC
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||||
|
#else
|
||||||
|
clock_gettime(CLOCK_REALTIME, &t);
|
||||||
|
#endif
|
||||||
|
return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// low resolution timer
|
||||||
|
mi_msecs_t _mi_prim_clock_now(void) {
|
||||||
|
return ((mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// Process info
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(__unix) || defined(unix) || defined(__APPLE__) || defined(__HAIKU__)
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__HAIKU__)
|
||||||
|
#include <kernel/OS.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
struct rusage rusage;
|
||||||
|
getrusage(RUSAGE_SELF, &rusage);
|
||||||
|
*utime = timeval_secs(&rusage.ru_utime);
|
||||||
|
*stime = timeval_secs(&rusage.ru_stime);
|
||||||
|
#if !defined(__HAIKU__)
|
||||||
|
*page_faults = rusage.ru_majflt;
|
||||||
|
#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__)
|
||||||
|
// Haiku does not have (yet?) a way to
|
||||||
|
// get these stats per process
|
||||||
|
thread_info tid;
|
||||||
|
area_info mem;
|
||||||
|
ssize_t c;
|
||||||
|
get_thread_info(find_thread(0), &tid);
|
||||||
|
while (get_next_area_info(tid.team, &c, &mem) == B_OK) {
|
||||||
|
*peak_rss += mem.ram_size;
|
||||||
|
}
|
||||||
|
*page_faults = 0;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
*peak_rss = rusage.ru_maxrss; // BSD reports in bytes
|
||||||
|
struct mach_task_basic_info info;
|
||||||
|
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) {
|
||||||
|
*current_rss = (size_t)info.resident_size;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
*peak_rss = rusage.ru_maxrss * 1024; // Linux reports in KiB
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef __wasi__
|
||||||
|
// WebAssembly instances are not processes
|
||||||
|
#pragma message("define a way to get process info")
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
*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));
|
||||||
|
*peak_rss = *peak_commit;
|
||||||
|
*current_rss = *current_commit;
|
||||||
|
*page_faults = 0;
|
||||||
|
*utime = 0;
|
||||||
|
*stime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -152,3 +152,49 @@ size_t _mi_prim_numa_node(void) {
|
||||||
size_t _mi_prim_numa_node_count(void) {
|
size_t _mi_prim_numa_node_count(void) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// Clock
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)
|
||||||
|
|
||||||
|
mi_msecs_t _mi_prim_clock_now(void) {
|
||||||
|
struct timespec t;
|
||||||
|
#ifdef CLOCK_MONOTONIC
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||||
|
#else
|
||||||
|
clock_gettime(CLOCK_REALTIME, &t);
|
||||||
|
#endif
|
||||||
|
return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// low resolution timer
|
||||||
|
mi_msecs_t _mi_prim_clock_now(void) {
|
||||||
|
return ((mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
*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));
|
||||||
|
*peak_rss = *peak_commit;
|
||||||
|
*current_rss = *current_commit;
|
||||||
|
*page_faults = 0;
|
||||||
|
*utime = 0;
|
||||||
|
*stime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -383,3 +383,75 @@ size_t _mi_prim_numa_node_count(void) {
|
||||||
}
|
}
|
||||||
return ((size_t)numa_max + 1);
|
return ((size_t)numa_max + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// Clock
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
static mi_msecs_t mi_to_msecs(LARGE_INTEGER t) {
|
||||||
|
static LARGE_INTEGER mfreq; // = 0
|
||||||
|
if (mfreq.QuadPart == 0LL) {
|
||||||
|
LARGE_INTEGER f;
|
||||||
|
QueryPerformanceFrequency(&f);
|
||||||
|
mfreq.QuadPart = f.QuadPart/1000LL;
|
||||||
|
if (mfreq.QuadPart == 0) mfreq.QuadPart = 1;
|
||||||
|
}
|
||||||
|
return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
mi_msecs_t _mi_prim_clock_now(void) {
|
||||||
|
LARGE_INTEGER t;
|
||||||
|
QueryPerformanceCounter(&t);
|
||||||
|
return mi_to_msecs(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// Process info
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <psapi.h>
|
||||||
|
|
||||||
|
static mi_msecs_t filetime_msecs(const FILETIME* ftime) {
|
||||||
|
ULARGE_INTEGER i;
|
||||||
|
i.LowPart = ftime->dwLowDateTime;
|
||||||
|
i.HighPart = ftime->dwHighDateTime;
|
||||||
|
mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds
|
||||||
|
return msecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
FILETIME ct;
|
||||||
|
FILETIME ut;
|
||||||
|
FILETIME st;
|
||||||
|
FILETIME et;
|
||||||
|
GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);
|
||||||
|
*utime = filetime_msecs(&ut);
|
||||||
|
*stime = filetime_msecs(&st);
|
||||||
|
|
||||||
|
// load psapi on demand
|
||||||
|
if (pGetProcessMemoryInfo == NULL) {
|
||||||
|
HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll"));
|
||||||
|
if (hDll != NULL) {
|
||||||
|
pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get process info
|
||||||
|
PROCESS_MEMORY_COUNTERS info;
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
if (pGetProcessMemoryInfo != NULL) {
|
||||||
|
pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
|
||||||
|
}
|
||||||
|
*current_rss = (size_t)info.WorkingSetSize;
|
||||||
|
*peak_rss = (size_t)info.PeakWorkingSetSize;
|
||||||
|
*current_commit = (size_t)info.PagefileUsage;
|
||||||
|
*peak_commit = (size_t)info.PeakPagefileUsage;
|
||||||
|
*page_faults = (size_t)info.PageFaultCount;
|
||||||
|
}
|
||||||
|
|
|
@ -58,6 +58,15 @@ size_t _mi_prim_numa_node(void);
|
||||||
// Return the number of logical NUMA nodes
|
// Return the number of logical NUMA nodes
|
||||||
size_t _mi_prim_numa_node_count(void);
|
size_t _mi_prim_numa_node_count(void);
|
||||||
|
|
||||||
|
// High resolution clock
|
||||||
|
mi_msecs_t _mi_prim_clock_now(void);
|
||||||
|
|
||||||
|
// Return process information
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // MIMALLOC_PRIM_H
|
#endif // MIMALLOC_PRIM_H
|
||||||
|
|
||||||
|
|
182
src/stats.c
182
src/stats.c
|
@ -7,8 +7,9 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#include "mimalloc.h"
|
#include "mimalloc.h"
|
||||||
#include "mimalloc-internal.h"
|
#include "mimalloc-internal.h"
|
||||||
#include "mimalloc-atomic.h"
|
#include "mimalloc-atomic.h"
|
||||||
|
#include "prim/prim.h"
|
||||||
|
|
||||||
#include <stdio.h> // fputs, stderr
|
#include <stdio.h> // snprintf
|
||||||
#include <string.h> // memset
|
#include <string.h> // memset
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1920)
|
#if defined(_MSC_VER) && (_MSC_VER < 1920)
|
||||||
|
@ -291,8 +292,6 @@ static void mi_cdecl mi_buffered_out(const char* msg, void* arg) {
|
||||||
// Print statistics
|
// Print statistics
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
|
||||||
static void mi_stat_process_info(mi_msecs_t* elapsed, 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);
|
|
||||||
|
|
||||||
static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept {
|
static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept {
|
||||||
// wrap the output function to be line buffered
|
// wrap the output function to be line buffered
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
@ -337,15 +336,15 @@ static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0)
|
||||||
mi_stat_counter_print_avg(&stats->searches, "searches", out, arg);
|
mi_stat_counter_print_avg(&stats->searches, "searches", out, arg);
|
||||||
_mi_fprintf(out, arg, "%10s: %7zu\n", "numa nodes", _mi_os_numa_node_count());
|
_mi_fprintf(out, arg, "%10s: %7zu\n", "numa nodes", _mi_os_numa_node_count());
|
||||||
|
|
||||||
mi_msecs_t elapsed;
|
size_t elapsed;
|
||||||
mi_msecs_t user_time;
|
size_t user_time;
|
||||||
mi_msecs_t sys_time;
|
size_t sys_time;
|
||||||
size_t current_rss;
|
size_t current_rss;
|
||||||
size_t peak_rss;
|
size_t peak_rss;
|
||||||
size_t current_commit;
|
size_t current_commit;
|
||||||
size_t peak_commit;
|
size_t peak_commit;
|
||||||
size_t page_faults;
|
size_t page_faults;
|
||||||
mi_stat_process_info(&elapsed, &user_time, &sys_time, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults);
|
mi_process_info(&elapsed, &user_time, &sys_time, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults);
|
||||||
_mi_fprintf(out, arg, "%10s: %7ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000);
|
_mi_fprintf(out, arg, "%10s: %7ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000);
|
||||||
_mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, rss: ", "process",
|
_mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, rss: ", "process",
|
||||||
user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults );
|
user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults );
|
||||||
|
@ -404,47 +403,13 @@ void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// Basic timer for convenience; use milli-seconds to avoid doubles
|
// Basic timer for convenience; use milli-seconds to avoid doubles
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
static mi_msecs_t mi_to_msecs(LARGE_INTEGER t) {
|
|
||||||
static LARGE_INTEGER mfreq; // = 0
|
|
||||||
if (mfreq.QuadPart == 0LL) {
|
|
||||||
LARGE_INTEGER f;
|
|
||||||
QueryPerformanceFrequency(&f);
|
|
||||||
mfreq.QuadPart = f.QuadPart/1000LL;
|
|
||||||
if (mfreq.QuadPart == 0) mfreq.QuadPart = 1;
|
|
||||||
}
|
|
||||||
return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart);
|
|
||||||
}
|
|
||||||
|
|
||||||
mi_msecs_t _mi_clock_now(void) {
|
|
||||||
LARGE_INTEGER t;
|
|
||||||
QueryPerformanceCounter(&t);
|
|
||||||
return mi_to_msecs(t);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#include <time.h>
|
|
||||||
#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC)
|
|
||||||
mi_msecs_t _mi_clock_now(void) {
|
|
||||||
struct timespec t;
|
|
||||||
#ifdef CLOCK_MONOTONIC
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
|
||||||
#else
|
|
||||||
clock_gettime(CLOCK_REALTIME, &t);
|
|
||||||
#endif
|
|
||||||
return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// low resolution timer
|
|
||||||
mi_msecs_t _mi_clock_now(void) {
|
|
||||||
return ((mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static mi_msecs_t mi_clock_diff;
|
static mi_msecs_t mi_clock_diff;
|
||||||
|
|
||||||
|
mi_msecs_t _mi_clock_now(void) {
|
||||||
|
return _mi_prim_clock_now();
|
||||||
|
}
|
||||||
|
|
||||||
mi_msecs_t _mi_clock_start(void) {
|
mi_msecs_t _mi_clock_start(void) {
|
||||||
if (mi_clock_diff == 0.0) {
|
if (mi_clock_diff == 0.0) {
|
||||||
mi_msecs_t t0 = _mi_clock_now();
|
mi_msecs_t t0 = _mi_clock_now();
|
||||||
|
@ -463,130 +428,9 @@ mi_msecs_t _mi_clock_end(mi_msecs_t start) {
|
||||||
// Basic process statistics
|
// Basic process statistics
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#include <windows.h>
|
|
||||||
#include <psapi.h>
|
|
||||||
|
|
||||||
static mi_msecs_t filetime_msecs(const FILETIME* ftime) {
|
|
||||||
ULARGE_INTEGER i;
|
|
||||||
i.LowPart = ftime->dwLowDateTime;
|
|
||||||
i.HighPart = ftime->dwHighDateTime;
|
|
||||||
mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds
|
|
||||||
return msecs;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
|
|
||||||
static PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL;
|
|
||||||
|
|
||||||
static void mi_stat_process_info(mi_msecs_t* elapsed, 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)
|
|
||||||
{
|
|
||||||
*elapsed = _mi_clock_end(mi_process_start);
|
|
||||||
FILETIME ct;
|
|
||||||
FILETIME ut;
|
|
||||||
FILETIME st;
|
|
||||||
FILETIME et;
|
|
||||||
GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);
|
|
||||||
*utime = filetime_msecs(&ut);
|
|
||||||
*stime = filetime_msecs(&st);
|
|
||||||
|
|
||||||
// load psapi on demand
|
|
||||||
if (pGetProcessMemoryInfo == NULL) {
|
|
||||||
HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll"));
|
|
||||||
if (hDll != NULL) {
|
|
||||||
pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get process info
|
|
||||||
PROCESS_MEMORY_COUNTERS info;
|
|
||||||
memset(&info, 0, sizeof(info));
|
|
||||||
if (pGetProcessMemoryInfo != NULL) {
|
|
||||||
pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
|
|
||||||
}
|
|
||||||
*current_rss = (size_t)info.WorkingSetSize;
|
|
||||||
*peak_rss = (size_t)info.PeakWorkingSetSize;
|
|
||||||
*current_commit = (size_t)info.PagefileUsage;
|
|
||||||
*peak_commit = (size_t)info.PeakPagefileUsage;
|
|
||||||
*page_faults = (size_t)info.PageFaultCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif !defined(__wasi__) && (defined(__unix__) || defined(__unix) || defined(unix) || defined(__APPLE__) || defined(__HAIKU__))
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <mach/mach.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__HAIKU__)
|
|
||||||
#include <kernel/OS.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mi_stat_process_info(mi_msecs_t* elapsed, 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)
|
|
||||||
{
|
|
||||||
*elapsed = _mi_clock_end(mi_process_start);
|
|
||||||
struct rusage rusage;
|
|
||||||
getrusage(RUSAGE_SELF, &rusage);
|
|
||||||
*utime = timeval_secs(&rusage.ru_utime);
|
|
||||||
*stime = timeval_secs(&rusage.ru_stime);
|
|
||||||
#if !defined(__HAIKU__)
|
|
||||||
*page_faults = rusage.ru_majflt;
|
|
||||||
#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__)
|
|
||||||
// Haiku does not have (yet?) a way to
|
|
||||||
// get these stats per process
|
|
||||||
thread_info tid;
|
|
||||||
area_info mem;
|
|
||||||
ssize_t c;
|
|
||||||
get_thread_info(find_thread(0), &tid);
|
|
||||||
while (get_next_area_info(tid.team, &c, &mem) == B_OK) {
|
|
||||||
*peak_rss += mem.ram_size;
|
|
||||||
}
|
|
||||||
*page_faults = 0;
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
*peak_rss = rusage.ru_maxrss; // BSD reports in bytes
|
|
||||||
struct mach_task_basic_info info;
|
|
||||||
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) {
|
|
||||||
*current_rss = (size_t)info.resident_size;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
*peak_rss = rusage.ru_maxrss * 1024; // Linux reports in KiB
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifndef __wasi__
|
|
||||||
// WebAssembly instances are not processes
|
|
||||||
#pragma message("define a way to get process info")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void mi_stat_process_info(mi_msecs_t* elapsed, 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)
|
|
||||||
{
|
|
||||||
*elapsed = _mi_clock_end(mi_process_start);
|
|
||||||
*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));
|
|
||||||
*peak_rss = *peak_commit;
|
|
||||||
*current_rss = *current_commit;
|
|
||||||
*page_faults = 0;
|
|
||||||
*utime = 0;
|
|
||||||
*stime = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
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 = 0;
|
mi_msecs_t elapsed = _mi_clock_end(mi_process_start);
|
||||||
mi_msecs_t utime = 0;
|
mi_msecs_t utime = 0;
|
||||||
mi_msecs_t stime = 0;
|
mi_msecs_t stime = 0;
|
||||||
size_t current_rss0 = 0;
|
size_t current_rss0 = 0;
|
||||||
|
@ -594,8 +438,8 @@ mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, s
|
||||||
size_t current_commit0 = 0;
|
size_t current_commit0 = 0;
|
||||||
size_t peak_commit0 = 0;
|
size_t peak_commit0 = 0;
|
||||||
size_t page_faults0 = 0;
|
size_t page_faults0 = 0;
|
||||||
mi_stat_process_info(&elapsed,&utime, &stime, ¤t_rss0, &peak_rss0, ¤t_commit0, &peak_commit0, &page_faults0);
|
_mi_prim_process_info(&utime, &stime, ¤t_rss0, &peak_rss0, ¤t_commit0, &peak_commit0, &page_faults0);
|
||||||
if (elapsed_msecs!=NULL) *elapsed_msecs = (elapsed < 0 ? 0 : (elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)elapsed : PTRDIFF_MAX));
|
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));
|
if (user_msecs!=NULL) *user_msecs = (utime < 0 ? 0 : (utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)utime : PTRDIFF_MAX));
|
||||||
if (system_msecs!=NULL) *system_msecs = (stime < 0 ? 0 : (stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)stime : PTRDIFF_MAX));
|
if (system_msecs!=NULL) *system_msecs = (stime < 0 ? 0 : (stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)stime : PTRDIFF_MAX));
|
||||||
if (current_rss!=NULL) *current_rss = current_rss0;
|
if (current_rss!=NULL) *current_rss = current_rss0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue