mirror of https://github.com/aristocratos/btop.git
Added some comments and changed some defaults
This commit is contained in:
parent
ced3d47ebe
commit
ee073f6ae5
87
src/btop.cpp
87
src/btop.cpp
|
@ -99,8 +99,8 @@ namespace Global {
|
|||
//* A simple argument parser
|
||||
void argumentParser(const int& argc, char **argv) {
|
||||
for(int i = 1; i < argc; i++) {
|
||||
string argument = argv[i];
|
||||
if (argument == "-h" or argument == "--help") {
|
||||
const string argument = argv[i];
|
||||
if (is_in(argument, "-h", "--help")) {
|
||||
cout << "usage: btop [-h] [-v] [-/+t] [--debug]\n\n"
|
||||
<< "optional arguments:\n"
|
||||
<< " -h, --help show this help message and exit\n"
|
||||
|
@ -113,18 +113,18 @@ void argumentParser(const int& argc, char **argv) {
|
|||
<< endl;
|
||||
exit(0);
|
||||
}
|
||||
if (argument == "-v" or argument == "--version") {
|
||||
if (is_in(argument, "-v", "--version")) {
|
||||
cout << "btop version: " << Global::Version << endl;
|
||||
exit(0);
|
||||
}
|
||||
else if (argument == "-lc" or argument == "--low-color") {
|
||||
else if (is_in(argument, "-lc", "--low-color")) {
|
||||
Global::arg_low_color = true;
|
||||
}
|
||||
else if (argument == "-t" or argument == "--tty_on") {
|
||||
else if (is_in(argument, "-t", "--tty_on")) {
|
||||
Config::set("tty_mode", true);
|
||||
Global::arg_tty = true;
|
||||
}
|
||||
else if (argument == "+t" or argument == "--tty_off") {
|
||||
else if (is_in(argument, "+t", "--tty_off")) {
|
||||
Config::set("tty_mode", false);
|
||||
Global::arg_tty = true;
|
||||
}
|
||||
|
@ -296,11 +296,11 @@ namespace Runner {
|
|||
const uint_fast8_t cpu_done = 0b1100'0000;
|
||||
|
||||
struct runner_conf {
|
||||
vector<string> boxes;
|
||||
bool no_update = false;
|
||||
bool force_redraw = false;
|
||||
string overlay = "";
|
||||
string clock = "";
|
||||
bitset<8> box_mask;
|
||||
bool no_update;
|
||||
bool force_redraw;
|
||||
string overlay;
|
||||
string clock;
|
||||
};
|
||||
|
||||
struct runner_conf current_conf;
|
||||
|
@ -334,12 +334,6 @@ namespace Runner {
|
|||
|
||||
output.clear();
|
||||
|
||||
//? Setup bitmask for selected boxes instead of parsing strings in the loop
|
||||
bitset<8> box_mask;
|
||||
for (const auto& box : conf->boxes) {
|
||||
box_mask |= box_bits.at(box);
|
||||
}
|
||||
|
||||
future<Cpu::cpu_info> cpu;
|
||||
future<Mem::mem_info> mem;
|
||||
future<Net::net_info> net;
|
||||
|
@ -348,33 +342,32 @@ namespace Runner {
|
|||
//* Start collection functions for all boxes in async threads and draw in this thread when finished
|
||||
//? Starting order below based on mean time to finish
|
||||
try {
|
||||
while (box_mask.count() > 0) {
|
||||
while (conf->box_mask.count() > 0) {
|
||||
if (stopping) break;
|
||||
//? PROC
|
||||
if (box_mask.test(proc_present)) {
|
||||
if (not box_mask.test(proc_running)) {
|
||||
if (conf->box_mask.test(proc_present)) {
|
||||
if (not conf->box_mask.test(proc_running)) {
|
||||
proc = async(Proc::collect, conf->no_update);
|
||||
box_mask.set(proc_running);
|
||||
conf->box_mask.set(proc_running);
|
||||
}
|
||||
else if (not proc.valid())
|
||||
throw std::runtime_error("Proc::collect() future not valid.");
|
||||
|
||||
else if (proc.wait_for(ZeroSec) == future_status::ready) {
|
||||
else if (proc.wait_for(std::chrono::microseconds(100)) == future_status::ready) {
|
||||
try {
|
||||
output += Proc::draw(proc.get(), conf->force_redraw, conf->no_update);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
throw std::runtime_error("Proc:: -> " + (string)e.what());
|
||||
}
|
||||
box_mask ^= proc_done;
|
||||
continue;
|
||||
conf->box_mask ^= proc_done;
|
||||
}
|
||||
}
|
||||
//? MEM
|
||||
if (box_mask.test(mem_present)) {
|
||||
if (not box_mask.test(mem_running)) {
|
||||
if (conf->box_mask.test(mem_present)) {
|
||||
if (not conf->box_mask.test(mem_running)) {
|
||||
mem = async(Mem::collect, conf->no_update);
|
||||
box_mask.set(mem_running);
|
||||
conf->box_mask.set(mem_running);
|
||||
}
|
||||
else if (not mem.valid())
|
||||
throw std::runtime_error("Mem::collect() future not valid.");
|
||||
|
@ -386,15 +379,14 @@ namespace Runner {
|
|||
catch (const std::exception& e) {
|
||||
throw std::runtime_error("Mem:: -> " + (string)e.what());
|
||||
}
|
||||
box_mask ^= mem_done;
|
||||
continue;
|
||||
conf->box_mask ^= mem_done;
|
||||
}
|
||||
}
|
||||
//? NET
|
||||
if (box_mask.test(net_present)) {
|
||||
if (not box_mask.test(net_running)) {
|
||||
if (conf->box_mask.test(net_present)) {
|
||||
if (not conf->box_mask.test(net_running)) {
|
||||
net = async(Net::collect, conf->no_update);
|
||||
box_mask.set(net_running);
|
||||
conf->box_mask.set(net_running);
|
||||
}
|
||||
else if (not net.valid())
|
||||
throw std::runtime_error("Net::collect() future not valid.");
|
||||
|
@ -406,15 +398,14 @@ namespace Runner {
|
|||
catch (const std::exception& e) {
|
||||
throw std::runtime_error("Net:: -> " + (string)e.what());
|
||||
}
|
||||
box_mask ^= net_done;
|
||||
continue;
|
||||
conf->box_mask ^= net_done;
|
||||
}
|
||||
}
|
||||
//? CPU
|
||||
if (box_mask.test(cpu_present)) {
|
||||
if (not box_mask.test(cpu_running)) {
|
||||
if (conf->box_mask.test(cpu_present)) {
|
||||
if (not conf->box_mask.test(cpu_running)) {
|
||||
cpu = async(Cpu::collect, conf->no_update);
|
||||
box_mask.set(cpu_running);
|
||||
conf->box_mask.set(cpu_running);
|
||||
}
|
||||
else if (not cpu.valid())
|
||||
throw std::runtime_error("Cpu::collect() future not valid.");
|
||||
|
@ -426,11 +417,9 @@ namespace Runner {
|
|||
catch (const std::exception& e) {
|
||||
throw std::runtime_error("Cpu:: -> " + (string)e.what());
|
||||
}
|
||||
box_mask ^= cpu_done;
|
||||
continue;
|
||||
conf->box_mask ^= cpu_done;
|
||||
}
|
||||
}
|
||||
sleep_micros(100);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
|
@ -457,7 +446,7 @@ namespace Runner {
|
|||
}
|
||||
//? ------------------------------------------ Secondary thread end -----------------------------------------------
|
||||
|
||||
//* Runs collect and draw in a secondary thread, unlocks and locks config to update cached values, box="all": all boxes
|
||||
//* Runs collect and draw in a secondary thread, unlocks and locks config to update cached values
|
||||
void run(const string& box, const bool no_update, const bool force_redraw) {
|
||||
atomic_lock lck(waiting);
|
||||
atomic_wait(active);
|
||||
|
@ -477,7 +466,13 @@ namespace Runner {
|
|||
Config::unlock();
|
||||
Config::lock();
|
||||
|
||||
current_conf = { (box == "all" ? Config::current_boxes : vector{box}), no_update, force_redraw, Global::overlay, Global::clock};
|
||||
//? Setup bitmask for selected boxes instead of parsing strings
|
||||
bitset<8> box_mask;
|
||||
for (const auto& box : (box == "all" ? Config::current_boxes : vector{box})) {
|
||||
box_mask |= box_bits.at(box);
|
||||
}
|
||||
|
||||
current_conf = {box_mask, no_update, force_redraw, Global::overlay, Global::clock};
|
||||
|
||||
pthread_t runner_id;
|
||||
if (pthread_create(&runner_id, NULL, &_runner, (void *) ¤t_conf) != 0)
|
||||
|
@ -609,7 +604,7 @@ int main(int argc, char **argv) {
|
|||
Logger::warning("No UTF-8 locale detected! Forcing start with --utf-force argument.");
|
||||
else if (not found) {
|
||||
Global::exit_error_msg = "No UTF-8 locale detected! Use --utf-force argument to start anyway.";
|
||||
clean_quit(1);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
Logger::debug("Setting LC_ALL=" + (string)std::setlocale(LC_ALL, NULL));
|
||||
|
@ -618,7 +613,7 @@ int main(int argc, char **argv) {
|
|||
//? Initialize terminal and set options
|
||||
if (not Term::init()) {
|
||||
Global::exit_error_msg = "No tty detected!\nbtop++ needs an interactive shell to run.";
|
||||
clean_quit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Logger::info("Running on " + Term::current_tty);
|
||||
|
@ -637,7 +632,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
catch (const std::exception& e) {
|
||||
Global::exit_error_msg = "Exception in Shared::init() -> " + (string)e.what();
|
||||
clean_quit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//? Update list of available themes and generate the selected theme
|
||||
|
@ -709,7 +704,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
catch (std::exception& e) {
|
||||
Global::exit_error_msg = "Exception in main loop -> " + (string)e.what();
|
||||
clean_quit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace Config {
|
|||
{"proc_tree", false},
|
||||
{"proc_colors", true},
|
||||
{"proc_gradient", true},
|
||||
{"proc_per_core", false},
|
||||
{"proc_per_core", true},
|
||||
{"proc_mem_bytes", true},
|
||||
{"proc_info_smaps", false},
|
||||
{"proc_left", false},
|
||||
|
@ -299,7 +299,7 @@ namespace Config {
|
|||
}
|
||||
catch (const std::exception& e) {
|
||||
Global::exit_error_msg = "Exception during Config::unlock() : " + (string)e.what();
|
||||
clean_quit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
locked = false;
|
||||
|
|
|
@ -453,11 +453,23 @@ namespace Cpu {
|
|||
|
||||
}
|
||||
try {
|
||||
//? Cpu graphs, cpu clock and cpu meter
|
||||
//? Cpu graphs
|
||||
out += Fx::ub + Mv::to(y + 1, x + 1) + graph_upper(cpu.cpu_percent.at(graph_up_field), (data_same or redraw));
|
||||
if (not single_graph)
|
||||
out += Mv::to( y + graph_up_height + 1 + (mid_line ? 1 : 0), x + 1) + graph_lower(cpu.cpu_percent.at(graph_lo_field), (data_same or redraw));
|
||||
|
||||
//? Uptime
|
||||
if (Config::getB("show_uptime")) {
|
||||
string upstr = sec_to_dhms(system_uptime());
|
||||
if (upstr.size() > 8) {
|
||||
upstr.resize(upstr.size() - 3);
|
||||
upstr = trans(upstr);
|
||||
}
|
||||
out += Mv::to(y + (single_graph or not Config::getB("cpu_invert_lower") ? 1 : height - 2), x + 2)
|
||||
+ Theme::c("graph_text") + "up" + Mv::r(1) + upstr;
|
||||
}
|
||||
|
||||
//? Cpu clock and cpu meter
|
||||
if (Config::getB("show_cpu_freq") and not cpuHz.empty())
|
||||
out += Mv::to(b_y, b_x + b_width - 10) + Fx::ub + Theme::c("div_line") + Symbols::h_line * (7 - cpuHz.size())
|
||||
+ Symbols::title_left + Fx::b + Theme::c("title") + cpuHz + Fx::ub + Theme::c("div_line") + Symbols::title_right;
|
||||
|
@ -519,16 +531,7 @@ namespace Cpu {
|
|||
out += Mv::to(b_y + b_height - 2, b_x + cx + 1) + Theme::c("main_fg") + lavg_pre + lavg;
|
||||
}
|
||||
|
||||
//? Uptime
|
||||
if (Config::getB("show_uptime")) {
|
||||
string upstr = sec_to_dhms(system_uptime());
|
||||
if (upstr.size() > 8) {
|
||||
upstr.resize(upstr.size() - 3);
|
||||
upstr = trans(upstr);
|
||||
}
|
||||
out += Mv::to(y + (single_graph or not Config::getB("cpu_invert_lower") ? 1 : height - 2), x + 2)
|
||||
+ Theme::c("graph_text") + "up" + Mv::r(1) + upstr;
|
||||
}
|
||||
|
||||
|
||||
redraw = false;
|
||||
return out + Fx::reset;
|
||||
|
|
|
@ -178,7 +178,7 @@ namespace Input {
|
|||
if (key.empty()) return;
|
||||
try {
|
||||
auto& filtering = Config::getB("proc_filtering");
|
||||
if (not filtering and key == "q") clean_quit(0);
|
||||
if (not filtering and key == "q") exit(0);
|
||||
|
||||
//? Global input actions
|
||||
if (not filtering) {
|
||||
|
|
|
@ -814,29 +814,6 @@ namespace Proc {
|
|||
int collapse = -1, expand = -1;
|
||||
uint64_t old_cputimes = 0;
|
||||
atomic<int> numpids = 0;
|
||||
vector<string> sort_vector = {
|
||||
"pid",
|
||||
"name",
|
||||
"command",
|
||||
"threads",
|
||||
"user",
|
||||
"memory",
|
||||
"cpu direct",
|
||||
"cpu lazy",
|
||||
};
|
||||
unordered_flat_map<char, string> proc_states = {
|
||||
{'R', "Running"},
|
||||
{'S', "Sleeping"},
|
||||
{'D', "Waiting"},
|
||||
{'Z', "Zombie"},
|
||||
{'T', "Stopped"},
|
||||
{'t', "Tracing"},
|
||||
{'X', "Dead"},
|
||||
{'x', "Dead"},
|
||||
{'K', "Wakekill"},
|
||||
{'W', "Unknown"},
|
||||
{'P', "Parked"}
|
||||
};
|
||||
|
||||
detail_container detailed;
|
||||
|
||||
|
@ -859,11 +836,13 @@ namespace Proc {
|
|||
}
|
||||
}
|
||||
|
||||
//? Add process to vector if not filtered out or currently in a collapsed sub-tree
|
||||
if (not collapsed and not filtering) {
|
||||
out_procs.push_back(cur_proc);
|
||||
if (std::string_view cmd_view = cur_proc.cmd; not cmd_view.empty()) {
|
||||
cmd_view = cmd_view.substr(0, std::min(cmd_view.find(' '), cmd_view.size()));
|
||||
cmd_view = cmd_view.substr(std::min(cmd_view.find_last_of('/') + 1, cmd_view.size()));
|
||||
//? Try to find name of the binary file and append to program name if not the same (replacing cmd string)
|
||||
if (std::string_view cmd_view = cur_proc.cmd; not cmd_view.empty() and not cmd_view.starts_with('(')) {
|
||||
cmd_view = cmd_view.substr(0, min(cmd_view.find(' '), cmd_view.size()));
|
||||
cmd_view = cmd_view.substr(min(cmd_view.find_last_of('/') + 1, cmd_view.size()));
|
||||
if (cmd_view == cur_proc.name)
|
||||
out_procs.back().cmd.clear();
|
||||
else
|
||||
|
@ -871,6 +850,7 @@ namespace Proc {
|
|||
}
|
||||
}
|
||||
|
||||
//? Recursive iteration over all children
|
||||
int children = 0;
|
||||
for (auto& p : rng::equal_range(in_procs, cur_proc.pid, rng::less{}, &proc_info::ppid)) {
|
||||
if (collapsed and not filtering) {
|
||||
|
@ -883,9 +863,11 @@ namespace Proc {
|
|||
}
|
||||
if (collapsed or filtering) return;
|
||||
|
||||
//? Add tree terminator symbol if it's the last child in a sub-tree
|
||||
if (out_procs.size() > cur_pos + 1 and not out_procs.back().prefix.ends_with("]─"))
|
||||
out_procs.back().prefix.replace(out_procs.back().prefix.size() - 8, 8, " └─ ");
|
||||
|
||||
//? Add collapse/expand symbols if process have any children
|
||||
out_procs.at(cur_pos).prefix = " │ "s * cur_depth + (children > 0 ? (cache.at(cur_proc.pid).collapsed ? "[+]─" : "[-]─") : " ├─ ");
|
||||
}
|
||||
|
||||
|
@ -1035,9 +1017,9 @@ namespace Proc {
|
|||
if (pread.good()) {
|
||||
pread.ignore(SSmax, ' ');
|
||||
for (uint64_t times; pread >> times; cputimes += times);
|
||||
pread.close();
|
||||
}
|
||||
else throw std::runtime_error("Failure to read /proc/stat");
|
||||
pread.close();
|
||||
|
||||
//? Iterate over all pids in /proc
|
||||
for (const auto& d: fs::directory_iterator(Shared::procPath)) {
|
||||
|
@ -1095,16 +1077,16 @@ namespace Proc {
|
|||
if (not pread.good()) continue;
|
||||
|
||||
//? Check cached value for whitespace characters in name and set offset to get correct fields from stat file
|
||||
size_t& offset = cache.at(new_proc.pid).name_offset;
|
||||
const auto& offset = cache.at(new_proc.pid).name_offset;
|
||||
short_str.clear();
|
||||
size_t x = 0, next_x = 3;
|
||||
uint64_t cpu_t = 0;
|
||||
try {
|
||||
for (;;) {
|
||||
while (pread.good() and ++x - offset < next_x) {
|
||||
while (pread.good() and ++x < next_x + offset) {
|
||||
pread.ignore(SSmax, ' ');
|
||||
}
|
||||
if (pread.bad()) goto stat_loop_done;
|
||||
if (pread.bad()) break;
|
||||
|
||||
getline(pread, short_str, ' ');
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ tab-size = 4
|
|||
|
||||
using std::string, std::vector, std::deque, robin_hood::unordered_flat_map, std::atomic, std::array;
|
||||
|
||||
void clean_quit(int sig=-1);
|
||||
void term_resize(bool force=false);
|
||||
void banner_gen();
|
||||
|
||||
|
@ -169,10 +168,31 @@ namespace Proc {
|
|||
extern int selected_pid, start, selected, collapse, expand;
|
||||
|
||||
//? Contains the valid sorting options for processes
|
||||
extern vector<string> sort_vector;
|
||||
const vector<string> sort_vector = {
|
||||
"pid",
|
||||
"name",
|
||||
"command",
|
||||
"threads",
|
||||
"user",
|
||||
"memory",
|
||||
"cpu direct",
|
||||
"cpu lazy",
|
||||
};
|
||||
|
||||
//? Translation from process state char to explanative string
|
||||
extern unordered_flat_map<char, string> proc_states;
|
||||
const unordered_flat_map<char, string> proc_states = {
|
||||
{'R', "Running"},
|
||||
{'S', "Sleeping"},
|
||||
{'D', "Waiting"},
|
||||
{'Z', "Zombie"},
|
||||
{'T', "Stopped"},
|
||||
{'t', "Tracing"},
|
||||
{'X', "Dead"},
|
||||
{'x', "Dead"},
|
||||
{'K', "Wakekill"},
|
||||
{'W', "Unknown"},
|
||||
{'P', "Parked"}
|
||||
};
|
||||
|
||||
//* Container for process information
|
||||
struct proc_info {
|
||||
|
|
Loading…
Reference in New Issue