mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-07 15:59:32 +03:00
update process info primitive api
This commit is contained in:
parent
eca98ac056
commit
8fbe7aae50
6 changed files with 59 additions and 59 deletions
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
36
src/stats.c
36
src/stats.c
|
@ -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, ¤t_rss0, &peak_rss0, ¤t_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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue