From c4f7cdeec45f3493834a27267818e7f7b8a81c5c Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Fri, 9 Aug 2019 10:40:33 +0000 Subject: [PATCH] memory: port parseMeminfo to BSDs --- include/factory.hpp | 2 + include/modules/memory.hpp | 1 - meson.build | 14 ++- src/factory.cpp | 2 + src/modules/memory/bsd.cpp | 89 +++++++++++++++++++ src/modules/{memory.cpp => memory/common.cpp} | 18 ---- src/modules/memory/linux.cpp | 20 +++++ 7 files changed, 126 insertions(+), 20 deletions(-) create mode 100644 src/modules/memory/bsd.cpp rename src/modules/{memory.cpp => memory/common.cpp} (78%) create mode 100644 src/modules/memory/linux.cpp diff --git a/include/factory.hpp b/include/factory.hpp index a5515b8f..dfd0cc7f 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -12,7 +12,9 @@ #endif #include "modules/cpu.hpp" #include "modules/idle_inhibitor.hpp" +#if defined(HAVE_MEMORY_LINUX) || defined(HAVE_MEMORY_BSD) #include "modules/memory.hpp" +#endif #include "modules/disk.hpp" #ifdef HAVE_DBUSMENU #include "modules/sni/tray.hpp" diff --git a/include/modules/memory.hpp b/include/modules/memory.hpp index 59f0e787..abfe2872 100644 --- a/include/modules/memory.hpp +++ b/include/modules/memory.hpp @@ -15,7 +15,6 @@ class Memory : public ALabel { auto update() -> void; private: - static inline const std::string data_dir_ = "/proc/meminfo"; void parseMeminfo(); std::unordered_map meminfo_; diff --git a/meson.build b/meson.build index d1528c44..5dd3b1b9 100644 --- a/meson.build +++ b/meson.build @@ -67,6 +67,10 @@ add_global_arguments(cpp_args, language : 'cpp') add_global_link_arguments(cpp_link_args, language : 'cpp') is_linux = host_machine.system() == 'linux' +is_dragonfly = host_machine.system() == 'dragonfly' +is_freebsd = host_machine.system() == 'freebsd' +is_netbsd = host_machine.system() == 'netbsd' +is_openbsd = host_machine.system() == 'openbsd' thread_dep = dependency('threads') fmt = dependency('fmt', version : ['>=5.3.0'], fallback : ['fmt', 'fmt_dep']) @@ -113,7 +117,6 @@ src_files = files( 'src/factory.cpp', 'src/AModule.cpp', 'src/ALabel.cpp', - 'src/modules/memory.cpp', 'src/modules/bluetooth.cpp', 'src/modules/clock.cpp', 'src/modules/custom.cpp', @@ -128,8 +131,17 @@ src_files = files( ) if is_linux + add_project_arguments('-DHAVE_MEMORY_LINUX', language: 'cpp') src_files += files( 'src/modules/battery.cpp', + 'src/modules/memory/common.cpp', + 'src/modules/memory/linux.cpp', + ) +elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd + add_project_arguments('-DHAVE_MEMORY_BSD', language: 'cpp') + src_files += files( + 'src/modules/memory/bsd.cpp', + 'src/modules/memory/common.cpp', ) endif diff --git a/src/factory.cpp b/src/factory.cpp index 263071b5..4b3f3377 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -26,9 +26,11 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "idle_inhibitor") { return new waybar::modules::IdleInhibitor(id, bar_, config_[name]); } +#if defined(HAVE_MEMORY_LINUX) || defined(HAVE_MEMORY_BSD) if (ref == "memory") { return new waybar::modules::Memory(id, config_[name]); } +#endif if (ref == "cpu") { return new waybar::modules::Cpu(id, config_[name]); } diff --git a/src/modules/memory/bsd.cpp b/src/modules/memory/bsd.cpp new file mode 100644 index 00000000..b3520d0c --- /dev/null +++ b/src/modules/memory/bsd.cpp @@ -0,0 +1,89 @@ +#include "modules/memory.hpp" + +#include +#include +#include // getpagesize + +#if defined(__DragonFly__) +# include // struct vmstats +#elif defined(__NetBSD__) +# include // struct uvmexp_sysctl +#elif defined(__OpenBSD__) +# include // struct uvmexp +#endif + +static uint64_t get_total_memory() { +#if defined(HW_MEMSIZE) || defined(HW_PHYSMEM64) + uint64_t physmem; +#else + u_long physmem; +#endif + int mib[] = { + CTL_HW, +#if defined(HW_MEMSIZE) + HW_MEMSIZE, +#elif defined(HW_PHYSMEM64) + HW_PHYSMEM64, +#else + HW_PHYSMEM, +#endif + }; + u_int miblen = sizeof(mib) / sizeof(mib[0]); + size_t sz = sizeof(physmem); + if (sysctl(mib, miblen, &physmem, &sz, NULL, 0)) { + throw std::runtime_error("sysctl hw.physmem failed"); + } + return physmem; +} + +static uint64_t get_free_memory() { +#if defined(__DragonFly__) + struct vmstats vms; + size_t sz = sizeof(vms); + if (sysctlbyname("vm.vmstats", &vms, &sz, NULL, 0)) { + throw std::runtime_error("sysctl vm.vmstats failed"); + } + return static_cast + (vms.v_free_count + vms.v_inactive_count + vms.v_cache_count) + * getpagesize(); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + u_int v_free_count = 0, v_inactive_count = 0, v_cache_count = 0; + size_t sz = sizeof(u_int); + sysctlbyname("vm.stats.vm.v_free_count", + &v_free_count, &sz, NULL, 0); + sysctlbyname("vm.stats.vm.v_inactive_count", + &v_inactive_count, &sz, NULL, 0); + sysctlbyname("vm.stats.vm.v_cache_count", + &v_cache_count, &sz, NULL, 0); + return static_cast + (v_free_count + v_inactive_count + v_cache_count) + * getpagesize(); +#elif defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef VM_UVMEXP2 +# undef VM_UVMEXP +# define VM_UVMEXP VM_UVMEXP2 +# define uvmexp uvmexp_sysctl +#else +# define filepages vnodepages +# define execpages vtextpages +#endif + int mib[] = { + CTL_VM, + VM_UVMEXP, + }; + u_int miblen = sizeof(mib) / sizeof(mib[0]); + struct uvmexp uvmexp; + size_t sz = sizeof(uvmexp); + if (sysctl(mib, miblen, &uvmexp, &sz, NULL, 0)) { + throw std::runtime_error("sysctl vm.uvmexp failed"); + } + return static_cast + (uvmexp.free + uvmexp.inactive + uvmexp.filepages + uvmexp.execpages) + * uvmexp.pagesize; +#endif +} + +void waybar::modules::Memory::parseMeminfo() { + meminfo_["MemTotal"] = get_total_memory() / 1024; + meminfo_["MemAvailable"] = get_free_memory() / 1024; +} diff --git a/src/modules/memory.cpp b/src/modules/memory/common.cpp similarity index 78% rename from src/modules/memory.cpp rename to src/modules/memory/common.cpp index 8e54d273..4875ec8f 100644 --- a/src/modules/memory.cpp +++ b/src/modules/memory/common.cpp @@ -45,21 +45,3 @@ auto waybar::modules::Memory::update() -> void { // Call parent update ALabel::update(); } - -void waybar::modules::Memory::parseMeminfo() { - std::ifstream info(data_dir_); - if (!info.is_open()) { - throw std::runtime_error("Can't open " + data_dir_); - } - std::string line; - while (getline(info, line)) { - auto posDelim = line.find(':'); - if (posDelim == std::string::npos) { - continue; - } - - std::string name = line.substr(0, posDelim); - int64_t value = std::stol(line.substr(posDelim + 1)); - meminfo_[name] = value; - } -} diff --git a/src/modules/memory/linux.cpp b/src/modules/memory/linux.cpp new file mode 100644 index 00000000..75f05fe3 --- /dev/null +++ b/src/modules/memory/linux.cpp @@ -0,0 +1,20 @@ +#include "modules/memory.hpp" + +void waybar::modules::Memory::parseMeminfo() { + const std::string data_dir_ = "/proc/meminfo"; + std::ifstream info(data_dir_); + if (!info.is_open()) { + throw std::runtime_error("Can't open " + data_dir_); + } + std::string line; + while (getline(info, line)) { + auto posDelim = line.find(':'); + if (posDelim == std::string::npos) { + continue; + } + + std::string name = line.substr(0, posDelim); + int64_t value = std::stol(line.substr(posDelim + 1)); + meminfo_[name] = value; + } +}