浏览代码

libobs/util: Add memory usage functions

Closes jp9000/obs-studio#953
mntone 8 年之前
父节点
当前提交
a6318ffdca
共有 4 个文件被更改,包括 251 次插入0 次删除
  1. 65 0
      libobs/util/platform-cocoa.m
  2. 124 0
      libobs/util/platform-nix.c
  3. 50 0
      libobs/util/platform-windows.c
  4. 12 0
      libobs/util/platform.h

+ 65 - 0
libobs/util/platform-cocoa.m

@@ -352,3 +352,68 @@ int os_get_logical_cores(void)
 		os_get_cores_internal();
 	return logical_cores;
 }
+
+static inline bool os_get_sys_memory_usage_internal(vm_statistics_t vmstat)
+{
+	mach_msg_type_number_t out_count = HOST_VM_INFO_COUNT;
+	if (host_statistics(mach_host_self(), HOST_VM_INFO,
+	    (host_info_t)vmstat, &out_count) != KERN_SUCCESS)
+		return false;
+	return true;
+}
+
+uint64_t os_get_sys_free_size(void)
+{
+	vm_statistics_data_t vmstat = {};
+	if (!os_get_sys_memory_usage_internal(&vmstat))
+		return 0;
+
+	return vmstat.free_count * vm_page_size;
+}
+
+#ifndef MACH_TASK_BASIC_INFO
+typedef task_basic_info_data_t mach_task_basic_info_data_t;
+#endif
+
+static inline bool os_get_proc_memory_usage_internal(
+		mach_task_basic_info_data_t *taskinfo)
+{
+#ifdef MACH_TASK_BASIC_INFO
+	const task_flavor_t flavor = MACH_TASK_BASIC_INFO;
+	mach_msg_type_number_t out_count = MACH_TASK_BASIC_INFO_COUNT;
+#else
+	const task_flavor_t flavor = TASK_BASIC_INFO;
+	mach_msg_type_number_t out_count = TASK_BASIC_INFO_COUNT;
+#endif
+	if (task_info(mach_task_self(), flavor,
+	    (task_info_t)taskinfo, &out_count) != KERN_SUCCESS)
+		return false;
+	return true;
+}
+
+bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage)
+{
+	mach_task_basic_info_data_t taskinfo = {};
+	if (!os_get_proc_memory_usage_internal(&taskinfo))
+		return false;
+
+	usage->resident_size = taskinfo.resident_size;
+	usage->virtual_size  = taskinfo.virtual_size;
+	return true;
+}
+
+uint64_t os_get_proc_resident_size(void)
+{
+	mach_task_basic_info_data_t taskinfo = {};
+	if (!os_get_proc_memory_usage_internal(&taskinfo))
+		return 0;
+	return taskinfo.resident_size;
+}
+
+uint64_t os_get_proc_virtual_size(void)
+{
+	mach_task_basic_info_data_t taskinfo = {};
+	if (!os_get_proc_memory_usage_internal(&taskinfo))
+		return 0;
+	return taskinfo.virtual_size;
+}

+ 124 - 0
libobs/util/platform-nix.c

@@ -33,6 +33,16 @@
 #if !defined(__APPLE__)
 #include <sys/times.h>
 #include <sys/wait.h>
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/user.h>
+#include <unistd.h>
+#include <libprocstat.h>
+#else
+#include <sys/resource.h>
+#endif
 #include <spawn.h>
 #endif
 
@@ -678,6 +688,120 @@ int os_get_logical_cores(void)
 		os_get_cores_internal();
 	return logical_cores;
 }
+
+#ifdef __FreeBSD__
+uint64_t os_get_sys_free_size(void)
+{
+	uint64_t mem_free = 0;
+	size_t length = sizeof(mem_free);
+	if (sysctlbyname("vm.stats.vm.v_free_count", &mem_free, &length,
+				NULL, 0) < 0)
+		return 0;
+	return mem_free;
+}
+
+static inline bool os_get_proc_memory_usage_internal(struct kinfo_proc *kinfo)
+{
+	int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
+	size_t length = sizeof(*kinfo);
+	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), kinfo, &length,
+				NULL, 0) < 0)
+		return false;
+	return true;
+}
+
+bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage)
+{
+	struct kinfo_proc kinfo;
+	if (!os_get_proc_memory_usage_internal(&kinfo))
+		return false;
+
+	usage->resident_size =
+			(uint64_t)kinfo.ki_rssize * sysconf(_SC_PAGESIZE);
+	usage->virtual_size  = (uint64_t)kinfo.ki_size;
+	return true;
+}
+
+uint64_t os_get_proc_resident_size(void)
+{
+	struct kinfo_proc kinfo;
+	if (!os_get_proc_memory_usage_internal(&kinfo))
+		return 0;
+	return (uint64_t)kinfo.ki_rssize * sysconf(_SC_PAGESIZE);
+}
+
+uint64_t os_get_proc_virtual_size(void)
+{
+	struct kinfo_proc kinfo;
+	if (!os_get_proc_memory_usage_internal(&kinfo))
+		return 0;
+	return (uint64_t)kinfo.ki_size;
+}
+#else
+uint64_t os_get_sys_free_size(void) {return 0;}
+
+typedef struct
+{
+	unsigned long virtual_size;
+	unsigned long resident_size;
+	unsigned long share_pages;
+	unsigned long text;
+	unsigned long library;
+	unsigned long data;
+	unsigned long dirty_pages;
+} statm_t;
+
+static inline bool os_get_proc_memory_usage_internal(statm_t *statm)
+{
+	const char *statm_path = "/proc/self/statm";
+
+	FILE *f = fopen(statm_path, "r");
+	if (!f)
+		return false;
+
+	if (fscanf(f, "%ld %ld %ld %ld %ld %ld %ld",
+	    &statm->virtual_size,
+	    &statm->resident_size,
+	    &statm->share_pages,
+	    &statm->text,
+	    &statm->library,
+	    &statm->data,
+	    &statm->dirty_pages) != 7) {
+		fclose(f);
+		return false;
+	}
+
+	fclose(f);
+	return true;
+}
+
+bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage)
+{
+	statm_t statm = {};
+	if (!os_get_proc_memory_usage_internal(&statm))
+		return false;
+
+	usage->resident_size = statm.resident_size;
+	usage->virtual_size  = statm.virtual_size;
+	return true;
+}
+
+uint64_t os_get_proc_resident_size(void)
+{
+	statm_t statm = {};
+	if (!os_get_proc_memory_usage_internal(&statm))
+		return 0;
+	return (uint64_t)statm.resident_size;
+}
+
+uint64_t os_get_proc_virtual_size(void)
+{
+	statm_t statm = {};
+	if (!os_get_proc_memory_usage_internal(&statm))
+		return 0;
+	return (uint64_t)statm.virtual_size;
+}
+#endif
 #endif
 
 uint64_t os_get_free_disk_space(const char *dir)

+ 50 - 0
libobs/util/platform-windows.c

@@ -19,6 +19,7 @@
 #include <shellapi.h>
 #include <shlobj.h>
 #include <intrin.h>
+#include <psapi.h>
 
 #include "base.h"
 #include "platform.h"
@@ -947,6 +948,55 @@ int os_get_logical_cores(void)
 	return logical_cores;
 }
 
+static inline bool os_get_sys_memory_usage_internal(MEMORYSTATUSEX *msex)
+{
+	if (!GlobalMemoryStatusEx(msex))
+		return false;
+	return true;
+}
+
+uint64_t os_get_sys_free_size(void)
+{
+	MEMORYSTATUSEX msex = {sizeof(MEMORYSTATUSEX)};
+	if (!os_get_sys_memory_usage_internal(&msex))
+		return 0;
+	return msex.ullAvailPhys;
+}
+
+static inline bool os_get_proc_memory_usage_internal(PROCESS_MEMORY_COUNTERS *pmc)
+{
+	if (!GetProcessMemoryInfo(GetCurrentProcess(), pmc, sizeof(*pmc)))
+		return false;
+	return true;
+}
+
+bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage)
+{
+	PROCESS_MEMORY_COUNTERS pmc = {sizeof(PROCESS_MEMORY_COUNTERS)};
+	if (!os_get_proc_memory_usage_internal(&pmc))
+		return false;
+
+	usage->resident_size = pmc.WorkingSetSize;
+	usage->virtual_size  = pmc.PagefileUsage;
+	return true;
+}
+
+uint64_t os_get_proc_resident_size(void)
+{
+	PROCESS_MEMORY_COUNTERS pmc = {sizeof(PROCESS_MEMORY_COUNTERS)};
+	if (!os_get_proc_memory_usage_internal(&pmc))
+		return 0;
+	return pmc.WorkingSetSize;
+}
+
+uint64_t os_get_proc_virtual_size(void)
+{
+	PROCESS_MEMORY_COUNTERS pmc = {sizeof(PROCESS_MEMORY_COUNTERS)};
+	if (!os_get_proc_memory_usage_internal(&pmc))
+		return 0;
+	return pmc.PagefileUsage;
+}
+
 uint64_t os_get_free_disk_space(const char *dir)
 {
 	wchar_t *wdir = NULL;

+ 12 - 0
libobs/util/platform.h

@@ -181,6 +181,18 @@ EXPORT void os_breakpoint(void);
 EXPORT int os_get_physical_cores(void);
 EXPORT int os_get_logical_cores(void);
 
+EXPORT uint64_t os_get_sys_free_size(void);
+
+struct os_proc_memory_usage {
+	uint64_t resident_size;
+	uint64_t virtual_size;
+};
+typedef struct os_proc_memory_usage os_proc_memory_usage_t;
+
+EXPORT bool os_get_proc_memory_usage(os_proc_memory_usage_t *usage);
+EXPORT uint64_t os_get_proc_resident_size(void);
+EXPORT uint64_t os_get_proc_virtual_size(void);
+
 #ifdef _MSC_VER
 #define strtoll _strtoi64
 #if _MSC_VER < 1900