From 2829c02762214ea4b3b743ba2dfa65f8a90a9c32 Mon Sep 17 00:00:00 2001 From: GeorgH93 Date: Sun, 1 Aug 2021 17:20:35 +0200 Subject: [PATCH] Add SystemInfo class --- CMakeLists.txt | 18 +++- openVulkanoCpp/Host/Linux/SystemInfo.cpp | 106 +++++++++++++++++++++ openVulkanoCpp/Host/SystemInfo.hpp | 21 ++++ openVulkanoCpp/Host/Windows/SystemInfo.cpp | 82 ++++++++++++++++ openVulkanoCpp/Host/iOS/SystemInfo.mm | 53 +++++++++++ 5 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 openVulkanoCpp/Host/Linux/SystemInfo.cpp create mode 100644 openVulkanoCpp/Host/SystemInfo.hpp create mode 100644 openVulkanoCpp/Host/Windows/SystemInfo.cpp create mode 100644 openVulkanoCpp/Host/iOS/SystemInfo.mm diff --git a/CMakeLists.txt b/CMakeLists.txt index 87a9144..e34f090 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ if(IOS) enable_language(Swift) file(GLOB_RECURSE sources CONFIGURE_DEPENDS "openVulkanoCpp/*.mm" "openVulkanoCpp/*.m" "openVulkanoCpp/*.cpp" "openVulkanoCpp/*.swift") list(FILTER sources EXCLUDE REGEX ".*GLFW.*") - list(FILTER sources EXCLUDE REGEX "main.cpp") + list(FILTER sources EXCLUDE REGEX "main\.cpp") file(GLOB_RECURSE resources CONFIGURE_DEPENDS "openVulkanoCpp/*.storyboard" "openVulkanoCpp/*.xib") add_executable(openVulkanoCpp openVulkanoCpp/main.m ${resources}) @@ -41,6 +41,18 @@ else() add_executable(openVulkanoCpp openVulkanoCpp/main.cpp ${resources}) endif() +#region Exclude platform files +if (NOT IOS) + list(FILTER sources EXCLUDE REGEX ".*[\\/]Host[\\/]iOS[\\/].*") +endif () +if (NOT LINUX) + list(FILTER sources EXCLUDE REGEX ".*[\\/]Host[\\/]Linux[\\/].*") +endif () +if (NOT WIN32) + list(FILTER sources EXCLUDE REGEX ".*[\\/]Host[\\/]Windows[\\/].*") +endif () +#endregion + target_sources(openVulkanoCpp PRIVATE ${sources} openVulkanoCpp/Shader/Shaders.c) target_include_directories(openVulkanoCpp PUBLIC openVulkanoCpp) @@ -159,3 +171,7 @@ target_link_libraries(openVulkanoCpp PRIVATE magic_enum yaml-cpp spdlog glm pugi add_compile_definitions(GLM_FORCE_INTRINSICS) add_compile_definitions(GLM_FORCE_SILENT_WARNINGS) add_compile_definitions(LIBARCHIVE_STATIC) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_compile_definitions(DEBUG) +endif() diff --git a/openVulkanoCpp/Host/Linux/SystemInfo.cpp b/openVulkanoCpp/Host/Linux/SystemInfo.cpp new file mode 100644 index 0000000..97101db --- /dev/null +++ b/openVulkanoCpp/Host/Linux/SystemInfo.cpp @@ -0,0 +1,106 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "Host/SystemInfo.hpp" +#include "Base/Logger.hpp" +#include "Base/Utils.hpp" +#include "Math/ByteSize.hpp" +#include +#include +#include +#include + +namespace openVulkanoCpp +{ + namespace + { + size_t ReadMemInfo(std::string_view value) + { + std::ifstream meminfoFile("/proc/meminfo"); + if (!meminfoFile) + { + Logger::PERF->error("Failed to open /proc/meminfo"); + return 0; + } + std::string line; + while (std::getline(meminfoFile, line)) + { + if (Utils::StartsWith(line, value)) + { + std::string n, t; + size_t v; + std::istringstream ss(line); + ss >> n >> v >> t; + return ByteSize(v, ByteSizeUnit::FromName(t)); + } + } + meminfoFile.close(); + return 0; + } + + size_t ReadProcStatus(std::string_view value) + { + std::ifstream statusFile("/proc/self/status"); + if (statusFile) + { + size_t mem = 0; + std::string line; + while (std::getline(statusFile, line)) + { + if (Utils::StartsWith(line, value)) + { + std::string n, t; + size_t v; + std::istringstream ss(line); + ss >> n >> v >> t; + return ByteSize(v, ByteSizeUnit::FromName(t)); + } + } + statusFile.close(); + return mem; + } + Logger::PERF->error("Failed to open /proc/self/status"); + return 0; + } + } + + size_t SystemInfo::GetSystemRam() + { + return ReadMemInfo("MemTotal"); + } + + size_t SystemInfo::GetSystemRamAvailable() + { + return ReadMemInfo("MemAvailable"); + } + + size_t SystemInfo::GetAppRamUsed() + { + return ReadProcStatus("VmSize"); + } + + size_t SystemInfo::GetAppRamAvailable() + { + return std::min(GetSystemRamAvailable(), GetAppVirtualMemoryMax() - GetAppRamUsed()); + } + + size_t SystemInfo::GetAppRamMax() + { + return std::min(GetSystemRam(), GetAppVirtualMemoryMax()); + } + + size_t SystemInfo::GetAppVirtualMemoryMax() + { + rlimit limit; + if (getrlimit(RLIMIT_AS, &limit) == 0) + { + std::cout << "Maximum memory usage: " << limit.rlim_cur << " bytes" << std::endl; + return limit.rlim_cur; + } + Logger::PERF->error("Failed to query max application memory"); + return 0; + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/SystemInfo.hpp b/openVulkanoCpp/Host/SystemInfo.hpp new file mode 100644 index 0000000..bdf3b04 --- /dev/null +++ b/openVulkanoCpp/Host/SystemInfo.hpp @@ -0,0 +1,21 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include + +namespace openVulkanoCpp +{ + class SystemInfo + { + public: + static size_t GetSystemRam(); + static size_t GetSystemRamAvailable(); + static size_t GetAppRamMax(); + static size_t GetAppVirtualMemoryMax(); + static size_t GetAppRamAvailable(); + static size_t GetAppRamUsed(); + }; +} diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp new file mode 100644 index 0000000..be485a2 --- /dev/null +++ b/openVulkanoCpp/Host/Windows/SystemInfo.cpp @@ -0,0 +1,82 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "Host/SystemInfo.hpp" +#include "Base/Logger.hpp" +#include +#include +#include + +namespace openVulkanoCpp +{ + namespace + { + enum class SYS_MEM_TYPE { TOTAL_PHYS, AVAIL_PHYS }; + + size_t ReadSystemMemInfo(SYS_MEM_TYPE type) + { + MEMORYSTATUSEX status; + status.dwLength = sizeof(status); + if (GlobalMemoryStatusEx(&status)) + { + switch (type) + { + case SYS_MEM_TYPE::TOTAL_PHYS: return status.ullTotalPhys; + case SYS_MEM_TYPE::AVAIL_PHYS: return status.ullAvailPhys; + } + } + Logger::PERF->error("Failed to get system RAM info"); + return 0; + } + + enum class APP_MEM_TYPE { VM_MAX, USED }; + + size_t ReadAppMemInfo(APP_MEM_TYPE type) + { + PROCESS_MEMORY_COUNTERS_EX counters; + if (GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast(&counters), sizeof(counters))) + { + switch(type) + { + case APP_MEM_TYPE::VM_MAX return counters.PeakWorkingSetSize; + case APP_MEM_TYPE::USED: return counters.PrivateUsage; + } + } + Logger::PERF->error("Failed to get process memory info"); + return 0; + } + } + + size_t SystemInfo::GetSystemRam() + { + return ReadSystemMemInfo(MEM_TYPE::TOTAL_PHYS); + } + + size_t SystemInfo::GetSystemRamAvailable() + { + return ReadSystemMemInfo(MEM_TYPE::AVAIL_PHYS); + } + + size_t SystemInfo::GetAppRamMax() + { + return std::min(GetSystemRam(), GetAppVirtualMemoryMax()); + } + + size_t SystemInfo::GetAppRamAvailable() + { + return std::min(GetSystemRamAvailable(), GetAppVirtualMemoryMax() - GetAppRamUsed()); + } + + size_t SystemInfo::GetAppRamUsed() + { + return ReadAppMemInfo(APP_MEM_TYPE::USED); + } + + size_t SystemInfo::GetAppVirtualMemoryMax() + { + return ReadAppMemInfo(APP_MEM_TYPE::VM_MAX); + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/iOS/SystemInfo.mm b/openVulkanoCpp/Host/iOS/SystemInfo.mm new file mode 100644 index 0000000..54d44fe --- /dev/null +++ b/openVulkanoCpp/Host/iOS/SystemInfo.mm @@ -0,0 +1,53 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "Host/SystemInfo.hpp" +#include "Base/Logger.hpp" +#include +#include + +#import + +namespace openVulkanoCpp +{ + size_t SystemInfo::GetSystemRam() + { + return [NSProcessInfo processInfo].physicalMemory; + } + + size_t SystemInfo::GetSystemRamAvailable() + { + return os_proc_available_memory(); + } + + size_t SystemInfo::GetAppRamMax() + { + return GetAppRamAvailable() + GetAppRamUsed(); + } + + size_t SystemInfo::GetAppVirtualMemoryMax() + { + return INT64_MAX; + } + + size_t SystemInfo::GetAppRamAvailable() + { + return os_proc_available_memory(); + } + + size_t SystemInfo::GetAppRamUsed() + { + struct task_basic_info info; + mach_msg_type_number_t size = sizeof(info); + kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size); + if( kerr == KERN_SUCCESS ) + { + return info.resident_size; + } + Logger::PERF->error("Failed to read memory consumption: {}", mach_error_string(kerr)); + return 0; + } +}