2021-05-07 06:32:03 +12:00
/* Copyright 2021 Aristocratos (jakob@qvantnet.com)
Licensed under the Apache License , Version 2.0 ( the " License " ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an " AS IS " BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
indent = tab
tab - size = 4
*/
2021-05-15 23:24:24 +12:00
2021-05-07 06:32:03 +12:00
# include <string>
2021-05-19 08:11:34 +12:00
# include <array>
2021-05-20 09:21:56 +12:00
# include <list>
2021-05-07 06:32:03 +12:00
# include <vector>
# include <thread>
# include <future>
# include <atomic>
2021-05-20 09:21:56 +12:00
# include <numeric>
2021-05-17 08:58:16 +12:00
# include <ranges>
2021-05-22 12:13:56 +12:00
# include <filesystem>
# include <unistd.h>
2021-05-29 12:32:36 +12:00
# include <robin_hood.h>
2021-05-07 06:32:03 +12:00
2021-05-24 08:25:07 +12:00
namespace Global {
const std : : vector < std : : array < std : : string , 2 > > Banner_src = {
{ " #E62525 " , " ██████╗ ████████╗ ██████╗ ██████╗ " } ,
{ " #CD2121 " , " ██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ ██╗ ██╗ " } ,
{ " #B31D1D " , " ██████╔╝ ██║ ██║ ██║██████╔╝ ██████╗██████╗ " } ,
{ " #9A1919 " , " ██╔══██╗ ██║ ██║ ██║██╔═══╝ ╚═██╔═╝╚═██╔═╝ " } ,
{ " #801414 " , " ██████╔╝ ██║ ╚██████╔╝██║ ╚═╝ ╚═╝ " } ,
{ " #000000 " , " ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ " } ,
} ;
2021-06-01 07:47:41 +12:00
const uint banner_width = 49 ;
2021-05-24 08:25:07 +12:00
const std : : string Version = " 0.0.10 " ;
}
2021-05-09 00:56:48 +12:00
# include <btop_globs.h>
# include <btop_tools.h>
# include <btop_config.h>
2021-05-09 06:37:36 +12:00
# include <btop_input.h>
# include <btop_theme.h>
2021-05-17 08:58:16 +12:00
# include <btop_draw.h>
2021-05-09 00:56:48 +12:00
# if defined(__linux__)
2021-05-20 09:21:56 +12:00
# define LINUX 1
2021-05-11 09:46:41 +12:00
# include <btop_linux.h>
2021-05-09 00:56:48 +12:00
# elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__)
# include <sys/param.h>
# if defined(BSD)
2021-05-14 07:11:10 +12:00
// #include <btop_bsd.h>
2021-05-20 09:21:56 +12:00
# error BSD support not yet implemented!
2021-05-09 00:56:48 +12:00
# endif
# elif defined(__APPLE__) && defined(__MACH__)
# include <TargetConditionals.h>
# if TARGET_OS_MAC == 1
2021-05-20 09:21:56 +12:00
# define OSX 1
2021-05-14 07:11:10 +12:00
// #include <btop_osx.h>
2021-05-20 09:21:56 +12:00
# error OSX support not yet implemented!
2021-05-09 00:56:48 +12:00
# endif
2021-05-20 09:21:56 +12:00
# else
2021-05-24 08:25:07 +12:00
# error Platform not supported!
2021-05-09 00:56:48 +12:00
# endif
2021-05-07 06:32:03 +12:00
2021-05-29 12:32:36 +12:00
using std : : string , std : : vector , std : : array , robin_hood : : unordered_flat_map , std : : atomic , std : : endl , std : : cout , std : : views : : iota , std : : list , std : : accumulate ;
2021-05-20 09:21:56 +12:00
using std : : flush , std : : endl , std : : future , std : : string_literals : : operator " " s , std : : future_status ;
2021-05-22 12:13:56 +12:00
namespace fs = std : : filesystem ;
2021-05-17 08:58:16 +12:00
using namespace Tools ;
2021-05-07 06:32:03 +12:00
2021-05-08 12:38:51 +12:00
2021-05-09 00:56:48 +12:00
namespace Global {
2021-05-15 04:54:37 +12:00
string banner ;
2021-05-23 11:59:13 +12:00
2021-05-29 12:32:36 +12:00
fs : : path self_path ;
bool debuginit = false ;
bool debug = false ;
uint64_t start_time ;
bool quitting = false ;
2021-05-09 00:56:48 +12:00
}
2021-05-07 06:32:03 +12:00
2021-05-09 00:56:48 +12:00
//* A simple argument parser
2021-05-08 12:38:51 +12:00
void argumentParser ( int argc , char * * argv ) {
string argument ;
for ( int i = 1 ; i < argc ; i + + ) {
argument = argv [ i ] ;
if ( argument = = " -v " | | argument = = " --version " ) {
2021-05-09 00:56:48 +12:00
cout < < " btop version: " < < Global : : Version < < endl ;
2021-05-08 12:38:51 +12:00
exit ( 0 ) ;
2021-05-29 12:32:36 +12:00
}
else if ( argument = = " -h " | | argument = = " --help " ) {
2021-05-08 12:38:51 +12:00
cout < < " help here " < < endl ;
exit ( 0 ) ;
2021-05-29 12:32:36 +12:00
}
else if ( argument = = " --debug " ) Global : : debug = true ;
else {
2021-05-08 12:38:51 +12:00
cout < < " Unknown argument: " < < argument < < " \n " < <
" Use -h or --help for help. " < < endl ;
exit ( 1 ) ;
}
}
}
2021-05-15 04:54:37 +12:00
//* Generate the btop++ banner
2021-05-19 08:11:34 +12:00
string createBanner ( ) {
2021-05-15 04:54:37 +12:00
size_t z = 0 ;
string b_color , bg , fg , out , oc , letter ;
bool truecolor = Config : : getB ( " truecolor " ) ;
int bg_i ;
for ( auto line : Global : : Banner_src ) {
fg = Theme : : hex_to_color ( line [ 0 ] , ! truecolor ) ;
bg_i = 120 - z * 12 ;
bg = Theme : : dec_to_color ( bg_i , bg_i , bg_i , ! truecolor ) ;
2021-05-19 08:11:34 +12:00
for ( size_t i = 0 ; i < line [ 1 ] . size ( ) ; i + = 3 ) {
2021-05-15 04:54:37 +12:00
if ( line [ 1 ] [ i ] = = ' ' ) {
letter = ' ' ;
i - = 2 ;
} else {
letter = line [ 1 ] . substr ( i , 3 ) ;
2021-05-07 06:32:03 +12:00
}
2021-05-15 04:54:37 +12:00
b_color = ( letter = = " █ " ) ? fg : bg ;
if ( b_color ! = oc ) out + = b_color ;
out + = letter ;
oc = b_color ;
2021-05-07 06:32:03 +12:00
}
2021-05-19 08:11:34 +12:00
if ( + + z < Global : : Banner_src . size ( ) ) out + = Mv : : l ( ulen ( line [ 1 ] ) ) + Mv : : d ( 1 ) ;
2021-05-07 06:32:03 +12:00
}
2021-05-15 04:54:37 +12:00
out + = Mv : : r ( 18 - Global : : Version . size ( ) ) + Fx : : i + Theme : : dec_to_color ( 0 , 0 , 0 , ! truecolor , " bg " ) +
2021-05-19 08:11:34 +12:00
Theme : : dec_to_color ( 150 , 150 , 150 , ! truecolor ) + " v " + Global : : Version + Fx : : ui ;
return out ;
2021-05-15 04:54:37 +12:00
}
2021-05-07 06:32:03 +12:00
2021-05-29 12:32:36 +12:00
void clean_quit ( int signal ) {
if ( Global : : quitting ) return ;
if ( Term : : initialized ) {
Term : : restore ( ) ;
if ( ! Global : : debuginit ) cout < < Term : : normal_screen < < Term : : show_cursor < < flush ;
}
if ( Global : : debug ) Logger : : debug ( " Quitting! Runtime: " + sec_to_dhms ( time_s ( ) - Global : : start_time ) ) ;
Global : : quitting = true ;
if ( signal ! = - 1 ) exit ( signal ) ;
}
void _exit_handler ( ) { clean_quit ( - 1 ) ; }
2021-05-07 06:32:03 +12:00
2021-05-10 08:25:41 +12:00
//* Threading test function
string my_worker ( int x ) {
for ( int i = 0 ; i < 100 + ( x * 100 ) ; i + + ) {
sleep_ms ( 10 ) ;
if ( Global : : stop_all . load ( ) ) return " Thread stopped! x= " + to_string ( x ) ;
}
return " Thread done! x= " + to_string ( x ) ;
}
2021-05-09 00:56:48 +12:00
2021-05-07 06:32:03 +12:00
//? --------------------------------------------- Main starts here! ---------------------------------------------------
int main ( int argc , char * * argv ) {
//? Init
2021-05-29 12:32:36 +12:00
Global : : start_time = time_s ( ) ;
2021-05-08 12:38:51 +12:00
cout . setf ( std : : ios : : boolalpha ) ;
2021-05-07 06:32:03 +12:00
if ( argc > 1 ) argumentParser ( argc , argv ) ;
2021-05-29 12:32:36 +12:00
std : : atexit ( _exit_handler ) ;
2021-05-20 09:21:56 +12:00
# if defined(LINUX)
2021-05-29 12:32:36 +12:00
//? Linux paths init
2021-05-23 11:59:13 +12:00
Global : : proc_path = ( fs : : is_directory ( fs : : path ( " /proc " ) ) & & access ( " /proc " , R_OK ) ! = - 1 ) ? " /proc " : " " ;
2021-05-14 07:11:10 +12:00
if ( Global : : proc_path . empty ( ) ) {
2021-05-23 11:59:13 +12:00
cout < < " ERROR: Proc filesystem not found or no permission to read from it! " < < endl ;
2021-05-14 07:11:10 +12:00
exit ( 1 ) ;
}
2021-05-29 12:32:36 +12:00
{
std : : error_code ec ;
Global : : self_path = fs : : read_symlink ( " /proc/self/exe " , ec ) . remove_filename ( ) ;
}
2021-05-20 09:21:56 +12:00
# endif
2021-05-14 07:11:10 +12:00
2021-05-23 11:59:13 +12:00
//? Setup paths for config, log and themes
for ( auto env : { " XDG_CONFIG_HOME " , " HOME " } ) {
if ( getenv ( env ) ! = NULL & & access ( getenv ( env ) , W_OK ) ! = - 1 ) {
2021-05-29 12:32:36 +12:00
Config : : conf_dir = fs : : path ( getenv ( env ) ) / ( ( ( string ) env = = " HOME " ) ? " .config/btop " : " btop " ) ;
2021-05-23 11:59:13 +12:00
break ;
}
}
2021-05-29 12:32:36 +12:00
if ( ! Config : : conf_dir . empty ( ) ) {
std : : error_code ec ;
if ( ! fs : : is_directory ( Config : : conf_dir ) & & ! fs : : create_directories ( Config : : conf_dir , ec ) ) {
2021-05-23 11:59:13 +12:00
cout < < " WARNING: Could not create or access btop config directory. Logging and config saving disabled. " < < endl ;
2021-05-29 12:32:36 +12:00
cout < < " Make sure your $HOME environment variable is correctly set to fix this. " < < endl ;
2021-05-23 11:59:13 +12:00
}
else {
2021-05-29 12:32:36 +12:00
std : : error_code ec ;
Config : : conf_file = Config : : conf_dir / " btop.conf " ;
Logger : : logfile = Config : : conf_dir / " btop.log " ;
Theme : : user_theme_dir = Config : : conf_dir / " themes " ;
if ( ! fs : : exists ( Theme : : user_theme_dir ) & & ! fs : : create_directory ( Theme : : user_theme_dir , ec ) ) Theme : : user_theme_dir . clear ( ) ;
2021-05-23 11:59:13 +12:00
}
}
2021-05-29 12:32:36 +12:00
if ( ! Global : : self_path . empty ( ) ) {
std : : error_code ec ;
Theme : : theme_dir = fs : : canonical ( Global : : self_path / " ../share/btop/themes " , ec ) ;
if ( ec | | access ( Theme : : theme_dir . c_str ( ) , R_OK ) = = - 1 ) Theme : : theme_dir . clear ( ) ;
}
if ( Theme : : theme_dir . empty ( ) ) {
for ( auto theme_path : { " /usr/local/share/btop/themes " , " /usr/share/btop/themes " } ) {
if ( fs : : exists ( fs : : path ( theme_path ) ) & & access ( theme_path , R_OK ) ! = - 1 ) {
Theme : : theme_dir = fs : : path ( theme_path ) ;
break ;
}
2021-05-23 11:59:13 +12:00
}
}
2021-05-29 12:32:36 +12:00
Global : : debug = true ;
if ( Global : : debug ) { Logger : : loglevel = 4 ; Logger : : debug ( " Starting in debug mode " ) ; }
2021-05-24 08:25:07 +12:00
if ( ! string ( getenv ( " LANG " ) ) . ends_with ( " UTF-8 " ) & & ! string ( getenv ( " LANG " ) ) . ends_with ( " utf-8 " ) ) {
2021-05-29 12:32:36 +12:00
string err_msg = " No UTF-8 locale was detected! Symbols might not look as intended. " ;
2021-05-24 08:25:07 +12:00
Logger : : warning ( err_msg ) ;
cout < < " WARNING: " < < err_msg < < endl ;
}
2021-05-23 11:59:13 +12:00
2021-05-09 10:18:51 +12:00
//? Initialize terminal and set options
2021-05-15 04:54:37 +12:00
if ( ! Term : : init ( ) ) {
2021-05-29 12:32:36 +12:00
string err_msg = " No tty detected! " ;
2021-05-24 08:25:07 +12:00
Logger : : error ( err_msg + " Quitting. " ) ;
cout < < " ERROR: " < < err_msg < < endl ;
2021-05-22 12:13:56 +12:00
cout < < " btop++ needs an interactive shell to run. " < < endl ;
2021-05-29 12:32:36 +12:00
clean_quit ( 1 ) ;
2021-05-07 06:32:03 +12:00
}
2021-05-09 10:18:51 +12:00
//? Read config file if present
2021-06-02 08:36:36 +12:00
Config : : load ( ) ;
2021-05-30 12:15:09 +12:00
// Config::setB("truecolor", false);
2021-05-09 10:18:51 +12:00
2021-05-17 08:58:16 +12:00
auto thts = time_ms ( ) ;
2021-05-09 10:18:51 +12:00
//? Generate the theme
2021-05-22 12:13:56 +12:00
Theme : : set ( Theme : : Default_theme ) ;
2021-05-09 10:18:51 +12:00
//? Create the btop++ banner
2021-05-19 08:11:34 +12:00
Global : : banner = createBanner ( ) ;
2021-05-09 10:18:51 +12:00
2021-05-08 12:38:51 +12:00
2021-05-09 10:18:51 +12:00
//* ------------------------------------------------ TESTING ------------------------------------------------------
2021-05-30 12:15:09 +12:00
Global : : debuginit = true ;
2021-05-24 08:25:07 +12:00
2021-05-15 04:54:37 +12:00
// cout << Theme("main_bg") << Term::clear << flush;
2021-05-10 08:25:41 +12:00
bool thread_test = false ;
2021-05-07 06:32:03 +12:00
2021-05-29 12:32:36 +12:00
if ( ! Global : : debuginit ) cout < < Term : : alt_screen < < Term : : hide_cursor < < flush ;
2021-05-10 08:25:41 +12:00
2021-05-15 04:54:37 +12:00
cout < < Theme : : c ( " main_fg " ) < < Theme : : c ( " main_bg " ) < < Term : : clear < < endl ;
2021-05-07 06:32:03 +12:00
2021-05-15 04:54:37 +12:00
cout < < Mv : : r ( Term : : width / 2 - Global : : banner_width / 2 ) < < Global : : banner < < endl ;
2021-05-18 11:16:22 +12:00
// cout << string(Term::width - 1, '-') << endl;
2021-05-20 09:21:56 +12:00
size_t blen = ( Term : : width > 200 ) ? 200 : Term : : width ;
if ( Term : : width > 203 ) cout < < Mv : : r ( Term : : width / 2 - blen / 2 ) < < flush ;
2021-05-19 08:11:34 +12:00
int ill = 0 ;
2021-05-20 09:21:56 +12:00
for ( int i : iota ( 0 , ( int ) blen ) ) {
ill = ( i < = ( int ) blen / 2 ) ? i : ill - 1 ;
2021-05-28 08:29:36 +12:00
cout < < Theme : : g ( " used " ) [ ill ] < < Symbols : : h_line ;
2021-05-17 08:58:16 +12:00
}
2021-05-18 11:16:22 +12:00
cout < < Fx : : reset < < endl ;
2021-05-08 12:38:51 +12:00
2021-05-07 06:32:03 +12:00
//* Test theme
2021-05-19 08:11:34 +12:00
if ( false ) {
2021-05-17 08:58:16 +12:00
cout < < " Theme generation took " < < time_ms ( ) - thts < < " ms " < < endl ;
cout < < " Colors: " < < endl ;
uint i = 0 ;
for ( auto & item : Theme : : colors ) {
cout < < rjust ( item . first , 15 ) < < " : " < < item . second < < " ■ " s * 10 < < Fx : : reset < < " " ;
// << Theme::dec(item.first)[0] << ":" << Theme::dec(item.first)[1] << ":" << Theme::dec(item.first)[2] << ;
if ( + + i = = 4 ) {
i = 0 ;
cout < < endl ;
}
2021-05-08 12:38:51 +12:00
}
2021-05-09 10:18:51 +12:00
cout < < Fx : : reset < < endl ;
2021-05-17 08:58:16 +12:00
cout < < " Gradients: " ;
for ( auto & [ name , cvec ] : Theme : : gradients ) {
cout < < endl < < rjust ( name + " : " , 10 ) ;
for ( auto & color : cvec ) {
cout < < color < < " ■ " ;
}
cout < < Fx : : reset < < endl ;
}
exit ( 0 ) ;
2021-05-08 12:38:51 +12:00
}
2021-05-29 12:32:36 +12:00
if ( false ) {
2021-05-28 08:29:36 +12:00
Draw : : Meter kmeter ;
kmeter ( Term : : width - 2 , " cpu " , false ) ;
cout < < kmeter ( 25 ) < < endl ;
cout < < kmeter ( 0 ) < < endl ;
cout < < kmeter ( 50 ) < < endl ;
cout < < kmeter ( 100 ) < < endl ;
cout < < kmeter ( 50 ) < < endl ;
exit ( 0 ) ;
}
2021-05-29 12:32:36 +12:00
if ( false ) {
cout < < fs : : absolute ( fs : : current_path ( ) / " .. " ) < < endl ;
cout < < Global : : self_path < < endl ;
cout < < Theme : : theme_dir < < endl ;
cout < < Config : : conf_dir < < endl ;
exit ( 0 ) ;
}
if ( false ) {
string a = " ⣿ ⣿ \n ⣿⣿⣿⣿ ⣿ \n ⣿⣿⣿⣿ ⣿ \n ⣿⣿⣿⣿ ⣿ \n ⣿⣿⣿ " ;
cout < < a < < endl ;
exit ( 0 ) ;
}
2021-05-30 12:15:09 +12:00
if ( true ) {
vector < long long > mydata ;
for ( long long i = 0 ; i < = 100 ; i + + ) mydata . push_back ( i ) ;
for ( long long i = 100 ; i > = 0 ; i - - ) mydata . push_back ( i ) ;
2021-06-01 07:47:41 +12:00
// mydata.push_back(0);
// mydata.push_back(0);
2021-06-02 08:36:36 +12:00
// mydata.push_back(50);
2021-05-30 12:15:09 +12:00
2021-05-31 03:01:57 +12:00
// for (long long i = 0; i <= 100; i++) mydata.push_back(i);
// for (long long i = 100; i >= 0; i--) mydata.push_back(i);
2021-05-30 12:15:09 +12:00
2021-05-31 03:01:57 +12:00
Draw : : Graph kgraph { } ;
2021-06-01 07:47:41 +12:00
Draw : : Meter kmeter { } ;
2021-05-31 03:01:57 +12:00
Draw : : Graph kgraph2 { } ;
Draw : : Graph kgraph3 { } ;
2021-05-30 12:15:09 +12:00
2021-05-31 03:01:57 +12:00
auto kts = time_micros ( ) ;
kgraph ( Term : : width , 10 , " process " , mydata , false , false ) ;
2021-06-01 07:47:41 +12:00
kmeter ( Term : : width , " process " ) ;
// cout << Mv::save << kgraph(mydata) << "\n\nInit took " << time_micros() - kts << " μs. " << endl;
// exit(0);
2021-05-31 03:01:57 +12:00
kgraph2 ( Term : : width , 10 , " process " , mydata , true , false ) ;
kgraph3 ( Term : : width , 1 , " process " , mydata , false , false ) ;
// cout << kgraph() << endl;
// cout << kgraph2() << endl;
// exit(0);
2021-06-01 07:47:41 +12:00
// cout << Mv::save << kgraph(mydata) << "\n" << kmeter(mydata.back()) << "\n\nInit took " << time_micros() - kts << " μs. " << endl;
2021-06-02 08:36:36 +12:00
cout < < Mv : : save < < kgraph ( mydata , true ) < < " \n " < < kgraph2 ( mydata , true ) < < " \n " < < kgraph3 ( mydata , true ) < < " \n " < < kmeter ( mydata . back ( ) ) < < " \n \n Init took " < < time_micros ( ) - kts < < " μs. " < < endl ;
2021-05-31 03:01:57 +12:00
// sleep_ms(1000);
// mydata.push_back(50);
// cout << Mv::restore << kgraph(mydata) << "\n" << kgraph2(mydata) << "\n\nInit took " << time_micros() - kts << " μs. " << endl;
// exit(0);
2021-05-30 12:15:09 +12:00
2021-06-01 07:47:41 +12:00
// int x = 0q;
long long y = 0 ;
bool flip = false ;
2021-05-30 12:15:09 +12:00
list < uint64_t > ktavg ;
2021-05-31 03:01:57 +12:00
while ( true ) {
2021-06-01 07:47:41 +12:00
// mydata.back() = std::rand() % 101;
mydata . back ( ) = y ;
2021-05-30 12:15:09 +12:00
kts = time_micros ( ) ;
2021-05-31 03:01:57 +12:00
// cout << Mv::restore << " "s * Term::width << "\n" << " "s * Term::width << endl;
2021-06-01 07:47:41 +12:00
// cout << Mv::restore << kgraph(mydata) << "\n" << kmeter(mydata.back()) << endl;
cout < < Mv : : restore < < kgraph ( mydata ) < < " \n " < < kgraph2 ( mydata ) < < " \n " < < " " s * Term : : width < < Mv : : l ( Term : : width ) < < kgraph3 ( mydata ) < < " \n " < < kmeter ( mydata . back ( ) ) < < endl ;
2021-05-30 12:15:09 +12:00
ktavg . push_front ( time_micros ( ) - kts ) ;
if ( ktavg . size ( ) > 100 ) ktavg . pop_back ( ) ;
cout < < " Time: " < < ktavg . front ( ) < < " μs. Avg: " < < accumulate ( ktavg . begin ( ) , ktavg . end ( ) , 0 ) / ktavg . size ( ) < < " μs. " < < flush ;
2021-06-01 07:47:41 +12:00
if ( flip ) y - - ;
else y + + ;
if ( y = = 100 | | y = = 0 ) flip = ! flip ;
2021-05-31 03:01:57 +12:00
if ( Input : : poll ( ) ) {
if ( Input : : get ( ) = = " space " ) Input : : wait ( true ) ;
else break ;
}
sleep_ms ( 100 ) ;
2021-05-30 12:15:09 +12:00
}
Input : : get ( ) ;
exit ( 0 ) ;
}
2021-05-28 08:29:36 +12:00
2021-05-10 08:25:41 +12:00
if ( thread_test ) {
2021-05-29 12:32:36 +12:00
unordered_flat_map < int , future < string > > runners ;
unordered_flat_map < int , string > outputs ;
2021-05-10 08:25:41 +12:00
2021-05-17 08:58:16 +12:00
for ( int i : iota ( 0 , 10 ) ) {
2021-05-10 08:25:41 +12:00
runners [ i ] = async ( my_worker , i ) ;
}
2021-05-17 08:58:16 +12:00
// uint i = 0;
2021-05-10 08:25:41 +12:00
while ( outputs . size ( ) < 10 ) {
2021-05-17 08:58:16 +12:00
for ( int i : iota ( 0 , 10 ) ) {
2021-05-20 09:21:56 +12:00
if ( runners [ i ] . valid ( ) & & runners [ i ] . wait_for ( std : : chrono : : milliseconds ( 10 ) ) = = future_status : : ready ) {
2021-05-10 08:25:41 +12:00
outputs [ i ] = runners [ i ] . get ( ) ;
cout < < " Thread " < < i < < " : " < < outputs [ i ] < < endl ;
}
}
// if (++i >= 10) i = 0;
if ( outputs . size ( ) > = 8 ) Global : : stop_all . store ( true ) ;
}
}
2021-05-07 06:32:03 +12:00
2021-05-13 13:11:29 +12:00
cout < < " Up for " < < sec_to_dhms ( round ( system_uptime ( ) ) ) < < endl ;
2021-05-07 06:32:03 +12:00
2021-05-10 08:25:41 +12:00
2021-05-22 12:13:56 +12:00
//*------>>>>>> Proc testing
2021-05-11 09:46:41 +12:00
2021-05-13 13:11:29 +12:00
2021-05-10 08:25:41 +12:00
auto timestamp = time_ms ( ) ;
2021-05-15 04:54:37 +12:00
Proc : : init ( ) ;
2021-05-11 09:46:41 +12:00
2021-05-10 08:25:41 +12:00
2021-05-14 07:11:10 +12:00
uint lc ;
2021-05-13 13:11:29 +12:00
string ostring ;
2021-05-22 12:13:56 +12:00
uint64_t tsl , timestamp2 , rcount = 0 ;
2021-05-29 12:32:36 +12:00
list < uint64_t > avgtimes = { 0 } ;
2021-05-20 09:21:56 +12:00
uint timer = 1000 ;
2021-05-15 04:54:37 +12:00
bool filtering = false ;
bool reversing = false ;
int sortint = Proc : : sort_map [ " cpu lazy " ] ;
2021-05-18 11:16:22 +12:00
vector < string > greyscale ;
2021-05-15 04:54:37 +12:00
string filter ;
string filter_cur ;
string key ;
2021-05-18 11:16:22 +12:00
int xc ;
for ( uint i : iota ( 0 , ( int ) Term : : height - 19 ) ) {
xc = 230 - i * 150 / ( Term : : height - 20 ) ;
greyscale . push_back ( Theme : : dec_to_color ( xc , xc , xc ) ) ;
}
2021-05-28 08:29:36 +12:00
string pbox = Draw : : createBox ( { . x = 0 , . y = 10 , . width = Term : : width , . height = Term : : height - 16 , . line_color = Theme : : c ( " proc_box " ) , . title = " testbox " , . title2 = " below " , . fill = false , . num = 7 } ) ;
2021-05-18 11:16:22 +12:00
pbox + = rjust ( " Pid: " , 8 ) + " " + ljust ( " Program: " , 16 ) + " " + ljust ( " Command: " , Term : : width - 69 ) + " Threads: " +
ljust ( " User: " , 10 ) + " " + rjust ( " MemB " , 5 ) + " " + rjust ( " Cpu% " , 14 ) + " \n " ;
2021-05-11 09:46:41 +12:00
2021-05-15 04:54:37 +12:00
while ( key ! = " q " ) {
2021-05-28 08:29:36 +12:00
timestamp = time_micros ( ) ;
tsl = time_ms ( ) + timer ;
2021-05-19 08:11:34 +12:00
auto plist = Proc : : collect ( Proc : : sort_array [ sortint ] , reversing , filter ) ;
2021-05-28 08:29:36 +12:00
timestamp2 = time_micros ( ) ;
2021-05-15 04:54:37 +12:00
timestamp = timestamp2 - timestamp ;
2021-05-13 13:11:29 +12:00
ostring . clear ( ) ;
lc = 0 ;
2021-05-15 04:54:37 +12:00
filter_cur = ( filtering ) ? Fx : : bl + " █ " + Fx : : reset : " " ;
2021-05-18 11:16:22 +12:00
ostring = Mv : : save + Mv : : u ( 2 ) + Mv : : r ( 20 ) + trans ( rjust ( " Filter: " + filter + filter_cur + string ( Term : : width / 3 , ' ' ) +
2021-05-20 09:21:56 +12:00
" Sorting: " + string ( Proc : : sort_array [ sortint ] ) , Term : : width - 25 , true , filtering ) ) + Mv : : restore ;
2021-05-15 04:54:37 +12:00
2021-05-19 08:11:34 +12:00
for ( auto & p : plist ) {
ostring + = Mv : : r ( 1 ) + greyscale [ lc ] + rjust ( to_string ( p . pid ) , 8 ) + " " + ljust ( p . name , 16 ) + " " + ljust ( p . cmd , Term : : width - 66 , true ) + " " +
rjust ( to_string ( p . threads ) , 5 ) + " " + ljust ( p . user , 10 ) + " " + rjust ( floating_humanizer ( p . mem , true ) , 5 ) + string ( 11 , ' ' ) ;
ostring + = ( p . cpu_p > 100 ) ? rjust ( to_string ( p . cpu_p ) , 3 ) + " " : rjust ( to_string ( p . cpu_p ) , 4 ) ;
2021-05-13 13:11:29 +12:00
ostring + = " \n " ;
2021-05-18 11:16:22 +12:00
if ( lc + + > Term : : height - 21 ) break ;
2021-05-15 04:54:37 +12:00
}
2021-05-28 08:29:36 +12:00
while ( lc + + < Term : : height - 19 ) ostring + = Mv : : r ( 1 ) + string ( Term : : width - 2 , ' ' ) + " \n " ;
2021-05-29 12:32:36 +12:00
if ( rcount > 0 ) avgtimes . push_front ( timestamp ) ;
if ( avgtimes . size ( ) > 10 ) avgtimes . pop_back ( ) ;
2021-05-18 11:16:22 +12:00
cout < < pbox < < ostring < < Fx : : reset < < " \n " < < endl ;
2021-05-28 08:29:36 +12:00
cout < < Mv : : to ( Term : : height - 4 , 1 ) < < " Processes call took: " < < rjust ( to_string ( timestamp ) , 5 ) < < " μs. Average: " < <
rjust ( to_string ( accumulate ( avgtimes . begin ( ) , avgtimes . end ( ) , 0 ) / avgtimes . size ( ) ) , 5 ) < < " μs of " < < avgtimes . size ( ) < <
" samples. Drawing took: " < < time_micros ( ) - timestamp2 < < " μs. \n Number of processes: " < < Proc : : numpids < < " . Run count: " < <
2021-05-27 02:23:29 +12:00
+ + rcount < < " . Time: " < < strf_time ( " %X " ) < < endl ;
2021-05-15 04:54:37 +12:00
while ( time_ms ( ) < tsl ) {
if ( Input : : poll ( tsl - time_ms ( ) ) ) key = Input : : get ( ) ;
else { key . clear ( ) ; continue ; }
if ( filtering ) {
if ( key = = " enter " ) filtering = false ;
else if ( key = = " backspace " ) { if ( ! filter . empty ( ) ) filter = uresize ( filter , ulen ( filter ) - 1 ) ; }
else if ( key = = " space " ) filter . push_back ( ' ' ) ;
else if ( ulen ( key ) = = 1 ) filter . append ( key ) ;
2021-05-19 08:11:34 +12:00
else { key . clear ( ) ; continue ; }
2021-05-15 04:54:37 +12:00
break ;
}
else if ( key = = " q " ) break ;
2021-05-19 08:11:34 +12:00
else if ( key = = " left " ) { if ( - - sortint < 0 ) sortint = ( int ) Proc : : sort_array . size ( ) - 1 ; }
else if ( key = = " right " ) { if ( + + sortint > ( int ) Proc : : sort_array . size ( ) - 1 ) sortint = 0 ; }
2021-05-15 04:54:37 +12:00
else if ( key = = " f " ) filtering = true ;
else if ( key = = " r " ) reversing = ! reversing ;
else if ( key = = " delete " ) filter . clear ( ) ;
else continue ;
break ;
2021-05-13 13:11:29 +12:00
}
}
2021-05-11 09:46:41 +12:00
// cout << "Found " << plist.size() << " pids\n" << endl;
2021-05-10 08:25:41 +12:00
2021-05-22 12:13:56 +12:00
//*-----<<<<<
2021-05-10 08:25:41 +12:00
2021-05-07 06:32:03 +12:00
return 0 ;
}