summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2022-07-28 12:06:06 +0800
committerGitHub <[email protected]>2022-07-28 12:06:06 +0800
commitacfcb30aaac116b093446615660a76ca2aab37f9 (patch)
treede3003aa5bce8265b1ac4a43cd6be5625827f712 /core/src
parent540ebd93b1fcec450ae81e3e95637b6dc0d051b5 (diff)
parente215d9b9ea21fe5eacb69a5eff90817293bc79db (diff)
Merge pull request #2608 from xmake-io/meminfo
add meminfo
Diffstat (limited to 'core/src')
-rw-r--r--core/src/xmake/os/meminfo.c134
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);
}