mirror of https://github.com/aristocratos/btop.git
Squashed commit of the following:
commit285fb215d1
Author: aristocratos <gnmjpl@gmail.com> Date: Thu Dec 28 13:10:18 2023 +0100 Proc::draw() -> Use std::erase_if() instead of for loops commit2fba934cde
Author: aristocratos <gnmjpl@gmail.com> Date: Wed Dec 27 00:54:28 2023 +0100 Fixed leftover code in GPU init logging false errors commitad14554f32
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 26 19:32:43 2023 +0100 Try alternative names for GPU libraries during GPU init commita8fda16bf6
Merge:e15e0b7
2796af3
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 26 19:19:14 2023 +0100 Merge pull request #696 from aristocratos/map_safety commit2796af3f37
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 26 19:18:37 2023 +0100 Document DEBUG flag for Makefile commitf484326bf2
Merge:b4eb397
e15e0b7
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 26 19:11:26 2023 +0100 Merge branch 'main' into map_safety commitb4eb397fc6
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 10:52:52 2023 +0100 Fix errors commit3c04a7a380
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 10:41:15 2023 +0100 Added more checks and debug logging commit8b81c4a4ec
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 03:28:35 2023 +0100 Return const refs commitf836233b64
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 02:49:24 2023 +0100 Remove robin_hood.h commit3a8ceacaf8
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 02:37:32 2023 +0100 Fix call to compact and missing utility include commite15e0b7188
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 02:27:38 2023 +0100 Revert "Replace robin_hood map and set with STD alternative and add safeVal() function for map/vector access with fallback" This reverts commit6c87ab6196
. commitced47a960f
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 02:26:13 2023 +0100 Replace robin_hood map and set with STD alternative and add safeVal() function for map/vector access with fallback commit6c87ab6196
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Dec 25 02:16:15 2023 +0100 Replace robin_hood map and set with STD alternative and add safeVal() function for map/vector access with fallback commita2325371d4
Merge:aab2e8c
b598f02
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sun Dec 17 19:56:31 2023 +0100 Merge pull request #690 from aristocratos/osx-fix commitb598f02468
Merge:b1fe377
aab2e8c
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sun Dec 17 12:06:39 2023 +0100 Merge branch 'main' into osx-fix commitaab2e8cc55
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sun Dec 17 12:03:47 2023 +0100 Fixed test-snap-can-build.yml commitb1fe3779e1
Merge:7805242
2d15c41
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sun Dec 17 11:56:14 2023 +0100 Merge branch 'main' into osx-fix commit2d15c41555
Merge:fe699b4
2d3e453
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sun Dec 17 11:54:49 2023 +0100 Merge pull request #684 from kz6fittycent/main commit2d3e453ed5
Merge:0a38864
fe699b4
Author: kz6fittycent <jimmy.tigert@gmail.com> Date: Fri Dec 15 12:02:11 2023 -0600 Merge branch 'main' into main commit0a388647cc
Author: kz6fittycent <jimmy.tigert@gmail.com> Date: Fri Dec 15 12:01:45 2023 -0600 Update test-snap-can-build.yml whoops commit49f425f356
Author: kz6fittycent <jimmy.tigert@gmail.com> Date: Fri Dec 15 12:00:48 2023 -0600 Update test-snap-can-build.yml https://github.com/aristocratos/btop/pull/684#issuecomment-1852801811 commit780524267f
Author: Jos Dehaes <jos.dehaes@gmail.com> Date: Fri Dec 15 09:02:57 2023 +0100 conditional compile on Big Sur and up commitfe699b4333
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 12 23:20:09 2023 +0100 Version bump to 1.3.0 in preparation for upcoming release commit2d2df23198
Merge:d7b581e
b71538e
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 12 23:19:31 2023 +0100 Merge branch 'main' of github.com:aristocratos/btop commitd7b581eda4
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 12 23:17:36 2023 +0100 Updated changes commitb71538eabe
Merge:a017056
730af5d
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 23:07:39 2023 +0100 Merge pull request #666 from muneebmahmed/macos-clang commit730af5d4e1
Merge:0246b1b
a017056
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 23:05:52 2023 +0100 Merge branch 'main' into macos-clang commita017056ea0
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 12 23:05:07 2023 +0100 Added swap to ignore for statvfs() since it will always fail commite770cccaf8
Author: aristocratos <gnmjpl@gmail.com> Date: Tue Dec 12 22:55:48 2023 +0100 Added try->catch for get_zfs_stat_file() to avoid fs error commit0246b1b971
Author: Muneeb Ahmed <32603485+muneebmahmed@users.noreply.github.com> Date: Mon Nov 20 12:18:40 2023 -0800 Enable macos clang Apple clang uses different versioning from LLVM, so 15.0.0 is compatible commit6282f36f8f
Merge:cfd20a3
be73160
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 22:06:02 2023 +0100 Merge pull request #675 from imwints/cmake commitbe731600f1
Merge:f4b14ce
cfd20a3
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 22:01:21 2023 +0100 Merge branch 'main' into cmake commit450b59b657
Merge:875f08b
cfd20a3
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 21:55:27 2023 +0100 Merge branch 'main' into main commitcfd20a374b
Merge:14e664e
b6a8696
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 21:48:55 2023 +0100 Merge pull request #677 from imwints/cpu-model commitb6a86962e2
Merge:8096433
14e664e
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 21:47:01 2023 +0100 Merge branch 'main' into cpu-model commit14e664e756
Merge:0d35746
5902484
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Dec 12 21:41:55 2023 +0100 Merge pull request #679 from masiboss/main commit875f08ba5e
Author: kz6fittycent <jimmy.tigert@gmail.com> Date: Tue Dec 12 14:27:16 2023 -0600 Update snapcraft.yaml - opengl - Testing opengl plug commit3ee4b18e57
Author: kz6fittycent <jimmy.tigert@gmail.com> Date: Tue Dec 12 14:14:59 2023 -0600 Update bug_report.md - added snap info for bug reports to delineate commit2973a76f2b
Merge:fb782a2
0d35746
Author: kz6fittycent <jimmy.tigert@gmail.com> Date: Tue Dec 12 14:06:44 2023 -0600 Merge branch 'aristocratos:main' into main commitfb782a2ab3
Author: kz6fittycent <jimmy.tigert@gmail.com> Date: Tue Dec 12 14:02:27 2023 -0600 Create test-snap-can-build.yml commit5902484f39
Author: masiboss <32394683+masiboss@users.noreply.github.com> Date: Thu Dec 7 21:42:11 2023 +0100 simplify removal of "Apple" commit5beb9e12e5
Author: masiboss <32394683+masiboss@users.noreply.github.com> Date: Thu Dec 7 20:56:40 2023 +0100 in case apple decides to add another suffix to the cpu name commit1b2f11b412
Author: masiboss <32394683+masiboss@users.noreply.github.com> Date: Thu Dec 7 20:49:34 2023 +0100 cut less of cpu name if frequency is not shown commitbcf4ad8ab6
Author: masiboss <32394683+masiboss@users.noreply.github.com> Date: Thu Dec 7 19:50:12 2023 +0100 fix array out of bounds on regular m chip commitaeefcacbc9
Author: masiboss <32394683+masiboss@users.noreply.github.com> Date: Thu Dec 7 19:34:11 2023 +0100 fix cpu version not included commit23698940df
Author: masiboss <32394683+masiboss@users.noreply.github.com> Date: Thu Dec 7 19:23:58 2023 +0100 strip "Apple" from name of Apple silicon chips commit8096433736
Author: Steffen Winter <steffen.winter@proton.me> Date: Tue Dec 5 02:34:24 2023 +0100 Fix printed model name for older Intel CPU commitf4b14ce97e
Author: Steffen Winter <steffen.winter@proton.me> Date: Tue Dec 5 01:00:14 2023 +0100 Add CMake compile instructions for macOS commit97b35d9720
Author: Steffen Winter <steffen.winter@proton.me> Date: Sat Dec 2 00:35:13 2023 +0100 Add cmake workflow for all platforms commite35538fa29
Author: Steffen Winter <steffen.winter@proton.me> Date: Sat Dec 2 00:34:32 2023 +0100 Patch RPATH on FreeBSD, support OSX and format commit0d357468b5
Merge:ebc46ca
00f58b6
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Fri Dec 1 22:52:51 2023 +0100 Merge pull request #674 from imwints/bsd-workflow Provide FreeBSD static release binaries commit00f58b6228
Author: Steffen Winter <steffen.winter@proton.me> Date: Thu Nov 30 23:07:52 2023 +0100 Provide FreeBSD static release binaries Bumps vmaction@freesdb-vm to version 1 which runs on Linux and doesn't hang all the time. Also uses clang for full static compilation commitebc46ca12c
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Mon Nov 27 18:21:42 2023 +0100 Clean up compile instructions commitd1384c9341
Merge:2b0cc37
6f12e35
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Mon Nov 27 17:53:39 2023 +0100 Merge pull request #671 from imwints/cmake-gpu Bring GPU support to CMake and improve how Make handles the ROCm library build commit6f12e3555d
Author: Steffen Winter <steffen.winter@proton.me> Date: Mon Nov 27 00:33:11 2023 +0100 Properly invoke CMake to build ROCm * Build an optimized library by default * Only build the library target * ROCm is build with debug symbols when `make DEBUG=true` * Enable LTO * Use the more generic CMake build command instead of calling make directly, this always uses all cores by default and makes it easier to switch to another generator e.g. Ninja * Use a variable to store the ROCm source directory. The directory can be changed with `make ROCM_DIR=<dir>` * The static library is now directly linked by CMake and not created off of the object files from a shared library build * The C++ compiler used to compile btop is now used to compile ROCm to avoid name mangling when `CXX` from the environment and `make CXX=` differ * CMake is invoked from btop's root directory commit0585bc9cfb
Author: Steffen Winter <steffen.winter@proton.me> Date: Mon Nov 27 00:31:10 2023 +0100 Suppress all output from ROCm build Similar to including external include files with `-isystem`, ignore output from ROCm build since these warnings aren't a concern here commit831be262b0
Author: Steffen Winter <steffen.winter@proton.me> Date: Mon Nov 27 00:29:14 2023 +0100 Remove ROCm object files with `make clean/distclean` commit2f59e61d87
Author: Steffen Winter <steffen.winter@proton.me> Date: Sun Nov 26 22:56:58 2023 +0100 Add GPU options for cmake based builds commit7588d96dd4
Author: Steffen Winter <steffen.winter@proton.me> Date: Sun Nov 26 21:40:29 2023 +0100 Add check for <ranges> header commitebbb769a6a
Author: Steffen Winter <steffen.winter@proton.me> Date: Sun Nov 26 21:39:13 2023 +0100 Move calls to find_package to where they're required commited0fa34a9d
Author: Steffen Winter <steffen.winter@proton.me> Date: Sun Nov 26 19:39:29 2023 +0100 Bump required CMake version commit2b0cc37632
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Nov 25 23:11:54 2023 +0100 Update compile instructions for Gpu support commit359c67136b
Author: aristocratos <gnmjpl@gmail.com> Date: Sat Nov 25 22:49:26 2023 +0100 Update changelog commit5b01235315
Merge:0267eba
0bb8599
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Nov 25 21:57:32 2023 +0100 Merge pull request #529 from romner-set/main Add GPU monitoring support commit0bb8599a96
Merge:94d4502
0267eba
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Nov 25 21:51:09 2023 +0100 Merge branch 'main' into main commit94d4502901
Author: aristocratos <gnmjpl@gmail.com> Date: Sat Nov 25 21:48:50 2023 +0100 Readme update and Makfile fixes. commit19bcff894b
Author: aristocratos <gnmjpl@gmail.com> Date: Sat Nov 25 21:01:11 2023 +0100 Squashed commit of the following: commit0267eba2bb
Merge:50bbab0
e81cf2b
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Nov 15 21:43:18 2023 +0100 Merge pull request #659 from ivanp7/patch-1 Add alternative key codes for Delete, Insert, Home, End commit50bbab0512
Merge:9edbf27
5a14c7b
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Nov 15 21:35:50 2023 +0100 Merge pull request #660 from stradicat/feature/elementarish Elementarish theme: color update according to Elementary palette commit5a14c7b6fa
Merge:979506f
71eb414
Author: Dennis Mayr <dmayr.dev@gmail.com> Date: Wed Nov 15 17:27:34 2023 -0300 Merge branch 'main' of https://github.com/stradicat/btop commit979506f18e
Author: Dennis Mayr <dmayr.dev@gmail.com> Date: Wed Nov 8 11:17:47 2023 -0300 Elementarish theme: color update according to Elementary palette commit71eb4142e8
Author: Dennis Mayr <dmayr.dev@gmail.com> Date: Wed Nov 8 11:17:47 2023 -0300 Elementarish theme: color update according to Elementary palette commite81cf2b7ff
Author: vân <3432246+ivanp7@users.noreply.github.com> Date: Tue Nov 7 15:12:27 2023 +0000 Add alternative key codes for Insert, Home, End commitf9452ff6d5
Author: vân <3432246+ivanp7@users.noreply.github.com> Date: Mon Nov 6 13:31:53 2023 +0000 Add alternative Delete key code Delete key not always produces ^[[3~, on some terminals (like st) it produces ^[[P. commit9edbf27f1b
Merge:2a864f6
ff1f51c
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Oct 21 02:09:55 2023 +0200 Merge pull request #649 from nobounce/workflow-timeout Set FreeBSD workflow timeout commitff1f51ccbb
Author: Steffen Winter <steffen.winter@proton.me> Date: Wed Oct 18 22:26:36 2023 +0200 Set FreeBSD workflow timeout Recently the FreeBSD workflow has started to hang in a boot loop when the VM starts up. The issue is being tracked upstream but there is not response at the moment. To work around this set a timeout to not waste CI minutes. Other workflows might also want this change since they don't take 20 minutes anyway. commit2a864f6f2e
Merge:636eb25
b2bf8ef
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Oct 7 10:40:54 2023 +0200 Merge pull request #643 from DecklynKern/main Fix scrollbar not clearing sometimes. commitb2bf8ef504
Author: DecklynKern <DecklynKern@gmail.com> Date: Fri Oct 6 17:33:38 2023 -0600 Fix scrollbar not clearing sometimes. commit636eb25f5e
Merge:260c0f6
b5ba2fc
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Sep 30 19:51:03 2023 +0200 Merge pull request #623 from rahulaggarwal965/main Add keybind for toggling memory display mode in PROC box commitb5ba2fc963
Author: Rahul Aggarwal <rahulaggarwal965@gmail.com> Date: Wed Sep 20 22:55:56 2023 -0400 Add keybind for toggling memory display mode in PROC box commit260c0f6623
Merge:52bfff7
e6a06eb
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Sep 30 18:56:25 2023 +0200 Merge pull request #635 from lvxnull/editorconfig Add hpp files to .editorconfig commite6a06eb729
Author: lvxnull <86745229+lvxnull@users.noreply.github.com> Date: Thu Sep 28 19:44:47 2023 +0200 Add hpp files to .editorconfig commit52bfff7ceb
Merge:1f72e56
19dbbe1
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Sep 30 18:55:08 2023 +0200 Merge pull request #636 from nobounce/performance-iili Minor string initialization improvement commit19dbbe1a17
Author: nobounce <steffen.winter@proton.me> Date: Fri Sep 29 12:20:59 2023 +0200 Minor string initialization improvement commit1f72e56c7d
Merge:278a0e6
cdcf8bc
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Fri Sep 29 10:43:21 2023 +0200 Merge pull request #633 from crestfallnatwork/main [fix] Made disks statvfs logic asynchronous. commitcdcf8bc929
Author: crestfalln <guptahiman01@gmail.com> Date: Fri Sep 29 09:07:27 2023 +0530 fixed bug where updated disks stats overrided disk io data commit9b4e85f08d
Author: crestfalln <no-reply@crestfalln.com> Date: Thu Sep 28 04:57:05 2023 +0530 fixed bug where updated disks stats overrided disk io data commit889623874e
Author: crestfalln <no-reply@crestfalln.com> Date: Wed Sep 27 23:57:06 2023 +0530 made disks stat logic async commit278a0e6b17
Merge:d16adc9
e89519f
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Thu Sep 28 18:32:09 2023 +0200 Merge pull request #630 from lvxnull/signal-list Fix signal list on non-linux/weird linux platforms commite89519fbb2
Author: lvxnull <86745229+lvxnull@users.noreply.github.com> Date: Sun Sep 24 21:44:38 2023 +0200 Fix signal list on non-linux/weird linux platforms commitd16adc9fd0
Merge:2c3ac48
f34b408
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Thu Sep 28 18:20:42 2023 +0200 Merge pull request #618 from nobounce/aggregate-child-processes Add option to accumulate a child's resources in parent in tree-view commitf34b40892f
Author: nobounce <steffen.winter@proton.me> Date: Sun Sep 24 16:34:50 2023 +0200 Make process thread count better readable when wider than 5 digits commit6027cedd42
Author: nobounce <steffen.winter@proton.me> Date: Thu Sep 14 23:27:05 2023 +0200 Add option to accumulate a child's resources in parent in tree-view commit2c3ac4855d
Merge:f90dc37
5c6a281
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Sep 13 21:14:56 2023 +0200 Merge pull request #589 from nobounce/cmake Add CMake support for Linux commitf90dc37c26
Merge:0cac861
68a49c1
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Sep 13 20:27:05 2023 +0200 Merge pull request #610 from SidVeld/feature/horizon-theme Horizon theme commit5c6a281002
Author: nobounce <steffen.winter@proton.me> Date: Tue Aug 29 20:39:00 2023 +0200 Add CMake support Linux is completly supported FreeBSD is not able to create a static executable for now. See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=273398 MacOS was not tested commit68a49c10a6
Author: SidVeld <sidveld@gmail.com> Date: Wed Sep 6 18:03:31 2023 +0300 Add horizon theme commit0cac861910
Merge:31be436
f798acd
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Sep 5 19:27:38 2023 +0200 Merge pull request #609 from scorpion-26/byteconv Fix short conversion of 1000-1023 *iB commitf798acdaf7
Author: scorpion-26 <dev.scorpion26@gmail.com> Date: Tue Sep 5 18:00:47 2023 +0200 Fix short conversion of 1000-1023*iB floating_humanizer([1000-1024], true) with base 8 returns "2K", whereas it should return "1.0K" to align with other formats. The conversion is also broken for all other units(e.g. 1023M is also broken and returns "2G") commit31be4362ce
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 02:00:07 2023 +0200 FreeBSD Github action 13.1 -> 13.2 and static libgcc and libstdc++ commitfc523fd1d0
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 01:36:26 2023 +0200 Fix for FreeBSD github action not failing "correctly"... commitb87772611c
Author: aristocratos <gnmjpl@gmail.com> Date: Sat Nov 25 20:44:45 2023 +0100 Added definition GPU_SUPPORT to toggle GPU related code commit0267eba2bb
Merge:50bbab0
e81cf2b
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Nov 15 21:43:18 2023 +0100 Merge pull request #659 from ivanp7/patch-1 Add alternative key codes for Delete, Insert, Home, End commit50bbab0512
Merge:9edbf27
5a14c7b
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Nov 15 21:35:50 2023 +0100 Merge pull request #660 from stradicat/feature/elementarish Elementarish theme: color update according to Elementary palette commit5a14c7b6fa
Merge:979506f
71eb414
Author: Dennis Mayr <dmayr.dev@gmail.com> Date: Wed Nov 15 17:27:34 2023 -0300 Merge branch 'main' of https://github.com/stradicat/btop commit979506f18e
Author: Dennis Mayr <dmayr.dev@gmail.com> Date: Wed Nov 8 11:17:47 2023 -0300 Elementarish theme: color update according to Elementary palette commit71eb4142e8
Author: Dennis Mayr <dmayr.dev@gmail.com> Date: Wed Nov 8 11:17:47 2023 -0300 Elementarish theme: color update according to Elementary palette commite81cf2b7ff
Author: vân <3432246+ivanp7@users.noreply.github.com> Date: Tue Nov 7 15:12:27 2023 +0000 Add alternative key codes for Insert, Home, End commitf9452ff6d5
Author: vân <3432246+ivanp7@users.noreply.github.com> Date: Mon Nov 6 13:31:53 2023 +0000 Add alternative Delete key code Delete key not always produces ^[[3~, on some terminals (like st) it produces ^[[P. commit9edbf27f1b
Merge:2a864f6
ff1f51c
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Oct 21 02:09:55 2023 +0200 Merge pull request #649 from nobounce/workflow-timeout Set FreeBSD workflow timeout commitff1f51ccbb
Author: Steffen Winter <steffen.winter@proton.me> Date: Wed Oct 18 22:26:36 2023 +0200 Set FreeBSD workflow timeout Recently the FreeBSD workflow has started to hang in a boot loop when the VM starts up. The issue is being tracked upstream but there is not response at the moment. To work around this set a timeout to not waste CI minutes. Other workflows might also want this change since they don't take 20 minutes anyway. commit2a864f6f2e
Merge:636eb25
b2bf8ef
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Oct 7 10:40:54 2023 +0200 Merge pull request #643 from DecklynKern/main Fix scrollbar not clearing sometimes. commitb2bf8ef504
Author: DecklynKern <DecklynKern@gmail.com> Date: Fri Oct 6 17:33:38 2023 -0600 Fix scrollbar not clearing sometimes. commit636eb25f5e
Merge:260c0f6
b5ba2fc
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Sep 30 19:51:03 2023 +0200 Merge pull request #623 from rahulaggarwal965/main Add keybind for toggling memory display mode in PROC box commitb5ba2fc963
Author: Rahul Aggarwal <rahulaggarwal965@gmail.com> Date: Wed Sep 20 22:55:56 2023 -0400 Add keybind for toggling memory display mode in PROC box commit260c0f6623
Merge:52bfff7
e6a06eb
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Sep 30 18:56:25 2023 +0200 Merge pull request #635 from lvxnull/editorconfig Add hpp files to .editorconfig commite6a06eb729
Author: lvxnull <86745229+lvxnull@users.noreply.github.com> Date: Thu Sep 28 19:44:47 2023 +0200 Add hpp files to .editorconfig commit52bfff7ceb
Merge:1f72e56
19dbbe1
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Sep 30 18:55:08 2023 +0200 Merge pull request #636 from nobounce/performance-iili Minor string initialization improvement commit19dbbe1a17
Author: nobounce <steffen.winter@proton.me> Date: Fri Sep 29 12:20:59 2023 +0200 Minor string initialization improvement commit1f72e56c7d
Merge:278a0e6
cdcf8bc
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Fri Sep 29 10:43:21 2023 +0200 Merge pull request #633 from crestfallnatwork/main [fix] Made disks statvfs logic asynchronous. commitcdcf8bc929
Author: crestfalln <guptahiman01@gmail.com> Date: Fri Sep 29 09:07:27 2023 +0530 fixed bug where updated disks stats overrided disk io data commit9b4e85f08d
Author: crestfalln <no-reply@crestfalln.com> Date: Thu Sep 28 04:57:05 2023 +0530 fixed bug where updated disks stats overrided disk io data commit889623874e
Author: crestfalln <no-reply@crestfalln.com> Date: Wed Sep 27 23:57:06 2023 +0530 made disks stat logic async commit278a0e6b17
Merge:d16adc9
e89519f
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Thu Sep 28 18:32:09 2023 +0200 Merge pull request #630 from lvxnull/signal-list Fix signal list on non-linux/weird linux platforms commite89519fbb2
Author: lvxnull <86745229+lvxnull@users.noreply.github.com> Date: Sun Sep 24 21:44:38 2023 +0200 Fix signal list on non-linux/weird linux platforms commitd16adc9fd0
Merge:2c3ac48
f34b408
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Thu Sep 28 18:20:42 2023 +0200 Merge pull request #618 from nobounce/aggregate-child-processes Add option to accumulate a child's resources in parent in tree-view commitf34b40892f
Author: nobounce <steffen.winter@proton.me> Date: Sun Sep 24 16:34:50 2023 +0200 Make process thread count better readable when wider than 5 digits commit6027cedd42
Author: nobounce <steffen.winter@proton.me> Date: Thu Sep 14 23:27:05 2023 +0200 Add option to accumulate a child's resources in parent in tree-view commit2c3ac4855d
Merge:f90dc37
5c6a281
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Sep 13 21:14:56 2023 +0200 Merge pull request #589 from nobounce/cmake Add CMake support for Linux commitf90dc37c26
Merge:0cac861
68a49c1
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Sep 13 20:27:05 2023 +0200 Merge pull request #610 from SidVeld/feature/horizon-theme Horizon theme commit5c6a281002
Author: nobounce <steffen.winter@proton.me> Date: Tue Aug 29 20:39:00 2023 +0200 Add CMake support Linux is completly supported FreeBSD is not able to create a static executable for now. See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=273398 MacOS was not tested commit68a49c10a6
Author: SidVeld <sidveld@gmail.com> Date: Wed Sep 6 18:03:31 2023 +0300 Add horizon theme commit0cac861910
Merge:31be436
f798acd
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Tue Sep 5 19:27:38 2023 +0200 Merge pull request #609 from scorpion-26/byteconv Fix short conversion of 1000-1023 *iB commitf798acdaf7
Author: scorpion-26 <dev.scorpion26@gmail.com> Date: Tue Sep 5 18:00:47 2023 +0200 Fix short conversion of 1000-1023*iB floating_humanizer([1000-1024], true) with base 8 returns "2K", whereas it should return "1.0K" to align with other formats. The conversion is also broken for all other units(e.g. 1023M is also broken and returns "2G") commit975525d38f
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 12:34:46 2023 +0200 Fix: Cpu gpu stats always shown when show_gpu_info is On and sizing issues commit08abf0b930
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 01:28:36 2023 +0200 Quickfixes for MacOS and FreeBSD compilation. commit7290109f80
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 00:58:30 2023 +0200 Merge fix commit283d463242
Merge:efddad4
c296ac1
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 00:56:22 2023 +0200 Merge branch 'main' into pr/romner-set/529 commitefddad42dc
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 00:39:57 2023 +0200 Changed: cpu_graph_lower Auto defaults to cpu_graph_upper when show_gpu_info is Off commita9bc0874d4
Author: aristocratos <gnmjpl@gmail.com> Date: Sun Aug 27 00:31:07 2023 +0200 Added show_gpu_info setting and Auto options for cpu graphs commitb3970ee19c
Author: aristocratos <gnmjpl@gmail.com> Date: Sat Aug 26 20:52:59 2023 +0200 Fixed: Key 5-0 gpu box toggle commitbd5d697830
Author: aristocratos <gnmjpl@gmail.com> Date: Sat Aug 26 20:29:43 2023 +0200 Squashed commit of the following: commitc296ac13cd
Merge:9a1e760
091c30a
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Aug 26 19:29:57 2023 +0200 Merge pull request #590 from nobounce/dangling-reference-config Convert parameters and config keys to std::string_view commit9a1e760a66
Merge:9c8af4d
22e64ca
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Aug 26 19:20:18 2023 +0200 Merge pull request #602 from jfouquart/main Fix getting zfs pool name with '.' char in freebsd commit9c8af4df43
Merge:8a49d8c
2217cbe
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Aug 26 19:18:55 2023 +0200 Merge pull request #601 from joske/cleanup [macos] don't check /sys on macos commit8a49d8cf45
Merge:1556388
008fcd8
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Aug 26 19:18:07 2023 +0200 Merge pull request #600 from joske/makefile [macos/freebsd] support gcc13 commit1556388c83
Merge:1b126f5
d17e1a2
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sat Aug 26 19:14:00 2023 +0200 Merge pull request #599 from joske/main [macos] fix temp sensor on system with many cores commitd17e1a2dac
Author: Jos Dehaes <jos.dehaes@gmail.com> Date: Fri Aug 25 16:18:39 2023 +0200 fix some warnings commit4d8aa6b118
Author: Jos Dehaes <jos.dehaes@gmail.com> Date: Fri Aug 25 15:52:58 2023 +0200 fix core check commit22e64caaff
Author: Jonathan Fouquart <jfouquart@hotmail.fr> Date: Fri Aug 25 09:37:49 2023 +0200 Fix getting zfs pool name with '.' char in freebsd commit2217cbe143
Author: Jos Dehaes <jos.dehaes@gmail.com> Date: Wed Aug 23 16:01:04 2023 +0200 [macos] don't check /sys on macos commit008fcd889e
Author: Jos Dehaes <jos.dehaes@gmail.com> Date: Wed Aug 23 16:05:00 2023 +0200 also add g++13 commit0fdca5eb03
Author: Jos Dehaes <jos.dehaes@gmail.com> Date: Wed Aug 23 15:54:07 2023 +0200 support gcc13 commitdcbdb7360d
Author: Jos Dehaes <jos.dehaes@gmail.com> Date: Wed Aug 23 15:46:47 2023 +0200 [macos] fix temp sensor on system with many cores commit1b126f55e3
Author: aristocratos <gnmjpl@gmail.com> Date: Fri Aug 4 01:08:27 2023 +0200 Update Makefile for partial static compilation on freebsd commitc8ec6bbb00
Author: aristocratos <gnmjpl@gmail.com> Date: Thu Aug 3 23:08:33 2023 +0200 Fix freebsd nullptr changes and makefile for gcc12 and newer commit8a33aab588
Merge:94e5c02
e4abcef
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Sun Jul 30 13:21:48 2023 +0200 Merge pull request #539 from nobounce/replace-NULL-nullptr Modernize using nullptr. commit94e5c02d11
Author: aristocratos <gnmjpl@gmail.com> Date: Thu Jul 27 20:51:21 2023 +0200 Better text editing commit091c30ab2b
Author: nobounce <steffen.winter@proton.me> Date: Thu Jul 27 14:17:54 2023 +0200 Convert parameters and config keys to std::string_view Using std::string_view instead of std::string& silences a new warning from GCC 13, -Wdangling-reference Also switch return type of `getI` from int& to int, trivial types are cheaper to copy by value commite4abcefbf9
Author: nobounce <steffen.winter@proton.me> Date: Wed Jul 26 16:19:17 2023 +0200 Use nullptr instead of NULL. See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf TLDR: NULL is of type int and relies on proper implicit pointer conversion which may lead to issues when using overloaded functions It is also considered a 'best practise' for modern C++ and conveys the programmers intention more precisly. commitd53307f14c
Author: nobounce <steffen.winter@proton.me> Date: Sun Jul 23 19:53:36 2023 +0200 Fix path to Linux CI file in itself The CI file has a list of dependent files including itself. The path was not updated when the CI was split into different files commit594f42b9eb
Merge:aca2e4b
53d6eba
Author: Jakob P. Liljenberg <admin@qvantnet.com> Date: Wed Jul 26 15:38:01 2023 +0200 Merge pull request #584 from nobounce/nb/fix-ci-path Fix path to Linux CI file in itself commitaca2e4be75
Author: aristocratos <gnmjpl@gmail.com> Date: Wed Jul 26 14:38:48 2023 +0200 Fix whitespace indent -> tab indent commit33faa01910
Author: aristocratos <gnmjpl@gmail.com> Date: Wed Jul 26 14:34:15 2023 +0200 Revert fmt submodule to static fmt folder in include commit53d6ebabc0
Author: nobounce <steffen.winter@proton.me> Date: Sun Jul 23 19:53:36 2023 +0200 Fix path to Linux CI file in itself The CI file has a list of dependent files including itself. The path was not updated when the CI was split into different files commit346c9e479b
Author: romner <roman@skotnica.com> Date: Wed Jul 19 16:53:58 2023 +0200 Fix GPU text overflow in CPU panel, again commit3a5e5fd5d3
Author: romner <roman@skotnica.com> Date: Wed Jul 19 16:22:45 2023 +0200 Improve 0-10 key input commit972b2b6a01
Author: romner <roman@skotnica.com> Date: Wed Jul 19 15:54:35 2023 +0200 Fix available boxes in menu & config description commit1f73453aec
Author: romner <roman@skotnica.com> Date: Wed Jul 19 15:34:23 2023 +0200 Fix crashes when trying to open nth GPU box with only n-1 GPUs in the system commit46c6be0a29
Author: romner <roman@skotnica.com> Date: Sun Jul 16 17:19:09 2023 +0200 Fix GPU horizontal text overflow in CPU panel commit85fb28cee6
Author: romner <roman@skotnica.com> Date: Fri Jul 14 02:39:44 2023 +0200 Fix RSMI_STATIC=true and add GPU section to README.md commit3fad8a6fde
Author: romner-set <roman@skotnica.com> Date: Mon Jun 26 13:10:31 2023 +0200 Add GPU options commit746f716a02
Author: romner-set <roman@skotnica.com> Date: Fri Jun 16 11:11:57 2023 +0200 Remove lib/rocm_smi_lib and add instructions for obtaining it to README commitd8ebbe1181
Author: romner <roman@skotnica.com> Date: Thu Jun 8 20:24:01 2023 +0200 Join NVML PCIe threads only if PCIe TX/RX is supported by GPU commitbe10989151
Author: romner <roman@skotnica.com> Date: Tue Jun 6 19:47:07 2023 +0200 Parallelize NVML PCIe TX/RX data collection commit85892a9fe3
Author: aristocratos <gnmjpl@gmail.com> Date: Mon Jun 5 21:59:26 2023 +0200 Fix type: ulong -> size_t and compare std::cmp_less commit85a10f0305
Author: romner <roman@skotnica.com> Date: Fri Jun 2 16:14:24 2023 +0200 Fix ROCm SMI makefile flags commitcd6979277d
Author: romner <roman@skotnica.com> Date: Fri Jun 2 15:44:44 2023 +0200 Fix error when ROCm SMI static compilation fails commitdaaa45324f
Author: romner <roman@skotnica.com> Date: Fri Jun 2 15:34:12 2023 +0200 Load ROCm SMI dynamically by default, optionally statically compile and link commit093edfe948
Author: aristocratos <gnmjpl@gmail.com> Date: Thu Jun 1 19:49:00 2023 +0200 Minor changes in wording... commitb9a4d31fa4
Author: aristocratos <gnmjpl@gmail.com> Date: Thu Jun 1 19:37:53 2023 +0200 Fix Makefile dependency order and layout commita0163ce220
Author: romner <roman@skotnica.com> Date: Thu Jun 1 16:42:02 2023 +0200 Statically link ROCm SMI commitb2df0696fd
Author: romner-set <roman@skotnica.com> Date: Thu Jun 1 03:41:56 2023 +0200 Dynamically load NVML commit547f17dda3
Author: romner-set <roman@skotnica.com> Date: Tue May 30 18:24:50 2023 +0200 Add more GPU graph types to the CPU panel commit842c761a73
Author: romner-set <roman@skotnica.com> Date: Mon May 22 09:46:20 2023 +0200 Fix crash when all GPU panels are open but the CPU panel is closed commit8c96bd51e9
Author: romner <roman@skotnica.com> Date: Sun May 21 20:34:47 2023 +0200 Handle GPUs which cannot report certain stats in GPU panel commit414d7eb94c
Author: romner <roman@skotnica.com> Date: Sun May 21 18:02:50 2023 +0200 Handle GPUs which cannot report certain stats in btop_collect.cpp and CPU panel commit005de97e6d
Author: aristocratos <gnmjpl@gmail.com> Date: Sun May 21 13:58:11 2023 +0200 Add missing fmt prefixes commit1fee2bc08b
Author: aristocratos <gnmjpl@gmail.com> Date: Sun May 21 13:52:19 2023 +0200 Add DebugTimer class and change some Logger::error calls to Logger::debug commit2e68c0b916
Author: aristocratos <gnmjpl@gmail.com> Date: Sat May 20 17:27:20 2023 +0200 Fixed key > gpu_names check commit04ed16a9f6
Author: aristocratos <gnmjpl@gmail.com> Date: Sat May 20 17:15:45 2023 +0200 Merged changes from main commit8c710a2b68
Author: aristocratos <gnmjpl@gmail.com> Date: Sat May 20 01:41:04 2023 +0200 Makefile auto detection and initial logic for excluding gpu code when libs are missing commit8bae1ec092
Author: aristocratos <gnmjpl@gmail.com> Date: Sat May 20 00:13:00 2023 +0200 Fixed debug timer for gpu commit01acfd603e
Author: romner-set <roman@skotnica.com> Date: Fri May 19 16:42:32 2023 +0200 Bind GPU panel to 5,6,7,8,9,0 and fully implement multi-GPU support commit22a463976d
Author: romner <roman@skotnica.com> Date: Thu May 18 16:07:05 2023 +0200 Add GPU info to CPU panel commitc352bf2613
Author: romner-set <roman@skotnica.com> Date: Mon May 15 19:42:55 2023 +0200 Add ROCm SMI backend for AMD GPU support commit917d568a77
Author: romner-set <roman@skotnica.com> Date: Mon May 15 13:58:54 2023 +0200 Add multi-GPU support for NVML data collection commit2d27f2ff61
Author: romner <roman@skotnica.com> Date: Sun May 14 17:40:50 2023 +0200 Fix crash when no nvidia GPU is detected commit0e0025a2c3
Author: romner <roman@skotnica.com> Date: Sun May 14 17:31:39 2023 +0200 Update makefile text, fix typo and adhere to contibuting guidelines commitbcffcdf19f
Author: romner <roman@skotnica.com> Date: Sun May 14 16:53:06 2023 +0200 Make GPU window's size dynamic and integrate it with the rest of btop commit95b3228308
Author: romner <roman@skotnica.com> Date: Sat May 13 19:41:51 2023 +0200 Improve GPU side panel commitadcdc583b0
Author: romner <roman@skotnica.com> Date: Sat May 13 00:27:23 2023 +0200 Add GPU side panel commitd522a91ef4
Author: romner <roman@skotnica.com> Date: Fri May 12 19:34:47 2023 +0200 Add rudimentary, fullscreen single-GPU NVML utilization graph
This commit is contained in:
parent
33595a2c9e
commit
934a9e3cf2
|
@ -1,4 +1,4 @@
|
||||||
[*.{cpp,h,sh,md,cfg,sample}]
|
[*.{cpp,h,hpp,sh,md,cfg,sample}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ Any bug that can be solved by just reading the [prerequisites](https://github.co
|
||||||
|
|
||||||
**Info (please complete the following information):**
|
**Info (please complete the following information):**
|
||||||
- btop++ version: `btop -v`
|
- btop++ version: `btop -v`
|
||||||
|
- If using snap: `snap info btop`
|
||||||
- Binary: [self compiled or static binary from release]
|
- Binary: [self compiled or static binary from release]
|
||||||
- (If compiled) Compiler and version:
|
- (If compiled) Compiler and version:
|
||||||
- Architecture: [x86_64, aarch64, etc.] `uname -m`
|
- Architecture: [x86_64, aarch64, etc.] `uname -m`
|
||||||
|
@ -40,7 +41,9 @@ Any bug that can be solved by just reading the [prerequisites](https://github.co
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
|
||||||
contents of `~/.config/btop/btop.log`
|
Contents of `~/.config/btop/btop.log`
|
||||||
|
|
||||||
|
Note: The snap uses: `~/snap/btop/current/.config/btop`
|
||||||
|
|
||||||
(try running btop with `--debug` flag if btop.log is empty)
|
(try running btop with `--debug` flag if btop.log is empty)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
name: FreeBSD CMake
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: main
|
||||||
|
tags-ignore: '*.*'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/cmake-freebsd.yml'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'include/**'
|
||||||
|
- 'src/*pp'
|
||||||
|
- 'src/freebsd/*pp'
|
||||||
|
pull_request:
|
||||||
|
branches: main
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/cmake-freebsd.yml'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'include/**'
|
||||||
|
- 'src/*pp'
|
||||||
|
- 'src/freebsd/*pp'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cmake_build_on_freebsd:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Compile
|
||||||
|
uses: vmactions/freebsd-vm@v1
|
||||||
|
with:
|
||||||
|
release: '14.0'
|
||||||
|
usesh: true
|
||||||
|
prepare: pkg install -y cmake ninja
|
||||||
|
run: |
|
||||||
|
CXX=clang++ cmake -B build -G Ninja -DBTOP_STATIC=ON
|
||||||
|
cmake --build build --verbose
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
name: Linux CMake
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: main
|
||||||
|
tags-ignore: '*.*'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/cmake-linux.yml'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'include/**'
|
||||||
|
- 'src/*pp'
|
||||||
|
- 'src/linux/*pp'
|
||||||
|
pull_request:
|
||||||
|
branches: main
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/cmake-linux.yml'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'include/**'
|
||||||
|
- 'src/*pp'
|
||||||
|
- 'src/linux/*pp'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cmake_build_on_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 clang cmake lld ninja
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: CXX=clang++ LDFLAGS=-fuse-ld=lld cmake -B build -G Ninja -DBTOP_STATIC=ON
|
||||||
|
|
||||||
|
- name: Compile
|
||||||
|
run: cmake --build build --verbose
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
name: macOS CMake
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: main
|
||||||
|
tags-ignore: '*.*'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/cmake-macos.yml'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'include/**'
|
||||||
|
- 'src/*pp'
|
||||||
|
- 'src/osx/*pp'
|
||||||
|
pull_request:
|
||||||
|
branches: main
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/cmake-macos.yml'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- 'include/**'
|
||||||
|
- 'src/*pp'
|
||||||
|
- 'src/osx/*pp'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cmake_build_on_macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
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: |
|
||||||
|
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||||
|
brew update --quiet
|
||||||
|
brew install --force --overwrite cmake llvm@17 ninja
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
export LLVM_PREFIX="$(brew --prefix llvm)"
|
||||||
|
export CXX="$LLVM_PREFIX/bin/clang++"
|
||||||
|
export CPPFLAGS="-I$LLVM_PREFIX/include"
|
||||||
|
export LDFLAGS="-L$LLVM_PREFIX/lib -L$LLVM_PREFIX/lib/c++ -Wl,-rpath,$LLVM_PREFIX/lib/c++ -fuse-ld=$LLVM_PREFIX/bin/ld64.lld"
|
||||||
|
cmake -B build -G Ninja
|
||||||
|
|
||||||
|
- name: Compile
|
||||||
|
run: cmake --build build --verbose
|
||||||
|
|
|
@ -27,28 +27,34 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-freebsd:
|
build-freebsd:
|
||||||
runs-on: macos-12
|
runs-on: ubuntu-22.04
|
||||||
|
timeout-minutes: 20
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
compiler: ["clang++", "g++"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Compile
|
- name: Compile
|
||||||
uses: vmactions/freebsd-vm@v0
|
uses: vmactions/freebsd-vm@v1
|
||||||
with:
|
with:
|
||||||
release: 13.2
|
release: '14.0'
|
||||||
usesh: true
|
usesh: true
|
||||||
prepare: |
|
prepare: |
|
||||||
pkg install -y gmake gcc11 coreutils git
|
pkg install -y gmake gcc coreutils git
|
||||||
git config --global --add safe.directory /Users/runner/work/btop/btop
|
git config --global --add safe.directory /home/runner/work/btop/btop
|
||||||
run: |
|
run: |
|
||||||
gmake STATIC=true STRIP=true
|
CXX=${{ matrix.compiler }} gmake STATIC=true STRIP=true
|
||||||
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
|
GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")
|
||||||
mv bin/btop bin/btop-$GIT_HASH
|
COMPILER=$(echo ${{ matrix.compiler }} | sed 's/clang++/llvm/' | sed 's/g++/gcc/')
|
||||||
|
mv bin/btop bin/btop-"$COMPILER"-"$GIT_HASH"
|
||||||
ls -alh bin
|
ls -alh bin
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: btop-x86_64-FreeBSD-13.2
|
name: btop-x86_64-freebsd-14
|
||||||
path: 'bin/*'
|
path: 'bin/*'
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
name: 🧪 Test snap can be built on x86_64
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
tags-ignore:
|
||||||
|
- '*.*'
|
||||||
|
paths:
|
||||||
|
- 'src/**'
|
||||||
|
- '!src/osx/**'
|
||||||
|
- '!src/freebsd/**'
|
||||||
|
- 'include/**'
|
||||||
|
- 'Makefile'
|
||||||
|
- '.github/workflows/test-snap-can-build.yml'
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
paths:
|
||||||
|
- 'src/**'
|
||||||
|
- '!src/osx/**'
|
||||||
|
- '!src/freebsd/**'
|
||||||
|
- 'include/**'
|
||||||
|
- 'Makefile'
|
||||||
|
- '.github/workflows/test-snap-can-build.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [16.x]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: snapcore/action-build@v1
|
||||||
|
id: build
|
||||||
|
|
||||||
|
- uses: diddlesnaps/snapcraft-review-action@v1
|
||||||
|
with:
|
||||||
|
snap: ${{ steps.build.outputs.snap }}
|
||||||
|
isClassic: 'false'
|
|
@ -51,9 +51,11 @@ bin
|
||||||
btop
|
btop
|
||||||
.*/
|
.*/
|
||||||
|
|
||||||
|
# Optional libraries
|
||||||
|
lib/rocm_smi_lib
|
||||||
|
|
||||||
#do not ignore .github directory
|
# Don't ignore .github directory
|
||||||
!.github
|
!.github/
|
||||||
|
|
||||||
# Ignore files created by Qt Creator
|
# Ignore files created by Qt Creator
|
||||||
*.config
|
*.config
|
||||||
|
@ -64,3 +66,19 @@ btop
|
||||||
*.cxxflags
|
*.cxxflags
|
||||||
*.files
|
*.files
|
||||||
*.includes
|
*.includes
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
CMakeLists.txt.user
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Testing
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
_deps
|
||||||
|
|
||||||
|
# CLion
|
||||||
|
cmake-build-*
|
||||||
|
|
46
CHANGELOG.md
46
CHANGELOG.md
|
@ -1,3 +1,49 @@
|
||||||
|
## v1.3.0
|
||||||
|
|
||||||
|
* Added Gpu Support | @romner-set | PR #529
|
||||||
|
|
||||||
|
* Enable macos clang | @muneebmahmed | PR #666
|
||||||
|
|
||||||
|
* Fix Apple Silicon CPUs misprinted | @masiboss | PR #679
|
||||||
|
|
||||||
|
* Cmake support for MacOS | @imwints | PR #675
|
||||||
|
|
||||||
|
* Elementarish theme: color update according to Elementary palette | @stradicat | PR #660
|
||||||
|
|
||||||
|
* Add alternative key codes for Delete, Insert, Home, End | @ivanp7 | PR #659
|
||||||
|
|
||||||
|
* Fix scrollbar not clearing sometimes. | @DecklynKern | PR #643
|
||||||
|
|
||||||
|
* Add keybind for toggling memory display mode in PROC box | @rahulaggarwal965 | PR #623
|
||||||
|
|
||||||
|
* Minor string initialization improvement | @imwints | PR #636
|
||||||
|
|
||||||
|
* Made disks statvfs logic asynchronous. | @crestfallnatwork | PR #633
|
||||||
|
|
||||||
|
* Fix signal list on non-linux/weird linux platforms | @lvxnull | PR #630
|
||||||
|
|
||||||
|
* Add option to accumulate a child's resources in parent in tree-view | @imwints | PR #618
|
||||||
|
|
||||||
|
* Add CMake support for Linux | @imwints | PR #589
|
||||||
|
|
||||||
|
* Horizon theme | @SidVeld | PR #610
|
||||||
|
|
||||||
|
* Fix short conversion of 1000-1023 *iB | @scorpion-26 | #609
|
||||||
|
|
||||||
|
* Fix integer overflows in btop_collect.cpp | @dorrellmw | #546
|
||||||
|
|
||||||
|
* Support compiling with LLVM | @imwints | #510
|
||||||
|
|
||||||
|
* Fix getting zfs pool name with '.' char in freebsd | @jfouquart | #602
|
||||||
|
|
||||||
|
* [macos/freebsd] support gcc13 | @joske | #600
|
||||||
|
|
||||||
|
* FreeBSD swap info | @rrveex | #560
|
||||||
|
|
||||||
|
* Create adwaita.theme | @flipflop133 | #485
|
||||||
|
|
||||||
|
+ Various fixes by @imwints, @simplepad, @joske, @gwena, @cpalv, @iambeingtracked, @mattico, @NexAdn
|
||||||
|
|
||||||
## v1.2.13
|
## v1.2.13
|
||||||
|
|
||||||
* Makefile: VERBOSE=true flag for Makefile to display all compiler commands and fixed so already set CXXFLAGS and LDFLAGS are displayed.
|
* Makefile: VERBOSE=true flag for Makefile to display all compiler commands and fixed so already set CXXFLAGS and LDFLAGS are displayed.
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# CMake configuration for btop
|
||||||
|
#
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.24)
|
||||||
|
|
||||||
|
# Disable in-source builds since they would override the Makefile
|
||||||
|
if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
message(FATAL_ERROR "In-source builds are not allowed")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
project("btop"
|
||||||
|
VERSION 1.2.13
|
||||||
|
DESCRIPTION "A monitor of resources"
|
||||||
|
HOMEPAGE_URL "https://github.com/aristocratos/btop"
|
||||||
|
LANGUAGES CXX
|
||||||
|
)
|
||||||
|
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
include(CheckIncludeFileCXX)
|
||||||
|
include(CheckIPOSupported)
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
|
||||||
|
# Make our Find<Package>.cmake files available
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
|
||||||
|
|
||||||
|
# When the build type is not set we can't fortify
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_COLOR_DIAGNOSTICS ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
option(BTOP_STATIC "Link btop statically" OFF)
|
||||||
|
option(BTOP_LTO "Enable LTO" ON)
|
||||||
|
option(BTOP_USE_MOLD "Use mold to link btop" OFF)
|
||||||
|
option(BTOP_PEDANTIC "Enable a bunch of additional warnings" OFF)
|
||||||
|
option(BTOP_WERROR "Compile with warnings as errors" OFF)
|
||||||
|
option(BTOP_GPU "Enable GPU support" ON)
|
||||||
|
cmake_dependent_option(BTOP_RSMI_STATIC "Link statically to ROCm SMI" OFF "BTOP_GPU" OFF)
|
||||||
|
|
||||||
|
if(BTOP_STATIC AND NOT APPLE)
|
||||||
|
# Set this before calling find_package
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(btop
|
||||||
|
src/btop.cpp
|
||||||
|
src/btop_config.cpp
|
||||||
|
src/btop_draw.cpp
|
||||||
|
src/btop_input.cpp
|
||||||
|
src/btop_menu.cpp
|
||||||
|
src/btop_shared.cpp
|
||||||
|
src/btop_theme.cpp
|
||||||
|
src/btop_tools.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
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(LINUX)
|
||||||
|
target_sources(btop PRIVATE src/linux/btop_collect.cpp)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "${CMAKE_SYSTEM_NAME} is not supported")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
check_include_file_cxx(ranges CXX_HAVE_RANGES)
|
||||||
|
if(NOT CXX_HAVE_RANGES)
|
||||||
|
message(FATAL_ERROR "The compiler doesn't support <ranges>")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check for and enable LTO
|
||||||
|
check_ipo_supported(RESULT ipo_supported)
|
||||||
|
if(ipo_supported AND BTOP_LTO)
|
||||||
|
set_target_properties(btop PROPERTIES INTERPROCEDURAL_OPTIMIZATION ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_options(btop PRIVATE -Wall -Wextra -Wpedantic -ftree-vectorize)
|
||||||
|
|
||||||
|
if(BTOP_PEDANTIC)
|
||||||
|
target_compile_options(btop PRIVATE
|
||||||
|
-Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused -Woverloaded-virtual
|
||||||
|
-Wconversion -Wsign-conversion -Wdouble-promotion -Wformat=2 -Wimplicit-fallthrough -Weffc++
|
||||||
|
$<$<CXX_COMPILER_ID:Clang>:-Wheader-hygiene -Wgnu -Wthread-safety>
|
||||||
|
$<$<CXX_COMPILER_ID:GNU>:-Wduplicated-cond -Wduplicated-branches -Wlogical-op>
|
||||||
|
$<$<CXX_COMPILER_ID:GNU>:-Wnull-dereference -Wuseless-cast>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(BTOP_WERROR)
|
||||||
|
target_compile_options(btop PRIVATE -Werror)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT APPLE)
|
||||||
|
target_compile_options(btop PRIVATE -fstack-clash-protection)
|
||||||
|
endif()
|
||||||
|
check_cxx_compiler_flag(-fstack-protector HAS_FSTACK_PROTECTOR)
|
||||||
|
if(HAS_FSTACK_PROTECTOR)
|
||||||
|
target_compile_options(btop PRIVATE -fstack-protector)
|
||||||
|
endif()
|
||||||
|
check_cxx_compiler_flag(-fcf-protection HAS_FCF_PROTECTION)
|
||||||
|
if(HAS_FCF_PROTECTION)
|
||||||
|
target_compile_options(btop PRIVATE -fcf-protection)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(btop PRIVATE
|
||||||
|
_FILE_OFFSET_BITS=64
|
||||||
|
$<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1>
|
||||||
|
# Only has an effect with optimizations enabled
|
||||||
|
$<$<NOT:$<CONFIG:Debug>>:_FORTIFY_SOURCE=2>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(btop SYSTEM PRIVATE include)
|
||||||
|
|
||||||
|
# Enable pthreads
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries(btop Threads::Threads)
|
||||||
|
|
||||||
|
# Enable GPU support
|
||||||
|
if(LINUX AND BTOP_GPU)
|
||||||
|
target_compile_definitions(btop PRIVATE GPU_SUPPORT)
|
||||||
|
|
||||||
|
if(BTOP_RSMI_STATIC)
|
||||||
|
# ROCm doesn't properly add it's folders to the module path if `CMAKE_MODULE_PATH` is already
|
||||||
|
# set
|
||||||
|
# We could also manully append ROCm's path here
|
||||||
|
set(_CMAKE_MODULE_PATH CMAKE_MODULE_PATH)
|
||||||
|
unset(CMAKE_MODULE_PATH)
|
||||||
|
|
||||||
|
# NOTE: This might be problematic in the future if other sub projects depend on this or if
|
||||||
|
# btop starts producing libraries
|
||||||
|
# Build a static ROCm library
|
||||||
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
add_subdirectory(lib/rocm_smi_lib EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_library(ROCm INTERFACE)
|
||||||
|
# Export ROCm's properties to a target
|
||||||
|
target_compile_definitions(ROCm INTERFACE RSMI_STATIC)
|
||||||
|
target_include_directories(ROCm INTERFACE lib/rocm_smi_lib/include)
|
||||||
|
target_link_libraries(ROCm INTERFACE rocm_smi64)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH _CMAKE_MODULE_PATH)
|
||||||
|
|
||||||
|
target_link_libraries(btop ROCm)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BTOP_USE_MOLD)
|
||||||
|
target_link_options(btop PRIVATE -fuse-ld=mold)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BTOP_STATIC)
|
||||||
|
target_compile_definitions(btop PRIVATE STATIC_BUILD)
|
||||||
|
target_link_options(btop PRIVATE -static LINKER:--fatal-warnings)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Other platform depdendent flags
|
||||||
|
if(APPLE)
|
||||||
|
target_link_libraries(btop
|
||||||
|
$<LINK_LIBRARY:FRAMEWORK,CoreFoundation> $<LINK_LIBRARY:FRAMEWORK,IOKit>
|
||||||
|
)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||||
|
# Avoid version mismatch for libstdc++ when a specific version of GCC is installed and not the
|
||||||
|
# default one since all use the default ones RPATH
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
string(REGEX MATCH "^[0-9]+" GCC_VERSION_MAJOR "${CMAKE_CXX_COMPILER_VERSION}")
|
||||||
|
set_target_properties(btop PROPERTIES
|
||||||
|
INSTALL_RPATH "/usr/local/lib/gcc${GCC_VERSION_MAJOR}"
|
||||||
|
BUILD_WITH_INSTALL_RPATH TRUE
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(devstat REQUIRED)
|
||||||
|
target_link_libraries(btop devstat::devstat)
|
||||||
|
if(BTOP_STATIC)
|
||||||
|
find_package(elf REQUIRED)
|
||||||
|
find_package(kvm REQUIRED)
|
||||||
|
target_link_libraries(btop elf::elf kvm::kvm)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS btop RUNTIME)
|
||||||
|
install(FILES "btop.desktop" DESTINATION "share/applications")
|
||||||
|
install(FILES "Img/icon.png" DESTINATION "share/icons/hicolor/48x48/apps" RENAME "btop.png")
|
||||||
|
install(FILES "Img/icon.svg" DESTINATION "share/icons/hicolor/scalable/apps" RENAME "btop.svg")
|
||||||
|
install(DIRECTORY "themes" DESTINATION "share/btop")
|
||||||
|
|
101
Makefile
101
Makefile
|
@ -12,10 +12,7 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(QUIET),true)
|
ifneq ($(QUIET),true)
|
||||||
override PRE := info info-quiet
|
|
||||||
override QUIET := false
|
override QUIET := false
|
||||||
else
|
|
||||||
override PRE := info-quiet
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OLDCXX := $(CXXFLAGS)
|
OLDCXX := $(CXXFLAGS)
|
||||||
|
@ -39,6 +36,20 @@ endif
|
||||||
|
|
||||||
override PLATFORM_LC := $(shell echo $(PLATFORM) | tr '[:upper:]' '[:lower:]')
|
override PLATFORM_LC := $(shell echo $(PLATFORM) | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
#? GPU Support
|
||||||
|
ifeq ($(PLATFORM_LC)$(ARCH),linuxx86_64)
|
||||||
|
ifneq ($(STATIC),true)
|
||||||
|
GPU_SUPPORT := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifneq ($(GPU_SUPPORT),true)
|
||||||
|
GPU_SUPPORT := false
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(GPU_SUPPORT),true)
|
||||||
|
override ADDFLAGS += -DGPU_SUPPORT
|
||||||
|
endif
|
||||||
|
|
||||||
#? Compiler and Linker
|
#? Compiler and Linker
|
||||||
ifeq ($(shell $(CXX) --version | grep clang >/dev/null 2>&1; echo $$?),0)
|
ifeq ($(shell $(CXX) --version | grep clang >/dev/null 2>&1; echo $$?),0)
|
||||||
override CXX_IS_CLANG := true
|
override CXX_IS_CLANG := true
|
||||||
|
@ -48,10 +59,18 @@ override CXX_VERSION_MAJOR := $(shell echo $(CXX_VERSION) | cut -d '.' -f 1)
|
||||||
|
|
||||||
CLANG_WORKS = false
|
CLANG_WORKS = false
|
||||||
GCC_WORKS = false
|
GCC_WORKS = false
|
||||||
|
MIN_CLANG_VERSION = 16
|
||||||
|
|
||||||
|
ifeq ($(DEBUG),true)
|
||||||
|
override ADDFLAGS += -DBTOP_DEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
#? Supported is Clang 16.0.0 and later
|
#? Supported is Clang 16.0.0 and later
|
||||||
ifeq ($(CXX_IS_CLANG),true)
|
ifeq ($(CXX_IS_CLANG),true)
|
||||||
ifneq ($(shell test $(CXX_VERSION_MAJOR) -lt 16; echo $$?),0)
|
ifeq ($(shell $(CXX) --version | grep Apple >/dev/null 2>&1; echo $$?),0)
|
||||||
|
MIN_CLANG_VERSION := 15
|
||||||
|
endif
|
||||||
|
ifneq ($(shell test $(CXX_VERSION_MAJOR) -lt $(MIN_CLANG_VERSION); echo $$?),0)
|
||||||
CLANG_WORKS := true
|
CLANG_WORKS := true
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -214,24 +233,38 @@ endif
|
||||||
|
|
||||||
P := %%
|
P := %%
|
||||||
|
|
||||||
#? Default Make
|
ifeq ($(VERBOSE),true)
|
||||||
all: $(PRE) directories btop
|
# Doesn't work with `&>`
|
||||||
|
override SUPPRESS := > /dev/null 2> /dev/null
|
||||||
|
else
|
||||||
|
override SUPPRESS :=
|
||||||
|
endif
|
||||||
|
|
||||||
|
#? Default Make
|
||||||
|
.ONESHELL:
|
||||||
|
all: | info rocm_smi info-quiet directories btop
|
||||||
|
|
||||||
|
ifneq ($(QUIET),true)
|
||||||
info:
|
info:
|
||||||
@printf " $(BANNER)\n"
|
@printf " $(BANNER)\n"
|
||||||
@printf "\033[1;92mPLATFORM \033[1;93m?| \033[0m$(PLATFORM)\n"
|
@printf "\033[1;92mPLATFORM \033[1;93m?| \033[0m$(PLATFORM)\n"
|
||||||
@printf "\033[1;96mARCH \033[1;93m?| \033[0m$(ARCH)\n"
|
@printf "\033[1;96mARCH \033[1;93m?| \033[0m$(ARCH)\n"
|
||||||
@printf "\033[1;93mCXX \033[1;93m?| \033[0m$(CXX) \033[1;93m(\033[97m$(CXX_VERSION)\033[93m)\n"
|
@printf "\033[1;95mGPU_SUPPORT \033[1;94m:| \033[0m$(GPU_SUPPORT)\n"
|
||||||
@printf "\033[1;94mTHREADS \033[1;94m:| \033[0m$(THREADS)\n"
|
@printf "\033[1;93mCXX \033[1;93m?| \033[0m$(CXX) \033[1;93m(\033[97m$(CXX_VERSION)\033[93m)\n"
|
||||||
@printf "\033[1;92mREQFLAGS \033[1;91m!| \033[0m$(REQFLAGS)\n"
|
@printf "\033[1;94mTHREADS \033[1;94m:| \033[0m$(THREADS)\n"
|
||||||
@printf "\033[1;91mWARNFLAGS \033[1;94m:| \033[0m$(WARNFLAGS)\n"
|
@printf "\033[1;92mREQFLAGS \033[1;91m!| \033[0m$(REQFLAGS)\n"
|
||||||
@printf "\033[1;94mOPTFLAGS \033[1;94m:| \033[0m$(OPTFLAGS)\n"
|
@printf "\033[1;91mWARNFLAGS \033[1;94m:| \033[0m$(WARNFLAGS)\n"
|
||||||
@printf "\033[1;93mLDCXXFLAGS \033[1;94m:| \033[0m$(LDCXXFLAGS)\n"
|
@printf "\033[1;94mOPTFLAGS \033[1;94m:| \033[0m$(OPTFLAGS)\n"
|
||||||
@printf "\033[1;95mCXXFLAGS \033[1;92m+| \033[0;37m\$$(\033[92mREQFLAGS\033[37m) \$$(\033[93mLDCXXFLAGS\033[37m) \$$(\033[94mOPTFLAGS\033[37m) \$$(\033[91mWARNFLAGS\033[37m) $(OLDCXX)\n"
|
@printf "\033[1;93mLDCXXFLAGS \033[1;94m:| \033[0m$(LDCXXFLAGS)\n"
|
||||||
@printf "\033[1;95mLDFLAGS \033[1;92m+| \033[0;37m\$$(\033[93mLDCXXFLAGS\033[37m) \$$(\033[94mOPTFLAGS\033[37m) \$$(\033[91mWARNFLAGS\033[37m) $(OLDLD)\n"
|
@printf "\033[1;95mCXXFLAGS \033[1;92m+| \033[0;37m\$$(\033[92mREQFLAGS\033[37m) \$$(\033[93mLDCXXFLAGS\033[37m) \$$(\033[94mOPTFLAGS\033[37m) \$$(\033[91mWARNFLAGS\033[37m) $(OLDCXX)\n"
|
||||||
|
@printf "\033[1;95mLDFLAGS \033[1;92m+| \033[0;37m\$$(\033[93mLDCXXFLAGS\033[37m) \$$(\033[94mOPTFLAGS\033[37m) \$$(\033[91mWARNFLAGS\033[37m) $(OLDLD)\n"
|
||||||
|
else
|
||||||
|
info:
|
||||||
|
@true
|
||||||
|
endif
|
||||||
|
|
||||||
info-quiet:
|
|
||||||
@sleep 0.1 2>/dev/null || true
|
info-quiet: | info rocm_smi
|
||||||
@printf "\n\033[1;92mBuilding btop++ \033[91m(\033[97mv$(BTOP_VERSION)\033[91m) \033[93m$(PLATFORM) \033[96m$(ARCH)\033[0m\n"
|
@printf "\n\033[1;92mBuilding btop++ \033[91m(\033[97mv$(BTOP_VERSION)\033[91m) \033[93m$(PLATFORM) \033[96m$(ARCH)\033[0m\n"
|
||||||
|
|
||||||
help:
|
help:
|
||||||
|
@ -258,11 +291,13 @@ directories:
|
||||||
clean:
|
clean:
|
||||||
@printf "\033[1;91mRemoving: \033[1;97mbuilt objects...\033[0m\n"
|
@printf "\033[1;91mRemoving: \033[1;97mbuilt objects...\033[0m\n"
|
||||||
@rm -rf $(BUILDDIR)
|
@rm -rf $(BUILDDIR)
|
||||||
|
@test -e lib/rocm_smi_lib/build && cmake --build lib/rocm_smi_lib/build --target clean &> /dev/null || true
|
||||||
|
|
||||||
#? Clean Objects and Binaries
|
#? Clean Objects and Binaries
|
||||||
distclean: clean
|
distclean: clean
|
||||||
@printf "\033[1;91mRemoving: \033[1;97mbuilt binaries...\033[0m\n"
|
@printf "\033[1;91mRemoving: \033[1;97mbuilt binaries...\033[0m\n"
|
||||||
@rm -rf $(TARGETDIR)
|
@rm -rf $(TARGETDIR)
|
||||||
|
@test -e lib/rocm_smi_lib/build && rm -rf lib/rocm_smi_lib/build || true
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@printf "\033[1;92mInstalling binary to: \033[1;97m$(DESTDIR)$(PREFIX)/bin/btop\n"
|
@printf "\033[1;92mInstalling binary to: \033[1;97m$(DESTDIR)$(PREFIX)/bin/btop\n"
|
||||||
|
@ -308,9 +343,35 @@ uninstall:
|
||||||
#? Pull in dependency info for *existing* .o files
|
#? Pull in dependency info for *existing* .o files
|
||||||
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
|
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
|
||||||
|
|
||||||
|
#? Compile rocm_smi
|
||||||
|
ifeq ($(GPU_SUPPORT)$(RSMI_STATIC),truetrue)
|
||||||
|
ROCM_DIR ?= lib/rocm_smi_lib
|
||||||
|
ROCM_BUILD_DIR := $(ROCM_DIR)/build
|
||||||
|
ifeq ($(DEBUG),true)
|
||||||
|
BUILD_TYPE := Debug
|
||||||
|
else
|
||||||
|
BUILD_TYPE := Release
|
||||||
|
endif
|
||||||
|
.ONESHELL:
|
||||||
|
rocm_smi:
|
||||||
|
@printf "\n\033[1;92mBuilding ROCm SMI static library\033[37m...\033[0m\n"
|
||||||
|
@TSTAMP=$$(date +%s 2>/dev/null || echo "0")
|
||||||
|
@$(QUIET) || printf "\033[1;97mRunning CMake...\033[0m\n"
|
||||||
|
CXX=$(CXX) cmake -S $(ROCM_DIR) -B $(ROCM_BUILD_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DBUILD_SHARED_LIBS=OFF $(SUPPRESS) || { printf "\033[1;91mCMake failed, continuing build without statically linking ROCm SMI\033[37m...\033[0m\n"; exit 0; }
|
||||||
|
@$(QUIET) || printf "\n\033[1;97mBuilding and linking...\033[0m\n"
|
||||||
|
@cmake --build $(ROCM_BUILD_DIR) -j -t rocm_smi64 $(SUPPRESS) || { printf "\033[1;91mMake failed, continuing build without statically linking ROCm SMI\033[37m...\033[0m\n"; exit 0; }
|
||||||
|
@printf "\033[1;92m100$(P)\033[10D\033[5C-> \033[1;37m$(ROCM_BUILD_DIR)/rocm_smi/librocm_smi64.a \033[1;93m(\033[1;97m$$(du -ah $(ROCM_BUILD_DIR)/rocm_smi/librocm_smi64.a | cut -f1)iB\033[1;93m)\033[0m\n"
|
||||||
|
@printf "\033[1;92mROCm SMI build complete in \033[92m(\033[97m$$($(DATE_CMD) -d @$$(expr $$(date +%s 2>/dev/null || echo "0") - $(TIMESTAMP) 2>/dev/null) -u +%Mm:%Ss 2>/dev/null | sed 's/^00m://' || echo "unknown")\033[92m)\033[0m\n"
|
||||||
|
@$(eval override LDFLAGS += $(ROCM_BUILD_DIR)/rocm_smi/librocm_smi64.a -DRSMI_STATIC) # TODO: this seems to execute every time, no matter if the compilation failed or succeeded
|
||||||
|
@$(eval override CXXFLAGS += -DRSMI_STATIC)
|
||||||
|
else
|
||||||
|
rocm_smi:
|
||||||
|
@true
|
||||||
|
endif
|
||||||
|
|
||||||
#? Link
|
#? Link
|
||||||
.ONESHELL:
|
.ONESHELL:
|
||||||
btop: $(OBJECTS) | directories
|
btop: $(OBJECTS) | rocm_smi directories
|
||||||
@sleep 0.2 2>/dev/null || true
|
@sleep 0.2 2>/dev/null || true
|
||||||
@TSTAMP=$$(date +%s 2>/dev/null || echo "0")
|
@TSTAMP=$$(date +%s 2>/dev/null || echo "0")
|
||||||
@$(QUIET) || printf "\n\033[1;92mLinking and optimizing binary\033[37m...\033[0m\n"
|
@$(QUIET) || printf "\n\033[1;92mLinking and optimizing binary\033[37m...\033[0m\n"
|
||||||
|
@ -321,7 +382,7 @@ btop: $(OBJECTS) | directories
|
||||||
|
|
||||||
#? Compile
|
#? Compile
|
||||||
.ONESHELL:
|
.ONESHELL:
|
||||||
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) | directories
|
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) | rocm_smi directories
|
||||||
@sleep 0.3 2>/dev/null || true
|
@sleep 0.3 2>/dev/null || true
|
||||||
@TSTAMP=$$(date +%s 2>/dev/null || echo "0")
|
@TSTAMP=$$(date +%s 2>/dev/null || echo "0")
|
||||||
@$(QUIET) || printf "\033[1;97mCompiling $<\033[0m\n"
|
@$(QUIET) || printf "\033[1;97mCompiling $<\033[0m\n"
|
||||||
|
|
459
README.md
459
README.md
|
@ -33,12 +33,33 @@
|
||||||
* [Compilation Linux](#compilation-linux)
|
* [Compilation Linux](#compilation-linux)
|
||||||
* [Compilation macOS](#compilation-macos-osx)
|
* [Compilation macOS](#compilation-macos-osx)
|
||||||
* [Compilation FreeBSD](#compilation-freebsd)
|
* [Compilation FreeBSD](#compilation-freebsd)
|
||||||
|
* [GPU compatibility](#gpu-compatibility)
|
||||||
* [Installing the snap](#installing-the-snap)
|
* [Installing the snap](#installing-the-snap)
|
||||||
* [Configurability](#configurability)
|
* [Configurability](#configurability)
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
|
|
||||||
## News
|
## News
|
||||||
|
|
||||||
|
##### 25 November 2023
|
||||||
|
|
||||||
|
GPU monitoring added for Linux!
|
||||||
|
|
||||||
|
Compile from git main to try it out.
|
||||||
|
|
||||||
|
Use keys `5`, `6`, `7` and `0` to show/hide the gpu monitoring boxes. `5` = Gpu 1, `6` = Gpu 2, etc.
|
||||||
|
|
||||||
|
Gpu stats/graphs can also be displayed in the "Cpu box" (not as verbose), see the cpu options menu for info and configuration.
|
||||||
|
|
||||||
|
Note that the binaries provided on the release page (when released) and the continuous builds will not have gpu support enabled.
|
||||||
|
|
||||||
|
Because the GPU support relies on loading of dynamic gpu libraries, gpu support will not work when also static linking.
|
||||||
|
|
||||||
|
See [Compilation Linux](#compilation-linux) for more info on how to compile with gpu monitoring support.
|
||||||
|
|
||||||
|
Many thanks to [@romner-set](https://github.com/romner-set) who wrote the vast majority of the implementation for GPU support.
|
||||||
|
|
||||||
|
Big update with version bump to 1.3 coming soon.
|
||||||
|
|
||||||
##### 28 August 2022
|
##### 28 August 2022
|
||||||
|
|
||||||
[![btop4win](https://github.com/aristocratos/btop4win/raw/master/Img/logo.png)](https://github.com/aristocratos/btop4win)
|
[![btop4win](https://github.com/aristocratos/btop4win/raw/master/Img/logo.png)](https://github.com/aristocratos/btop4win)
|
||||||
|
@ -305,16 +326,46 @@ Also needs a UTF8 locale and a font that covers:
|
||||||
|
|
||||||
## Compilation Linux
|
## Compilation Linux
|
||||||
|
|
||||||
Needs GCC 10 or higher, (GCC 11 or above strongly recommended for better CPU efficiency in the compiled binary).
|
Requires at least GCC 10 or Clang 16.
|
||||||
|
|
||||||
The makefile also needs GNU coreutils and `sed` (should already be installed on any modern distribution).
|
The makefile also needs GNU coreutils and `sed` (should already be installed on any modern distribution).
|
||||||
|
|
||||||
For a `cmake` based build alternative see the [fork](https://github.com/jan-guenter/btop/tree/main) by @jan-guenter
|
### GPU compatibility
|
||||||
|
|
||||||
|
Btop++ supports NVIDIA and AMD GPUs out of the box on Linux x86_64, provided you have the correct drivers and libraries.
|
||||||
|
|
||||||
|
Compatibility with Intel GPUs using generic DRM calls is planned, as is compatibility for FreeBSD and macOS.
|
||||||
|
|
||||||
|
Gpu support will not work when static linking glibc (or musl, etc.)!
|
||||||
|
|
||||||
|
For x86_64 Linux the flag `GPU_SUPPORT` is automatically set to `true`, to manually disable gpu support set the flag to false, like:
|
||||||
|
|
||||||
|
`make GPU_SUPPORT=false` (or `cmake -DBTOP_GPU=false` with CMake)
|
||||||
|
|
||||||
|
* **NVIDIA**
|
||||||
|
|
||||||
|
You must use an official NVIDIA driver, both the closed-source and [open-source](https://github.com/NVIDIA/open-gpu-kernel-modules) ones have been verified to work.
|
||||||
|
|
||||||
|
In addition to that you must also have the `nvidia-ml` dynamic library installed, which should be included with the driver package of your distribution.
|
||||||
|
|
||||||
|
* **AMD**
|
||||||
|
|
||||||
|
AMDGPU data is queried using the [ROCm SMI](https://github.com/RadeonOpenCompute/rocm_smi_lib) library, which may or may not be packaged for your distribution. If your distribution doesn't provide a package, btop++ is statically linked to ROCm SMI with the `RSMI_STATIC=true` make flag.
|
||||||
|
|
||||||
|
This flag expects the ROCm SMI source code in `lib/rocm_smi_lib`, and compilation will fail if it's not there. The latest tested version is 5.6.x, which can be obtained with the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/RadeonOpenCompute/rocm_smi_lib.git --depth 1 -b rocm-5.6.x lib/rocm_smi_lib
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
### With Make
|
||||||
|
</summary>
|
||||||
|
|
||||||
1. **Install dependencies (example for Ubuntu 21.04 Hirsute)**
|
1. **Install dependencies (example for Ubuntu 21.04 Hirsute)**
|
||||||
|
|
||||||
Use gcc-10 g++-10 if gcc-11 isn't available
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install coreutils sed git build-essential gcc-11 g++-11
|
sudo apt install coreutils sed git build-essential gcc-11 g++-11
|
||||||
```
|
```
|
||||||
|
@ -328,51 +379,51 @@ Also needs a UTF8 locale and a font that covers:
|
||||||
|
|
||||||
3. **Compile**
|
3. **Compile**
|
||||||
|
|
||||||
Append `VERBOSE=true` to display full compiler/linker commands.
|
|
||||||
|
|
||||||
Append `STATIC=true` for static compilation.
|
|
||||||
|
|
||||||
Notice! If using LDAP Authentication, usernames will show as UID number for LDAP users if compiling statically with glibc.
|
|
||||||
|
|
||||||
Append `QUIET=true` for less verbose output.
|
|
||||||
|
|
||||||
Append `STRIP=true` to force stripping of debug symbols (adds `-s` linker flag).
|
|
||||||
|
|
||||||
Append `ARCH=<architecture>` to manually set the target architecture.
|
|
||||||
If omitted the makefile uses the machine triple (output of `-dumpmachine` compiler parameter) to detect the target system.
|
|
||||||
|
|
||||||
Use `ADDFLAGS` variable for appending flags to both compiler and linker.
|
|
||||||
|
|
||||||
For example: `ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
|
||||||
|
|
||||||
If `g++` is linked to an older version of gcc on your system specify the correct version by appending `CXX=g++-10` or `CXX=g++-11`.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Options for make:
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|---------------------------------|-------------------------------------------------------------------------|
|
||||||
|
| `VERBOSE=true` | To display full compiler/linker commands |
|
||||||
|
| `STATIC=true` | For static compilation |
|
||||||
|
| `QUIET=true` | For less verbose output |
|
||||||
|
| `STRIP=true` | To force stripping of debug symbols (adds `-s` linker flag) |
|
||||||
|
| `DEBUG=true` | Sets OPTFLAGS to `-O0 -g` and enables more verbose debug logging |
|
||||||
|
| `ARCH=<architecture>` | To manually set the target architecture |
|
||||||
|
| `GPU_SUPPORT=<true\|false>` | Enable/disable GPU support (Enabled by default on X86_64 Linux) |
|
||||||
|
| `RSMI_STATIC=true` | To statically link the ROCm SMI library used for querying AMDGPU |
|
||||||
|
| `ADDFLAGS=<flags>` | For appending flags to both compiler and linker |
|
||||||
|
| `CXX=<compiler>` | Manualy set which compiler to use |
|
||||||
|
|
||||||
|
Example: `make ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
||||||
|
|
||||||
|
Notice! If using LDAP Authentication, usernames will show as UID number for LDAP users if compiling statically with glibc.
|
||||||
|
|
||||||
4. **Install**
|
4. **Install**
|
||||||
|
|
||||||
Append `PREFIX=/target/dir` to set target, default: `/usr/local`
|
|
||||||
|
|
||||||
Notice! Only use "sudo" when installing to a NON user owned directory.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo make install
|
sudo make install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Append `PREFIX=/target/dir` to set target, default: `/usr/local`
|
||||||
|
|
||||||
|
Notice! Only use "sudo" when installing to a NON user owned directory.
|
||||||
|
|
||||||
5. **(Optional) Set suid bit to make btop always run as root (or other user)**
|
5. **(Optional) Set suid bit to make btop always run as root (or other user)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo make setuid
|
||||||
|
```
|
||||||
|
|
||||||
No need for `sudo` to enable signal sending to any process and to prevent /proc read permissions problems on some systems.
|
No need for `sudo` to enable signal sending to any process and to prevent /proc read permissions problems on some systems.
|
||||||
|
|
||||||
Run after make install and use same PREFIX if any was used at install.
|
Run after make install and use same PREFIX if any was used at install.
|
||||||
|
|
||||||
Set `SU_USER` and `SU_GROUP` to select user and group, default is `root` and `root`
|
Set `SU_USER` and `SU_GROUP` to select user and group, default is `root` and `root`
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo make setuid
|
|
||||||
```
|
|
||||||
|
|
||||||
* **Uninstall**
|
* **Uninstall**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -397,16 +448,94 @@ Also needs a UTF8 locale and a font that covers:
|
||||||
make help
|
make help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
### With CMake (Community maintained)
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
1. **Install build dependencies**
|
||||||
|
|
||||||
|
Requires Clang / GCC, CMake, Ninja and Git
|
||||||
|
|
||||||
|
For example, with Debian Bookworm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install cmake git g++ ninja-build
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Clone the repository**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/aristocratos/btop.git && cd btop
|
||||||
|
``````
|
||||||
|
|
||||||
|
3. **Compile**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Configure
|
||||||
|
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_STATIC=<ON\|OFF>` | Enables static linking (OFF by default) |
|
||||||
|
| `-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_GPU=<ON\|OFF>` | Enable GPU support (ON by default) |
|
||||||
|
| `-DBTOP_RSMI_STATIC=<ON\|OFF>` | Build and link the ROCm SMI library statically (OFF 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>
|
||||||
|
|
||||||
## Compilation macOS OSX
|
## Compilation macOS OSX
|
||||||
|
|
||||||
Needs GCC 10 or higher, (GCC 11 or above strongly recommended for better CPU efficiency in the compiled binary).
|
Requires at least GCC 10 or Clang 16.
|
||||||
|
|
||||||
GCC 12 needed for macOS Ventura. If you get linker errors on Ventura you'll need to upgrade your command line tools (Version 14.0) is bugged.
|
With GCC, version 12 (or better) is needed for macOS Ventura. If you get linker errors on Ventura you'll need to upgrade your command line tools (Version 14.0) is bugged.
|
||||||
|
|
||||||
The makefile also needs GNU coreutils and `sed`.
|
The makefile also needs GNU coreutils and `sed`.
|
||||||
|
|
||||||
Install and use Homebrew or MacPorts package managers for easy dependency installation
|
Install and use Homebrew or MacPorts package managers for easy dependency installation
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
### With Make
|
||||||
|
</summary>
|
||||||
|
|
||||||
1. **Install dependencies (example for Homebrew)**
|
1. **Install dependencies (example for Homebrew)**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -419,50 +548,49 @@ Also needs a UTF8 locale and a font that covers:
|
||||||
git clone https://github.com/aristocratos/btop.git
|
git clone https://github.com/aristocratos/btop.git
|
||||||
cd btop
|
cd btop
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Compile**
|
3. **Compile**
|
||||||
|
|
||||||
Append `VERBOSE=true` to display full compiler/linker commands.
|
|
||||||
|
|
||||||
Append `STATIC=true` for static compilation (only libgcc and libstdc++ will be static!).
|
|
||||||
|
|
||||||
Append `QUIET=true` for less verbose output.
|
|
||||||
|
|
||||||
Append `STRIP=true` to force stripping of debug symbols (adds `-s` linker flag).
|
|
||||||
|
|
||||||
Append `ARCH=<architecture>` to manually set the target architecture.
|
|
||||||
If omitted the makefile uses the machine triple (output of `-dumpmachine` compiler parameter) to detect the target system.
|
|
||||||
|
|
||||||
Use `ADDFLAGS` variable for appending flags to both compiler and linker.
|
|
||||||
|
|
||||||
For example: `ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gmake
|
gmake
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Options for make:
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|---------------------------------|-------------------------------------------------------------------------|
|
||||||
|
| `VERBOSE=true` | To display full compiler/linker commands |
|
||||||
|
| `STATIC=true` | For static compilation (only libgcc and libstdc++) |
|
||||||
|
| `QUIET=true` | For less verbose output |
|
||||||
|
| `STRIP=true` | To force stripping of debug symbols (adds `-s` linker flag) |
|
||||||
|
| `DEBUG=true` | Sets OPTFLAGS to `-O0 -g` and enables more verbose debug logging |
|
||||||
|
| `ARCH=<architecture>` | To manually set the target architecture |
|
||||||
|
| `ADDFLAGS=<flags>` | For appending flags to both compiler and linker |
|
||||||
|
| `CXX=<compiler>` | Manualy set which compiler to use |
|
||||||
|
|
||||||
|
Example: `gmake ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
||||||
|
|
||||||
4. **Install**
|
4. **Install**
|
||||||
|
|
||||||
Append `PREFIX=/target/dir` to set target, default: `/usr/local`
|
|
||||||
|
|
||||||
Notice! Only use "sudo" when installing to a NON user owned directory.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo gmake install
|
sudo gmake install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Append `PREFIX=/target/dir` to set target, default: `/usr/local`
|
||||||
|
|
||||||
|
Notice! Only use "sudo" when installing to a NON user owned directory.
|
||||||
|
|
||||||
5. **(Recommended) Set suid bit to make btop always run as root (or other user)**
|
5. **(Recommended) Set suid bit to make btop always run as root (or other user)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo gmake setuid
|
||||||
|
```
|
||||||
|
|
||||||
No need for `sudo` to see information for non user owned processes and to enable signal sending to any process.
|
No need for `sudo` to see information for non user owned processes and to enable signal sending to any process.
|
||||||
|
|
||||||
Run after make install and use same PREFIX if any was used at install.
|
Run after make install and use same PREFIX if any was used at install.
|
||||||
|
|
||||||
Set `SU_USER` and `SU_GROUP` to select user and group, default is `root` and `wheel`
|
Set `SU_USER` and `SU_GROUP` to select user and group, default is `root` and `wheel`
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo gmake setuid
|
|
||||||
```
|
|
||||||
|
|
||||||
* **Uninstall**
|
* **Uninstall**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -487,12 +615,92 @@ Also needs a UTF8 locale and a font that covers:
|
||||||
gmake help
|
gmake help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
### With CMake (Community maintained)
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
1. **Install build dependencies**
|
||||||
|
|
||||||
|
Requires Clang, CMake, Ninja and Git
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew update --quiet
|
||||||
|
brew install cmake git llvm ninja
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Clone the repository**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/aristocratos/btop.git && cd btop
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Compile**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Configure
|
||||||
|
export LLVM_PREFIX="$(brew --prefix llvm)"
|
||||||
|
export CXX="$LLVM_PREFIX/bin/clang++"
|
||||||
|
export CPPFLAGS="-I$LLVM_PREFIX/include"
|
||||||
|
export LDFLAGS="-L$LLVM_PREFIX/lib -L$LLVM_PREFIX/lib/c++ -Wl,-rpath,$LLVM_PREFIX/lib/c++ -fuse-ld=$LLVM_PREFIX/bin/ld64.lld"
|
||||||
|
cmake -B build -G Ninja
|
||||||
|
# Build
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
_**Note:** btop uses lots of C++ 20 features, so it's necessary to be specific about the compiler and the standard library. If you get a compile with Apple-Clang or GCC, feel free to add the instructions here._
|
||||||
|
|
||||||
|
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) |
|
||||||
|
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
|
||||||
|
|
||||||
|
To force any specific 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>
|
||||||
|
|
||||||
## Compilation FreeBSD
|
## Compilation FreeBSD
|
||||||
|
|
||||||
Needs GCC 10 or higher, (GCC 11 or above strongly recommended for better CPU efficiency in the compiled binary).
|
Requires at least GCC 10 or Clang 16.
|
||||||
|
|
||||||
Note that GNU make (`gmake`) is required to compile on FreeBSD.
|
Note that GNU make (`gmake`) is required to compile on FreeBSD.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
### With gmake
|
||||||
|
</summary>
|
||||||
|
|
||||||
1. **Install dependencies**
|
1. **Install dependencies**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -508,47 +716,47 @@ Also needs a UTF8 locale and a font that covers:
|
||||||
|
|
||||||
3. **Compile**
|
3. **Compile**
|
||||||
|
|
||||||
Append `VERBOSE=true` to display full compiler/linker commands.
|
|
||||||
|
|
||||||
Append `STATIC=true` for static compilation (only libgcc and libstdc++ will be static!).
|
|
||||||
|
|
||||||
Append `QUIET=true` for less verbose output.
|
|
||||||
|
|
||||||
Append `STRIP=true` to force stripping of debug symbols (adds `-s` linker flag).
|
|
||||||
|
|
||||||
Append `ARCH=<architecture>` to manually set the target architecture.
|
|
||||||
If omitted the makefile uses the machine triple (output of `-dumpmachine` compiler parameter) to detect the target system.
|
|
||||||
|
|
||||||
Use `ADDFLAGS` variable for appending flags to both compiler and linker.
|
|
||||||
|
|
||||||
For example: `ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gmake
|
gmake
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Options for make:
|
||||||
|
|
||||||
|
| Flag | Description |
|
||||||
|
|---------------------------------|-------------------------------------------------------------------------|
|
||||||
|
| `VERBOSE=true` | To display full compiler/linker commands |
|
||||||
|
| `STATIC=true` | For static compilation (only libgcc and libstdc++) |
|
||||||
|
| `QUIET=true` | For less verbose output |
|
||||||
|
| `STRIP=true` | To force stripping of debug symbols (adds `-s` linker flag) |
|
||||||
|
| `DEBUG=true` | Sets OPTFLAGS to `-O0 -g` and enables more verbose debug logging |
|
||||||
|
| `ARCH=<architecture>` | To manually set the target architecture |
|
||||||
|
| `ADDFLAGS=<flags>` | For appending flags to both compiler and linker |
|
||||||
|
| `CXX=<compiler>` | Manualy set which compiler to use |
|
||||||
|
|
||||||
|
Example: `gmake ADDFLAGS=-march=native` might give a performance boost if compiling only for your own system.
|
||||||
|
|
||||||
4. **Install**
|
4. **Install**
|
||||||
|
|
||||||
Append `PREFIX=/target/dir` to set target, default: `/usr/local`
|
|
||||||
|
|
||||||
Notice! Only use "sudo" when installing to a NON user owned directory.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo gmake install
|
sudo gmake install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Append `PREFIX=/target/dir` to set target, default: `/usr/local`
|
||||||
|
|
||||||
|
Notice! Only use "sudo" when installing to a NON user owned directory.
|
||||||
|
|
||||||
5. **(Recommended) Set suid bit to make btop always run as root (or other user)**
|
5. **(Recommended) Set suid bit to make btop always run as root (or other user)**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo gmake setuid
|
||||||
|
```
|
||||||
|
|
||||||
No need for `sudo` to see information for non user owned processes and to enable signal sending to any process.
|
No need for `sudo` to see information for non user owned processes and to enable signal sending to any process.
|
||||||
|
|
||||||
Run after make install and use same PREFIX if any was used at install.
|
Run after make install and use same PREFIX if any was used at install.
|
||||||
|
|
||||||
Set `SU_USER` and `SU_GROUP` to select user and group, default is `root` and `wheel`
|
Set `SU_USER` and `SU_GROUP` to select user and group, default is `root` and `wheel`
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo gmake setuid
|
|
||||||
```
|
|
||||||
|
|
||||||
* **Uninstall**
|
* **Uninstall**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -573,6 +781,93 @@ Also needs a UTF8 locale and a font that covers:
|
||||||
gmake help
|
gmake help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
|
||||||
|
### With CMake (Community maintained)
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
1. **Install build dependencies**
|
||||||
|
|
||||||
|
Requires Clang / GCC, CMake, Ninja and Git
|
||||||
|
|
||||||
|
_**Note:** LLVM's libc++ shipped with FreeBSD 13 is too old and cannot compile btop._
|
||||||
|
|
||||||
|
FreeBSD 14 and later:
|
||||||
|
```bash
|
||||||
|
pkg install cmake ninja
|
||||||
|
```
|
||||||
|
|
||||||
|
FreeBSD 13:
|
||||||
|
```bash
|
||||||
|
pkg install cmake gcc13 ninja
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Clone the repository**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/aristocratos/btop.git && cd btop
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Compile**
|
||||||
|
|
||||||
|
FreeBSD 14 and later:
|
||||||
|
```bash
|
||||||
|
# Configure
|
||||||
|
cmake -B build -G Ninja
|
||||||
|
# Build
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
FreeBSD 13:
|
||||||
|
```bash
|
||||||
|
# Configure
|
||||||
|
CXX=g++13 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_STATIC=<ON\|OFF>` | Enables static linking (OFF by default) |
|
||||||
|
| `-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) |
|
||||||
|
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
|
||||||
|
|
||||||
|
_**Note:** Static linking does not work with GCC._
|
||||||
|
|
||||||
|
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
|
## Installing the snap
|
||||||
[![btop](https://snapcraft.io/btop/badge.svg)](https://snapcraft.io/btop)
|
[![btop](https://snapcraft.io/btop/badge.svg)](https://snapcraft.io/btop)
|
||||||
|
|
||||||
|
@ -657,7 +952,7 @@ graph_symbol_net = "default"
|
||||||
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
|
||||||
graph_symbol_proc = "default"
|
graph_symbol_proc = "default"
|
||||||
|
|
||||||
#* Manually set which boxes to show. Available values are "cpu mem net proc", separate values with whitespace.
|
#* Manually set which boxes to show. Available values are "cpu mem net proc" and "gpu0" through "gpu5", separate values with whitespace.
|
||||||
shown_boxes = "proc cpu mem net"
|
shown_boxes = "proc cpu mem net"
|
||||||
|
|
||||||
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
|
#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs.
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# Find devstat, the Device Statistics Library
|
||||||
|
#
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||||
|
find_path(devstat_INCLUDE_DIR NAMES devstat.h)
|
||||||
|
find_library(devstat_LIBRARY NAMES devstat)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(devstat REQUIRED_VARS devstat_LIBRARY devstat_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if(devstat_FOUND AND NOT TARGET devstat::devstat)
|
||||||
|
add_library(devstat::devstat UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(devstat::devstat PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${devstat_LIBRARY}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${devstat_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(devstat_INCLUDE_DIR devstat_LIBRARY)
|
||||||
|
endif()
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# Find libelf, the ELF Access Library
|
||||||
|
#
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||||
|
find_path(elf_INCLUDE_DIR NAMES libelf.h)
|
||||||
|
find_library(elf_LIBRARY NAMES elf)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(elf REQUIRED_VARS elf_LIBRARY elf_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if(elf_FOUND AND NOT TARGET elf::elf)
|
||||||
|
add_library(elf::elf UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(elf::elf PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${elf_LIBRARY}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${elf_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(elf_INCLUDE_DIR elf_LIBRARY)
|
||||||
|
endif()
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# Find libkvm, the Kernel Data Access Library
|
||||||
|
#
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||||
|
find_path(kvm_INCLUDE_DIR NAMES kvm.h)
|
||||||
|
find_library(kvm_LIBRARY NAMES kvm)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(kvm REQUIRED_VARS kvm_LIBRARY kvm_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if(kvm_FOUND AND NOT TARGET kvm::kvm)
|
||||||
|
add_library(kvm::kvm UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(kvm::kvm PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${kvm_LIBRARY}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${kvm_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(kvm_INCLUDE_DIR kvm_LIBRARY)
|
||||||
|
endif()
|
||||||
|
|
2544
include/robin_hood.h
2544
include/robin_hood.h
File diff suppressed because it is too large
Load Diff
|
@ -37,6 +37,7 @@ apps:
|
||||||
- network-observe
|
- network-observe
|
||||||
- home
|
- home
|
||||||
- removable-media
|
- removable-media
|
||||||
|
- opengl
|
||||||
|
|
||||||
parts:
|
parts:
|
||||||
btop:
|
btop:
|
||||||
|
@ -47,7 +48,6 @@ parts:
|
||||||
- PREFIX=/usr/local
|
- PREFIX=/usr/local
|
||||||
- STATIC=true
|
- STATIC=true
|
||||||
- ADDFLAGS="-D SNAPPED"
|
- ADDFLAGS="-D SNAPPED"
|
||||||
|
|
||||||
build-packages:
|
build-packages:
|
||||||
- coreutils
|
- coreutils
|
||||||
- sed
|
- sed
|
||||||
|
|
109
src/btop.cpp
109
src/btop.cpp
|
@ -32,6 +32,7 @@ tab-size = 4
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <utility>
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
|
@ -75,7 +76,7 @@ namespace Global {
|
||||||
{"#801414", "██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ╚═╝"},
|
{"#801414", "██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ╚═╝"},
|
||||||
{"#000000", "╚═════╝ ╚═╝ ╚═════╝ ╚═╝"},
|
{"#000000", "╚═════╝ ╚═╝ ╚═════╝ ╚═╝"},
|
||||||
};
|
};
|
||||||
const string Version = "1.2.13";
|
const string Version = "1.3.0";
|
||||||
|
|
||||||
int coreCount;
|
int coreCount;
|
||||||
string overlay;
|
string overlay;
|
||||||
|
@ -183,8 +184,11 @@ void term_resize(bool force) {
|
||||||
if (force and refreshed) force = false;
|
if (force and refreshed) force = false;
|
||||||
}
|
}
|
||||||
else return;
|
else return;
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
static const array<string, 4> all_boxes = {"cpu", "mem", "net", "proc"};
|
static const array<string, 10> all_boxes = {"gpu5", "cpu", "mem", "net", "proc", "gpu0", "gpu1", "gpu2", "gpu3", "gpu4"};
|
||||||
|
#else
|
||||||
|
static const array<string, 5> all_boxes = {"", "cpu", "mem", "net", "proc"};
|
||||||
|
#endif
|
||||||
Global::resized = true;
|
Global::resized = true;
|
||||||
if (Runner::active) Runner::stop();
|
if (Runner::active) Runner::stop();
|
||||||
Term::refresh();
|
Term::refresh();
|
||||||
|
@ -222,10 +226,18 @@ void term_resize(bool force) {
|
||||||
auto key = Input::get();
|
auto key = Input::get();
|
||||||
if (key == "q")
|
if (key == "q")
|
||||||
clean_quit(0);
|
clean_quit(0);
|
||||||
else if (is_in(key, "1", "2", "3", "4")) {
|
else if (key.size() == 1 and isint(key)) {
|
||||||
Config::current_preset = -1;
|
auto intKey = stoi(key);
|
||||||
Config::toggle_box(all_boxes.at(std::stoi(key) - 1));
|
#ifdef GPU_SUPPORT
|
||||||
boxes = Config::getS("shown_boxes");
|
if ((intKey == 0 and Gpu::gpu_names.size() >= 5) or (intKey >= 5 and std::cmp_greater_equal(Gpu::gpu_names.size(), intKey - 4))) {
|
||||||
|
#else
|
||||||
|
if (intKey > 0 and intKey < 5) {
|
||||||
|
#endif
|
||||||
|
auto box = all_boxes.at(intKey);
|
||||||
|
Config::current_preset = -1;
|
||||||
|
Config::toggle_box(box);
|
||||||
|
boxes = Config::getS("shown_boxes");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
min_size = Term::get_min_size(boxes);
|
min_size = Term::get_min_size(boxes);
|
||||||
|
@ -258,6 +270,11 @@ void clean_quit(int sig) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
Gpu::Nvml::shutdown();
|
||||||
|
Gpu::Rsmi::shutdown();
|
||||||
|
#endif
|
||||||
|
|
||||||
Config::write();
|
Config::write();
|
||||||
|
|
||||||
if (Term::initialized) {
|
if (Term::initialized) {
|
||||||
|
@ -388,7 +405,9 @@ namespace Runner {
|
||||||
|
|
||||||
enum debug_actions {
|
enum debug_actions {
|
||||||
collect_begin,
|
collect_begin,
|
||||||
|
collect_done,
|
||||||
draw_begin,
|
draw_begin,
|
||||||
|
draw_begin_only,
|
||||||
draw_done
|
draw_done
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -398,7 +417,7 @@ namespace Runner {
|
||||||
};
|
};
|
||||||
|
|
||||||
string debug_bg;
|
string debug_bg;
|
||||||
unordered_flat_map<string, array<uint64_t, 2>> debug_times;
|
std::unordered_map<string, array<uint64_t, 2>> debug_times;
|
||||||
|
|
||||||
class MyNumPunct : public std::numpunct<char>
|
class MyNumPunct : public std::numpunct<char>
|
||||||
{
|
{
|
||||||
|
@ -424,6 +443,13 @@ namespace Runner {
|
||||||
case collect_begin:
|
case collect_begin:
|
||||||
debug_times[name].at(collect) = time_micros();
|
debug_times[name].at(collect) = time_micros();
|
||||||
return;
|
return;
|
||||||
|
case collect_done:
|
||||||
|
debug_times[name].at(collect) = time_micros() - debug_times[name].at(collect);
|
||||||
|
debug_times["total"].at(collect) += debug_times[name].at(collect);
|
||||||
|
return;
|
||||||
|
case draw_begin_only:
|
||||||
|
debug_times[name].at(draw) = time_micros();
|
||||||
|
return;
|
||||||
case draw_begin:
|
case draw_begin:
|
||||||
debug_times[name].at(draw) = time_micros();
|
debug_times[name].at(draw) = time_micros();
|
||||||
debug_times[name].at(collect) = debug_times[name].at(draw) - debug_times[name].at(collect);
|
debug_times[name].at(collect) = debug_times[name].at(draw) - debug_times[name].at(collect);
|
||||||
|
@ -480,10 +506,14 @@ namespace Runner {
|
||||||
|
|
||||||
//! DEBUG stats
|
//! DEBUG stats
|
||||||
if (Global::debug) {
|
if (Global::debug) {
|
||||||
if (debug_bg.empty() or redraw)
|
if (debug_bg.empty() or redraw)
|
||||||
Runner::debug_bg = Draw::createBox(2, 2, 33, 8, "", true, "μs");
|
Runner::debug_bg = Draw::createBox(2, 2, 33,
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
9,
|
||||||
|
#else
|
||||||
|
8,
|
||||||
|
#endif
|
||||||
|
"", true, "μs");
|
||||||
|
|
||||||
debug_times.clear();
|
debug_times.clear();
|
||||||
debug_times["total"] = {0, 0};
|
debug_times["total"] = {0, 0};
|
||||||
|
@ -493,6 +523,29 @@ namespace Runner {
|
||||||
|
|
||||||
//* Run collection and draw functions for all boxes
|
//* Run collection and draw functions for all boxes
|
||||||
try {
|
try {
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
//? GPU data collection
|
||||||
|
const bool gpu_in_cpu_panel = Gpu::gpu_names.size() > 0 and (
|
||||||
|
Config::getS("cpu_graph_lower").starts_with("gpu-") or Config::getS("cpu_graph_upper").starts_with("gpu-")
|
||||||
|
or (Gpu::shown == 0 and Config::getS("show_gpu_info") != "Off")
|
||||||
|
);
|
||||||
|
|
||||||
|
vector<unsigned int> gpu_panels = {};
|
||||||
|
for (auto& box : conf.boxes)
|
||||||
|
if (box.starts_with("gpu"))
|
||||||
|
gpu_panels.push_back(box.back()-'0');
|
||||||
|
|
||||||
|
vector<Gpu::gpu_info> gpus;
|
||||||
|
if (gpu_in_cpu_panel or not gpu_panels.empty()) {
|
||||||
|
if (Global::debug) debug_timer("gpu", collect_begin);
|
||||||
|
gpus = Gpu::collect(conf.no_update);
|
||||||
|
if (Global::debug) debug_timer("gpu", collect_done);
|
||||||
|
}
|
||||||
|
auto& gpus_ref = gpus;
|
||||||
|
#else
|
||||||
|
vector<Gpu::gpu_info> gpus_ref{};
|
||||||
|
#endif
|
||||||
|
|
||||||
//? CPU
|
//? CPU
|
||||||
if (v_contains(conf.boxes, "cpu")) {
|
if (v_contains(conf.boxes, "cpu")) {
|
||||||
try {
|
try {
|
||||||
|
@ -512,7 +565,7 @@ namespace Runner {
|
||||||
if (Global::debug) debug_timer("cpu", draw_begin);
|
if (Global::debug) debug_timer("cpu", draw_begin);
|
||||||
|
|
||||||
//? Draw box
|
//? Draw box
|
||||||
if (not pause_output) output += Cpu::draw(cpu, conf.force_redraw, conf.no_update);
|
if (not pause_output) output += Cpu::draw(cpu, gpus_ref, conf.force_redraw, conf.no_update);
|
||||||
|
|
||||||
if (Global::debug) debug_timer("cpu", draw_done);
|
if (Global::debug) debug_timer("cpu", draw_done);
|
||||||
}
|
}
|
||||||
|
@ -520,7 +573,24 @@ namespace Runner {
|
||||||
throw std::runtime_error("Cpu:: -> " + string{e.what()});
|
throw std::runtime_error("Cpu:: -> " + string{e.what()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
//? GPU
|
||||||
|
if (not gpu_panels.empty() and not gpus_ref.empty()) {
|
||||||
|
try {
|
||||||
|
if (Global::debug) debug_timer("gpu", draw_begin_only);
|
||||||
|
|
||||||
|
//? Draw box
|
||||||
|
if (not pause_output)
|
||||||
|
for (unsigned long i = 0; i < gpu_panels.size(); ++i)
|
||||||
|
output += Gpu::draw(gpus_ref[gpu_panels[i]], i, conf.force_redraw, conf.no_update);
|
||||||
|
|
||||||
|
if (Global::debug) debug_timer("gpu", draw_done);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
throw std::runtime_error("Gpu:: -> " + string{e.what()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
//? MEM
|
//? MEM
|
||||||
if (v_contains(conf.boxes, "mem")) {
|
if (v_contains(conf.boxes, "mem")) {
|
||||||
try {
|
try {
|
||||||
|
@ -580,6 +650,7 @@ namespace Runner {
|
||||||
throw std::runtime_error("Proc:: -> " + string{e.what()});
|
throw std::runtime_error("Proc:: -> " + string{e.what()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
Global::exit_error_msg = "Exception in runner thread -> " + string{e.what()};
|
Global::exit_error_msg = "Exception in runner thread -> " + string{e.what()};
|
||||||
|
@ -610,8 +681,9 @@ namespace Runner {
|
||||||
"{mv3}{hiFg}2 {mainFg}| Show MEM box"
|
"{mv3}{hiFg}2 {mainFg}| Show MEM box"
|
||||||
"{mv4}{hiFg}3 {mainFg}| Show NET box"
|
"{mv4}{hiFg}3 {mainFg}| Show NET box"
|
||||||
"{mv5}{hiFg}4 {mainFg}| Show PROC box"
|
"{mv5}{hiFg}4 {mainFg}| Show PROC box"
|
||||||
"{mv6}{hiFg}esc {mainFg}| Show menu"
|
"{mv6}{hiFg}5-0 {mainFg}| Show GPU boxes"
|
||||||
"{mv7}{hiFg}q {mainFg}| Quit",
|
"{mv7}{hiFg}esc {mainFg}| Show menu"
|
||||||
|
"{mv8}{hiFg}q {mainFg}| Quit",
|
||||||
"banner"_a = Draw::banner_gen(y, 0, true),
|
"banner"_a = Draw::banner_gen(y, 0, true),
|
||||||
"titleFg"_a = Theme::c("title"), "b"_a = Fx::b, "hiFg"_a = Theme::c("hi_fg"), "mainFg"_a = Theme::c("main_fg"),
|
"titleFg"_a = Theme::c("title"), "b"_a = Fx::b, "hiFg"_a = Theme::c("hi_fg"), "mainFg"_a = Theme::c("main_fg"),
|
||||||
"mv1"_a = Mv::to(y+6, x),
|
"mv1"_a = Mv::to(y+6, x),
|
||||||
|
@ -620,7 +692,8 @@ namespace Runner {
|
||||||
"mv4"_a = Mv::to(y+10, x),
|
"mv4"_a = Mv::to(y+10, x),
|
||||||
"mv5"_a = Mv::to(y+11, x),
|
"mv5"_a = Mv::to(y+11, x),
|
||||||
"mv6"_a = Mv::to(y+12, x-2),
|
"mv6"_a = Mv::to(y+12, x-2),
|
||||||
"mv7"_a = Mv::to(y+13, x)
|
"mv7"_a = Mv::to(y+13, x-2),
|
||||||
|
"mv8"_a = Mv::to(y+14, x)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
output += empty_bg;
|
output += empty_bg;
|
||||||
|
@ -634,7 +707,11 @@ namespace Runner {
|
||||||
"post"_a = Theme::c("main_fg") + Fx::ub
|
"post"_a = Theme::c("main_fg") + Fx::ub
|
||||||
);
|
);
|
||||||
static auto loc = std::locale(std::locale::classic(), new MyNumPunct);
|
static auto loc = std::locale(std::locale::classic(), new MyNumPunct);
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
for (const string name : {"cpu", "mem", "net", "proc", "gpu", "total"}) {
|
||||||
|
#else
|
||||||
for (const string name : {"cpu", "mem", "net", "proc", "total"}) {
|
for (const string name : {"cpu", "mem", "net", "proc", "total"}) {
|
||||||
|
#endif
|
||||||
if (not debug_times.contains(name)) debug_times[name] = {0,0};
|
if (not debug_times.contains(name)) debug_times[name] = {0,0};
|
||||||
const auto& [time_collect, time_draw] = debug_times.at(name);
|
const auto& [time_collect, time_draw] = debug_times.at(name);
|
||||||
if (name == "total") output += Fx::b;
|
if (name == "total") output += Fx::b;
|
||||||
|
|
|
@ -21,6 +21,7 @@ tab-size = 4
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
|
|
||||||
|
@ -73,14 +74,16 @@ namespace Config {
|
||||||
"#* Note that \"tty\" only has half the horizontal resolution of the other two, so will show a shorter historical view."},
|
"#* Note that \"tty\" only has half the horizontal resolution of the other two, so will show a shorter historical view."},
|
||||||
|
|
||||||
{"graph_symbol_cpu", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
{"graph_symbol_cpu", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
{"graph_symbol_gpu", "# Graph symbol to use for graphs in gpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
||||||
|
#endif
|
||||||
{"graph_symbol_mem", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
{"graph_symbol_mem", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
||||||
|
|
||||||
{"graph_symbol_net", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
{"graph_symbol_net", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
||||||
|
|
||||||
{"graph_symbol_proc", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
{"graph_symbol_proc", "# Graph symbol to use for graphs in cpu box, \"default\", \"braille\", \"block\" or \"tty\"."},
|
||||||
|
|
||||||
{"shown_boxes", "#* Manually set which boxes to show. Available values are \"cpu mem net proc\", separate values with whitespace."},
|
{"shown_boxes", "#* Manually set which boxes to show. Available values are \"cpu mem net proc\" and \"gpu0\" through \"gpu5\", separate values with whitespace."},
|
||||||
|
|
||||||
{"update_ms", "#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs."},
|
{"update_ms", "#* Update time in milliseconds, recommended 2000 ms or above for better sample times for graphs."},
|
||||||
|
|
||||||
|
@ -107,12 +110,16 @@ namespace Config {
|
||||||
|
|
||||||
{"proc_filter_kernel", "#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop)."},
|
{"proc_filter_kernel", "#* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop)."},
|
||||||
|
|
||||||
|
{"proc_aggregate", "#* In tree-view, always accumulate child process resources in the parent process."},
|
||||||
|
|
||||||
{"cpu_graph_upper", "#* Sets the CPU stat shown in upper half of the CPU graph, \"total\" is always available.\n"
|
{"cpu_graph_upper", "#* Sets the CPU stat shown in upper half of the CPU graph, \"total\" is always available.\n"
|
||||||
"#* Select from a list of detected attributes from the options menu."},
|
"#* Select from a list of detected attributes from the options menu."},
|
||||||
|
|
||||||
{"cpu_graph_lower", "#* Sets the CPU stat shown in lower half of the CPU graph, \"total\" is always available.\n"
|
{"cpu_graph_lower", "#* Sets the CPU stat shown in lower half of the CPU graph, \"total\" is always available.\n"
|
||||||
"#* Select from a list of detected attributes from the options menu."},
|
"#* Select from a list of detected attributes from the options menu."},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
{"show_gpu_info", "#* If gpu info should be shown in the cpu box. Available values = \"Auto\", \"On\" and \"Off\"."},
|
||||||
|
#endif
|
||||||
{"cpu_invert_lower", "#* Toggles if the lower CPU graph should be inverted."},
|
{"cpu_invert_lower", "#* Toggles if the lower CPU graph should be inverted."},
|
||||||
|
|
||||||
{"cpu_single_graph", "#* Set to True to completely disable the lower CPU graph."},
|
{"cpu_single_graph", "#* Set to True to completely disable the lower CPU graph."},
|
||||||
|
@ -192,21 +199,36 @@ namespace Config {
|
||||||
{"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."},
|
{"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."},
|
||||||
|
|
||||||
{"log_level", "#* Set loglevel for \"~/.config/btop/btop.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
|
{"log_level", "#* Set loglevel for \"~/.config/btop/btop.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
|
||||||
"#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."}
|
"#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
|
||||||
|
{"nvml_measure_pcie_speeds",
|
||||||
|
"#* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards."},
|
||||||
|
|
||||||
|
{"gpu_mirror_graph", "#* Horizontally mirror the GPU graph."},
|
||||||
|
|
||||||
|
{"custom_gpu_name0", "#* Custom gpu0 model name, empty string to disable."},
|
||||||
|
{"custom_gpu_name1", "#* Custom gpu1 model name, empty string to disable."},
|
||||||
|
{"custom_gpu_name2", "#* Custom gpu2 model name, empty string to disable."},
|
||||||
|
{"custom_gpu_name3", "#* Custom gpu3 model name, empty string to disable."},
|
||||||
|
{"custom_gpu_name4", "#* Custom gpu4 model name, empty string to disable."},
|
||||||
|
{"custom_gpu_name5", "#* Custom gpu5 model name, empty string to disable."},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
unordered_flat_map<std::string_view, string> strings = {
|
std::unordered_map<std::string_view, string> strings = {
|
||||||
{"color_theme", "Default"},
|
{"color_theme", "Default"},
|
||||||
{"shown_boxes", "cpu mem net proc"},
|
{"shown_boxes", "cpu mem net proc"},
|
||||||
{"graph_symbol", "braille"},
|
{"graph_symbol", "braille"},
|
||||||
{"presets", "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"},
|
{"presets", "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:default cpu:0:block,net:0:tty"},
|
||||||
{"graph_symbol_cpu", "default"},
|
{"graph_symbol_cpu", "default"},
|
||||||
|
{"graph_symbol_gpu", "default"},
|
||||||
{"graph_symbol_mem", "default"},
|
{"graph_symbol_mem", "default"},
|
||||||
{"graph_symbol_net", "default"},
|
{"graph_symbol_net", "default"},
|
||||||
{"graph_symbol_proc", "default"},
|
{"graph_symbol_proc", "default"},
|
||||||
{"proc_sorting", "cpu lazy"},
|
{"proc_sorting", "cpu lazy"},
|
||||||
{"cpu_graph_upper", "total"},
|
{"cpu_graph_upper", "Auto"},
|
||||||
{"cpu_graph_lower", "total"},
|
{"cpu_graph_lower", "Auto"},
|
||||||
{"cpu_sensor", "Auto"},
|
{"cpu_sensor", "Auto"},
|
||||||
{"selected_battery", "Auto"},
|
{"selected_battery", "Auto"},
|
||||||
{"cpu_core_map", ""},
|
{"cpu_core_map", ""},
|
||||||
|
@ -220,10 +242,19 @@ namespace Config {
|
||||||
{"proc_filter", ""},
|
{"proc_filter", ""},
|
||||||
{"proc_command", ""},
|
{"proc_command", ""},
|
||||||
{"selected_name", ""},
|
{"selected_name", ""},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
{"custom_gpu_name0", ""},
|
||||||
|
{"custom_gpu_name1", ""},
|
||||||
|
{"custom_gpu_name2", ""},
|
||||||
|
{"custom_gpu_name3", ""},
|
||||||
|
{"custom_gpu_name4", ""},
|
||||||
|
{"custom_gpu_name5", ""},
|
||||||
|
{"show_gpu_info", "Auto"}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
unordered_flat_map<std::string_view, string> stringsTmp;
|
std::unordered_map<std::string_view, string> stringsTmp;
|
||||||
|
|
||||||
unordered_flat_map<std::string_view, bool> bools = {
|
std::unordered_map<std::string_view, bool> bools = {
|
||||||
{"theme_background", true},
|
{"theme_background", true},
|
||||||
{"truecolor", true},
|
{"truecolor", true},
|
||||||
{"rounded_corners", true},
|
{"rounded_corners", true},
|
||||||
|
@ -268,10 +299,15 @@ namespace Config {
|
||||||
{"lowcolor", false},
|
{"lowcolor", false},
|
||||||
{"show_detailed", false},
|
{"show_detailed", false},
|
||||||
{"proc_filtering", false},
|
{"proc_filtering", false},
|
||||||
|
{"proc_aggregate", false},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
{"nvml_measure_pcie_speeds", true},
|
||||||
|
{"gpu_mirror_graph", true},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
unordered_flat_map<std::string_view, bool> boolsTmp;
|
std::unordered_map<std::string_view, bool> boolsTmp;
|
||||||
|
|
||||||
unordered_flat_map<std::string_view, int> ints = {
|
std::unordered_map<std::string_view, int> ints = {
|
||||||
{"update_ms", 2000},
|
{"update_ms", 2000},
|
||||||
{"net_download", 100},
|
{"net_download", 100},
|
||||||
{"net_upload", 100},
|
{"net_upload", 100},
|
||||||
|
@ -282,7 +318,7 @@ namespace Config {
|
||||||
{"proc_selected", 0},
|
{"proc_selected", 0},
|
||||||
{"proc_last_selected", 0},
|
{"proc_last_selected", 0},
|
||||||
};
|
};
|
||||||
unordered_flat_map<std::string_view, int> intsTmp;
|
std::unordered_map<std::string_view, int> intsTmp;
|
||||||
|
|
||||||
bool _locked(const std::string_view name) {
|
bool _locked(const std::string_view name) {
|
||||||
atomic_wait(writelock, true);
|
atomic_wait(writelock, true);
|
||||||
|
@ -318,7 +354,7 @@ namespace Config {
|
||||||
validError = "Malformatted preset in config value presets!";
|
validError = "Malformatted preset in config value presets!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (not is_in(vals.at(0), "cpu", "mem", "net", "proc")) {
|
if (not is_in(vals.at(0), "cpu", "mem", "net", "proc", "gpu0", "gpu1", "gpu2", "gpu3", "gpu4", "gpu5")) {
|
||||||
validError = "Invalid box name in config value presets!";
|
validError = "Invalid box name in config value presets!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -414,6 +450,11 @@ namespace Config {
|
||||||
else if (name == "shown_boxes" and not value.empty() and not check_boxes(value))
|
else if (name == "shown_boxes" and not value.empty() and not check_boxes(value))
|
||||||
validError = "Invalid box name(s) in shown_boxes!";
|
validError = "Invalid box name(s) in shown_boxes!";
|
||||||
|
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
else if (name == "show_gpu_info" and not v_contains(show_gpu_values, value))
|
||||||
|
validError = "Invalid value for show_gpu_info: " + value;
|
||||||
|
#endif
|
||||||
|
|
||||||
else if (name == "presets" and not presetsValid(value))
|
else if (name == "presets" and not presetsValid(value))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -516,6 +557,13 @@ namespace Config {
|
||||||
auto new_boxes = ssplit(boxes);
|
auto new_boxes = ssplit(boxes);
|
||||||
for (auto& box : new_boxes) {
|
for (auto& box : new_boxes) {
|
||||||
if (not v_contains(valid_boxes, box)) return false;
|
if (not v_contains(valid_boxes, box)) return false;
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
if (box.starts_with("gpu")) {
|
||||||
|
size_t gpu_num = stoi(box.substr(3));
|
||||||
|
if (gpu_num == 0) gpu_num = 5;
|
||||||
|
if (std::cmp_greater(gpu_num, Gpu::gpu_names.size())) return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
current_boxes = std::move(new_boxes);
|
current_boxes = std::move(new_boxes);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -22,11 +22,10 @@ tab-size = 4
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include <robin_hood.h>
|
#include <unordered_map>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using robin_hood::unordered_flat_map;
|
|
||||||
|
|
||||||
//* Functions and variables for reading and writing the btop config file
|
//* Functions and variables for reading and writing the btop config file
|
||||||
namespace Config {
|
namespace Config {
|
||||||
|
@ -34,18 +33,25 @@ namespace Config {
|
||||||
extern std::filesystem::path conf_dir;
|
extern std::filesystem::path conf_dir;
|
||||||
extern std::filesystem::path conf_file;
|
extern std::filesystem::path conf_file;
|
||||||
|
|
||||||
extern unordered_flat_map<std::string_view, string> strings;
|
extern std::unordered_map<std::string_view, string> strings;
|
||||||
extern unordered_flat_map<std::string_view, string> stringsTmp;
|
extern std::unordered_map<std::string_view, string> stringsTmp;
|
||||||
extern unordered_flat_map<std::string_view, bool> bools;
|
extern std::unordered_map<std::string_view, bool> bools;
|
||||||
extern unordered_flat_map<std::string_view, bool> boolsTmp;
|
extern std::unordered_map<std::string_view, bool> boolsTmp;
|
||||||
extern unordered_flat_map<std::string_view, int> ints;
|
extern std::unordered_map<std::string_view, int> ints;
|
||||||
extern unordered_flat_map<std::string_view, int> intsTmp;
|
extern std::unordered_map<std::string_view, int> intsTmp;
|
||||||
|
|
||||||
const vector<string> valid_graph_symbols = { "braille", "block", "tty" };
|
const vector<string> valid_graph_symbols = { "braille", "block", "tty" };
|
||||||
const vector<string> valid_graph_symbols_def = { "default", "braille", "block", "tty" };
|
const vector<string> valid_graph_symbols_def = { "default", "braille", "block", "tty" };
|
||||||
const vector<string> valid_boxes = { "cpu", "mem", "net", "proc" };
|
const vector<string> valid_boxes = {
|
||||||
|
"cpu", "mem", "net", "proc"
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
,"gpu0", "gpu1", "gpu2", "gpu3", "gpu4", "gpu5"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
const vector<string> temp_scales = { "celsius", "fahrenheit", "kelvin", "rankine" };
|
const vector<string> temp_scales = { "celsius", "fahrenheit", "kelvin", "rankine" };
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
const vector<string> show_gpu_values = { "Auto", "On", "Off" };
|
||||||
|
#endif
|
||||||
extern vector<string> current_boxes;
|
extern vector<string> current_boxes;
|
||||||
extern vector<string> preset_list;
|
extern vector<string> preset_list;
|
||||||
extern vector<string> available_batteries;
|
extern vector<string> available_batteries;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,10 +21,9 @@ tab-size = 4
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <robin_hood.h>
|
#include <unordered_map>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
using robin_hood::unordered_flat_map;
|
|
||||||
using std::array;
|
using std::array;
|
||||||
using std::deque;
|
using std::deque;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -108,7 +107,7 @@ namespace Draw {
|
||||||
long long offset;
|
long long offset;
|
||||||
long long last = 0, max_value = 0;
|
long long last = 0, max_value = 0;
|
||||||
bool current = true, tty_mode = false;
|
bool current = true, tty_mode = false;
|
||||||
unordered_flat_map<bool, vector<string>> graphs = { {true, {}}, {false, {}}};
|
std::unordered_map<bool, vector<string>> graphs = { {true, {}}, {false, {}}};
|
||||||
|
|
||||||
//* Create two representations of the graph to switch between to represent two values for each braille character
|
//* Create two representations of the graph to switch between to represent two values for each braille character
|
||||||
void _create(const deque<long long>& data, int data_offset);
|
void _create(const deque<long long>& data, int data_offset);
|
||||||
|
@ -135,6 +134,6 @@ namespace Draw {
|
||||||
|
|
||||||
namespace Proc {
|
namespace Proc {
|
||||||
extern Draw::TextEdit filter;
|
extern Draw::TextEdit filter;
|
||||||
extern unordered_flat_map<size_t, Draw::Graph> p_graphs;
|
extern std::unordered_map<size_t, Draw::Graph> p_graphs;
|
||||||
extern unordered_flat_map<size_t, int> p_counters;
|
extern std::unordered_map<size_t, int> p_counters;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,15 @@ tab-size = 4
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "btop_input.hpp"
|
||||||
|
#include "btop_tools.hpp"
|
||||||
|
#include "btop_config.hpp"
|
||||||
|
#include "btop_shared.hpp"
|
||||||
|
#include "btop_menu.hpp"
|
||||||
|
#include "btop_draw.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include "btop_input.hpp"
|
#include "btop_input.hpp"
|
||||||
#include "btop_tools.hpp"
|
#include "btop_tools.hpp"
|
||||||
|
@ -40,7 +49,7 @@ namespace rng = std::ranges;
|
||||||
namespace Input {
|
namespace Input {
|
||||||
|
|
||||||
//* Map for translating key codes to readable values
|
//* Map for translating key codes to readable values
|
||||||
const unordered_flat_map<string, string> Key_escapes = {
|
const std::unordered_map<string, string> Key_escapes = {
|
||||||
{"\033", "escape"},
|
{"\033", "escape"},
|
||||||
{"\n", "enter"},
|
{"\n", "enter"},
|
||||||
{" ", "space"},
|
{" ", "space"},
|
||||||
|
@ -55,9 +64,13 @@ namespace Input {
|
||||||
{"[C", "right"},
|
{"[C", "right"},
|
||||||
{"OC", "right"},
|
{"OC", "right"},
|
||||||
{"[2~", "insert"},
|
{"[2~", "insert"},
|
||||||
|
{"[4h", "insert"},
|
||||||
{"[3~", "delete"},
|
{"[3~", "delete"},
|
||||||
|
{"[P", "delete"},
|
||||||
{"[H", "home"},
|
{"[H", "home"},
|
||||||
|
{"[1~", "home"},
|
||||||
{"[F", "end"},
|
{"[F", "end"},
|
||||||
|
{"[4~", "end"},
|
||||||
{"[5~", "page_up"},
|
{"[5~", "page_up"},
|
||||||
{"[6~", "page_down"},
|
{"[6~", "page_down"},
|
||||||
{"\t", "tab"},
|
{"\t", "tab"},
|
||||||
|
@ -79,7 +92,7 @@ namespace Input {
|
||||||
std::atomic<bool> interrupt (false);
|
std::atomic<bool> interrupt (false);
|
||||||
std::atomic<bool> polling (false);
|
std::atomic<bool> polling (false);
|
||||||
array<int, 2> mouse_pos;
|
array<int, 2> mouse_pos;
|
||||||
unordered_flat_map<string, Mouse_loc> mouse_mappings;
|
std::unordered_map<string, Mouse_loc> mouse_mappings;
|
||||||
|
|
||||||
deque<string> history(50, "");
|
deque<string> history(50, "");
|
||||||
string old_filter;
|
string old_filter;
|
||||||
|
@ -260,11 +273,21 @@ namespace Input {
|
||||||
Menu::show(Menu::Menus::Options);
|
Menu::show(Menu::Menus::Options);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (is_in(key, "1", "2", "3", "4")) {
|
else if (key.size() == 1 and isint(key)) {
|
||||||
|
auto intKey = stoi(key);
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
static const array<string, 10> boxes = {"gpu5", "cpu", "mem", "net", "proc", "gpu0", "gpu1", "gpu2", "gpu3", "gpu4"};
|
||||||
|
if ((intKey == 0 and Gpu::gpu_names.size() < 5) or (intKey >= 5 and std::cmp_less(Gpu::gpu_names.size(), intKey - 4)))
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
static const array<string, 10> boxes = {"", "cpu", "mem", "net", "proc"};
|
||||||
|
if (intKey == 0 or intKey > 4)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
atomic_wait(Runner::active);
|
atomic_wait(Runner::active);
|
||||||
Config::current_preset = -1;
|
Config::current_preset = -1;
|
||||||
static const array<string, 4> boxes = {"cpu", "mem", "net", "proc"};
|
|
||||||
Config::toggle_box(boxes.at(std::stoi(key) - 1));
|
Config::toggle_box(boxes.at(intKey));
|
||||||
Draw::calcSizes();
|
Draw::calcSizes();
|
||||||
Runner::run("all", false, true);
|
Runner::run("all", false, true);
|
||||||
return;
|
return;
|
||||||
|
@ -343,6 +366,9 @@ namespace Input {
|
||||||
else if (key == "c")
|
else if (key == "c")
|
||||||
Config::flip("proc_per_core");
|
Config::flip("proc_per_core");
|
||||||
|
|
||||||
|
else if (key == "%")
|
||||||
|
Config::flip("proc_mem_bytes");
|
||||||
|
|
||||||
else if (key == "delete" and not Config::getS("proc_filter").empty())
|
else if (key == "delete" and not Config::getS("proc_filter").empty())
|
||||||
Config::set("proc_filter", ""s);
|
Config::set("proc_filter", ""s);
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,9 @@ tab-size = 4
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <robin_hood.h>
|
#include <unordered_map>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
using robin_hood::unordered_flat_map;
|
|
||||||
using std::array;
|
using std::array;
|
||||||
using std::atomic;
|
using std::atomic;
|
||||||
using std::deque;
|
using std::deque;
|
||||||
|
@ -44,7 +43,7 @@ namespace Input {
|
||||||
};
|
};
|
||||||
|
|
||||||
//? line, col, height, width
|
//? line, col, height, width
|
||||||
extern unordered_flat_map<string, Mouse_loc> mouse_mappings;
|
extern std::unordered_map<string, Mouse_loc> mouse_mappings;
|
||||||
|
|
||||||
extern atomic<bool> interrupt;
|
extern atomic<bool> interrupt;
|
||||||
extern atomic<bool> polling;
|
extern atomic<bool> polling;
|
||||||
|
|
|
@ -17,7 +17,7 @@ tab-size = 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <robin_hood.h>
|
#include <unordered_map>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -31,7 +31,6 @@ tab-size = 4
|
||||||
#include "btop_draw.hpp"
|
#include "btop_draw.hpp"
|
||||||
#include "btop_shared.hpp"
|
#include "btop_shared.hpp"
|
||||||
|
|
||||||
using robin_hood::unordered_flat_map;
|
|
||||||
using std::array;
|
using std::array;
|
||||||
using std::ceil;
|
using std::ceil;
|
||||||
using std::max;
|
using std::max;
|
||||||
|
@ -54,18 +53,76 @@ namespace Menu {
|
||||||
int signalKillRet{}; // defaults to 0
|
int signalKillRet{}; // defaults to 0
|
||||||
|
|
||||||
const array<string, 32> P_Signals = {
|
const array<string, 32> P_Signals = {
|
||||||
"0",
|
"0",
|
||||||
|
#ifdef __linux__
|
||||||
|
#if defined(__hppa__)
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
||||||
|
"SIGTRAP", "SIGABRT", "SIGSTKFLT", "SIGFPE",
|
||||||
|
"SIGKILL", "SIGBUS", "SIGSEGV", "SIGXCPU",
|
||||||
|
"SIGPIPE", "SIGALRM", "SIGTERM", "SIGUSR1",
|
||||||
|
"SIGUSR2", "SIGCHLD", "SIGPWR", "SIGVTALRM",
|
||||||
|
"SIGPROF", "SIGIO", "SIGWINCH", "SIGSTOP",
|
||||||
|
"SIGTSTP", "SIGCONT", "SIGTTIN", "SIGTTOU",
|
||||||
|
"SIGURG", "SIGXFSZ", "SIGSYS"
|
||||||
|
#elif defined(__mips__)
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
||||||
|
"SIGTRAP", "SIGABRT", "SIGEMT", "SIGFPE",
|
||||||
|
"SIGKILL", "SIGBUS", "SIGSEGV", "SIGSYS",
|
||||||
|
"SIGPIPE", "SIGALRM", "SIGTERM", "SIGUSR1",
|
||||||
|
"SIGUSR2", "SIGCHLD", "SIGPWR", "SIGWINCH",
|
||||||
|
"SIGURG", "SIGIO", "SIGSTOP", "SIGTSTP",
|
||||||
|
"SIGCONT", "SIGTTIN", "SIGTTOU", "SIGVTALRM",
|
||||||
|
"SIGPROF", "SIGXCPU", "SIGXFSZ"
|
||||||
|
#elif defined(__alpha__)
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
||||||
|
"SIGTRAP", "SIGABRT", "SIGEMT", "SIGFPE",
|
||||||
|
"SIGKILL", "SIGBUS", "SIGSEGV", "SIGSYS",
|
||||||
|
"SIGPIPE", "SIGALRM", "SIGTERM", "SIGURG",
|
||||||
|
"SIGSTOP", "SIGTSTP", "SIGCONT", "SIGCHLD",
|
||||||
|
"SIGTTIN", "SIGTTOU", "SIGIO", "SIGXCPU",
|
||||||
|
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH",
|
||||||
|
"SIGPWR", "SIGUSR1", "SIGUSR2"
|
||||||
|
#elif defined (__sparc__)
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
||||||
|
"SIGTRAP", "SIGABRT", "SIGEMT", "SIGFPE",
|
||||||
|
"SIGKILL", "SIGBUS", "SIGSEGV", "SIGSYS",
|
||||||
|
"SIGPIPE", "SIGALRM", "SIGTERM", "SIGURG",
|
||||||
|
"SIGSTOP", "SIGTSTP", "SIGCONT", "SIGCHLD",
|
||||||
|
"SIGTTIN", "SIGTTOU", "SIGIO", "SIGXCPU",
|
||||||
|
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH",
|
||||||
|
"SIGLOST", "SIGUSR1", "SIGUSR2"
|
||||||
|
#else
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
||||||
"SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE",
|
"SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE",
|
||||||
"SIGKILL", "SIGUSR1", "SIGSEGV", "SIGUSR2",
|
"SIGKILL", "SIGUSR1", "SIGSEGV", "SIGUSR2",
|
||||||
"SIGPIPE", "SIGALRM", "SIGTERM", "16", "SIGCHLD",
|
"SIGPIPE", "SIGALRM", "SIGTERM", "SIGSTKFLT",
|
||||||
"SIGCONT", "SIGSTOP", "SIGTSTP", "SIGTTIN",
|
"SIGCHLD", "SIGCONT", "SIGSTOP", "SIGTSTP",
|
||||||
"SIGTTOU", "SIGURG", "SIGXCPU", "SIGXFSZ",
|
"SIGTTIN", "SIGTTOU", "SIGURG", "SIGXCPU",
|
||||||
"SIGVTALRM", "SIGPROF", "SIGWINCH", "SIGIO",
|
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH",
|
||||||
"SIGPWR", "SIGSYS"
|
"SIGIO", "SIGPWR", "SIGSYS"
|
||||||
|
#endif
|
||||||
|
#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
||||||
|
"SIGTRAP", "SIGABRT", "SIGEMT", "SIGFPE",
|
||||||
|
"SIGKILL", "SIGBUS", "SIGSEGV", "SIGSYS",
|
||||||
|
"SIGPIPE", "SIGALRM", "SIGTERM", "SIGURG",
|
||||||
|
"SIGSTOP", "SIGTSTP", "SIGCONT", "SIGCHLD",
|
||||||
|
"SIGTTIN", "SIGTTOU", "SIGIO", "SIGXCPU",
|
||||||
|
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH",
|
||||||
|
"SIGINFO", "SIGUSR1", "SIGUSR2"
|
||||||
|
#else
|
||||||
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
|
||||||
|
"SIGTRAP", "SIGABRT", "7", "SIGFPE",
|
||||||
|
"SIGKILL", "10", "SIGSEGV", "12",
|
||||||
|
"SIGPIPE", "SIGALRM", "SIGTERM", "16",
|
||||||
|
"17", "18", "19", "20",
|
||||||
|
"21", "22", "23", "24",
|
||||||
|
"25", "26", "27", "28",
|
||||||
|
"29", "30", "31"
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
unordered_flat_map<string, Input::Mouse_loc> mouse_mappings;
|
std::unordered_map<string, Input::Mouse_loc> mouse_mappings;
|
||||||
|
|
||||||
const array<array<string, 3>, 3> menu_normal = {
|
const array<array<string, 3>, 3> menu_normal = {
|
||||||
array<string, 3>{
|
array<string, 3>{
|
||||||
|
@ -115,6 +172,7 @@ namespace Menu {
|
||||||
{"2", "Toggle MEM box."},
|
{"2", "Toggle MEM box."},
|
||||||
{"3", "Toggle NET box."},
|
{"3", "Toggle NET box."},
|
||||||
{"4", "Toggle PROC box."},
|
{"4", "Toggle PROC box."},
|
||||||
|
{"5", "Toggle GPU box."},
|
||||||
{"d", "Toggle disks view in MEM box."},
|
{"d", "Toggle disks view in MEM box."},
|
||||||
{"F2, o", "Shows options."},
|
{"F2, o", "Shows options."},
|
||||||
{"F1, ?, h", "Shows this window."},
|
{"F1, ?, h", "Shows this window."},
|
||||||
|
@ -137,6 +195,7 @@ namespace Menu {
|
||||||
{"c", "Toggle per-core cpu usage of processes."},
|
{"c", "Toggle per-core cpu usage of processes."},
|
||||||
{"r", "Reverse sorting order in processes box."},
|
{"r", "Reverse sorting order in processes box."},
|
||||||
{"e", "Toggle processes tree view."},
|
{"e", "Toggle processes tree view."},
|
||||||
|
{"%", "Toggles memory display mode in processes box."},
|
||||||
{"Selected +, -", "Expand/collapse the selected process in tree view."},
|
{"Selected +, -", "Expand/collapse the selected process in tree view."},
|
||||||
{"Selected t", "Terminate selected process with SIGTERM - 15."},
|
{"Selected t", "Terminate selected process with SIGTERM - 15."},
|
||||||
{"Selected k", "Kill selected process with SIGKILL - 9."},
|
{"Selected k", "Kill selected process with SIGKILL - 9."},
|
||||||
|
@ -212,6 +271,9 @@ namespace Menu {
|
||||||
"Manually set which boxes to show.",
|
"Manually set which boxes to show.",
|
||||||
"",
|
"",
|
||||||
"Available values are \"cpu mem net proc\".",
|
"Available values are \"cpu mem net proc\".",
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
"Or \"gpu0\" through \"gpu5\" for GPU boxes.",
|
||||||
|
#endif
|
||||||
"Separate values with whitespace.",
|
"Separate values with whitespace.",
|
||||||
"",
|
"",
|
||||||
"Toggle between presets with key \"p\"."},
|
"Toggle between presets with key \"p\"."},
|
||||||
|
@ -314,23 +376,49 @@ namespace Menu {
|
||||||
{"cpu_graph_upper",
|
{"cpu_graph_upper",
|
||||||
"Cpu upper graph.",
|
"Cpu upper graph.",
|
||||||
"",
|
"",
|
||||||
"Sets the CPU stat shown in upper half of",
|
"Sets the CPU/GPU stat shown in upper half of",
|
||||||
"the CPU graph.",
|
"the CPU graph.",
|
||||||
"",
|
"",
|
||||||
"\"total\" = Total cpu usage.",
|
"CPU:",
|
||||||
|
"\"total\" = Total cpu usage. (Auto)",
|
||||||
"\"user\" = User mode cpu usage.",
|
"\"user\" = User mode cpu usage.",
|
||||||
"\"system\" = Kernel mode cpu usage.",
|
"\"system\" = Kernel mode cpu usage.",
|
||||||
"+ more depending on kernel."},
|
"+ more depending on kernel.",
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
"",
|
||||||
|
"GPU:",
|
||||||
|
"\"gpu-totals\" = GPU usage split by device.",
|
||||||
|
"\"gpu-vram-totals\" = VRAM usage split by GPU.",
|
||||||
|
"\"gpu-pwr-totals\" = Power usage split by GPU.",
|
||||||
|
"\"gpu-average\" = Avg usage of all GPUs.",
|
||||||
|
"\"gpu-vram-total\" = VRAM usage of all GPUs.",
|
||||||
|
"\"gpu-pwr-total\" = Power usage of all GPUs.",
|
||||||
|
"Not all stats are supported on all devices."
|
||||||
|
#endif
|
||||||
|
},
|
||||||
{"cpu_graph_lower",
|
{"cpu_graph_lower",
|
||||||
"Cpu lower graph.",
|
"Cpu lower graph.",
|
||||||
"",
|
"",
|
||||||
"Sets the CPU stat shown in lower half of",
|
"Sets the CPU/GPU stat shown in lower half of",
|
||||||
"the CPU graph.",
|
"the CPU graph.",
|
||||||
"",
|
"",
|
||||||
|
"CPU:",
|
||||||
"\"total\" = Total cpu usage.",
|
"\"total\" = Total cpu usage.",
|
||||||
"\"user\" = User mode cpu usage.",
|
"\"user\" = User mode cpu usage.",
|
||||||
"\"system\" = Kernel mode cpu usage.",
|
"\"system\" = Kernel mode cpu usage.",
|
||||||
"+ more depending on kernel."},
|
"+ more depending on kernel.",
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
"",
|
||||||
|
"GPU:",
|
||||||
|
"\"gpu-totals\" = GPU usage split/device. (Auto)",
|
||||||
|
"\"gpu-vram-totals\" = VRAM usage split by GPU.",
|
||||||
|
"\"gpu-pwr-totals\" = Power usage split by GPU.",
|
||||||
|
"\"gpu-average\" = Avg usage of all GPUs.",
|
||||||
|
"\"gpu-vram-total\" = VRAM usage of all GPUs.",
|
||||||
|
"\"gpu-pwr-total\" = Power usage of all GPUs.",
|
||||||
|
"Not all stats are supported on all devices."
|
||||||
|
#endif
|
||||||
|
},
|
||||||
{"cpu_invert_lower",
|
{"cpu_invert_lower",
|
||||||
"Toggles orientation of the lower CPU graph.",
|
"Toggles orientation of the lower CPU graph.",
|
||||||
"",
|
"",
|
||||||
|
@ -342,12 +430,24 @@ namespace Menu {
|
||||||
"to fit to box height.",
|
"to fit to box height.",
|
||||||
"",
|
"",
|
||||||
"True or False."},
|
"True or False."},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
{"show_gpu_info",
|
||||||
|
"Show gpu info in cpu box.",
|
||||||
|
"",
|
||||||
|
"Toggles gpu stats in cpu box and the",
|
||||||
|
"gpu graph (if \"cpu_graph_lower\" is set to",
|
||||||
|
"\"Auto\").",
|
||||||
|
"",
|
||||||
|
"\"Auto\" to show when no gpu box is shown.",
|
||||||
|
"\"On\" to always show.",
|
||||||
|
"\"Off\" to never show."},
|
||||||
|
#endif
|
||||||
{"check_temp",
|
{"check_temp",
|
||||||
"Enable cpu temperature reporting.",
|
"Enable cpu temperature reporting.",
|
||||||
"",
|
"",
|
||||||
"True or False."},
|
"True or False."},
|
||||||
{"cpu_sensor",
|
{"cpu_sensor",
|
||||||
"Cpu temperature sensor",
|
"Cpu temperature sensor.",
|
||||||
"",
|
"",
|
||||||
"Select the sensor that corresponds to",
|
"Select the sensor that corresponds to",
|
||||||
"your cpu temperature.",
|
"your cpu temperature.",
|
||||||
|
@ -387,7 +487,7 @@ namespace Menu {
|
||||||
"Rankine, 0 = abosulte zero, 1 degree change",
|
"Rankine, 0 = abosulte zero, 1 degree change",
|
||||||
"equals 1 degree change in Fahrenheit."},
|
"equals 1 degree change in Fahrenheit."},
|
||||||
{"show_cpu_freq",
|
{"show_cpu_freq",
|
||||||
"Show CPU frequency",
|
"Show CPU frequency.",
|
||||||
"",
|
"",
|
||||||
"Can cause slowdowns on systems with many",
|
"Can cause slowdowns on systems with many",
|
||||||
"cores and certain kernel versions."},
|
"cores and certain kernel versions."},
|
||||||
|
@ -403,6 +503,50 @@ namespace Menu {
|
||||||
"",
|
"",
|
||||||
"True or False."},
|
"True or False."},
|
||||||
},
|
},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
{
|
||||||
|
{"nvml_measure_pcie_speeds",
|
||||||
|
"Measure PCIe throughput on NVIDIA cards.",
|
||||||
|
"",
|
||||||
|
"May impact performance on certain cards.",
|
||||||
|
"",
|
||||||
|
"True or False."},
|
||||||
|
{"graph_symbol_gpu",
|
||||||
|
"Graph symbol to use for graphs in gpu box.",
|
||||||
|
"",
|
||||||
|
"\"default\", \"braille\", \"block\" or \"tty\".",
|
||||||
|
"",
|
||||||
|
"\"default\" for the general default symbol.",},
|
||||||
|
{"gpu_mirror_graph",
|
||||||
|
"Horizontally mirror the GPU graph.",
|
||||||
|
"",
|
||||||
|
"True or False."},
|
||||||
|
{"custom_gpu_name0",
|
||||||
|
"Custom gpu0 model name in gpu stats box.",
|
||||||
|
"",
|
||||||
|
"Empty string to disable."},
|
||||||
|
{"custom_gpu_name1",
|
||||||
|
"Custom gpu1 model name in gpu stats box.",
|
||||||
|
"",
|
||||||
|
"Empty string to disable."},
|
||||||
|
{"custom_gpu_name2",
|
||||||
|
"Custom gpu2 model name in gpu stats box.",
|
||||||
|
"",
|
||||||
|
"Empty string to disable."},
|
||||||
|
{"custom_gpu_name3",
|
||||||
|
"Custom gpu3 model name in gpu stats box.",
|
||||||
|
"",
|
||||||
|
"Empty string to disable."},
|
||||||
|
{"custom_gpu_name4",
|
||||||
|
"Custom gpu4 model name in gpu stats box.",
|
||||||
|
"",
|
||||||
|
"Empty string to disable."},
|
||||||
|
{"custom_gpu_name5",
|
||||||
|
"Custom gpu5 model name in gpu stats box.",
|
||||||
|
"",
|
||||||
|
"Empty string to disable."},
|
||||||
|
},
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
{"mem_below_net",
|
{"mem_below_net",
|
||||||
"Mem box location.",
|
"Mem box location.",
|
||||||
|
@ -589,6 +733,11 @@ namespace Menu {
|
||||||
"Set true to show processes grouped by",
|
"Set true to show processes grouped by",
|
||||||
"parents with lines drawn between parent",
|
"parents with lines drawn between parent",
|
||||||
"and child process."},
|
"and child process."},
|
||||||
|
{"proc_aggregate",
|
||||||
|
"Aggregate child's resources in parent.",
|
||||||
|
"",
|
||||||
|
"In tree-view, include all child resources",
|
||||||
|
"with the parent even while expanded."},
|
||||||
{"proc_colors",
|
{"proc_colors",
|
||||||
"Enable colors in process view.",
|
"Enable colors in process view.",
|
||||||
"",
|
"",
|
||||||
|
@ -1015,7 +1164,7 @@ namespace Menu {
|
||||||
static Draw::TextEdit editor;
|
static Draw::TextEdit editor;
|
||||||
static string warnings;
|
static string warnings;
|
||||||
static bitset<8> selPred;
|
static bitset<8> selPred;
|
||||||
static const unordered_flat_map<string, std::reference_wrapper<const vector<string>>> optionsList = {
|
static const std::unordered_map<string, std::reference_wrapper<const vector<string>>> optionsList = {
|
||||||
{"color_theme", std::cref(Theme::themes)},
|
{"color_theme", std::cref(Theme::themes)},
|
||||||
{"log_level", std::cref(Logger::log_levels)},
|
{"log_level", std::cref(Logger::log_levels)},
|
||||||
{"temp_scale", std::cref(Config::temp_scales)},
|
{"temp_scale", std::cref(Config::temp_scales)},
|
||||||
|
@ -1029,6 +1178,10 @@ namespace Menu {
|
||||||
{"cpu_graph_lower", std::cref(Cpu::available_fields)},
|
{"cpu_graph_lower", std::cref(Cpu::available_fields)},
|
||||||
{"cpu_sensor", std::cref(Cpu::available_sensors)},
|
{"cpu_sensor", std::cref(Cpu::available_sensors)},
|
||||||
{"selected_battery", std::cref(Config::available_batteries)},
|
{"selected_battery", std::cref(Config::available_batteries)},
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
{"show_gpu_info", std::cref(Config::show_gpu_values)},
|
||||||
|
{"graph_symbol_gpu", std::cref(Config::valid_graph_symbols_def)},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
auto tty_mode = Config::getB("tty_mode");
|
auto tty_mode = Config::getB("tty_mode");
|
||||||
auto vim_keys = Config::getB("vim_keys");
|
auto vim_keys = Config::getB("vim_keys");
|
||||||
|
@ -1080,7 +1233,8 @@ namespace Menu {
|
||||||
const auto& option = categories[selected_cat][item_height * page + selected][0];
|
const auto& option = categories[selected_cat][item_height * page + selected][0];
|
||||||
if (selPred.test(isString) and Config::stringValid(option, editor.text)) {
|
if (selPred.test(isString) and Config::stringValid(option, editor.text)) {
|
||||||
Config::set(option, editor.text);
|
Config::set(option, editor.text);
|
||||||
if (option == "custom_cpu_name") screen_redraw = true;
|
if (option == "custom_cpu_name" or option.starts_with("custom_gpu_name"))
|
||||||
|
screen_redraw = true;
|
||||||
else if (is_in(option, "shown_boxes", "presets")) {
|
else if (is_in(option, "shown_boxes", "presets")) {
|
||||||
screen_redraw = true;
|
screen_redraw = true;
|
||||||
Config::current_preset = -1;
|
Config::current_preset = -1;
|
||||||
|
@ -1161,7 +1315,7 @@ namespace Menu {
|
||||||
if (--selected_cat < 0) selected_cat = (int)categories.size() - 1;
|
if (--selected_cat < 0) selected_cat = (int)categories.size() - 1;
|
||||||
page = selected = 0;
|
page = selected = 0;
|
||||||
}
|
}
|
||||||
else if (is_in(key, "1", "2", "3", "4", "5") or key.starts_with("select_cat_")) {
|
else if (is_in(key, "1", "2", "3", "4", "5", "6") or key.starts_with("select_cat_")) {
|
||||||
selected_cat = key.back() - '0' - 1;
|
selected_cat = key.back() - '0' - 1;
|
||||||
page = selected = 0;
|
page = selected = 0;
|
||||||
}
|
}
|
||||||
|
@ -1213,7 +1367,7 @@ namespace Menu {
|
||||||
Logger::set(optList.at(i));
|
Logger::set(optList.at(i));
|
||||||
Logger::info("Logger set to " + optList.at(i));
|
Logger::info("Logger set to " + optList.at(i));
|
||||||
}
|
}
|
||||||
else if (is_in(option, "proc_sorting", "cpu_sensor") or option.starts_with("graph_symbol") or option.starts_with("cpu_graph_"))
|
else if (is_in(option, "proc_sorting", "cpu_sensor", "show_gpu_info") or option.starts_with("graph_symbol") or option.starts_with("cpu_graph_"))
|
||||||
screen_redraw = true;
|
screen_redraw = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1259,11 +1413,19 @@ namespace Menu {
|
||||||
|
|
||||||
//? Category buttons
|
//? Category buttons
|
||||||
out += Mv::to(y+7, x+4);
|
out += Mv::to(y+7, x+4);
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
for (int i = 0; const auto& m : {"general", "cpu", "gpu", "mem", "net", "proc"}) {
|
||||||
|
#else
|
||||||
for (int i = 0; const auto& m : {"general", "cpu", "mem", "net", "proc"}) {
|
for (int i = 0; const auto& m : {"general", "cpu", "mem", "net", "proc"}) {
|
||||||
|
#endif
|
||||||
out += Fx::b + (i == selected_cat
|
out += Fx::b + (i == selected_cat
|
||||||
? Theme::c("hi_fg") + '[' + Theme::c("title") + m + Theme::c("hi_fg") + ']'
|
? Theme::c("hi_fg") + '[' + Theme::c("title") + m + Theme::c("hi_fg") + ']'
|
||||||
: Theme::c("hi_fg") + to_string(i + 1) + Theme::c("title") + m + ' ')
|
: Theme::c("hi_fg") + to_string(i + 1) + Theme::c("title") + m + ' ')
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
+ Mv::r(7);
|
||||||
|
#else
|
||||||
+ Mv::r(10);
|
+ Mv::r(10);
|
||||||
|
#endif
|
||||||
if (string button_name = "select_cat_" + to_string(i + 1); not editing and not mouse_mappings.contains(button_name))
|
if (string button_name = "select_cat_" + to_string(i + 1); not editing and not mouse_mappings.contains(button_name))
|
||||||
mouse_mappings[button_name] = {y+6, x+2 + 15*i, 3, 15};
|
mouse_mappings[button_name] = {y+6, x+2 + 15*i, 3, 15};
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace Menu {
|
||||||
extern bool redraw;
|
extern bool redraw;
|
||||||
|
|
||||||
//? line, col, height, width
|
//? line, col, height, width
|
||||||
extern unordered_flat_map<string, Input::Mouse_loc> mouse_mappings;
|
extern std::unordered_map<string, Input::Mouse_loc> mouse_mappings;
|
||||||
|
|
||||||
//* Creates a message box centered on screen
|
//* Creates a message box centered on screen
|
||||||
//? Height of box is determined by size of content vector
|
//? Height of box is determined by size of content vector
|
||||||
|
|
|
@ -18,12 +18,25 @@ tab-size = 4
|
||||||
|
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
|
#include "btop_config.hpp"
|
||||||
#include "btop_shared.hpp"
|
#include "btop_shared.hpp"
|
||||||
#include "btop_tools.hpp"
|
#include "btop_tools.hpp"
|
||||||
|
|
||||||
namespace rng = std::ranges;
|
namespace rng = std::ranges;
|
||||||
using namespace Tools;
|
using namespace Tools;
|
||||||
|
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
namespace Gpu {
|
||||||
|
vector<string> gpu_names;
|
||||||
|
vector<int> gpu_b_height_offsets;
|
||||||
|
std::unordered_map<string, deque<long long>> shared_gpu_percent = {
|
||||||
|
{"gpu-average", {}},
|
||||||
|
{"gpu-vram-total", {}},
|
||||||
|
{"gpu-pwr-total", {}},
|
||||||
|
};
|
||||||
|
long long gpu_pwr_total_max;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Proc {
|
namespace Proc {
|
||||||
void proc_sorter(vector<proc_info>& proc_vec, const string& sorting, bool reverse, bool tree) {
|
void proc_sorter(vector<proc_info>& proc_vec, const string& sorting, bool reverse, bool tree) {
|
||||||
|
@ -156,6 +169,12 @@ namespace Proc {
|
||||||
filter_found++;
|
filter_found++;
|
||||||
p.filtered = true;
|
p.filtered = true;
|
||||||
}
|
}
|
||||||
|
else if (Config::getB("proc_aggregate")) {
|
||||||
|
cur_proc.cpu_p += p.cpu_p;
|
||||||
|
cur_proc.cpu_c += p.cpu_c;
|
||||||
|
cur_proc.mem += p.mem;
|
||||||
|
cur_proc.threads += p.threads;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (collapsed or filtering) {
|
if (collapsed or filtering) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -26,10 +26,9 @@ tab-size = 4
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <robin_hood.h>
|
#include <unordered_map>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
using robin_hood::unordered_flat_map;
|
|
||||||
using std::array;
|
using std::array;
|
||||||
using std::atomic;
|
using std::atomic;
|
||||||
using std::deque;
|
using std::deque;
|
||||||
|
@ -86,6 +85,91 @@ namespace Shared {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Gpu {
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
extern vector<string> box;
|
||||||
|
extern int width, height, min_width, min_height;
|
||||||
|
extern vector<int> x_vec, y_vec;
|
||||||
|
extern vector<bool> redraw;
|
||||||
|
extern int shown;
|
||||||
|
extern vector<char> shown_panels;
|
||||||
|
extern vector<string> gpu_names;
|
||||||
|
extern vector<int> gpu_b_height_offsets;
|
||||||
|
extern long long gpu_pwr_total_max;
|
||||||
|
|
||||||
|
extern std::unordered_map<string, deque<long long>> shared_gpu_percent; // averages, power/vram total
|
||||||
|
|
||||||
|
const array mem_names { "used"s, "free"s };
|
||||||
|
|
||||||
|
//* Container for process information // TODO
|
||||||
|
/*struct proc_info {
|
||||||
|
unsigned int pid;
|
||||||
|
unsigned long long mem;
|
||||||
|
};*/
|
||||||
|
|
||||||
|
//* Container for supported Gpu::*::collect() functions
|
||||||
|
struct gpu_info_supported {
|
||||||
|
bool gpu_utilization = true,
|
||||||
|
mem_utilization = true,
|
||||||
|
gpu_clock = true,
|
||||||
|
mem_clock = true,
|
||||||
|
pwr_usage = true,
|
||||||
|
pwr_state = true,
|
||||||
|
temp_info = true,
|
||||||
|
mem_total = true,
|
||||||
|
mem_used = true,
|
||||||
|
pcie_txrx = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
//* Per-device container for GPU info
|
||||||
|
struct gpu_info {
|
||||||
|
std::unordered_map<string, deque<long long>> gpu_percent = {
|
||||||
|
{"gpu-totals", {}},
|
||||||
|
{"gpu-vram-totals", {}},
|
||||||
|
{"gpu-pwr-totals", {}},
|
||||||
|
};
|
||||||
|
unsigned int gpu_clock_speed; // MHz
|
||||||
|
|
||||||
|
long long pwr_usage; // mW
|
||||||
|
long long pwr_max_usage = 255000;
|
||||||
|
long long pwr_state;
|
||||||
|
|
||||||
|
deque<long long> temp = {0};
|
||||||
|
long long temp_max = 110;
|
||||||
|
|
||||||
|
long long mem_total = 0;
|
||||||
|
long long mem_used = 0;
|
||||||
|
deque<long long> mem_utilization_percent = {0}; // TODO: properly handle GPUs that can't report some stats
|
||||||
|
long long mem_clock_speed = 0; // MHz
|
||||||
|
|
||||||
|
long long pcie_tx = 0; // KB/s
|
||||||
|
long long pcie_rx = 0;
|
||||||
|
|
||||||
|
gpu_info_supported supported_functions;
|
||||||
|
|
||||||
|
// vector<proc_info> graphics_processes = {}; // TODO
|
||||||
|
// vector<proc_info> compute_processes = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Nvml {
|
||||||
|
extern bool shutdown();
|
||||||
|
}
|
||||||
|
namespace Rsmi {
|
||||||
|
extern bool shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
//* Collect gpu stats and temperatures
|
||||||
|
auto collect(bool no_update = false) -> vector<gpu_info>&;
|
||||||
|
|
||||||
|
//* Draw contents of gpu box using <gpus> as source
|
||||||
|
string draw(const gpu_info& gpu, unsigned long index, bool force_redraw, bool data_same);
|
||||||
|
#else
|
||||||
|
struct gpu_info {
|
||||||
|
bool supported = false;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
namespace Cpu {
|
namespace Cpu {
|
||||||
extern string box;
|
extern string box;
|
||||||
extern int x, y, width, height, min_width, min_height;
|
extern int x, y, width, height, min_width, min_height;
|
||||||
|
@ -96,7 +180,7 @@ namespace Cpu {
|
||||||
extern tuple<int, long, string> current_bat;
|
extern tuple<int, long, string> current_bat;
|
||||||
|
|
||||||
struct cpu_info {
|
struct cpu_info {
|
||||||
unordered_flat_map<string, deque<long long>> cpu_percent = {
|
std::unordered_map<string, deque<long long>> cpu_percent = {
|
||||||
{"total", {}},
|
{"total", {}},
|
||||||
{"user", {}},
|
{"user", {}},
|
||||||
{"nice", {}},
|
{"nice", {}},
|
||||||
|
@ -119,11 +203,13 @@ namespace Cpu {
|
||||||
auto collect(bool no_update = false) -> cpu_info&;
|
auto collect(bool no_update = false) -> cpu_info&;
|
||||||
|
|
||||||
//* Draw contents of cpu box using <cpu> as source
|
//* Draw contents of cpu box using <cpu> as source
|
||||||
string draw(const cpu_info& cpu, bool force_redraw = false, bool data_same = false);
|
string draw(const cpu_info& cpu, const vector<Gpu::gpu_info>& gpu, bool force_redraw = false, bool data_same = false);
|
||||||
|
|
||||||
//* Parse /proc/cpu info for mapping of core ids
|
//* Parse /proc/cpu info for mapping of core ids
|
||||||
auto get_core_mapping() -> unordered_flat_map<int, int>;
|
auto get_core_mapping() -> std::unordered_map<int, int>;
|
||||||
extern unordered_flat_map<int, int> core_mapping;
|
extern std::unordered_map<int, int> core_mapping;
|
||||||
|
|
||||||
|
auto get_cpuHz() -> string;
|
||||||
|
|
||||||
//* Get battery info from /sys
|
//* Get battery info from /sys
|
||||||
auto get_battery() -> tuple<int, long, string>;
|
auto get_battery() -> tuple<int, long, string>;
|
||||||
|
@ -155,13 +241,13 @@ namespace Mem {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mem_info {
|
struct mem_info {
|
||||||
unordered_flat_map<string, uint64_t> stats =
|
std::unordered_map<string, uint64_t> stats =
|
||||||
{{"used", 0}, {"available", 0}, {"cached", 0}, {"free", 0},
|
{{"used", 0}, {"available", 0}, {"cached", 0}, {"free", 0},
|
||||||
{"swap_total", 0}, {"swap_used", 0}, {"swap_free", 0}};
|
{"swap_total", 0}, {"swap_used", 0}, {"swap_free", 0}};
|
||||||
unordered_flat_map<string, deque<long long>> percent =
|
std::unordered_map<string, deque<long long>> percent =
|
||||||
{{"used", {}}, {"available", {}}, {"cached", {}}, {"free", {}},
|
{{"used", {}}, {"available", {}}, {"cached", {}}, {"free", {}},
|
||||||
{"swap_total", {}}, {"swap_used", {}}, {"swap_free", {}}};
|
{"swap_total", {}}, {"swap_used", {}}, {"swap_free", {}}};
|
||||||
unordered_flat_map<string, disk_info> disks;
|
std::unordered_map<string, disk_info> disks;
|
||||||
vector<string> disks_order;
|
vector<string> disks_order;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,7 +269,7 @@ namespace Net {
|
||||||
extern string selected_iface;
|
extern string selected_iface;
|
||||||
extern vector<string> interfaces;
|
extern vector<string> interfaces;
|
||||||
extern bool rescale;
|
extern bool rescale;
|
||||||
extern unordered_flat_map<string, uint64_t> graph_max;
|
extern std::unordered_map<string, uint64_t> graph_max;
|
||||||
|
|
||||||
struct net_stat {
|
struct net_stat {
|
||||||
uint64_t speed{}; // defaults to 0
|
uint64_t speed{}; // defaults to 0
|
||||||
|
@ -195,14 +281,14 @@ namespace Net {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct net_info {
|
struct net_info {
|
||||||
unordered_flat_map<string, deque<long long>> bandwidth = { {"download", {}}, {"upload", {}} };
|
std::unordered_map<string, deque<long long>> bandwidth = { {"download", {}}, {"upload", {}} };
|
||||||
unordered_flat_map<string, net_stat> stat = { {"download", {}}, {"upload", {}} };
|
std::unordered_map<string, net_stat> stat = { {"download", {}}, {"upload", {}} };
|
||||||
string ipv4{}; // defaults to ""
|
string ipv4{}; // defaults to ""
|
||||||
string ipv6{}; // defaults to ""
|
string ipv6{}; // defaults to ""
|
||||||
bool connected{}; // defaults to false
|
bool connected{}; // defaults to false
|
||||||
};
|
};
|
||||||
|
|
||||||
extern unordered_flat_map<string, net_info> current_net;
|
extern std::unordered_map<string, net_info> current_net;
|
||||||
|
|
||||||
//* Collect net upload/download stats
|
//* Collect net upload/download stats
|
||||||
auto collect(bool no_update=false) -> net_info&;
|
auto collect(bool no_update=false) -> net_info&;
|
||||||
|
@ -235,7 +321,7 @@ namespace Proc {
|
||||||
};
|
};
|
||||||
|
|
||||||
//? Translation from process state char to explanative string
|
//? Translation from process state char to explanative string
|
||||||
const unordered_flat_map<char, string> proc_states = {
|
const std::unordered_map<char, string> proc_states = {
|
||||||
{'R', "Running"},
|
{'R', "Running"},
|
||||||
{'S', "Sleeping"},
|
{'S', "Sleeping"},
|
||||||
{'D', "Waiting"},
|
{'D', "Waiting"},
|
||||||
|
|
|
@ -42,11 +42,11 @@ namespace Theme {
|
||||||
fs::path theme_dir;
|
fs::path theme_dir;
|
||||||
fs::path user_theme_dir;
|
fs::path user_theme_dir;
|
||||||
vector<string> themes;
|
vector<string> themes;
|
||||||
unordered_flat_map<string, string> colors;
|
std::unordered_map<string, string> colors;
|
||||||
unordered_flat_map<string, array<int, 3>> rgbs;
|
std::unordered_map<string, array<int, 3>> rgbs;
|
||||||
unordered_flat_map<string, array<string, 101>> gradients;
|
std::unordered_map<string, array<string, 101>> gradients;
|
||||||
|
|
||||||
const unordered_flat_map<string, string> Default_theme = {
|
const std::unordered_map<string, string> Default_theme = {
|
||||||
{ "main_bg", "#00" },
|
{ "main_bg", "#00" },
|
||||||
{ "main_fg", "#cc" },
|
{ "main_fg", "#cc" },
|
||||||
{ "title", "#ee" },
|
{ "title", "#ee" },
|
||||||
|
@ -91,7 +91,7 @@ namespace Theme {
|
||||||
{ "process_end", "#d45454" }
|
{ "process_end", "#d45454" }
|
||||||
};
|
};
|
||||||
|
|
||||||
const unordered_flat_map<string, string> TTY_theme = {
|
const std::unordered_map<string, string> TTY_theme = {
|
||||||
{ "main_bg", "\x1b[0;40m" },
|
{ "main_bg", "\x1b[0;40m" },
|
||||||
{ "main_fg", "\x1b[37m" },
|
{ "main_fg", "\x1b[37m" },
|
||||||
{ "title", "\x1b[97m" },
|
{ "title", "\x1b[97m" },
|
||||||
|
@ -224,7 +224,7 @@ namespace Theme {
|
||||||
}
|
}
|
||||||
|
|
||||||
//* Generate colors and rgb decimal vectors for the theme
|
//* Generate colors and rgb decimal vectors for the theme
|
||||||
void generateColors(const unordered_flat_map<string, string>& source) {
|
void generateColors(const std::unordered_map<string, string>& source) {
|
||||||
vector<string> t_rgb;
|
vector<string> t_rgb;
|
||||||
string depth;
|
string depth;
|
||||||
bool t_to_256 = Config::getB("lowcolor");
|
bool t_to_256 = Config::getB("lowcolor");
|
||||||
|
@ -372,7 +372,7 @@ namespace Theme {
|
||||||
|
|
||||||
//* Load a .theme file from disk
|
//* Load a .theme file from disk
|
||||||
auto loadFile(const string& filename) {
|
auto loadFile(const string& filename) {
|
||||||
unordered_flat_map<string, string> theme_out;
|
std::unordered_map<string, string> theme_out;
|
||||||
const fs::path filepath = filename;
|
const fs::path filepath = filename;
|
||||||
if (not fs::exists(filepath))
|
if (not fs::exists(filepath))
|
||||||
return Default_theme;
|
return Default_theme;
|
||||||
|
|
|
@ -22,12 +22,11 @@ tab-size = 4
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <robin_hood.h>
|
#include <unordered_map>
|
||||||
|
|
||||||
using std::array;
|
using std::array;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using robin_hood::unordered_flat_map;
|
|
||||||
|
|
||||||
namespace Theme {
|
namespace Theme {
|
||||||
extern std::filesystem::path theme_dir;
|
extern std::filesystem::path theme_dir;
|
||||||
|
@ -54,9 +53,9 @@ namespace Theme {
|
||||||
//* Set current theme from current "color_theme" value in config
|
//* Set current theme from current "color_theme" value in config
|
||||||
void setTheme();
|
void setTheme();
|
||||||
|
|
||||||
extern unordered_flat_map<string, string> colors;
|
extern std::unordered_map<string, string> colors;
|
||||||
extern unordered_flat_map<string, array<int, 3>> rgbs;
|
extern std::unordered_map<string, array<int, 3>> rgbs;
|
||||||
extern unordered_flat_map<string, array<string, 101>> gradients;
|
extern std::unordered_map<string, array<string, 101>> gradients;
|
||||||
|
|
||||||
//* Return escape code for color <name>
|
//* Return escape code for color <name>
|
||||||
inline const string& c(const string& name) { return colors.at(name); }
|
inline const string& c(const string& name) { return colors.at(name); }
|
||||||
|
|
|
@ -30,7 +30,7 @@ tab-size = 4
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
#include "robin_hood.h"
|
#include "unordered_map"
|
||||||
#include "widechar_width.hpp"
|
#include "widechar_width.hpp"
|
||||||
#include "btop_shared.hpp"
|
#include "btop_shared.hpp"
|
||||||
#include "btop_tools.hpp"
|
#include "btop_tools.hpp"
|
||||||
|
@ -43,7 +43,6 @@ using std::flush;
|
||||||
using std::max;
|
using std::max;
|
||||||
using std::string_view;
|
using std::string_view;
|
||||||
using std::to_string;
|
using std::to_string;
|
||||||
using robin_hood::unordered_flat_map;
|
|
||||||
|
|
||||||
using namespace std::literals; // to use operator""s
|
using namespace std::literals; // to use operator""s
|
||||||
|
|
||||||
|
@ -99,19 +98,31 @@ namespace Term {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_min_size(const string& boxes) -> array<int, 2> {
|
auto get_min_size(const string& boxes) -> array<int, 2> {
|
||||||
bool cpu = boxes.find("cpu") != string::npos;
|
bool cpu = boxes.find("cpu") != string::npos;
|
||||||
bool mem = boxes.find("mem") != string::npos;
|
bool mem = boxes.find("mem") != string::npos;
|
||||||
bool net = boxes.find("net") != string::npos;
|
bool net = boxes.find("net") != string::npos;
|
||||||
bool proc = boxes.find("proc") != string::npos;
|
bool proc = boxes.find("proc") != string::npos;
|
||||||
int width = 0;
|
#ifdef GPU_SUPPORT
|
||||||
|
int gpu = 0;
|
||||||
|
if (not Gpu::gpu_names.empty())
|
||||||
|
for (char i = '0'; i <= '5'; ++i)
|
||||||
|
gpu += (boxes.find(std::string("gpu") + i) != string::npos);
|
||||||
|
#endif
|
||||||
|
int width = 0;
|
||||||
if (mem) width = Mem::min_width;
|
if (mem) width = Mem::min_width;
|
||||||
else if (net) width = Mem::min_width;
|
else if (net) width = Mem::min_width;
|
||||||
width += (proc ? Proc::min_width : 0);
|
width += (proc ? Proc::min_width : 0);
|
||||||
if (cpu and width < Cpu::min_width) width = Cpu::min_width;
|
if (cpu and width < Cpu::min_width) width = Cpu::min_width;
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
if (gpu != 0 and width < Gpu::min_width) width = Gpu::min_width;
|
||||||
|
#endif
|
||||||
|
|
||||||
int height = (cpu ? Cpu::min_height : 0);
|
int height = (cpu ? Cpu::min_height : 0);
|
||||||
if (proc) height += Proc::min_height;
|
if (proc) height += Proc::min_height;
|
||||||
else height += (mem ? Mem::min_height : 0) + (net ? Net::min_height : 0);
|
else height += (mem ? Mem::min_height : 0) + (net ? Net::min_height : 0);
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
height += Gpu::min_height*gpu;
|
||||||
|
#endif
|
||||||
|
|
||||||
return { width, height };
|
return { width, height };
|
||||||
}
|
}
|
||||||
|
@ -445,7 +456,7 @@ namespace Tools {
|
||||||
out = to_string((int)round(stod(out)));
|
out = to_string((int)round(stod(out)));
|
||||||
}
|
}
|
||||||
if (out.size() > 3) {
|
if (out.size() > 3) {
|
||||||
out = to_string((int)(out[0] - '0') + 1);
|
out = to_string((int)(out[0] - '0')) + ".0";
|
||||||
start++;
|
start++;
|
||||||
}
|
}
|
||||||
out.push_back(units[start][0]);
|
out.push_back(units[start][0]);
|
||||||
|
@ -537,6 +548,74 @@ namespace Tools {
|
||||||
return (user != nullptr ? user : "");
|
return (user != nullptr ? user : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DebugTimer::DebugTimer(const string name, bool start, bool delayed_report) : name(name), delayed_report(delayed_report) {
|
||||||
|
if (start)
|
||||||
|
this->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugTimer::~DebugTimer() {
|
||||||
|
if (running)
|
||||||
|
this->stop(true);
|
||||||
|
this->force_report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTimer::start() {
|
||||||
|
if (running) return;
|
||||||
|
running = true;
|
||||||
|
start_time = time_micros();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTimer::stop(bool report) {
|
||||||
|
if (not running) return;
|
||||||
|
running = false;
|
||||||
|
elapsed_time = time_micros() - start_time;
|
||||||
|
if (report) this->report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTimer::reset(bool restart) {
|
||||||
|
running = false;
|
||||||
|
start_time = 0;
|
||||||
|
elapsed_time = 0;
|
||||||
|
if (restart) this->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTimer::stop_rename_reset(const string &new_name, bool report, bool restart) {
|
||||||
|
this->stop(report);
|
||||||
|
name = new_name;
|
||||||
|
this->reset(restart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTimer::report() {
|
||||||
|
string report_line;
|
||||||
|
if (start_time == 0 and elapsed_time == 0)
|
||||||
|
report_line = fmt::format("DebugTimer::report() warning -> Timer [{}] has not been started!", name);
|
||||||
|
else if (running)
|
||||||
|
report_line = fmt::format(custom_locale, "Timer [{}] (running) currently at {:L} μs", name, time_micros() - start_time);
|
||||||
|
else
|
||||||
|
report_line = fmt::format(custom_locale, "Timer [{}] took {:L} μs", name, elapsed_time);
|
||||||
|
|
||||||
|
if (delayed_report)
|
||||||
|
report_buffer.emplace_back(report_line);
|
||||||
|
else
|
||||||
|
Logger::log_write(log_level, report_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugTimer::force_report() {
|
||||||
|
if (report_buffer.empty()) return;
|
||||||
|
for (const auto& line : report_buffer)
|
||||||
|
Logger::log_write(log_level, line);
|
||||||
|
report_buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t DebugTimer::elapsed() {
|
||||||
|
if (running)
|
||||||
|
return time_micros() - start_time;
|
||||||
|
return elapsed_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugTimer::is_running() {
|
||||||
|
return running;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Logger {
|
namespace Logger {
|
||||||
|
@ -568,7 +647,7 @@ namespace Logger {
|
||||||
loglevel = v_index(log_levels, level);
|
loglevel = v_index(log_levels, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_write(const size_t level, const string& msg) {
|
void log_write(const Level level, const string& msg) {
|
||||||
if (loglevel < level or logfile.empty()) return;
|
if (loglevel < level or logfile.empty()) return;
|
||||||
atomic_lock lck(busy, true);
|
atomic_lock lck(busy, true);
|
||||||
lose_priv neutered{};
|
lose_priv neutered{};
|
||||||
|
|
|
@ -31,6 +31,10 @@ tab-size = 4
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#ifdef BTOP_DEBUG
|
||||||
|
#include <source_location>
|
||||||
|
#endif
|
||||||
#ifndef HOST_NAME_MAX
|
#ifndef HOST_NAME_MAX
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define HOST_NAME_MAX 255
|
#define HOST_NAME_MAX 255
|
||||||
|
@ -146,11 +150,46 @@ namespace Term {
|
||||||
void restore();
|
void restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//* Simple logging implementation
|
||||||
|
namespace Logger {
|
||||||
|
const vector<string> log_levels = {
|
||||||
|
"DISABLED",
|
||||||
|
"ERROR",
|
||||||
|
"WARNING",
|
||||||
|
"INFO",
|
||||||
|
"DEBUG",
|
||||||
|
};
|
||||||
|
extern std::filesystem::path logfile;
|
||||||
|
|
||||||
|
enum Level : size_t {
|
||||||
|
DISABLED = 0,
|
||||||
|
ERROR = 1,
|
||||||
|
WARNING = 2,
|
||||||
|
INFO = 3,
|
||||||
|
DEBUG = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
//* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
|
||||||
|
void set(const string& level);
|
||||||
|
|
||||||
|
void log_write(const Level level, const string& msg);
|
||||||
|
inline void error(const string msg) { log_write(ERROR, msg); }
|
||||||
|
inline void warning(const string msg) { log_write(WARNING, msg); }
|
||||||
|
inline void info(const string msg) { log_write(INFO, msg); }
|
||||||
|
inline void debug(const string msg) { log_write(DEBUG, msg); }
|
||||||
|
}
|
||||||
|
|
||||||
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
||||||
|
|
||||||
namespace Tools {
|
namespace Tools {
|
||||||
constexpr auto SSmax = std::numeric_limits<std::streamsize>::max();
|
constexpr auto SSmax = std::numeric_limits<std::streamsize>::max();
|
||||||
|
|
||||||
|
class MyNumPunct : public std::numpunct<char> {
|
||||||
|
protected:
|
||||||
|
virtual char do_thousands_sep() const { return '\''; }
|
||||||
|
virtual std::string do_grouping() const { return "\03"; }
|
||||||
|
};
|
||||||
|
|
||||||
size_t wide_ulen(const string& str);
|
size_t wide_ulen(const string& str);
|
||||||
size_t wide_ulen(const std::wstring& w_str);
|
size_t wide_ulen(const std::wstring& w_str);
|
||||||
|
|
||||||
|
@ -298,6 +337,50 @@ namespace Tools {
|
||||||
//* Add std::string operator * : Repeat string <str> <n> number of times
|
//* Add std::string operator * : Repeat string <str> <n> number of times
|
||||||
std::string operator*(const string& str, int64_t n);
|
std::string operator*(const string& str, int64_t n);
|
||||||
|
|
||||||
|
template <typename K, typename T>
|
||||||
|
#ifdef BTOP_DEBUG
|
||||||
|
const T& safeVal(const std::unordered_map<K, T>& map, const K& key, const T& fallback = T{}, std::source_location loc = std::source_location::current()) {
|
||||||
|
if (map.contains(key)) {
|
||||||
|
return map.at(key);
|
||||||
|
} else {
|
||||||
|
Logger::error(fmt::format("safeVal() called with invalid key: [{}] in file: {} on line: {}", key, loc.file_name(), loc.line()));
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
const T& safeVal(const std::unordered_map<K, T>& map, const K& key, const T& fallback = T{}) {
|
||||||
|
if (map.contains(key)) {
|
||||||
|
return map.at(key);
|
||||||
|
} else {
|
||||||
|
Logger::error(fmt::format("safeVal() called with invalid key: [{}] (Compile btop with DEBUG=true for more extensive logging!)", key));
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
#ifdef BTOP_DEBUG
|
||||||
|
const T& safeVal(const std::vector<T>& vec, const size_t& index, const T& fallback = T{}, std::source_location loc = std::source_location::current()) {
|
||||||
|
if (index < vec.size()) {
|
||||||
|
return vec.at(index);
|
||||||
|
} else {
|
||||||
|
Logger::error(fmt::format("safeVal() called with invalid index: [{}] in file: {} on line: {}", index, loc.file_name(), loc.line()));
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
const T& safeVal(const std::vector<T>& vec, const size_t& index, const T& fallback = T{}) {
|
||||||
|
if (index < vec.size()) {
|
||||||
|
return vec.at(index);
|
||||||
|
} else {
|
||||||
|
Logger::error(fmt::format("safeVal() called with invalid index: [{}] (Compile btop with DEBUG=true for more extensive logging!)", index));
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//* Return current time in <strf> format
|
//* Return current time in <strf> format
|
||||||
string strf_time(const string& strf);
|
string strf_time(const string& strf);
|
||||||
|
|
||||||
|
@ -334,27 +417,40 @@ namespace Tools {
|
||||||
|
|
||||||
//* Convert a celsius value to celsius, fahrenheit, kelvin or rankin and return tuple with new value and unit.
|
//* Convert a celsius value to celsius, fahrenheit, kelvin or rankin and return tuple with new value and unit.
|
||||||
auto celsius_to(const long long& celsius, const string& scale) -> tuple<long long, string>;
|
auto celsius_to(const long long& celsius, const string& scale) -> tuple<long long, string>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//* Simple logging implementation
|
namespace Tools {
|
||||||
namespace Logger {
|
//* Creates a named timer that is started on construct (by default) and reports elapsed time in microseconds to Logger::debug() on destruct if running
|
||||||
const vector<string> log_levels = {
|
//* Unless delayed_report is set to false, all reporting is buffered and delayed until DebugTimer is destructed or .force_report() is called
|
||||||
"DISABLED",
|
//* Usage example: Tools::DebugTimer timer(name:"myTimer", [start:true], [delayed_report:true]) // Create timer and start
|
||||||
"ERROR",
|
//* timer.stop(); // Stop timer and report elapsed time
|
||||||
"WARNING",
|
//* timer.stop_rename_reset("myTimer2"); // Stop timer, report elapsed time, rename timer, reset and restart
|
||||||
"INFO",
|
class DebugTimer {
|
||||||
"DEBUG",
|
uint64_t start_time{};
|
||||||
|
uint64_t elapsed_time{};
|
||||||
|
bool running{};
|
||||||
|
std::locale custom_locale = std::locale(std::locale::classic(), new Tools::MyNumPunct);
|
||||||
|
vector<string> report_buffer{};
|
||||||
|
public:
|
||||||
|
string name{};
|
||||||
|
bool delayed_report{};
|
||||||
|
Logger::Level log_level = Logger::DEBUG;
|
||||||
|
DebugTimer() = default;
|
||||||
|
DebugTimer(const string name, bool start = true, bool delayed_report = true);
|
||||||
|
~DebugTimer();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop(bool report = true);
|
||||||
|
void reset(bool restart = true);
|
||||||
|
//* Stops and reports (default), renames timer then resets and restarts (default)
|
||||||
|
void stop_rename_reset(const string& new_name, bool report = true, bool restart = true);
|
||||||
|
void report();
|
||||||
|
void force_report();
|
||||||
|
uint64_t elapsed();
|
||||||
|
bool is_running();
|
||||||
};
|
};
|
||||||
extern std::filesystem::path logfile;
|
|
||||||
|
|
||||||
//* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
|
|
||||||
void set(const string& level);
|
|
||||||
|
|
||||||
void log_write(const size_t level, const string& msg);
|
|
||||||
inline void error(const string msg) { log_write(1, msg); }
|
|
||||||
inline void warning(const string msg) { log_write(2, msg); }
|
|
||||||
inline void info(const string msg) { log_write(3, msg); }
|
|
||||||
inline void debug(const string msg) { log_write(4, msg); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ tab-size = 4
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "../btop_config.hpp"
|
#include "../btop_config.hpp"
|
||||||
#include "../btop_shared.hpp"
|
#include "../btop_shared.hpp"
|
||||||
|
@ -74,7 +75,7 @@ using namespace Tools;
|
||||||
namespace Cpu {
|
namespace Cpu {
|
||||||
vector<long long> core_old_totals;
|
vector<long long> core_old_totals;
|
||||||
vector<long long> core_old_idles;
|
vector<long long> core_old_idles;
|
||||||
vector<string> available_fields = {"total"};
|
vector<string> available_fields = {"Auto", "total"};
|
||||||
vector<string> available_sensors = {"Auto"};
|
vector<string> available_sensors = {"Auto"};
|
||||||
cpu_info current_cpu;
|
cpu_info current_cpu;
|
||||||
bool got_sensors = false, cpu_temp_only = false;
|
bool got_sensors = false, cpu_temp_only = false;
|
||||||
|
@ -98,7 +99,7 @@ namespace Cpu {
|
||||||
|
|
||||||
string cpu_sensor;
|
string cpu_sensor;
|
||||||
vector<string> core_sensors;
|
vector<string> core_sensors;
|
||||||
unordered_flat_map<int, int> core_mapping;
|
std::unordered_map<int, int> core_mapping;
|
||||||
} // namespace Cpu
|
} // namespace Cpu
|
||||||
|
|
||||||
namespace Mem {
|
namespace Mem {
|
||||||
|
@ -169,17 +170,23 @@ namespace Shared {
|
||||||
Cpu::current_cpu.temp.insert(Cpu::current_cpu.temp.begin(), Shared::coreCount + 1, {});
|
Cpu::current_cpu.temp.insert(Cpu::current_cpu.temp.begin(), Shared::coreCount + 1, {});
|
||||||
Cpu::core_old_totals.insert(Cpu::core_old_totals.begin(), Shared::coreCount, 0);
|
Cpu::core_old_totals.insert(Cpu::core_old_totals.begin(), Shared::coreCount, 0);
|
||||||
Cpu::core_old_idles.insert(Cpu::core_old_idles.begin(), Shared::coreCount, 0);
|
Cpu::core_old_idles.insert(Cpu::core_old_idles.begin(), Shared::coreCount, 0);
|
||||||
|
Logger::debug("Init -> Cpu::collect()");
|
||||||
Cpu::collect();
|
Cpu::collect();
|
||||||
for (auto &[field, vec] : Cpu::current_cpu.cpu_percent) {
|
for (auto &[field, vec] : Cpu::current_cpu.cpu_percent) {
|
||||||
if (not vec.empty() and not v_contains(Cpu::available_fields, field)) Cpu::available_fields.push_back(field);
|
if (not vec.empty() and not v_contains(Cpu::available_fields, field)) Cpu::available_fields.push_back(field);
|
||||||
}
|
}
|
||||||
|
Logger::debug("Init -> Cpu::get_cpuName()");
|
||||||
Cpu::cpuName = Cpu::get_cpuName();
|
Cpu::cpuName = Cpu::get_cpuName();
|
||||||
|
Logger::debug("Init -> Cpu::get_sensors()");
|
||||||
Cpu::got_sensors = Cpu::get_sensors();
|
Cpu::got_sensors = Cpu::get_sensors();
|
||||||
|
Logger::debug("Init -> Cpu::get_core_mapping()");
|
||||||
Cpu::core_mapping = Cpu::get_core_mapping();
|
Cpu::core_mapping = Cpu::get_core_mapping();
|
||||||
|
|
||||||
//? Init for namespace Mem
|
//? Init for namespace Mem
|
||||||
Mem::old_uptime = system_uptime();
|
Mem::old_uptime = system_uptime();
|
||||||
|
Logger::debug("Init -> Mem::collect()");
|
||||||
Mem::collect();
|
Mem::collect();
|
||||||
|
Logger::debug("Init -> Mem::get_zpools()");
|
||||||
Mem::get_zpools();
|
Mem::get_zpools();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +211,7 @@ namespace Cpu {
|
||||||
|
|
||||||
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
|
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
|
||||||
|
|
||||||
unordered_flat_map<string, long long> cpu_old = {
|
std::unordered_map<string, long long> cpu_old = {
|
||||||
{"totals", 0},
|
{"totals", 0},
|
||||||
{"idles", 0},
|
{"idles", 0},
|
||||||
{"user", 0},
|
{"user", 0},
|
||||||
|
@ -323,8 +330,8 @@ namespace Cpu {
|
||||||
return std::to_string(freq / 1000.0 ).substr(0, 3); // seems to be in MHz
|
return std::to_string(freq / 1000.0 ).substr(0, 3); // seems to be in MHz
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_core_mapping() -> unordered_flat_map<int, int> {
|
auto get_core_mapping() -> std::unordered_map<int, int> {
|
||||||
unordered_flat_map<int, int> core_map;
|
std::unordered_map<int, int> core_map;
|
||||||
if (cpu_temp_only) return core_map;
|
if (cpu_temp_only) return core_map;
|
||||||
|
|
||||||
for (long i = 0; i < Shared::coreCount; i++) {
|
for (long i = 0; i < Shared::coreCount; i++) {
|
||||||
|
@ -557,7 +564,7 @@ namespace Mem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_disk(unordered_flat_map<string, disk_info> &disks, unordered_flat_map<string, string> &mapping) {
|
void collect_disk(std::unordered_map<string, disk_info> &disks, std::unordered_map<string, string> &mapping) {
|
||||||
// this bit is for 'regular' mounts
|
// this bit is for 'regular' mounts
|
||||||
static struct statinfo cur;
|
static struct statinfo cur;
|
||||||
long double etime = 0;
|
long double etime = 0;
|
||||||
|
@ -572,7 +579,7 @@ namespace Mem {
|
||||||
auto d = cur.dinfo->devices[i];
|
auto d = cur.dinfo->devices[i];
|
||||||
string devStatName = "/dev/" + string(d.device_name) + std::to_string(d.unit_number);
|
string devStatName = "/dev/" + string(d.device_name) + std::to_string(d.unit_number);
|
||||||
for (auto& [ignored, disk] : disks) { // find matching mountpoints - could be multiple as d.device_name is only ada (and d.unit_number is the device number), while the disk.dev is like /dev/ada0s1
|
for (auto& [ignored, disk] : disks) { // find matching mountpoints - could be multiple as d.device_name is only ada (and d.unit_number is the device number), while the disk.dev is like /dev/ada0s1
|
||||||
if (disk.dev.string().rfind(devStatName, 0) == 0) {
|
if (disk.dev.string().rfind(devStatName, 0) == 0 and mapping.contains(disk.dev)) {
|
||||||
devstat_compute_statistics(&d, nullptr, etime, DSM_TOTAL_BYTES_READ, &total_bytes_read, DSM_TOTAL_BYTES_WRITE, &total_bytes_write, DSM_NONE);
|
devstat_compute_statistics(&d, nullptr, etime, DSM_TOTAL_BYTES_READ, &total_bytes_read, DSM_TOTAL_BYTES_WRITE, &total_bytes_write, DSM_NONE);
|
||||||
assign_values(disk, total_bytes_read, total_bytes_write);
|
assign_values(disk, total_bytes_read, total_bytes_write);
|
||||||
string mountpoint = mapping.at(disk.dev);
|
string mountpoint = mapping.at(disk.dev);
|
||||||
|
@ -581,7 +588,6 @@ namespace Mem {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Logger::debug("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this code is for ZFS mounts
|
// this code is for ZFS mounts
|
||||||
|
@ -691,7 +697,7 @@ namespace Mem {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_disks) {
|
if (show_disks) {
|
||||||
unordered_flat_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
|
std::unordered_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
|
||||||
double uptime = system_uptime();
|
double uptime = system_uptime();
|
||||||
auto &disks_filter = Config::getS("disks_filter");
|
auto &disks_filter = Config::getS("disks_filter");
|
||||||
bool filter_exclude = false;
|
bool filter_exclude = false;
|
||||||
|
@ -807,13 +813,13 @@ namespace Mem {
|
||||||
} // namespace Mem
|
} // namespace Mem
|
||||||
|
|
||||||
namespace Net {
|
namespace Net {
|
||||||
unordered_flat_map<string, net_info> current_net;
|
std::unordered_map<string, net_info> current_net;
|
||||||
net_info empty_net = {};
|
net_info empty_net = {};
|
||||||
vector<string> interfaces;
|
vector<string> interfaces;
|
||||||
string selected_iface;
|
string selected_iface;
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
unordered_flat_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
|
std::unordered_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
|
||||||
unordered_flat_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
|
std::unordered_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
|
||||||
bool rescale = true;
|
bool rescale = true;
|
||||||
uint64_t timestamp = 0;
|
uint64_t timestamp = 0;
|
||||||
|
|
||||||
|
@ -892,7 +898,7 @@ namespace Net {
|
||||||
} //else, ignoring family==AF_LINK (see man 3 getifaddrs)
|
} //else, ignoring family==AF_LINK (see man 3 getifaddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_flat_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
|
std::unordered_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
|
||||||
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
|
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
|
||||||
size_t len;
|
size_t len;
|
||||||
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
|
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
|
||||||
|
@ -966,7 +972,6 @@ namespace Net {
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
net.compact();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp = new_timestamp;
|
timestamp = new_timestamp;
|
||||||
|
@ -1037,7 +1042,7 @@ namespace Net {
|
||||||
namespace Proc {
|
namespace Proc {
|
||||||
|
|
||||||
vector<proc_info> current_procs;
|
vector<proc_info> current_procs;
|
||||||
unordered_flat_map<string, string> uid_user;
|
std::unordered_map<string, string> uid_user;
|
||||||
string current_sort;
|
string current_sort;
|
||||||
string current_filter;
|
string current_filter;
|
||||||
bool current_rev = false;
|
bool current_rev = false;
|
||||||
|
|
|
@ -17,7 +17,8 @@ tab-size = 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <robin_hood.h>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -29,6 +30,14 @@ tab-size = 4
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <arpa/inet.h> // for inet_ntop()
|
#include <arpa/inet.h> // for inet_ntop()
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <future>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#if defined(RSMI_STATIC)
|
||||||
|
#include <rocm_smi/rocm_smi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !(defined(STATIC_BUILD) && defined(__GLIBC__))
|
#if !(defined(STATIC_BUILD) && defined(__GLIBC__))
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
@ -48,18 +57,23 @@ using std::numeric_limits;
|
||||||
using std::round;
|
using std::round;
|
||||||
using std::streamsize;
|
using std::streamsize;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using std::future;
|
||||||
|
using std::async;
|
||||||
|
using std::pair;
|
||||||
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
namespace rng = std::ranges;
|
namespace rng = std::ranges;
|
||||||
|
|
||||||
using namespace Tools;
|
using namespace Tools;
|
||||||
using namespace std::literals; // for operator""s
|
using namespace std::literals; // for operator""s
|
||||||
|
using namespace std::chrono_literals;
|
||||||
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
||||||
|
|
||||||
namespace Cpu {
|
namespace Cpu {
|
||||||
vector<long long> core_old_totals;
|
vector<long long> core_old_totals;
|
||||||
vector<long long> core_old_idles;
|
vector<long long> core_old_idles;
|
||||||
vector<string> available_fields;
|
vector<string> available_fields = {"Auto", "total"};
|
||||||
vector<string> available_sensors = {"Auto"};
|
vector<string> available_sensors = {"Auto"};
|
||||||
cpu_info current_cpu;
|
cpu_info current_cpu;
|
||||||
fs::path freq_path = "/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq";
|
fs::path freq_path = "/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq";
|
||||||
|
@ -83,10 +97,110 @@ namespace Cpu {
|
||||||
int64_t crit{}; // defaults to 0
|
int64_t crit{}; // defaults to 0
|
||||||
};
|
};
|
||||||
|
|
||||||
unordered_flat_map<string, Sensor> found_sensors;
|
std::unordered_map<string, Sensor> found_sensors;
|
||||||
string cpu_sensor;
|
string cpu_sensor;
|
||||||
vector<string> core_sensors;
|
vector<string> core_sensors;
|
||||||
unordered_flat_map<int, int> core_mapping;
|
std::unordered_map<int, int> core_mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Gpu {
|
||||||
|
vector<gpu_info> gpus;
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
//? NVIDIA data collection
|
||||||
|
namespace Nvml {
|
||||||
|
//? NVML defines, structs & typedefs
|
||||||
|
#define NVML_DEVICE_NAME_BUFFER_SIZE 64
|
||||||
|
#define NVML_SUCCESS 0
|
||||||
|
#define NVML_TEMPERATURE_THRESHOLD_SHUTDOWN 0
|
||||||
|
#define NVML_CLOCK_GRAPHICS 0
|
||||||
|
#define NVML_CLOCK_MEM 2
|
||||||
|
#define NVML_TEMPERATURE_GPU 0
|
||||||
|
#define NVML_PCIE_UTIL_TX_BYTES 0
|
||||||
|
#define NVML_PCIE_UTIL_RX_BYTES 1
|
||||||
|
|
||||||
|
typedef void* nvmlDevice_t; // we won't be accessing any of the underlying struct's properties, so this is fine
|
||||||
|
typedef int nvmlReturn_t, // enums are basically ints
|
||||||
|
nvmlTemperatureThresholds_t,
|
||||||
|
nvmlClockType_t,
|
||||||
|
nvmlPstates_t,
|
||||||
|
nvmlTemperatureSensors_t,
|
||||||
|
nvmlPcieUtilCounter_t;
|
||||||
|
|
||||||
|
struct nvmlUtilization_t {unsigned int gpu, memory;};
|
||||||
|
struct nvmlMemory_t {unsigned long long total, free, used;};
|
||||||
|
|
||||||
|
//? Function pointers
|
||||||
|
const char* (*nvmlErrorString)(nvmlReturn_t);
|
||||||
|
nvmlReturn_t (*nvmlInit)();
|
||||||
|
nvmlReturn_t (*nvmlShutdown)();
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetCount)(unsigned int*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetHandleByIndex)(unsigned int, nvmlDevice_t*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetName)(nvmlDevice_t, char*, unsigned int);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetPowerManagementLimit)(nvmlDevice_t, unsigned int*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetTemperatureThreshold)(nvmlDevice_t, nvmlTemperatureThresholds_t, unsigned int*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetUtilizationRates)(nvmlDevice_t, nvmlUtilization_t*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetClockInfo)(nvmlDevice_t, nvmlClockType_t, unsigned int*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetPowerUsage)(nvmlDevice_t, unsigned int*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetPowerState)(nvmlDevice_t, nvmlPstates_t*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetTemperature)(nvmlDevice_t, nvmlTemperatureSensors_t, unsigned int*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetMemoryInfo)(nvmlDevice_t, nvmlMemory_t*);
|
||||||
|
nvmlReturn_t (*nvmlDeviceGetPcieThroughput)(nvmlDevice_t, nvmlPcieUtilCounter_t, unsigned int*);
|
||||||
|
|
||||||
|
//? Data
|
||||||
|
void* nvml_dl_handle;
|
||||||
|
bool initialized = false;
|
||||||
|
bool init();
|
||||||
|
bool shutdown();
|
||||||
|
template <bool is_init> bool collect(gpu_info* gpus_slice);
|
||||||
|
vector<nvmlDevice_t> devices;
|
||||||
|
unsigned int device_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? AMD data collection
|
||||||
|
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
|
||||||
|
|
||||||
|
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];};
|
||||||
|
|
||||||
|
//? Function pointers
|
||||||
|
rsmi_status_t (*rsmi_init)(uint64_t);
|
||||||
|
rsmi_status_t (*rsmi_shut_down)();
|
||||||
|
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_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*);
|
||||||
|
|
||||||
|
//? Data
|
||||||
|
void* rsmi_dl_handle;
|
||||||
|
#endif
|
||||||
|
bool initialized = false;
|
||||||
|
bool init();
|
||||||
|
bool shutdown();
|
||||||
|
template <bool is_init> bool collect(gpu_info* gpus_slice);
|
||||||
|
uint32_t device_count = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Mem {
|
namespace Mem {
|
||||||
|
@ -139,7 +253,7 @@ namespace Shared {
|
||||||
Cpu::collect();
|
Cpu::collect();
|
||||||
if (Runner::coreNum_reset) Runner::coreNum_reset = false;
|
if (Runner::coreNum_reset) Runner::coreNum_reset = false;
|
||||||
for (auto& [field, vec] : Cpu::current_cpu.cpu_percent) {
|
for (auto& [field, vec] : Cpu::current_cpu.cpu_percent) {
|
||||||
if (not vec.empty()) Cpu::available_fields.push_back(field);
|
if (not vec.empty() and not v_contains(Cpu::available_fields, field)) Cpu::available_fields.push_back(field);
|
||||||
}
|
}
|
||||||
Cpu::cpuName = Cpu::get_cpuName();
|
Cpu::cpuName = Cpu::get_cpuName();
|
||||||
Cpu::got_sensors = Cpu::get_sensors();
|
Cpu::got_sensors = Cpu::get_sensors();
|
||||||
|
@ -148,12 +262,32 @@ namespace Shared {
|
||||||
}
|
}
|
||||||
Cpu::core_mapping = Cpu::get_core_mapping();
|
Cpu::core_mapping = Cpu::get_core_mapping();
|
||||||
|
|
||||||
|
//? Init for namespace Gpu
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
Gpu::Nvml::init();
|
||||||
|
Gpu::Rsmi::init();
|
||||||
|
if (not Gpu::gpu_names.empty()) {
|
||||||
|
for (auto const& [key, _] : Gpu::gpus[0].gpu_percent)
|
||||||
|
Cpu::available_fields.push_back(key);
|
||||||
|
for (auto const& [key, _] : Gpu::shared_gpu_percent)
|
||||||
|
Cpu::available_fields.push_back(key);
|
||||||
|
|
||||||
|
using namespace Gpu;
|
||||||
|
gpu_b_height_offsets.resize(gpus.size());
|
||||||
|
for (size_t i = 0; i < gpu_b_height_offsets.size(); ++i)
|
||||||
|
gpu_b_height_offsets[i] = gpus[i].supported_functions.gpu_utilization
|
||||||
|
+ gpus[i].supported_functions.pwr_usage
|
||||||
|
+ (gpus[i].supported_functions.mem_total or gpus[i].supported_functions.mem_used)
|
||||||
|
* (1 + 2*(gpus[i].supported_functions.mem_total and gpus[i].supported_functions.mem_used) + 2*gpus[i].supported_functions.mem_utilization);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//? Init for namespace Mem
|
//? Init for namespace Mem
|
||||||
Mem::old_uptime = system_uptime();
|
Mem::old_uptime = system_uptime();
|
||||||
Mem::collect();
|
Mem::collect();
|
||||||
|
|
||||||
|
Logger::debug("Shared::init() : Initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Cpu {
|
namespace Cpu {
|
||||||
|
@ -167,7 +301,7 @@ namespace Cpu {
|
||||||
"irq"s, "softirq"s, "steal"s, "guest"s, "guest_nice"s
|
"irq"s, "softirq"s, "steal"s, "guest"s, "guest_nice"s
|
||||||
};
|
};
|
||||||
|
|
||||||
unordered_flat_map<string, long long> cpu_old = {
|
std::unordered_map<string, long long> cpu_old = {
|
||||||
{"totals", 0},
|
{"totals", 0},
|
||||||
{"idles", 0},
|
{"idles", 0},
|
||||||
{"user", 0},
|
{"user", 0},
|
||||||
|
@ -208,7 +342,7 @@ namespace Cpu {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name_vec = ssplit(name);
|
auto name_vec = ssplit(name, ' ');
|
||||||
|
|
||||||
if ((s_contains(name, "Xeon"s) or v_contains(name_vec, "Duo"s)) and v_contains(name_vec, "CPU"s)) {
|
if ((s_contains(name, "Xeon"s) or v_contains(name_vec, "Duo"s)) and v_contains(name_vec, "CPU"s)) {
|
||||||
auto cpu_pos = v_index(name_vec, "CPU"s);
|
auto cpu_pos = v_index(name_vec, "CPU"s);
|
||||||
|
@ -224,7 +358,7 @@ namespace Cpu {
|
||||||
}
|
}
|
||||||
else if (s_contains(name, "Intel"s) and v_contains(name_vec, "CPU"s)) {
|
else if (s_contains(name, "Intel"s) and v_contains(name_vec, "CPU"s)) {
|
||||||
auto cpu_pos = v_index(name_vec, "CPU"s);
|
auto cpu_pos = v_index(name_vec, "CPU"s);
|
||||||
if (cpu_pos < name_vec.size() - 1 and not name_vec.at(cpu_pos + 1).ends_with(')') and name_vec.at(cpu_pos + 1) != "@")
|
if (cpu_pos < name_vec.size() - 1 and not name_vec.at(cpu_pos + 1).ends_with(')') and name_vec.at(cpu_pos + 1).size() != 1)
|
||||||
name = name_vec.at(cpu_pos + 1);
|
name = name_vec.at(cpu_pos + 1);
|
||||||
else
|
else
|
||||||
name.clear();
|
name.clear();
|
||||||
|
@ -464,8 +598,8 @@ namespace Cpu {
|
||||||
return cpuhz;
|
return cpuhz;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_core_mapping() -> unordered_flat_map<int, int> {
|
auto get_core_mapping() -> std::unordered_map<int, int> {
|
||||||
unordered_flat_map<int, int> core_map;
|
std::unordered_map<int, int> core_map;
|
||||||
if (cpu_temp_only) return core_map;
|
if (cpu_temp_only) return core_map;
|
||||||
|
|
||||||
//? Try to get core mapping from /proc/cpuinfo
|
//? Try to get core mapping from /proc/cpuinfo
|
||||||
|
@ -538,7 +672,7 @@ namespace Cpu {
|
||||||
auto get_battery() -> tuple<int, long, string> {
|
auto get_battery() -> tuple<int, long, string> {
|
||||||
if (not has_battery) return {0, 0, ""};
|
if (not has_battery) return {0, 0, ""};
|
||||||
static string auto_sel;
|
static string auto_sel;
|
||||||
static unordered_flat_map<string, battery> batteries;
|
static std::unordered_map<string, battery> batteries;
|
||||||
|
|
||||||
//? Get paths to needed files and check for valid values on first run
|
//? Get paths to needed files and check for valid values on first run
|
||||||
if (batteries.empty() and has_battery) {
|
if (batteries.empty() and has_battery) {
|
||||||
|
@ -807,6 +941,572 @@ namespace Cpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GPU_SUPPORT
|
||||||
|
namespace Gpu {
|
||||||
|
//? NVIDIA
|
||||||
|
namespace Nvml {
|
||||||
|
bool init() {
|
||||||
|
if (initialized) return false;
|
||||||
|
|
||||||
|
//? Dynamic loading & linking
|
||||||
|
//? Try possible library names for libnvidia-ml.so
|
||||||
|
const array libNvAlts = {
|
||||||
|
"libnvidia-ml.so",
|
||||||
|
"libnvidia-ml.so.1",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& l : libNvAlts) {
|
||||||
|
nvml_dl_handle = dlopen(l, RTLD_LAZY);
|
||||||
|
if (nvml_dl_handle != nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!nvml_dl_handle) {
|
||||||
|
Logger::info("Failed to load libnvidia-ml.so, NVIDIA GPUs will not be detected: "s + dlerror());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto load_nvml_sym = [&](const char sym_name[]) {
|
||||||
|
auto sym = dlsym(nvml_dl_handle, sym_name);
|
||||||
|
auto err = dlerror();
|
||||||
|
if (err != nullptr) {
|
||||||
|
Logger::error(string("NVML: Couldn't find function ") + sym_name + ": " + err);
|
||||||
|
return (void*)nullptr;
|
||||||
|
} else return sym;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOAD_SYM(NAME) if ((NAME = (decltype(NAME))load_nvml_sym(#NAME)) == nullptr) return false
|
||||||
|
|
||||||
|
LOAD_SYM(nvmlErrorString);
|
||||||
|
LOAD_SYM(nvmlInit);
|
||||||
|
LOAD_SYM(nvmlShutdown);
|
||||||
|
LOAD_SYM(nvmlDeviceGetCount);
|
||||||
|
LOAD_SYM(nvmlDeviceGetHandleByIndex);
|
||||||
|
LOAD_SYM(nvmlDeviceGetName);
|
||||||
|
LOAD_SYM(nvmlDeviceGetPowerManagementLimit);
|
||||||
|
LOAD_SYM(nvmlDeviceGetTemperatureThreshold);
|
||||||
|
LOAD_SYM(nvmlDeviceGetUtilizationRates);
|
||||||
|
LOAD_SYM(nvmlDeviceGetClockInfo);
|
||||||
|
LOAD_SYM(nvmlDeviceGetPowerUsage);
|
||||||
|
LOAD_SYM(nvmlDeviceGetPowerState);
|
||||||
|
LOAD_SYM(nvmlDeviceGetTemperature);
|
||||||
|
LOAD_SYM(nvmlDeviceGetMemoryInfo);
|
||||||
|
LOAD_SYM(nvmlDeviceGetPcieThroughput);
|
||||||
|
|
||||||
|
#undef LOAD_SYM
|
||||||
|
|
||||||
|
//? Function calls
|
||||||
|
nvmlReturn_t result = nvmlInit();
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::debug(std::string("Failed to initialize NVML, NVIDIA GPUs will not be detected: ") + nvmlErrorString(result));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Device count
|
||||||
|
result = nvmlDeviceGetCount(&device_count);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get device count: ") + nvmlErrorString(result));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_count > 0) {
|
||||||
|
devices.resize(device_count);
|
||||||
|
gpus.resize(device_count);
|
||||||
|
gpu_names.resize(device_count);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
//? Check supported functions & get maximums
|
||||||
|
Nvml::collect<1>(gpus.data());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {initialized = true; shutdown(); return false;}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shutdown() {
|
||||||
|
if (!initialized) return false;
|
||||||
|
nvmlReturn_t result = nvmlShutdown();
|
||||||
|
if (NVML_SUCCESS == result) {
|
||||||
|
initialized = false;
|
||||||
|
dlclose(nvml_dl_handle);
|
||||||
|
} else Logger::warning(std::string("Failed to shutdown NVML: ") + nvmlErrorString(result));
|
||||||
|
|
||||||
|
return !initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool is_init> // collect<1> is called in Nvml::init(), and populates gpus.supported_functions
|
||||||
|
bool collect(gpu_info* gpus_slice) { // raw pointer to vector data, size == device_count
|
||||||
|
if (!initialized) return false;
|
||||||
|
|
||||||
|
nvmlReturn_t result;
|
||||||
|
std::thread pcie_tx_thread, pcie_rx_thread;
|
||||||
|
// DebugTimer nvTotalTimer("Nvidia Total");
|
||||||
|
for (unsigned int i = 0; i < device_count; ++i) {
|
||||||
|
if constexpr(is_init) {
|
||||||
|
//? Device Handle
|
||||||
|
result = nvmlDeviceGetHandleByIndex(i, devices.data() + i);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get device handle: ") + nvmlErrorString(result));
|
||||||
|
gpus[i].supported_functions = {false, false, false, false, false, false, false, false};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Device name
|
||||||
|
char name[NVML_DEVICE_NAME_BUFFER_SIZE];
|
||||||
|
result = nvmlDeviceGetName(devices[i], name, NVML_DEVICE_NAME_BUFFER_SIZE);
|
||||||
|
if (result != NVML_SUCCESS)
|
||||||
|
Logger::warning(std::string("NVML: Failed to get device name: ") + nvmlErrorString(result));
|
||||||
|
else {
|
||||||
|
gpu_names[i] = string(name);
|
||||||
|
for (const auto& brand : {"NVIDIA", "Nvidia", "(R)", "(TM)"}) {
|
||||||
|
gpu_names[i] = s_replace(gpu_names[i], brand, "");
|
||||||
|
}
|
||||||
|
gpu_names[i] = trim(gpu_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Power usage
|
||||||
|
unsigned int max_power;
|
||||||
|
result = nvmlDeviceGetPowerManagementLimit(devices[i], &max_power);
|
||||||
|
if (result != NVML_SUCCESS)
|
||||||
|
Logger::warning(std::string("NVML: Failed to get maximum GPU power draw, defaulting to 225W: ") + nvmlErrorString(result));
|
||||||
|
else {
|
||||||
|
gpus[i].pwr_max_usage = max_power; // RSMI reports power in microWatts
|
||||||
|
gpu_pwr_total_max += max_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Get temp_max
|
||||||
|
unsigned int temp_max;
|
||||||
|
result = nvmlDeviceGetTemperatureThreshold(devices[i], NVML_TEMPERATURE_THRESHOLD_SHUTDOWN, &temp_max);
|
||||||
|
if (result != NVML_SUCCESS)
|
||||||
|
Logger::warning(std::string("NVML: Failed to get maximum GPU temperature, defaulting to 110°C: ") + nvmlErrorString(result));
|
||||||
|
else gpus[i].temp_max = (long long)temp_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? PCIe link speeds, the data collection takes >=20ms each call so they run on separate threads
|
||||||
|
if (gpus_slice[i].supported_functions.pcie_txrx and (Config::getB("nvml_measure_pcie_speeds") or is_init)) {
|
||||||
|
pcie_tx_thread = std::thread([gpus_slice, i]() {
|
||||||
|
unsigned int tx;
|
||||||
|
nvmlReturn_t result = nvmlDeviceGetPcieThroughput(devices[i], NVML_PCIE_UTIL_TX_BYTES, &tx);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get PCIe TX throughput: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.pcie_txrx = false;
|
||||||
|
} else gpus_slice[i].pcie_tx = (long long)tx;
|
||||||
|
});
|
||||||
|
|
||||||
|
pcie_rx_thread = std::thread([gpus_slice, i]() {
|
||||||
|
unsigned int rx;
|
||||||
|
nvmlReturn_t result = nvmlDeviceGetPcieThroughput(devices[i], NVML_PCIE_UTIL_RX_BYTES, &rx);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get PCIe RX throughput: ") + nvmlErrorString(result));
|
||||||
|
} else gpus_slice[i].pcie_rx = (long long)rx;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// DebugTimer nvTimer("Nv utilization");
|
||||||
|
//? GPU & memory utilization
|
||||||
|
if (gpus_slice[i].supported_functions.gpu_utilization) {
|
||||||
|
nvmlUtilization_t utilization;
|
||||||
|
result = nvmlDeviceGetUtilizationRates(devices[i], &utilization);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get GPU utilization: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.gpu_utilization = false;
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.mem_utilization = false;
|
||||||
|
} else {
|
||||||
|
gpus_slice[i].gpu_percent.at("gpu-totals").push_back((long long)utilization.gpu);
|
||||||
|
gpus_slice[i].mem_utilization_percent.push_back((long long)utilization.memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nvTimer.stop_rename_reset("Nv clock");
|
||||||
|
//? Clock speeds
|
||||||
|
if (gpus_slice[i].supported_functions.gpu_clock) {
|
||||||
|
unsigned int gpu_clock;
|
||||||
|
result = nvmlDeviceGetClockInfo(devices[i], NVML_CLOCK_GRAPHICS, &gpu_clock);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get GPU clock speed: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.gpu_clock = false;
|
||||||
|
} else gpus_slice[i].gpu_clock_speed = (long long)gpu_clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpus_slice[i].supported_functions.mem_clock) {
|
||||||
|
unsigned int mem_clock;
|
||||||
|
result = nvmlDeviceGetClockInfo(devices[i], NVML_CLOCK_MEM, &mem_clock);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get VRAM clock speed: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.mem_clock = false;
|
||||||
|
} else gpus_slice[i].mem_clock_speed = (long long)mem_clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nvTimer.stop_rename_reset("Nv power");
|
||||||
|
//? Power usage & state
|
||||||
|
if (gpus_slice[i].supported_functions.pwr_usage) {
|
||||||
|
unsigned int power;
|
||||||
|
result = nvmlDeviceGetPowerUsage(devices[i], &power);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get GPU power usage: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.pwr_usage = false;
|
||||||
|
} else {
|
||||||
|
gpus_slice[i].pwr_usage = (long long)power;
|
||||||
|
gpus_slice[i].gpu_percent.at("gpu-pwr-totals").push_back(clamp((long long)round((double)gpus_slice[i].pwr_usage * 100.0 / (double)gpus_slice[i].pwr_max_usage), 0ll, 100ll));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpus_slice[i].supported_functions.pwr_state) {
|
||||||
|
nvmlPstates_t pState;
|
||||||
|
result = nvmlDeviceGetPowerState(devices[i], &pState);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get GPU power state: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.pwr_state = false;
|
||||||
|
} else gpus_slice[i].pwr_state = static_cast<int>(pState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// nvTimer.stop_rename_reset("Nv temp");
|
||||||
|
//? GPU temperature
|
||||||
|
if (gpus_slice[i].supported_functions.temp_info) {
|
||||||
|
if (Config::getB("check_temp")) {
|
||||||
|
unsigned int temp;
|
||||||
|
nvmlReturn_t result = nvmlDeviceGetTemperature(devices[i], NVML_TEMPERATURE_GPU, &temp);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get GPU temperature: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.temp_info = false;
|
||||||
|
} else gpus_slice[i].temp.push_back((long long)temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nvTimer.stop_rename_reset("Nv mem");
|
||||||
|
//? Memory info
|
||||||
|
if (gpus_slice[i].supported_functions.mem_total) {
|
||||||
|
nvmlMemory_t memory;
|
||||||
|
result = nvmlDeviceGetMemoryInfo(devices[i], &memory);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get VRAM info: ") + nvmlErrorString(result));
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.mem_total = false;
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.mem_used = false;
|
||||||
|
} else {
|
||||||
|
gpus_slice[i].mem_total = memory.total;
|
||||||
|
gpus_slice[i].mem_used = memory.used;
|
||||||
|
//gpu.mem_free = memory.free;
|
||||||
|
|
||||||
|
auto used_percent = (long long)round((double)memory.used * 100.0 / (double)memory.total);
|
||||||
|
gpus_slice[i].gpu_percent.at("gpu-vram-totals").push_back(used_percent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//? TODO: Processes using GPU
|
||||||
|
/*unsigned int proc_info_len;
|
||||||
|
nvmlProcessInfo_t* proc_info = 0;
|
||||||
|
result = nvmlDeviceGetComputeRunningProcesses_v3(device, &proc_info_len, proc_info);
|
||||||
|
if (result != NVML_SUCCESS) {
|
||||||
|
Logger::warning(std::string("NVML: Failed to get compute processes: ") + nvmlErrorString(result));
|
||||||
|
} else {
|
||||||
|
for (unsigned int i = 0; i < proc_info_len; ++i)
|
||||||
|
gpus_slice[i].graphics_processes.push_back({proc_info[i].pid, proc_info[i].usedGpuMemory});
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// nvTimer.stop_rename_reset("Nv pcie thread join");
|
||||||
|
//? Join PCIE TX/RX threads
|
||||||
|
if constexpr(is_init) { // there doesn't seem to be a better way to do this, but this should be fine considering it's just 2 lines
|
||||||
|
pcie_tx_thread.join();
|
||||||
|
pcie_rx_thread.join();
|
||||||
|
} else if (gpus_slice[i].supported_functions.pcie_txrx and Config::getB("nvml_measure_pcie_speeds")) {
|
||||||
|
pcie_tx_thread.join();
|
||||||
|
pcie_rx_thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//? AMD
|
||||||
|
namespace Rsmi {
|
||||||
|
bool init() {
|
||||||
|
if (initialized) return false;
|
||||||
|
|
||||||
|
//? Dynamic loading & linking
|
||||||
|
#if !defined(RSMI_STATIC)
|
||||||
|
|
||||||
|
//? Try possible library paths and names for librocm_smi64.so
|
||||||
|
const array libRocAlts = {
|
||||||
|
"/opt/rocm/lib/librocm_smi64.so",
|
||||||
|
"librocm_smi64.so",
|
||||||
|
"librocm_smi64.so.5", // fedora
|
||||||
|
"librocm_smi64.so.1.0", // debian
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& l : libRocAlts) {
|
||||||
|
rsmi_dl_handle = dlopen(l, RTLD_LAZY);
|
||||||
|
if (rsmi_dl_handle != nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rsmi_dl_handle) {
|
||||||
|
Logger::info("Failed to load librocm_smi64.so, AMD GPUs will not be detected: "s + dlerror());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto load_rsmi_sym = [&](const char sym_name[]) {
|
||||||
|
auto sym = dlsym(rsmi_dl_handle, sym_name);
|
||||||
|
auto err = dlerror();
|
||||||
|
if (err != nullptr) {
|
||||||
|
Logger::error(string("ROCm SMI: Couldn't find function ") + sym_name + ": " + err);
|
||||||
|
return (void*)nullptr;
|
||||||
|
} else return sym;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOAD_SYM(NAME) if ((NAME = (decltype(NAME))load_rsmi_sym(#NAME)) == nullptr) return false
|
||||||
|
|
||||||
|
LOAD_SYM(rsmi_init);
|
||||||
|
LOAD_SYM(rsmi_shut_down);
|
||||||
|
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);
|
||||||
|
LOAD_SYM(rsmi_dev_pci_throughput_get);
|
||||||
|
|
||||||
|
#undef LOAD_SYM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//? Function calls
|
||||||
|
rsmi_status_t result = rsmi_init(0);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::debug("Failed to initialize ROCm SMI, AMD GPUs will not be detected");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Device count
|
||||||
|
result = rsmi_num_monitor_devices(&device_count);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to fetch number of devices");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_count > 0) {
|
||||||
|
gpus.resize(gpus.size() + device_count);
|
||||||
|
gpu_names.resize(gpus.size() + device_count);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
//? Check supported functions & get maximums
|
||||||
|
Rsmi::collect<1>(gpus.data() + Nvml::device_count);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {initialized = true; shutdown(); return false;}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shutdown() {
|
||||||
|
if (!initialized) return false;
|
||||||
|
if (rsmi_shut_down() == RSMI_STATUS_SUCCESS) {
|
||||||
|
initialized = false;
|
||||||
|
#if !defined(RSMI_STATIC)
|
||||||
|
dlclose(rsmi_dl_handle);
|
||||||
|
#endif
|
||||||
|
} else Logger::warning("Failed to shutdown ROCm SMI");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool is_init>
|
||||||
|
bool collect(gpu_info* gpus_slice) { // raw pointer to vector data, size == device_count, offset by Nvml::device_count elements
|
||||||
|
if (!initialized) return false;
|
||||||
|
rsmi_status_t result;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < device_count; ++i) {
|
||||||
|
if constexpr(is_init) {
|
||||||
|
//? Device name
|
||||||
|
char name[NVML_DEVICE_NAME_BUFFER_SIZE]; // ROCm SMI does not provide a constant for this as far as I can tell, this should be good enough
|
||||||
|
result = rsmi_dev_name_get(i, name, NVML_DEVICE_NAME_BUFFER_SIZE);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS)
|
||||||
|
Logger::warning("ROCm SMI: Failed to get device name");
|
||||||
|
else gpu_names[Nvml::device_count + i] = string(name);
|
||||||
|
|
||||||
|
//? Power usage
|
||||||
|
uint64_t max_power;
|
||||||
|
result = rsmi_dev_power_cap_get(i, 0, &max_power);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS)
|
||||||
|
Logger::warning("ROCm SMI: Failed to get maximum GPU power draw, defaulting to 225W");
|
||||||
|
else {
|
||||||
|
gpus_slice[i].pwr_max_usage = (long long)(max_power/1000); // RSMI reports power in microWatts
|
||||||
|
gpu_pwr_total_max += gpus_slice[i].pwr_max_usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Get temp_max
|
||||||
|
int64_t temp_max;
|
||||||
|
result = rsmi_dev_temp_metric_get(i, RSMI_TEMP_TYPE_EDGE, RSMI_TEMP_MAX, &temp_max);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS)
|
||||||
|
Logger::warning("ROCm SMI: Failed to get maximum GPU temperature, defaulting to 110°C");
|
||||||
|
else gpus_slice[i].temp_max = (long long)temp_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? GPU utilization
|
||||||
|
if (gpus_slice[i].supported_functions.gpu_utilization) {
|
||||||
|
uint32_t utilization;
|
||||||
|
result = rsmi_dev_busy_percent_get(i, &utilization);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to get GPU utilization");
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.gpu_utilization = false;
|
||||||
|
} else gpus_slice[i].gpu_percent.at("gpu-totals").push_back((long long)utilization);
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Memory utilization
|
||||||
|
if (gpus_slice[i].supported_functions.mem_utilization) {
|
||||||
|
uint32_t utilization;
|
||||||
|
result = rsmi_dev_memory_busy_percent_get(i, &utilization);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to get VRAM utilization");
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.mem_utilization = false;
|
||||||
|
} else gpus_slice[i].mem_utilization_percent.push_back((long long)utilization);
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Clock speeds
|
||||||
|
if (gpus_slice[i].supported_functions.gpu_clock) {
|
||||||
|
rsmi_frequencies_t frequencies;
|
||||||
|
result = rsmi_dev_gpu_clk_freq_get(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) {
|
||||||
|
rsmi_frequencies_t frequencies;
|
||||||
|
result = rsmi_dev_gpu_clk_freq_get(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
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Power usage & state
|
||||||
|
if (gpus_slice[i].supported_functions.pwr_usage) {
|
||||||
|
uint64_t power;
|
||||||
|
result = rsmi_dev_power_ave_get(i, 0, &power);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to get GPU power usage");
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.pwr_usage = false;
|
||||||
|
} else gpus_slice[i].gpu_percent.at("gpu-pwr-totals").push_back(clamp((long long)round((double)gpus_slice[i].pwr_usage * 100.0 / (double)gpus_slice[i].pwr_max_usage), 0ll, 100ll));
|
||||||
|
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.pwr_state = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//? GPU temperature
|
||||||
|
if (gpus_slice[i].supported_functions.temp_info) {
|
||||||
|
if (Config::getB("check_temp") or is_init) {
|
||||||
|
int64_t temp;
|
||||||
|
result = rsmi_dev_temp_metric_get(i, RSMI_TEMP_TYPE_EDGE, RSMI_TEMP_CURRENT, &temp);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to get GPU temperature");
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.temp_info = false;
|
||||||
|
} else gpus_slice[i].temp.push_back((long long)temp/1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//? Memory info
|
||||||
|
if (gpus_slice[i].supported_functions.mem_total) {
|
||||||
|
uint64_t total;
|
||||||
|
result = rsmi_dev_memory_total_get(i, RSMI_MEM_TYPE_VRAM, &total);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to get total VRAM");
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.mem_total = false;
|
||||||
|
} else gpus_slice[i].mem_total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpus_slice[i].supported_functions.mem_used) {
|
||||||
|
uint64_t used;
|
||||||
|
result = rsmi_dev_memory_usage_get(i, RSMI_MEM_TYPE_VRAM, &used);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to get VRAM usage");
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.mem_used = false;
|
||||||
|
} else {
|
||||||
|
gpus_slice[i].mem_used = used;
|
||||||
|
if (gpus_slice[i].supported_functions.mem_total)
|
||||||
|
gpus_slice[i].gpu_percent.at("gpu-vram-totals").push_back((long long)round((double)used * 100.0 / (double)gpus_slice[i].mem_total));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//? PCIe link speeds
|
||||||
|
if (gpus_slice[i].supported_functions.pcie_txrx) {
|
||||||
|
uint64_t tx, rx;
|
||||||
|
result = rsmi_dev_pci_throughput_get(i, &tx, &rx, 0);
|
||||||
|
if (result != RSMI_STATUS_SUCCESS) {
|
||||||
|
Logger::warning("ROCm SMI: Failed to get PCIe throughput");
|
||||||
|
if constexpr(is_init) gpus_slice[i].supported_functions.pcie_txrx = false;
|
||||||
|
} else {
|
||||||
|
gpus_slice[i].pcie_tx = (long long)tx;
|
||||||
|
gpus_slice[i].pcie_rx = (long long)rx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Intel
|
||||||
|
|
||||||
|
//? Collect data from GPU-specific libraries
|
||||||
|
auto collect(bool no_update) -> vector<gpu_info>& {
|
||||||
|
if (Runner::stopping or (no_update and not gpus.empty())) return gpus;
|
||||||
|
|
||||||
|
// DebugTimer gpu_timer("GPU Total");
|
||||||
|
|
||||||
|
//* Collect data
|
||||||
|
Nvml::collect<0>(gpus.data()); // raw pointer to vector data, size == Nvml::device_count
|
||||||
|
Rsmi::collect<0>(gpus.data() + Nvml::device_count); // size = Rsmi::device_count
|
||||||
|
|
||||||
|
//* Calculate average usage
|
||||||
|
long long avg = 0;
|
||||||
|
long long mem_usage_total = 0;
|
||||||
|
long long mem_total = 0;
|
||||||
|
long long pwr_total = 0;
|
||||||
|
for (auto& gpu : gpus) {
|
||||||
|
if (gpu.supported_functions.gpu_utilization)
|
||||||
|
avg += gpu.gpu_percent.at("gpu-totals").back();
|
||||||
|
if (gpu.supported_functions.mem_used)
|
||||||
|
mem_usage_total += gpu.mem_used;
|
||||||
|
if (gpu.supported_functions.mem_total)
|
||||||
|
mem_total += gpu.mem_total;
|
||||||
|
if (gpu.supported_functions.pwr_usage)
|
||||||
|
mem_total += gpu.pwr_usage;
|
||||||
|
|
||||||
|
//* Trim vectors if there are more values than needed for graphs
|
||||||
|
if (width != 0) {
|
||||||
|
//? GPU & memory utilization
|
||||||
|
while (cmp_greater(gpu.gpu_percent.at("gpu-totals").size(), width * 2)) gpu.gpu_percent.at("gpu-totals").pop_front();
|
||||||
|
while (cmp_greater(gpu.mem_utilization_percent.size(), width)) gpu.mem_utilization_percent.pop_front();
|
||||||
|
//? Power usage
|
||||||
|
while (cmp_greater(gpu.gpu_percent.at("gpu-pwr-totals").size(), width)) gpu.gpu_percent.at("gpu-pwr-totals").pop_front();
|
||||||
|
//? Temperature
|
||||||
|
while (cmp_greater(gpu.temp.size(), 18)) gpu.temp.pop_front();
|
||||||
|
//? Memory usage
|
||||||
|
while (cmp_greater(gpu.gpu_percent.at("gpu-vram-totals").size(), width/2)) gpu.gpu_percent.at("gpu-vram-totals").pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_gpu_percent.at("gpu-average").push_back(avg / gpus.size());
|
||||||
|
if (mem_total != 0)
|
||||||
|
shared_gpu_percent.at("gpu-vram-total").push_back(mem_usage_total / mem_total);
|
||||||
|
if (gpu_pwr_total_max != 0)
|
||||||
|
shared_gpu_percent.at("gpu-pwr-total").push_back(pwr_total / gpu_pwr_total_max);
|
||||||
|
|
||||||
|
if (width != 0) {
|
||||||
|
while (cmp_greater(shared_gpu_percent.at("gpu-average").size(), width * 2)) shared_gpu_percent.at("gpu-average").pop_front();
|
||||||
|
while (cmp_greater(shared_gpu_percent.at("gpu-pwr-total").size(), width * 2)) shared_gpu_percent.at("gpu-pwr-total").pop_front();
|
||||||
|
while (cmp_greater(shared_gpu_percent.at("gpu-vram-total").size(), width * 2)) shared_gpu_percent.at("gpu-vram-total").pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
return gpus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Mem {
|
namespace Mem {
|
||||||
bool has_swap{}; // defaults to false
|
bool has_swap{}; // defaults to false
|
||||||
vector<string> fstab;
|
vector<string> fstab;
|
||||||
|
@ -939,6 +1639,7 @@ namespace Mem {
|
||||||
auto only_physical = Config::getB("only_physical");
|
auto only_physical = Config::getB("only_physical");
|
||||||
auto zfs_hide_datasets = Config::getB("zfs_hide_datasets");
|
auto zfs_hide_datasets = Config::getB("zfs_hide_datasets");
|
||||||
auto& disks = mem.disks;
|
auto& disks = mem.disks;
|
||||||
|
static std::unordered_map<string, future<pair<disk_info, int>>> disks_stats_promises;
|
||||||
ifstream diskread;
|
ifstream diskread;
|
||||||
|
|
||||||
vector<string> filter;
|
vector<string> filter;
|
||||||
|
@ -1078,31 +1779,47 @@ namespace Mem {
|
||||||
diskread.close();
|
diskread.close();
|
||||||
|
|
||||||
//? Get disk/partition stats
|
//? Get disk/partition stats
|
||||||
bool new_ignored = false;
|
for (auto it = disks.begin(); it != disks.end(); ) {
|
||||||
for (auto& [mountpoint, disk] : disks) {
|
auto &[mountpoint, disk] = *it;
|
||||||
if (std::error_code ec; not fs::exists(mountpoint, ec) or v_contains(ignore_list, mountpoint)) continue;
|
if (v_contains(ignore_list, mountpoint) or disk.name == "swap") {
|
||||||
struct statvfs vfs;
|
it = disks.erase(it);
|
||||||
if (statvfs(mountpoint.c_str(), &vfs) < 0) {
|
|
||||||
Logger::warning("Failed to get disk/partition stats for mount \""+ mountpoint + "\" with statvfs error code: " + to_string(errno) + ". Ignoring...");
|
|
||||||
ignore_list.push_back(mountpoint);
|
|
||||||
new_ignored = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
disk.total = vfs.f_blocks * vfs.f_frsize;
|
if(auto promises_it = disks_stats_promises.find(mountpoint); promises_it != disks_stats_promises.end()){
|
||||||
disk.free = (free_priv ? vfs.f_bfree : vfs.f_bavail) * vfs.f_frsize;
|
auto& promise = promises_it->second;
|
||||||
disk.used = disk.total - disk.free;
|
if(promise.valid() &&
|
||||||
disk.used_percent = round((double)disk.used * 100 / disk.total);
|
promise.wait_for(0s) == std::future_status::timeout) {
|
||||||
disk.free_percent = 100 - disk.used_percent;
|
++it;
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
//? Remove any problematic disks added to the ignore_list
|
auto promise_res = promises_it->second.get();
|
||||||
if (new_ignored) {
|
if(promise_res.second != -1){
|
||||||
for (auto it = disks.begin(); it != disks.end();) {
|
ignore_list.push_back(mountpoint);
|
||||||
if (v_contains(ignore_list, it->first))
|
Logger::warning("Failed to get disk/partition stats for mount \""+ mountpoint + "\" with statvfs error code: " + to_string(promise_res.second) + ". Ignoring...");
|
||||||
it = disks.erase(it);
|
it = disks.erase(it);
|
||||||
else
|
continue;
|
||||||
it++;
|
}
|
||||||
|
auto &updated_stats = promise_res.first;
|
||||||
|
disk.total = updated_stats.total;
|
||||||
|
disk.free = updated_stats.free;
|
||||||
|
disk.used = updated_stats.used;
|
||||||
|
disk.used_percent = updated_stats.used_percent;
|
||||||
|
disk.free_percent = updated_stats.free_percent;
|
||||||
}
|
}
|
||||||
|
disks_stats_promises[mountpoint] = async(std::launch::async, [mountpoint, &free_priv]() -> pair<disk_info, int> {
|
||||||
|
struct statvfs vfs;
|
||||||
|
disk_info disk;
|
||||||
|
if (statvfs(mountpoint.c_str(), &vfs) < 0) {
|
||||||
|
return pair{disk, errno};
|
||||||
|
}
|
||||||
|
disk.total = vfs.f_blocks * vfs.f_frsize;
|
||||||
|
disk.free = (free_priv ? vfs.f_bfree : vfs.f_bavail) * vfs.f_frsize;
|
||||||
|
disk.used = disk.total - disk.free;
|
||||||
|
disk.used_percent = round((double)disk.used * 100 / disk.total);
|
||||||
|
disk.free_percent = 100 - disk.used_percent;
|
||||||
|
return pair{disk, -1};
|
||||||
|
});
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
//? Setup disks order in UI and add swap if enabled
|
//? Setup disks order in UI and add swap if enabled
|
||||||
|
@ -1245,29 +1962,32 @@ namespace Mem {
|
||||||
}
|
}
|
||||||
|
|
||||||
// looking through all files that start with 'objset' to find the one containing `device_name` object stats
|
// looking through all files that start with 'objset' to find the one containing `device_name` object stats
|
||||||
for (const auto& file: fs::directory_iterator(zfs_pool_stat_path)) {
|
try {
|
||||||
filename = file.path().filename();
|
for (const auto& file: fs::directory_iterator(zfs_pool_stat_path)) {
|
||||||
if (filename.starts_with("objset")) {
|
filename = file.path().filename();
|
||||||
filestream.open(file.path());
|
if (filename.starts_with("objset")) {
|
||||||
if (filestream.good()) {
|
filestream.open(file.path());
|
||||||
// skip first two lines
|
if (filestream.good()) {
|
||||||
for (int i = 0; i < 2; i++) filestream.ignore(numeric_limits<streamsize>::max(), '\n');
|
// skip first two lines
|
||||||
// skip characters until '7' is reached, indicating data type 7, next value will be object name
|
for (int i = 0; i < 2; i++) filestream.ignore(numeric_limits<streamsize>::max(), '\n');
|
||||||
filestream.ignore(numeric_limits<streamsize>::max(), '7');
|
// skip characters until '7' is reached, indicating data type 7, next value will be object name
|
||||||
filestream >> name_compare;
|
filestream.ignore(numeric_limits<streamsize>::max(), '7');
|
||||||
if (name_compare == device_name) {
|
filestream >> name_compare;
|
||||||
filestream.close();
|
if (name_compare == device_name) {
|
||||||
if (access(file.path().c_str(), R_OK) == 0) {
|
filestream.close();
|
||||||
return file.path();
|
if (access(file.path().c_str(), R_OK) == 0) {
|
||||||
} else {
|
return file.path();
|
||||||
Logger::debug("Can't access file: " + file.path().string());
|
} else {
|
||||||
return "";
|
Logger::debug("Can't access file: " + file.path().string());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
filestream.close();
|
||||||
}
|
}
|
||||||
filestream.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (fs::filesystem_error& e) {}
|
||||||
|
|
||||||
Logger::debug("Could not read directory: " + zfs_pool_stat_path.string());
|
Logger::debug("Could not read directory: " + zfs_pool_stat_path.string());
|
||||||
return "";
|
return "";
|
||||||
|
@ -1354,13 +2074,13 @@ namespace Mem {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Net {
|
namespace Net {
|
||||||
unordered_flat_map<string, net_info> current_net;
|
std::unordered_map<string, net_info> current_net;
|
||||||
net_info empty_net = {};
|
net_info empty_net = {};
|
||||||
vector<string> interfaces;
|
vector<string> interfaces;
|
||||||
string selected_iface;
|
string selected_iface;
|
||||||
int errors{}; // defaults to 0
|
int errors{}; // defaults to 0
|
||||||
unordered_flat_map<string, uint64_t> graph_max = { {"download", {}}, {"upload", {}} };
|
std::unordered_map<string, uint64_t> graph_max = { {"download", {}}, {"upload", {}} };
|
||||||
unordered_flat_map<string, array<int, 2>> max_count = { {"download", {}}, {"upload", {}} };
|
std::unordered_map<string, array<int, 2>> max_count = { {"download", {}}, {"upload", {}} };
|
||||||
bool rescale{true};
|
bool rescale{true};
|
||||||
uint64_t timestamp{}; // defaults to 0
|
uint64_t timestamp{}; // defaults to 0
|
||||||
|
|
||||||
|
@ -1499,7 +2219,6 @@ namespace Net {
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
net.compact();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp = new_timestamp;
|
timestamp = new_timestamp;
|
||||||
|
@ -1569,7 +2288,7 @@ namespace Net {
|
||||||
namespace Proc {
|
namespace Proc {
|
||||||
|
|
||||||
vector<proc_info> current_procs;
|
vector<proc_info> current_procs;
|
||||||
unordered_flat_map<string, string> uid_user;
|
std::unordered_map<string, string> uid_user;
|
||||||
string current_sort;
|
string current_sort;
|
||||||
string current_filter;
|
string current_filter;
|
||||||
bool current_rev{}; // defaults to false
|
bool current_rev{}; // defaults to false
|
||||||
|
@ -1584,7 +2303,7 @@ namespace Proc {
|
||||||
|
|
||||||
detail_container detailed;
|
detail_container detailed;
|
||||||
constexpr size_t KTHREADD = 2;
|
constexpr size_t KTHREADD = 2;
|
||||||
static robin_hood::unordered_set<size_t> kernels_procs = {KTHREADD};
|
static std::unordered_set<size_t> kernels_procs = {KTHREADD};
|
||||||
|
|
||||||
//* Get detailed info for selected process
|
//* Get detailed info for selected process
|
||||||
void _collect_details(const size_t pid, const uint64_t uptime, vector<proc_info>& procs) {
|
void _collect_details(const size_t pid, const uint64_t uptime, vector<proc_info>& procs) {
|
||||||
|
@ -2070,6 +2789,6 @@ namespace Tools {
|
||||||
catch (const std::invalid_argument&) {}
|
catch (const std::invalid_argument&) {}
|
||||||
catch (const std::out_of_range&) {}
|
catch (const std::out_of_range&) {}
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Failed get uptime from from " + string{Shared::procPath} + "/uptime");
|
throw std::runtime_error("Failed to get uptime from " + string{Shared::procPath} + "/uptime");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ indent = tab
|
||||||
tab-size = 4
|
tab-size = 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <Availability.h>
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <IOKit/IOKitLib.h>
|
#include <IOKit/IOKitLib.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
@ -44,6 +45,7 @@ tab-size = 4
|
||||||
#include <netinet/in.h> // for inet_ntop
|
#include <netinet/in.h> // for inet_ntop
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -56,7 +58,9 @@ tab-size = 4
|
||||||
#include "../btop_shared.hpp"
|
#include "../btop_shared.hpp"
|
||||||
#include "../btop_tools.hpp"
|
#include "../btop_tools.hpp"
|
||||||
|
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED > 101504
|
||||||
#include "sensors.hpp"
|
#include "sensors.hpp"
|
||||||
|
#endif
|
||||||
#include "smc.hpp"
|
#include "smc.hpp"
|
||||||
|
|
||||||
using std::clamp, std::string_literals::operator""s, std::cmp_equal, std::cmp_less, std::cmp_greater;
|
using std::clamp, std::string_literals::operator""s, std::cmp_equal, std::cmp_less, std::cmp_greater;
|
||||||
|
@ -70,7 +74,7 @@ using namespace Tools;
|
||||||
namespace Cpu {
|
namespace Cpu {
|
||||||
vector<long long> core_old_totals;
|
vector<long long> core_old_totals;
|
||||||
vector<long long> core_old_idles;
|
vector<long long> core_old_idles;
|
||||||
vector<string> available_fields = {"total"};
|
vector<string> available_fields = {"Auto", "total"};
|
||||||
vector<string> available_sensors = {"Auto"};
|
vector<string> available_sensors = {"Auto"};
|
||||||
cpu_info current_cpu;
|
cpu_info current_cpu;
|
||||||
bool got_sensors = false, cpu_temp_only = false;
|
bool got_sensors = false, cpu_temp_only = false;
|
||||||
|
@ -95,7 +99,7 @@ namespace Cpu {
|
||||||
|
|
||||||
string cpu_sensor;
|
string cpu_sensor;
|
||||||
vector<string> core_sensors;
|
vector<string> core_sensors;
|
||||||
unordered_flat_map<int, int> core_mapping;
|
std::unordered_map<int, int> core_mapping;
|
||||||
} // namespace Cpu
|
} // namespace Cpu
|
||||||
|
|
||||||
namespace Mem {
|
namespace Mem {
|
||||||
|
@ -191,7 +195,7 @@ namespace Cpu {
|
||||||
|
|
||||||
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
|
const array<string, 10> time_names = {"user", "nice", "system", "idle"};
|
||||||
|
|
||||||
unordered_flat_map<string, long long> cpu_old = {
|
std::unordered_map<string, long long> cpu_old = {
|
||||||
{"totals", 0},
|
{"totals", 0},
|
||||||
{"idles", 0},
|
{"idles", 0},
|
||||||
{"user", 0},
|
{"user", 0},
|
||||||
|
@ -236,7 +240,7 @@ namespace Cpu {
|
||||||
name += n + ' ';
|
name += n + ' ';
|
||||||
}
|
}
|
||||||
name.pop_back();
|
name.pop_back();
|
||||||
for (const auto& replace : {"Processor", "CPU", "(R)", "(TM)", "Intel", "AMD", "Core"}) {
|
for (const auto& replace : {"Processor", "CPU", "(R)", "(TM)", "Intel", "AMD", "Apple", "Core"}) {
|
||||||
name = s_replace(name, replace, "");
|
name = s_replace(name, replace, "");
|
||||||
name = s_replace(name, " ", " ");
|
name = s_replace(name, " ", " ");
|
||||||
}
|
}
|
||||||
|
@ -250,6 +254,7 @@ namespace Cpu {
|
||||||
Logger::debug("get_sensors(): show_coretemp=" + std::to_string(Config::getB("show_coretemp")) + " check_temp=" + std::to_string(Config::getB("check_temp")));
|
Logger::debug("get_sensors(): show_coretemp=" + std::to_string(Config::getB("show_coretemp")) + " check_temp=" + std::to_string(Config::getB("check_temp")));
|
||||||
got_sensors = false;
|
got_sensors = false;
|
||||||
if (Config::getB("show_coretemp") and Config::getB("check_temp")) {
|
if (Config::getB("show_coretemp") and Config::getB("check_temp")) {
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED > 101504
|
||||||
ThermalSensors sensors;
|
ThermalSensors sensors;
|
||||||
if (sensors.getSensors() > 0) {
|
if (sensors.getSensors() > 0) {
|
||||||
Logger::debug("M1 sensors found");
|
Logger::debug("M1 sensors found");
|
||||||
|
@ -257,6 +262,7 @@ namespace Cpu {
|
||||||
cpu_temp_only = true;
|
cpu_temp_only = true;
|
||||||
macM1 = true;
|
macM1 = true;
|
||||||
} else {
|
} else {
|
||||||
|
#endif
|
||||||
// try SMC (intel)
|
// try SMC (intel)
|
||||||
Logger::debug("checking intel");
|
Logger::debug("checking intel");
|
||||||
SMCConnection smcCon;
|
SMCConnection smcCon;
|
||||||
|
@ -281,7 +287,9 @@ namespace Cpu {
|
||||||
// ignore, we don't have temp
|
// ignore, we don't have temp
|
||||||
got_sensors = false;
|
got_sensors = false;
|
||||||
}
|
}
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED > 101504
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return got_sensors;
|
return got_sensors;
|
||||||
}
|
}
|
||||||
|
@ -290,11 +298,12 @@ namespace Cpu {
|
||||||
current_cpu.temp_max = 95; // we have no idea how to get the critical temp
|
current_cpu.temp_max = 95; // we have no idea how to get the critical temp
|
||||||
try {
|
try {
|
||||||
if (macM1) {
|
if (macM1) {
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED > 101504
|
||||||
ThermalSensors sensors;
|
ThermalSensors sensors;
|
||||||
current_cpu.temp.at(0).push_back(sensors.getSensors());
|
current_cpu.temp.at(0).push_back(sensors.getSensors());
|
||||||
if (current_cpu.temp.at(0).size() > 20)
|
if (current_cpu.temp.at(0).size() > 20)
|
||||||
current_cpu.temp.at(0).pop_front();
|
current_cpu.temp.at(0).pop_front();
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
SMCConnection smcCon;
|
SMCConnection smcCon;
|
||||||
int threadsPerCore = Shared::coreCount / Shared::physicalCoreCount;
|
int threadsPerCore = Shared::coreCount / Shared::physicalCoreCount;
|
||||||
|
@ -329,8 +338,8 @@ namespace Cpu {
|
||||||
return std::to_string(freq / 1000.0 / 1000.0 / 1000.0).substr(0, 3);
|
return std::to_string(freq / 1000.0 / 1000.0 / 1000.0).substr(0, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_core_mapping() -> unordered_flat_map<int, int> {
|
auto get_core_mapping() -> std::unordered_map<int, int> {
|
||||||
unordered_flat_map<int, int> core_map;
|
std::unordered_map<int, int> core_map;
|
||||||
if (cpu_temp_only) return core_map;
|
if (cpu_temp_only) return core_map;
|
||||||
|
|
||||||
natural_t cpu_count;
|
natural_t cpu_count;
|
||||||
|
@ -591,7 +600,7 @@ namespace Mem {
|
||||||
io_object_t &object;
|
io_object_t &object;
|
||||||
};
|
};
|
||||||
|
|
||||||
void collect_disk(unordered_flat_map<string, disk_info> &disks, unordered_flat_map<string, string> &mapping) {
|
void collect_disk(std::unordered_map<string, disk_info> &disks, std::unordered_map<string, string> &mapping) {
|
||||||
io_registry_entry_t drive;
|
io_registry_entry_t drive;
|
||||||
io_iterator_t drive_list;
|
io_iterator_t drive_list;
|
||||||
|
|
||||||
|
@ -708,7 +717,7 @@ namespace Mem {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_disks) {
|
if (show_disks) {
|
||||||
unordered_flat_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
|
std::unordered_map<string, string> mapping; // keep mapping from device -> mountpoint, since IOKit doesn't give us the mountpoint
|
||||||
double uptime = system_uptime();
|
double uptime = system_uptime();
|
||||||
auto &disks_filter = Config::getS("disks_filter");
|
auto &disks_filter = Config::getS("disks_filter");
|
||||||
bool filter_exclude = false;
|
bool filter_exclude = false;
|
||||||
|
@ -821,13 +830,13 @@ namespace Mem {
|
||||||
} // namespace Mem
|
} // namespace Mem
|
||||||
|
|
||||||
namespace Net {
|
namespace Net {
|
||||||
unordered_flat_map<string, net_info> current_net;
|
std::unordered_map<string, net_info> current_net;
|
||||||
net_info empty_net = {};
|
net_info empty_net = {};
|
||||||
vector<string> interfaces;
|
vector<string> interfaces;
|
||||||
string selected_iface;
|
string selected_iface;
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
unordered_flat_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
|
std::unordered_map<string, uint64_t> graph_max = {{"download", {}}, {"upload", {}}};
|
||||||
unordered_flat_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
|
std::unordered_map<string, array<int, 2>> max_count = {{"download", {}}, {"upload", {}}};
|
||||||
bool rescale = true;
|
bool rescale = true;
|
||||||
uint64_t timestamp = 0;
|
uint64_t timestamp = 0;
|
||||||
|
|
||||||
|
@ -904,7 +913,7 @@ namespace Net {
|
||||||
} // else, ignoring family==AF_LINK (see man 3 getifaddrs)
|
} // else, ignoring family==AF_LINK (see man 3 getifaddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
unordered_flat_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
|
std::unordered_map<string, std::tuple<uint64_t, uint64_t>> ifstats;
|
||||||
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0};
|
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0};
|
||||||
size_t len;
|
size_t len;
|
||||||
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
|
if (sysctl(mib, 6, nullptr, &len, nullptr, 0) < 0) {
|
||||||
|
@ -978,7 +987,6 @@ namespace Net {
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
net.compact();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp = new_timestamp;
|
timestamp = new_timestamp;
|
||||||
|
@ -1049,7 +1057,7 @@ namespace Net {
|
||||||
namespace Proc {
|
namespace Proc {
|
||||||
|
|
||||||
vector<proc_info> current_procs;
|
vector<proc_info> current_procs;
|
||||||
unordered_flat_map<string, string> uid_user;
|
std::unordered_map<string, string> uid_user;
|
||||||
string current_sort;
|
string current_sort;
|
||||||
string current_filter;
|
string current_filter;
|
||||||
bool current_rev = false;
|
bool current_rev = false;
|
||||||
|
|
|
@ -16,6 +16,8 @@ indent = tab
|
||||||
tab-size = 4
|
tab-size = 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <Availability.h>
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED > 101504
|
||||||
#include "sensors.hpp"
|
#include "sensors.hpp"
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
@ -109,3 +111,4 @@ long long Cpu::ThermalSensors::getSensors() {
|
||||||
if (temps.empty()) return 0ll;
|
if (temps.empty()) return 0ll;
|
||||||
return round(std::accumulate(temps.begin(), temps.end(), 0ll) / temps.size());
|
return round(std::accumulate(temps.begin(), temps.end(), 0ll) / temps.size());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -16,9 +16,12 @@ indent = tab
|
||||||
tab-size = 4
|
tab-size = 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <Availability.h>
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED > 101504
|
||||||
namespace Cpu {
|
namespace Cpu {
|
||||||
class ThermalSensors {
|
class ThermalSensors {
|
||||||
public:
|
public:
|
||||||
long long getSensors();
|
long long getSensors();
|
||||||
};
|
};
|
||||||
} // namespace Cpu
|
} // namespace Cpu
|
||||||
|
#endif
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# By: Dennis Mayr
|
# By: Dennis Mayr
|
||||||
|
|
||||||
# Main bg
|
# Main bg
|
||||||
theme[main_bg]="#2b2b2b"
|
theme[main_bg]="#333333"
|
||||||
|
|
||||||
# Main text color
|
# Main text color
|
||||||
theme[main_fg]="#eee8d5"
|
theme[main_fg]="#eee8d5"
|
||||||
|
@ -12,71 +12,71 @@ theme[main_fg]="#eee8d5"
|
||||||
theme[title]="#eee8d5"
|
theme[title]="#eee8d5"
|
||||||
|
|
||||||
# Higlight color for keyboard shortcuts
|
# Higlight color for keyboard shortcuts
|
||||||
theme[hi_fg]="#dc322f"
|
theme[hi_fg]="#d1302c"
|
||||||
|
|
||||||
# Background color of selected item in processes box
|
# Background color of selected item in processes box
|
||||||
theme[selected_bg]="#268bd2"
|
theme[selected_bg]="#268ad0"
|
||||||
|
|
||||||
# Foreground color of selected item in processes box
|
# Foreground color of selected item in processes box
|
||||||
theme[selected_fg]="#eee8d5"
|
theme[selected_fg]="#eee8d5"
|
||||||
|
|
||||||
# Color of inactive/disabled text
|
# Color of inactive/disabled text
|
||||||
theme[inactive_fg]="#586e75"
|
theme[inactive_fg]="#657b83"
|
||||||
|
|
||||||
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
||||||
theme[proc_misc]="#268bd2"
|
theme[proc_misc]="#268ad0"
|
||||||
|
|
||||||
# Cpu box outline color
|
# Cpu box outline color
|
||||||
theme[cpu_box]="#586e75"
|
theme[cpu_box]="#657b83"
|
||||||
|
|
||||||
# Memory/disks box outline color
|
# Memory/disks box outline color
|
||||||
theme[mem_box]="#586e75"
|
theme[mem_box]="#657b83"
|
||||||
|
|
||||||
# Net up/down box outline color
|
# Net up/down box outline color
|
||||||
theme[net_box]="#586e75"
|
theme[net_box]="#657b83"
|
||||||
|
|
||||||
# Processes box outline color
|
# Processes box outline color
|
||||||
theme[proc_box]="#586e75"
|
theme[proc_box]="#657b83"
|
||||||
|
|
||||||
# Box divider line and small boxes line color
|
# Box divider line and small boxes line color
|
||||||
theme[div_line]="#586e75"
|
theme[div_line]="#657b83"
|
||||||
|
|
||||||
# Temperature graph colors
|
# Temperature graph colors
|
||||||
theme[temp_start]="#859900"
|
theme[temp_start]="#859900"
|
||||||
theme[temp_mid]="#b58901"
|
theme[temp_mid]="#b28602"
|
||||||
theme[temp_end]="#dc322f"
|
theme[temp_end]="#d1302c"
|
||||||
|
|
||||||
# CPU graph colors
|
# CPU graph colors
|
||||||
theme[cpu_start]="#859900"
|
theme[cpu_start]="#859900"
|
||||||
theme[cpu_mid]="#b58901"
|
theme[cpu_mid]="#b28602"
|
||||||
theme[cpu_end]="#dc322f"
|
theme[cpu_end]="#d1302c"
|
||||||
|
|
||||||
# Mem/Disk free meter
|
# Mem/Disk free meter
|
||||||
theme[free_start]="#268bd2"
|
theme[free_start]="#268ad0"
|
||||||
theme[free_mid]="#6c71c4"
|
theme[free_mid]="#6c71c4"
|
||||||
theme[free_end]="#2a9d95"
|
theme[free_end]="#2a9d95"
|
||||||
|
|
||||||
# Mem/Disk cached meter
|
# Mem/Disk cached meter
|
||||||
theme[cached_start]="#268bd2"
|
theme[cached_start]="#268ad0"
|
||||||
theme[cached_mid]="#6c71c4"
|
theme[cached_mid]="#6c71c4"
|
||||||
theme[cached_end]="#dc322f"
|
theme[cached_end]="#d1302c"
|
||||||
|
|
||||||
# Mem/Disk available meter
|
# Mem/Disk available meter
|
||||||
theme[available_start]="#268bd2"
|
theme[available_start]="#268ad0"
|
||||||
theme[available_mid]="#6c71c4"
|
theme[available_mid]="#6c71c4"
|
||||||
theme[available_end]="#dc322f"
|
theme[available_end]="#d1302c"
|
||||||
|
|
||||||
# Mem/Disk used meter
|
# Mem/Disk used meter
|
||||||
theme[used_start]="#859900"
|
theme[used_start]="#859900"
|
||||||
theme[used_mid]="#b58901"
|
theme[used_mid]="#b28602"
|
||||||
theme[used_end]="#dc322f"
|
theme[used_end]="#d1302c"
|
||||||
|
|
||||||
# Download graph colors
|
# Download graph colors
|
||||||
theme[download_start]="#268bd2"
|
theme[download_start]="#268ad0"
|
||||||
theme[download_mid]="#6c71c4"
|
theme[download_mid]="#6c71c4"
|
||||||
theme[download_end]="#dc322f"
|
theme[download_end]="#d1302c"
|
||||||
|
|
||||||
# Upload graph colors
|
# Upload graph colors
|
||||||
theme[upload_start]="#268bd2"
|
theme[upload_start]="#268ad0"
|
||||||
theme[upload_mid]="#6c71c4"
|
theme[upload_mid]="#6c71c4"
|
||||||
theme[upload_end]="#dc322f"
|
theme[upload_end]="#d1302c"
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
# All graphs and meters can be gradients
|
||||||
|
# For single color graphs leave "mid" and "end" variable empty.
|
||||||
|
# Use "start" and "end" variables for two color gradient
|
||||||
|
# Use "start", "mid" and "end" for three color gradient
|
||||||
|
|
||||||
|
# Main background, empty for terminal default, need to be empty if you want transparent background
|
||||||
|
theme[main_bg]="#1C1E26"
|
||||||
|
|
||||||
|
# Main text color
|
||||||
|
theme[main_fg]="#f8f8f2"
|
||||||
|
|
||||||
|
# Title color for boxes
|
||||||
|
theme[title]="#f8f8f2"
|
||||||
|
|
||||||
|
# Highlight color for keyboard shortcuts
|
||||||
|
theme[hi_fg]="#B877DB"
|
||||||
|
|
||||||
|
# Background color of selected items
|
||||||
|
theme[selected_bg]="#282b37"
|
||||||
|
|
||||||
|
# Foreground color of selected items
|
||||||
|
theme[selected_fg]="#f8f8f2"
|
||||||
|
|
||||||
|
# Color of inactive/disabled text
|
||||||
|
theme[inactive_fg]="#272e33"
|
||||||
|
|
||||||
|
# Color of text appearing on top of graphs, i.e uptime and current network graph scaling
|
||||||
|
theme[graph_text]="#f8f8f2"
|
||||||
|
|
||||||
|
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
||||||
|
theme[proc_misc]="#27D796"
|
||||||
|
|
||||||
|
# Cpu box outline color
|
||||||
|
theme[cpu_box]="#B877DB"
|
||||||
|
|
||||||
|
# Memory/disks box outline color
|
||||||
|
theme[mem_box]="#27D796"
|
||||||
|
|
||||||
|
# Net up/down box outline color
|
||||||
|
theme[net_box]="#E95678"
|
||||||
|
|
||||||
|
# Processes box outline color
|
||||||
|
theme[proc_box]="#25B2BC"
|
||||||
|
|
||||||
|
# Box divider line and small boxes line color
|
||||||
|
theme[div_line]="#272e33"
|
||||||
|
|
||||||
|
# Temperature graph colors
|
||||||
|
theme[temp_start]="#27D796"
|
||||||
|
theme[temp_mid]="#FAC29A"
|
||||||
|
theme[temp_end]="#E95678"
|
||||||
|
|
||||||
|
# CPU graph colors
|
||||||
|
theme[cpu_start]="#27D796"
|
||||||
|
theme[cpu_mid]="#FAC29A"
|
||||||
|
theme[cpu_end]="#E95678"
|
||||||
|
|
||||||
|
# Mem/Disk free meter
|
||||||
|
theme[free_start]="#E95678"
|
||||||
|
theme[free_mid]="#FAC29A"
|
||||||
|
theme[free_end]="#27D796"
|
||||||
|
|
||||||
|
# Mem/Disk cached meter
|
||||||
|
theme[cached_start]="#27D796"
|
||||||
|
theme[cached_mid]="#FAC29A"
|
||||||
|
theme[cached_end]="#E95678"
|
||||||
|
|
||||||
|
# Mem/Disk available meter
|
||||||
|
theme[available_start]="#27D796"
|
||||||
|
theme[available_mid]="#FAC29A"
|
||||||
|
theme[available_end]="#E95678"
|
||||||
|
|
||||||
|
# Mem/Disk used meter
|
||||||
|
theme[used_start]="#27D796"
|
||||||
|
theme[used_mid]="#FAC29A"
|
||||||
|
theme[used_end]="#E95678"
|
||||||
|
|
||||||
|
# Download graph colors
|
||||||
|
theme[download_start]="#27D796"
|
||||||
|
theme[download_mid]="#FAC29A"
|
||||||
|
theme[download_end]="#E95678"
|
||||||
|
|
||||||
|
# Upload graph colors
|
||||||
|
theme[upload_start]="#27D796"
|
||||||
|
theme[upload_mid]="#FAC29A"
|
||||||
|
theme[upload_end]="#E95678"
|
Loading…
Reference in New Issue