summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob P. Liljenberg <admin@qvantnet.com>2024-02-11 16:33:01 +0100
committerGitHub <noreply@github.com>2024-02-11 16:33:01 +0100
commit842b9f83b25a02fa88e1051785c9fcebb4493e62 (patch)
treea7595cccc382ea5a63d6609292eaeb06f864dd6c
parent81d09860f7b815a662c5192e36fcf5e83b3729f6 (diff)
parentcae6c86ecd838ef3d69b2d38656beb9bdd236cbe (diff)
Merge branch 'main' into main
-rw-r--r--.github/workflows/continuous-build-gpu.yml45
-rw-r--r--CMakeLists.txt9
-rw-r--r--Makefile4
-rw-r--r--README.md68
-rw-r--r--cmake/Modules/Findkvm.cmake2
-rw-r--r--src/btop.cpp1
-rw-r--r--src/btop_draw.cpp5
-rw-r--r--src/btop_tools.hpp8
-rw-r--r--src/linux/btop_collect.cpp89
-rw-r--r--src/osx/btop_collect.cpp2
10 files changed, 213 insertions, 20 deletions
diff --git a/.github/workflows/continuous-build-gpu.yml b/.github/workflows/continuous-build-gpu.yml
new file mode 100644
index 0000000..e3bdf01
--- /dev/null
+++ b/.github/workflows/continuous-build-gpu.yml
@@ -0,0 +1,45 @@
+name: Continuous Build Gpu
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ tags-ignore:
+ - '*.*'
+ paths:
+ - 'src/**'
+ - '!src/osx/**'
+ - '!src/freebsd/**'
+ - '!src/openbsd/**'
+ - 'include/**'
+ - 'Makefile'
+ - '.github/workflows/continuous-build-gpu.yml'
+ pull_request:
+ branches:
+ - main
+ paths:
+ - 'src/**'
+ - '!src/osx/**'
+ - '!src/freebsd/**'
+ - '!src/openbsd/**'
+ - 'include/**'
+ - 'Makefile'
+ - '.github/workflows/continuous-build-gpu.yml'
+
+jobs:
+ gpu_build_linux:
+ runs-on: ubuntu-latest
+ container: alpine:edge
+ concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install build tools
+ run: apk add --no-cache --update gcc g++ make
+
+ - name: Compile
+ run: make CXX=g++ GPU_SUPPORT=true
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd39946..5039cdf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,6 +65,8 @@ if(APPLE)
target_sources(btop PRIVATE src/osx/btop_collect.cpp src/osx/sensors.cpp src/osx/smc.cpp)
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
target_sources(btop PRIVATE src/freebsd/btop_collect.cpp)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+ target_sources(btop PRIVATE src/openbsd/btop_collect.cpp src/openbsd/sysctlbyname.cpp)
elseif(LINUX)
target_sources(btop PRIVATE src/linux/btop_collect.cpp)
else()
@@ -110,6 +112,7 @@ if(HAS_FCF_PROTECTION)
endif()
target_compile_definitions(btop PRIVATE
+ FMT_HEADER_ONLY
_FILE_OFFSET_BITS=64
$<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1>
# Only has an effect with optimizations enabled
@@ -185,6 +188,12 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
find_package(kvm REQUIRED)
target_link_libraries(btop elf::elf kvm::kvm)
endif()
+elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ target_compile_options(btop PRIVATE -static-libstdc++)
+ endif()
+ find_package(kvm REQUIRED)
+ target_link_libraries(btop kvm::kvm)
endif()
install(TARGETS btop RUNTIME)
diff --git a/Makefile b/Makefile
index ed80899..9af2aa9 100644
--- a/Makefile
+++ b/Makefile
@@ -143,7 +143,7 @@ else ifeq ($(PLATFORM_LC),macos)
else ifeq ($(PLATFORM_LC),openbsd)
PLATFORM_DIR := openbsd
THREADS := $(shell sysctl -n hw.ncpu || echo 1)
- override ADDFLAGS += -lkvm
+ override ADDFLAGS += -lkvm -static-libstdc++
export MAKE = gmake
SU_GROUP := wheel
else
@@ -179,7 +179,7 @@ override GOODFLAGS := $(foreach flag,$(TESTFLAGS),$(strip $(shell echo "int main
override REQFLAGS := -std=c++20
WARNFLAGS := -Wall -Wextra -pedantic
OPTFLAGS := -O2 -ftree-vectorize -flto=$(LTO)
-LDCXXFLAGS := -pthread -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS)
+LDCXXFLAGS := -pthread -DFMT_HEADER_ONLY -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS)
override CXXFLAGS += $(REQFLAGS) $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
override LDFLAGS += $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
INC := $(foreach incdir,$(INCDIRS),-isystem $(incdir)) -I$(SRCDIR)
diff --git a/README.md b/README.md
index 13e57ae..042b49b 100644
--- a/README.md
+++ b/README.md
@@ -996,6 +996,74 @@ If you have an AMD GPU `rocm_smi_lib` is required, which may or may not be packa
```
</details>
+<details>
+<summary>
+
+### With CMake (Community maintained)
+</summary>
+
+1. **Install build dependencies**
+
+ Requires GCC, CMake, Ninja and Git
+
+ _**Note:** LLVM's libc++ shipped with OpenBSD 7.4 is too old and cannot compile btop._
+
+ ```bash
+ pkg_add cmake g++%11 git ninja
+ ```
+
+2. **Clone the repository**
+
+ ```bash
+ git clone https://github.com/aristocratos/btop.git && cd btop
+ ```
+
+3. **Compile**
+
+ ```bash
+ # Configure
+ CXX=eg++ cmake -B build -G Ninja
+ # Build
+ cmake --build build
+ ```
+
+ This will automatically build a release version of btop.
+
+ Some useful options to pass to the configure step:
+
+ | Configure flag | Description |
+ |---------------------------------|-------------------------------------------------------------------------|
+ | `-DBTOP_LTO=<ON\|OFF>` | Enables link time optimization (ON by default) |
+ | `-DBTOP_USE_MOLD=<ON\|OFF>` | Use mold to link btop (OFF by default) |
+ | `-DBTOP_PEDANTIC=<ON\|OFF>` | Compile with additional warnings (OFF by default) |
+ | `-DBTOP_WERROR=<ON\|OFF>` | Compile with warnings as errors (OFF by default) |
+ | `-DBTOP_FORTIFY=<ON\|OFF>` | Detect buffer overflows with `_FORTIFY_SOURCE=3` (ON by default) |
+ | `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
+
+ To force any other compiler, run `CXX=<compiler> cmake -B build -G Ninja`
+
+4. **Install**
+
+ ```bash
+ cmake --install build
+ ```
+
+ May require root privileges
+
+5. **Uninstall**
+
+ CMake doesn't generate an uninstall target by default. To remove installed files, run
+ ```
+ cat build/install_manifest.txt | xargs rm -irv
+ ```
+
+6. **Cleanup build directory**
+
+ ```bash
+ cmake --build build -t clean
+ ```
+
+</details>
## Installing the snap
[![btop](https://snapcraft.io/btop/badge.svg)](https://snapcraft.io/btop)
diff --git a/cmake/Modules/Findkvm.cmake b/cmake/Modules/Findkvm.cmake
index a0847de..9e4d82b 100644
--- a/cmake/Modules/Findkvm.cmake
+++ b/cmake/Modules/Findkvm.cmake
@@ -3,7 +3,7 @@
# Find libkvm, the Kernel Data Access Library
#
-if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+if(BSD)
find_path(kvm_INCLUDE_DIR NAMES kvm.h)
find_library(kvm_LIBRARY NAMES kvm)
diff --git a/src/btop.cpp b/src/btop.cpp
index 736854f..aac8e9c 100644
--- a/src/btop.cpp
+++ b/src/btop.cpp
@@ -53,6 +53,7 @@ tab-size = 4
#include "btop_draw.hpp"
#include "btop_menu.hpp"
#include "fmt/core.h"
+#include "fmt/ostream.h"
using std::atomic;
using std::cout;
diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp
index acab14c..5e3cc5b 100644
--- a/src/btop_draw.cpp
+++ b/src/btop_draw.cpp
@@ -1361,6 +1361,7 @@ namespace Net {
int x = 1, y, width = 20, height;
int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height;
bool shown = true, redraw = true;
+ const int MAX_IFNAMSIZ = 15;
string old_ip;
std::unordered_map<string, Draw::Graph> graphs;
string box;
@@ -1381,7 +1382,7 @@ namespace Net {
out.reserve(width * height);
const string title_left = Theme::c("net_box") + Fx::ub + Symbols::title_left;
const string title_right = Theme::c("net_box") + Fx::ub + Symbols::title_right;
- const int i_size = min((int)selected_iface.size(), 10);
+ const int i_size = min((int)selected_iface.size(), MAX_IFNAMSIZ);
const long long down_max = (net_auto ? safeVal(graph_max, "download"s) : ((long long)(Config::getI("net_download")) << 20) / 8);
const long long up_max = (net_auto ? safeVal(graph_max, "upload"s) : ((long long)(Config::getI("net_upload")) << 20) / 8);
@@ -1403,7 +1404,7 @@ namespace Net {
//? Interface selector and buttons
out += Mv::to(y, x+width - i_size - 9) + title_left + Fx::b + Theme::c("hi_fg") + "<b " + Theme::c("title")
- + uresize(selected_iface, 10) + Theme::c("hi_fg") + " n>" + title_right
+ + uresize(selected_iface, MAX_IFNAMSIZ) + Theme::c("hi_fg") + " n>" + title_right
+ Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (safeVal(net.stat, "download"s).offset + safeVal(net.stat, "upload"s).offset > 0 ? Fx::b : "") + 'z'
+ Theme::c("title") + "ero" + title_right;
Input::mouse_mappings["b"] = {y, x+width - i_size - 8, 1, 3};
diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp
index 705a5eb..2502786 100644
--- a/src/btop_tools.hpp
+++ b/src/btop_tools.hpp
@@ -18,6 +18,10 @@ tab-size = 4
#pragma once
+#if !defined(NDEBUG)
+# define BTOP_DEBUG
+#endif
+
#include <algorithm> // for std::ranges::count_if
#include <array>
#include <atomic>
@@ -42,11 +46,9 @@ tab-size = 4
#define HOST_NAME_MAX 64
#endif
#endif
-#define FMT_HEADER_ONLY
+
#include "fmt/core.h"
#include "fmt/format.h"
-#include "fmt/ostream.h"
-#include "fmt/ranges.h"
using std::array;
using std::atomic;
diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp
index 5e0af36..3a11e7e 100644
--- a/src/linux/btop_collect.cpp
+++ b/src/linux/btop_collect.cpp
@@ -160,37 +160,44 @@ namespace Gpu {
namespace Rsmi {
#if !defined(RSMI_STATIC)
//? RSMI defines, structs & typedefs
- #define RSMI_MAX_NUM_FREQUENCIES 32
- #define RSMI_STATUS_SUCCESS 0
- #define RSMI_MEM_TYPE_VRAM 0
- #define RSMI_TEMP_CURRENT 0
- #define RSMI_TEMP_TYPE_EDGE 0
- #define RSMI_CLK_TYPE_MEM 4
- #define RSMI_CLK_TYPE_SYS 0
- #define RSMI_TEMP_MAX 1
+ #define RSMI_MAX_NUM_FREQUENCIES_V5 32
+ #define RSMI_MAX_NUM_FREQUENCIES_V6 33
+ #define RSMI_STATUS_SUCCESS 0
+ #define RSMI_MEM_TYPE_VRAM 0
+ #define RSMI_TEMP_CURRENT 0
+ #define RSMI_TEMP_TYPE_EDGE 0
+ #define RSMI_CLK_TYPE_MEM 4
+ #define RSMI_CLK_TYPE_SYS 0
+ #define RSMI_TEMP_MAX 1
typedef int rsmi_status_t,
rsmi_temperature_metric_t,
rsmi_clk_type_t,
rsmi_memory_type_t;
- struct rsmi_frequencies_t {uint32_t num_supported, current, frequency[RSMI_MAX_NUM_FREQUENCIES];};
+ struct rsmi_version_t {uint32_t major, minor, patch; const char* build;};
+ struct rsmi_frequencies_t_v5 {uint32_t num_supported, current; uint64_t frequency[RSMI_MAX_NUM_FREQUENCIES_V5];};
+ struct rsmi_frequencies_t_v6 {bool has_deep_sleep; uint32_t num_supported, current; uint64_t frequency[RSMI_MAX_NUM_FREQUENCIES_V6];};
//? Function pointers
rsmi_status_t (*rsmi_init)(uint64_t);
rsmi_status_t (*rsmi_shut_down)();
+ rsmi_status_t (*rsmi_version_get)(rsmi_version_t*);
rsmi_status_t (*rsmi_num_monitor_devices)(uint32_t*);
rsmi_status_t (*rsmi_dev_name_get)(uint32_t, char*, size_t);
rsmi_status_t (*rsmi_dev_power_cap_get)(uint32_t, uint32_t, uint64_t*);
rsmi_status_t (*rsmi_dev_temp_metric_get)(uint32_t, uint32_t, rsmi_temperature_metric_t, int64_t*);
rsmi_status_t (*rsmi_dev_busy_percent_get)(uint32_t, uint32_t*);
rsmi_status_t (*rsmi_dev_memory_busy_percent_get)(uint32_t, uint32_t*);
- rsmi_status_t (*rsmi_dev_gpu_clk_freq_get)(uint32_t, rsmi_clk_type_t, rsmi_frequencies_t*);
+ rsmi_status_t (*rsmi_dev_gpu_clk_freq_get_v5)(uint32_t, rsmi_clk_type_t, rsmi_frequencies_t_v5*);
+ rsmi_status_t (*rsmi_dev_gpu_clk_freq_get_v6)(uint32_t, rsmi_clk_type_t, rsmi_frequencies_t_v6*);
rsmi_status_t (*rsmi_dev_power_ave_get)(uint32_t, uint32_t, uint64_t*);
rsmi_status_t (*rsmi_dev_memory_total_get)(uint32_t, rsmi_memory_type_t, uint64_t*);
rsmi_status_t (*rsmi_dev_memory_usage_get)(uint32_t, rsmi_memory_type_t, uint64_t*);
rsmi_status_t (*rsmi_dev_pci_throughput_get)(uint32_t, uint64_t*, uint64_t*, uint64_t*);
+ uint32_t version_major = 0;
+
//? Data
void* rsmi_dl_handle;
#endif
@@ -1259,13 +1266,13 @@ namespace Gpu {
LOAD_SYM(rsmi_init);
LOAD_SYM(rsmi_shut_down);
+ LOAD_SYM(rsmi_version_get);
LOAD_SYM(rsmi_num_monitor_devices);
LOAD_SYM(rsmi_dev_name_get);
LOAD_SYM(rsmi_dev_power_cap_get);
LOAD_SYM(rsmi_dev_temp_metric_get);
LOAD_SYM(rsmi_dev_busy_percent_get);
LOAD_SYM(rsmi_dev_memory_busy_percent_get);
- LOAD_SYM(rsmi_dev_gpu_clk_freq_get);
LOAD_SYM(rsmi_dev_power_ave_get);
LOAD_SYM(rsmi_dev_memory_total_get);
LOAD_SYM(rsmi_dev_memory_usage_get);
@@ -1281,6 +1288,26 @@ namespace Gpu {
return false;
}
+ #if !defined(RSMI_STATIC)
+ //? Check version
+ rsmi_version_t version;
+ result = rsmi_version_get(&version);
+ if (result != RSMI_STATUS_SUCCESS) {
+ Logger::warning("ROCm SMI: Failed to get version");
+ return false;
+ } else if (version.major == 5) {
+ if ((rsmi_dev_gpu_clk_freq_get_v5 = (decltype(rsmi_dev_gpu_clk_freq_get_v5))load_rsmi_sym("rsmi_dev_gpu_clk_freq_get")) == nullptr)
+ return false;
+ } else if (version.major == 6) {
+ if ((rsmi_dev_gpu_clk_freq_get_v6 = (decltype(rsmi_dev_gpu_clk_freq_get_v6))load_rsmi_sym("rsmi_dev_gpu_clk_freq_get")) == nullptr)
+ return false;
+ } else {
+ Logger::warning("ROCm SMI: Dynamic loading only supported for version 5 and 6");
+ return false;
+ }
+ version_major = version.major;
+ #endif
+
//? Device count
result = rsmi_num_monitor_devices(&device_count);
if (result != RSMI_STATUS_SUCCESS) {
@@ -1364,7 +1391,46 @@ namespace Gpu {
if constexpr(is_init) gpus_slice[i].supported_functions.mem_utilization = false;
} else gpus_slice[i].mem_utilization_percent.push_back((long long)utilization);
}
+ #if !defined(RSMI_STATIC)
+ //? Clock speeds
+ if (gpus_slice[i].supported_functions.gpu_clock) {
+ if (version_major == 5) {
+ rsmi_frequencies_t_v5 frequencies;
+ result = rsmi_dev_gpu_clk_freq_get_v5(i, RSMI_CLK_TYPE_SYS, &frequencies);
+ if (result != RSMI_STATUS_SUCCESS) {
+ Logger::warning("ROCm SMI: Failed to get GPU clock speed: ");
+ if constexpr(is_init) gpus_slice[i].supported_functions.gpu_clock = false;
+ } else gpus_slice[i].gpu_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
+ }
+ else if (version_major == 6) {
+ rsmi_frequencies_t_v6 frequencies;
+ result = rsmi_dev_gpu_clk_freq_get_v6(i, RSMI_CLK_TYPE_SYS, &frequencies);
+ if (result != RSMI_STATUS_SUCCESS) {
+ Logger::warning("ROCm SMI: Failed to get GPU clock speed: ");
+ if constexpr(is_init) gpus_slice[i].supported_functions.gpu_clock = false;
+ } else gpus_slice[i].gpu_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
+ }
+ }
+ if (gpus_slice[i].supported_functions.mem_clock) {
+ if (version_major == 5) {
+ rsmi_frequencies_t_v5 frequencies;
+ result = rsmi_dev_gpu_clk_freq_get_v5(i, RSMI_CLK_TYPE_MEM, &frequencies);
+ if (result != RSMI_STATUS_SUCCESS) {
+ Logger::warning("ROCm SMI: Failed to get VRAM clock speed: ");
+ if constexpr(is_init) gpus_slice[i].supported_functions.mem_clock = false;
+ } else gpus_slice[i].mem_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
+ }
+ else if (version_major == 6) {
+ rsmi_frequencies_t_v6 frequencies;
+ result = rsmi_dev_gpu_clk_freq_get_v6(i, RSMI_CLK_TYPE_MEM, &frequencies);
+ if (result != RSMI_STATUS_SUCCESS) {
+ Logger::warning("ROCm SMI: Failed to get VRAM clock speed: ");
+ if constexpr(is_init) gpus_slice[i].supported_functions.mem_clock = false;
+ } else gpus_slice[i].mem_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
+ }
+ }
+ #else
//? Clock speeds
if (gpus_slice[i].supported_functions.gpu_clock) {
rsmi_frequencies_t frequencies;
@@ -1383,6 +1449,7 @@ namespace Gpu {
if constexpr(is_init) gpus_slice[i].supported_functions.mem_clock = false;
} else gpus_slice[i].mem_clock_speed = (long long)frequencies.frequency[frequencies.current]/1000000; // Hz to MHz
}
+ #endif
//? Power usage & state
if (gpus_slice[i].supported_functions.pwr_usage) {
diff --git a/src/osx/btop_collect.cpp b/src/osx/btop_collect.cpp
index 76b63c0..860e457 100644
--- a/src/osx/btop_collect.cpp
+++ b/src/osx/btop_collect.cpp
@@ -686,7 +686,7 @@ namespace Mem {
if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&p, &info_size) == 0) {
mem.stats.at("free") = p.free_count * Shared::pageSize;
mem.stats.at("cached") = p.external_page_count * Shared::pageSize;
- mem.stats.at("used") = (p.active_count + p.inactive_count + p.wire_count) * Shared::pageSize;
+ mem.stats.at("used") = (p.active_count + p.wire_count) * Shared::pageSize;
mem.stats.at("available") = Shared::totalMem - mem.stats.at("used");
}