diff options
| author | ruki <[email protected]> | 2022-07-28 12:06:06 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-07-28 12:06:06 +0800 |
| commit | acfcb30aaac116b093446615660a76ca2aab37f9 (patch) | |
| tree | de3003aa5bce8265b1ac4a43cd6be5625827f712 /core/src | |
| parent | 540ebd93b1fcec450ae81e3e95637b6dc0d051b5 (diff) | |
| parent | e215d9b9ea21fe5eacb69a5eff90817293bc79db (diff) | |
Merge pull request #2608 from xmake-io/meminfo
add meminfo
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/os/meminfo.c | 134 |
1 files changed, 103 insertions, 31 deletions
diff --git a/core/src/xmake/os/meminfo.c b/core/src/xmake/os/meminfo.c index a9a1d9719..b679e5aee 100644 --- a/core/src/xmake/os/meminfo.c +++ b/core/src/xmake/os/meminfo.c @@ -30,19 +30,33 @@ */ #include "prefix.h" #if defined(TB_CONFIG_OS_MACOSX) -# include <sys/sysctl.h> # include <mach/mach.h> # include <mach/machine.h> +# include <mach/vm_statistics.h> # include <mach-o/dyld.h> # include <mach-o/nlist.h> +#elif defined(TB_CONFIG_OS_LINUX) +# include <sys/sysinfo.h> +#elif defined(TB_CONFIG_OS_WINDOWS) +# include <windows.h> +#elif defined(TB_CONFIG_OS_BSD) +# include <sys/types.h> +# include <sys/sysctl.h> #endif /* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ +#ifdef TB_CONFIG_OS_LINUX +static tb_int64_t xm_os_meminfo_get_value(tb_char_t const* buffer, tb_char_t const* name) +{ + tb_char_t const* p = tb_strstr(buffer, name); + return p? tb_stoi64(p + tb_strlen(name)) : 0; +} +#endif // get the used memory size (MB) -static tb_bool_t xm_os_meminfo_vmstats(tb_int_t* vm_totalsize, tb_int_t* vm_availsize) +static tb_bool_t xm_os_meminfo_stats(tb_int_t* ptotalsize, tb_int_t* pavailsize) { #if defined(TB_CONFIG_OS_MACOSX) vm_statistics64_data_t vmstat; @@ -59,25 +73,89 @@ static tb_bool_t xm_os_meminfo_vmstats(tb_int_t* vm_totalsize, tb_int_t* vm_avai * */ tb_int64_t availsize = (tb_int64_t)(vmstat.inactive_count + vmstat.free_count - vmstat.speculative_count) * pagesize; - *vm_totalsize = (tb_int_t)(totalsize / (1024 * 1024)); - *vm_availsize = (tb_int_t)(availsize / (1024 * 1024)); + *ptotalsize = (tb_int_t)(totalsize / (1024 * 1024)); + *pavailsize = (tb_int_t)(availsize / (1024 * 1024)); return tb_true; } -#endif - return tb_false; -} +#elif defined(TB_CONFIG_OS_LINUX) + /* we get meminfo from /proc/meminfo + * + * @see https://github.com/rfjakob/earlyoom/blob/cba1d599e4a7484c45ac017aa7702ff879f15846/meminfo.c#L52 + */ + if (tb_file_info("/proc/meminfo", tb_null)) + { + tb_bool_t ok = tb_false; + FILE* fp = fopen("/proc/meminfo", "r"); + if (fp) + { + // 8192 should be enough for the foreseeable future. + tb_char_t buffer[8192]; + size_t len = fread(buffer, 1, sizeof(buffer) - 1, fp); + if (!ferror(fp) && len) + { + tb_int64_t totalsize = xm_os_meminfo_get_value(buffer, "MemTotal:"); + tb_int64_t availsize = xm_os_meminfo_get_value(buffer, "MemAvailable:"); + if (availsize <= 0) + { + tb_int64_t cachesize = xm_os_meminfo_get_value(buffer, "Cached:"); + tb_int64_t freesize = xm_os_meminfo_get_value(buffer, "MemFree:"); + tb_int64_t buffersize = xm_os_meminfo_get_value(buffer, "Buffers:"); + tb_int64_t shmemsize = xm_os_meminfo_get_value(buffer, "Shmem:"); + if (cachesize >= 0 && freesize >= 0 && buffersize >= 0 && shmemsize >= 0) + availsize = freesize + buffersize + cachesize - shmemsize; + } + if (totalsize > 0 && availsize >= 0) + { + *ptotalsize = (tb_int_t)(totalsize / 1024); + *pavailsize = (tb_int_t)(availsize / 1024); + ok = tb_true; + } + } + fclose(fp); + } + return ok; + } + else + { + struct sysinfo info = {0}; + if (sysinfo(&info) == 0) + { + *ptotalsize = (tb_int_t)(info.totalram / (1024 * 1024)); + *pavailsize = (tb_int_t)((info.freeram + info.bufferram/* + cache size */) / (1024 * 1024)); + return tb_true; + } + } +#elif defined(TB_CONFIG_OS_WINDOWS) + MEMORYSTATUSEX statex; + statex.dwLength = sizeof(statex); + if (GlobalMemoryStatusEx(&statex)) + { + *ptotalsize = (tb_int_t)(statex.ullTotalPhys / (1024 * 1024)); + *pavailsize = (tb_int_t)(statex.ullAvailPhys / (1024 * 1024)); + return tb_true; + } +#elif defined(TB_CONFIG_OS_BSD) + unsigned long totalsize; + size_t size = sizeof(totalsize); + if (sysctlbyname("hw.physmem", &totalsize, &size, tb_null, 0) != 0) + return tb_false; -// get the total physical memory size (MB) -static tb_int_t xm_os_meminfo_physmem() -{ -#if defined(TB_CONFIG_OS_MACOSX) - tb_int_t mib[] = { CTL_HW, HW_MEMSIZE }; - tb_int64_t value = 0; - size_t length = sizeof(value); - if (sysctl(mib, 2, &value, &length, tb_null, 0) == 0) - return (tb_int_t)(value / (1024 * 1024)); + // http://web.mit.edu/freebsd/head/usr.bin/systat/vmstat.c + tb_uint32_t v_free_count; + size = sizeof(v_free_count); + if (sysctlbyname("vm.stats.vm.v_free_count", &v_free_count, &size, tb_null, 0) != 0) + return tb_false; + + tb_uint32_t v_inactive_count; + size = sizeof(v_inactive_count); + if (sysctlbyname("vm.stats.vm.v_inactive_count", &v_inactive_count, &size, tb_null, 0) != 0) + return tb_false; + + *ptotalsize = (tb_int_t)(totalsize / (1024 * 1024)); + *pavailsize = (tb_int_t)(((tb_int64_t)(v_free_count + v_inactive_count) * tb_page_size()) / (1024 * 1024)); + return tb_true; #endif - return 0; + return tb_false; } /* ////////////////////////////////////////////////////////////////////////////////////// @@ -97,23 +175,17 @@ tb_int_t xm_os_meminfo(lua_State* lua) lua_pushinteger(lua, pagesize); lua_settable(lua, -3); - // get the total memory size (MB) - tb_int_t physmem = xm_os_meminfo_physmem(); - lua_pushstring(lua, "physmem"); - lua_pushinteger(lua, physmem); - lua_settable(lua, -3); - - // get the vm memory size (MB) - tb_int_t vm_availsize = 0; - tb_int_t vm_totalsize = 0; - if (xm_os_meminfo_vmstats(&vm_totalsize, &vm_availsize)) + // get the memory size (MB) + tb_int_t availsize = 0; + tb_int_t totalsize = 0; + if (xm_os_meminfo_stats(&totalsize, &availsize)) { - lua_pushstring(lua, "vm_totalsize"); - lua_pushinteger(lua, vm_totalsize); + lua_pushstring(lua, "totalsize"); + lua_pushinteger(lua, totalsize); lua_settable(lua, -3); - lua_pushstring(lua, "vm_availsize"); - lua_pushinteger(lua, vm_availsize); + lua_pushstring(lua, "availsize"); + lua_pushinteger(lua, availsize); lua_settable(lua, -3); } |
