diff -Niur openmosix-tools-0.3.6-2/mosmon/mosmon.1 openmosix-tools-0.3.6-3/mosmon/mosmon.1 --- openmosix-tools-0.3.6-2/mosmon/mosmon.1 Mon Apr 19 11:32:23 2004 +++ openmosix-tools-0.3.6-3/mosmon/mosmon.1 Tue Dec 21 20:34:35 2004 @@ -3,7 +3,10 @@ .\" .\" openMosix $Id: mosmon.1,v 1.1 2004/04/19 09:32:23 sithender Exp $ .\" -.\" Last Modified (almost rewritten) 2004/04/07 by: +.\" Last modified 2004/11/15 by: +.\" Moreno 'baro' Baricevic +.\" +.\" Modified (almost rewritten) 2004/04/07 by: .\" - Moreno 'baro' Baricevic .\" - Tony Travis .\" @@ -16,7 +19,7 @@ .\" FROM THE USE OF THIS MANUAL WILL BE ACCEPTED. .\" .\" =========================================================================== -.TH MOSMON 1 "April 07, 2004" "openMosix" "openMosix tools User's Manual" +.TH MOSMON 1 "November 14, 2004" "openMosix" "openMosix tools User's Manual" .\" =========================================================================== . . @@ -39,6 +42,9 @@ [ \fB-w\fR | \fB-v\fR | \fB-V\fR | \fB-a\fR ] .B mosmon +[ \fB-1\fR | \fB-2\fR | \fB-3\fR | \fB-4\fR | \fB-5\fR ] + +.B mosmon [ \fB-s\fR | \fB-m\fR | \fB-r\fR | \fB-u\fR | [ \fB-l\fR | \fB-L\fR ] ] .B mosmon @@ -86,6 +92,13 @@ nodes to be displayed simultaneously. Otherwise, horizontal numbering is selected. +.TP +.\".BR -[12345] \ ([\fI12345\fR]) +.BR -1 | -2 | -3 | -4 | -5 \ (\fI1\fR|\fI2\fR|\fI3\fR|\fI4\fR|\fI5\fR) +Display is splitted into multiple rows. This allows the maximum number of nodes +to be displayed, even though the load lacks of precision. Default is a single +row (1). + .\" - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - .TP .BR -s \ (\fIs\fR) @@ -333,11 +346,11 @@ Adapted to openMosix from Mosix and bugfixing by David Santo Orcero -Last (heavily) modified on 2004/04/07 by Moreno 'baro' Baricevic -. - +Heavily modified on 2004/04/07 by Moreno 'baro' Baricevic . Thanks also to Tony Travis for his log-load patch. +Modified on 2004/11/14 by Jozef Ivanecky and Moreno Baricevic. + Permission to use, copy and distribute this software is hereby granted under the terms of version 2 or any later version of the GNU General Public License, as published by the Free Software Foundation. diff -Niur openmosix-tools-0.3.6-2/mosmon/mosmon.c openmosix-tools-0.3.6-3/mosmon/mosmon.c --- openmosix-tools-0.3.6-2/mosmon/mosmon.c Mon Apr 19 11:31:11 2004 +++ openmosix-tools-0.3.6-3/mosmon/mosmon.c Tue Dec 21 21:44:30 2004 @@ -21,7 +21,7 @@ /* -** Last modified on 7 April 2004 by Moreno 'baro' Baricevic +** Modified on 7 April 2004 by Moreno 'baro' Baricevic ** ** ** This version of mosmon is independent of kernel headers. @@ -38,6 +38,16 @@ ** - ... */ + +/* +** Last modified on December 2004 by Jozef Ivanecky and Moreno Baricevic +** - +** +** - main() splitted into several subroutines; +** - multirows display (-12345). +*/ + + #include #include #include @@ -56,7 +66,7 @@ #define PROGNAME "mosmon" -#define PROGVER "2.0" +#define PROGVER "2.1" #include "utils.h" @@ -89,7 +99,8 @@ #define KEY_C3 0540 /* Lower right of keypad */ #define KEY_END 0550 /* end key */ -#define KEY_IC 0513 /* insert-character key */ +#define KEY_DC 0512 /* delete-character key */ +#define KEY_IC 0513 /* insert-character key */ /************************************************************** @@ -133,6 +144,7 @@ "t toggle display of total operational node count\n" \ " (not recommended on very large clusters - will be very slow)\n" \ "y display the yardstick (i.e. speed of a standard processor)\n" \ +"1/2/3/4/5 split display into 2, 3, 4 or 5 rows (default 1)\n" \ "\n" \ "Enter redraw the screen\n" \ "Insert force update after openMosix is restarted\n" \ @@ -146,7 +158,19 @@ "\n" \ "Try \"" PROGNAME " -h\" to see command line options or " \ "\"man " PROGNAME "\" for details.\n" \ -"\n" +"" + + +/************************************************************** +** new types +*/ +typedef struct { // Display: + int dead; // dead nodes + int vert; // vertical numbering + int wide; // wide (horizontal) numbering + int tot; // total number of operational nodes +} disp_flag_s; + /************************************************************** @@ -170,6 +194,25 @@ void sleep_or_input( unsigned int secs ); void onint( int i ); +/* ex-main() */ +void process_args( int argc , char * argv[] , disp_flag_s * flg , int * need_count ); +void initialization( const char * file ); +void get_screen_size( void ); +void get_total_counts( int * first_read , int * nread , int * tot_display , int * cpus_display , unsigned int turns ); +void get_counts( int * first_read , int * nread , int * tot , int dflg , int tflg ); +void calculate_screen_width( int * wid , int * ver , int vflg , int wflg , int tot ); +void display_header( void ); +void display_item_text( void ); +void display_axes( int wid ); +void display_total_info( int tot_display , int cpus_display ); +void collect_nodes_stats( int * dead , int first_read , int nread , int dflg , int tflg , float * max ); +void check_max_value( float * max , float * curmax ); +NCURSES_CONST char * get_item_format( float max ); +void display_x_labels( int ver , int wid , int dflg ); +void display_y_labels( int ver , float max ); +void display_bars( int ver , int wid , int dflg , int rev , char space , float max ); +void check_input( disp_flag_s * flg , int * need_count , float * curmax ); + /* ! openMosix */ static void not_mosix( void ) { @@ -182,16 +225,25 @@ /************************************************************** ** some useful macros */ +#define PROC_HPC_SSPEED "/proc/hpc/admin/sspeed" #define COL_FROM_0 7 #define MAX_SILENT ( -5 ) #define VERY_DEAD ( MAX_SILENT - 1 ) -#define PROC_HPC_SSPEED "/proc/hpc/admin/sspeed" +#define N_STRLEN( _x ) ( 1 + ( _x > 9 ) + ( _x > 99 ) + ( _x > 999 ) + ( _x > 9999 ) ) /************************************************************** -** global variables (arrays numbering starts at 1) +** global variables */ int screen_width; +int screen_cols = 80 , screen_rows = 24 ; +int base; /* baseline location */ +int rows = 1; /* number of rows (multirow display) */ +//#define ROW_OFFSET( _row ) ( ( _row - 1 ) * ( base / rows ) ) /* constant */ +#define ROW_OFFSET( _row ) ( base * ( _row - 1 ) / rows ) + + +/* arrays numbering starts at 1 */ mosix_info_s info[MOSIX_MAX+1]; float load[MOSIX_MAX+1], other[MOSIX_MAX+1]; char valid[MOSIX_MAX+1]; @@ -206,7 +258,7 @@ } item = D_GETLOAD; int ifd = -1; /* input file */ -int npe = 0; /* number of record */ +int npe = 0; /* number of records */ int first = 1; /* first node displayed */ @@ -225,34 +277,193 @@ ************/ int main( int argc , char * argv[] ) { - int l , col ; - register int i = 0 , j = 0 , k = 0 ; - float max , curmax = 0 ; - int cool = 0 ; - int dead ; - struct winsize ws ; - int vflg = 0 , wflg = 0 , tflg = 0 ; - int dflg = 0 ; - int last ; - int base ; /* baseline location */ - int ver = 0 ; - int wid ; /* width of processor numbers */ - char need_count = 1 ; - int tot = 0 , tot_display = 0 , cpus_display = 0 ; - NCURSES_CONST char * fmt ; - unsigned int turns = 0 ; - char space , ospace ; - int rev ; - int first_read , nread ; - const char * file = PROC_HPC_INFOS ; + disp_flag_s flg = { 0 , 0 , 0 , 0 }; + int ver = 0 ; /* vertical display */ + int wid ; /* width of nodes numbers */ + + int dead ; /* Number of dead nodes ... */ + int last ; /* last node displayed */ + int first_read , nread ; /* nodes */ + + int tot = 0 , + tot_display = 0 , /* number of available nodes */ + cpus_display = 0 ; /* total number of available cpus */ + float max , curmax = 0 ; /* max value displayed (load/mem/speed/...) */ + + int need_count = 1 ; + + unsigned int turns = 0 ; /* turns from startup */ + + char space ; /* character used as vertical bar */ + int rev ; /* reverse highlight (solid bar) */ + #ifdef DEBUG stdreopen(); #endif - /* - ** command line options parser - */ + process_args( argc , argv , &flg , &need_count ); + + initialization( PROC_HPC_INFOS ); + + while ( 1 ) // start neverending loop + { + // if oM un/configured while we are running, recheck for recsz and npe. + if ( vernum == _UNKNOWN ) + vernum = guess_by_recsz( ifd ) , get_npe(); + + first_read = nread = 0; + + /* get the new (if changed) win size */ + get_screen_size(); + if ( screen_cols != COLS || screen_rows != LINES ) + { + if ( is_term_resized( screen_rows , screen_cols ) ) + { + DBGprint( "resizing window to %dx%d" , screen_cols , screen_rows ); + resizeterm( screen_rows , screen_cols ); + } + initscr(); + refresh(); + need_count = 1; + vernum = _UNKNOWN; // force reload (previous acquisition maybe interrupted by SIGWINCH) + continue; + } + + if ( flg.tot ) + get_total_counts( &first_read , &nread , &tot_display , &cpus_display , turns ); + + if ( need_count && ! flg.vert && ! flg.wide ) + get_counts( &first_read , &nread , &tot , flg.dead , flg.tot ) , need_count = 0; + + calculate_screen_width( &wid , &ver , flg.vert , flg.wide , tot ); + + display_item_text(); + display_axes( wid ); + + if ( flg.tot ) + display_total_info( tot_display , cpus_display ); + + max = 0; + dead = 0; /* number of not responding machines */ + turns++; + + collect_nodes_stats( &dead , first_read , nread , flg.dead , flg.tot , &max ); + + check_max_value( &max , &curmax ); + + display_y_labels( ver , max ); + + last = first + screen_width + dead - 1; + if ( npe < last ) + last = npe; + if ( wid == 0 && 2 * ( last - first + 1 - dead ) <= screen_width ) + wid = 1; + if ( wid == 0 ) + space = '|' , rev = 0; + else + space = ' ' , rev = 1; + if ( rev ) + standout(); + + if ( max ) + display_bars( ver , wid , flg.dead , rev , space , max ); + + if ( rev ) + standend(); + + display_x_labels( ver , wid , flg.dead ); /* Nodes numbers */ + + if ( turns % 60 == 0 ) + get_npe(); + + /* + ** screen's out, check for interactive keys + */ + sleep_or_input( 1 ); + check_input( &flg , &need_count , &curmax ); + + } /* neverending loop */ + +} /* main */ + + + +/******************************************************************** + *_____________________________ USAGE _____________________________* + ********************************************************************/ +/* +** ...does something useful +** should fit on 80x24 screen (error + help + prompt) +*/ +#define BELL { if ( isatty( STDERR_FILENO ) ) putc( '\a' , stderr ); } +void usage ( const char * errmsg , ... ) +{ + + if ( errmsg && *errmsg ) + { + va_list args; + BELL; + fprintf( stderr , "*** Usage error: " ); + va_start( args , errmsg ); + vfprintf( stderr , errmsg , args ); + va_end( args ); + putc( '\n' , stderr ); + } + + fprintf ( stderr , + "\n" + "Usage: %s [options]\n" + "\n" + " -w horizontal (wide) numbering\n" + " -v vertical numbering\n" + " -V super-vertical (tight) numbering\n" + " -a automatic selection of numbering (default)\n" + "\n" + " -s show CPU speed (10,000 = 400MHz Pentium-2)\n" + " -m show memory (used out of total)\n" + " -r show memory (raw used/free out of total)\n" + " -u show utilizability (%%)\n" + " -l show load (default, 1.0 = 100%% standard CPU)\n" +#ifdef USE_LOG_LOAD + " -L show load (log scale, 2.0 = 100%% standard CPU)\n" +#endif /* USE_LOG_LOAD */ +// "\n" + " -d show dead nodes (configured but not-responding)\n" + " -t show total number of operational nodes\n" +// " (not recommended on very large clusters, will\n" +// " be very slow)\n" + " -[12345] split display into 2, 3, 4 or 5 rows (default 1)\n" +// "\n" + " +NODE_NUMBER begin the display at a particular node-number\n" + "\n" + " -F KVER force kernel version instead of guessing record size\n" +// " (KVER = [2416|...|2419|2420|2421|2422|2423|...])\n" + "\n" + " -h|-H display this message\n" +// "\n" +// "Try 'man %s' for details.\n" + "\n" + , PROGNAME +// , PROGNAME + ); + + exit( errmsg ? 1 : 0 ); + +} /* usage */ + + + +/*************************************************************************** + *_____________________________ PROCESS_ARGS _____________________________* + ***************************************************************************/ +/* +** command line options parser +*/ +void process_args( int argc , char * argv[] , disp_flag_s * flg , int * need_count ) +{ + register int j = 0 ; + while ( argc > 1 && ( argv[1][0] == '-' || argv[1][0] == '+' ) ) { if ( argv[1][0] == '+' ) @@ -280,20 +491,20 @@ usage( NULL ); //--------------------------------- case 'v': - vflg = 1; - wflg = 0; + flg->vert = 1; + flg->wide = 0; break; case 'V': - vflg = 2; - wflg = 0; + flg->vert = 2; + flg->wide = 0; break; case 'w': - vflg = 0; - wflg = 1; + flg->vert = 0; + flg->wide = 1; break; case 'a': - wflg = vflg = 0; - need_count = 1; + flg->wide = flg->vert = 0; + *need_count = 1; break; //--------------------------------- case 's': item = D_GETSPEED; break; @@ -306,10 +517,18 @@ case 'l': item = D_GETLOAD; break; //--------------------------------- case 't': - tflg = 1; + flg->tot = 1; break; case 'd': - dflg = 1; + flg->dead = 1; + break; + //--------------------------------- + case '1': + case '2': + case '3': + case '4': + case '5': + rows = argv[1][j] - '0' ; break; //--------------------------------- case 'F': @@ -340,6 +559,16 @@ if ( argc > 1 ) usage( "too many arguments [%s]" , argv[1] ); +} /* process_args */ + + + +/***************************************************************************** + *_____________________________ INITIALIZATION _____________________________* + *****************************************************************************/ +void initialization( const char * file ) +{ + DBGprint( "using file \"%s\" ..." , file ); ifd = open( file , O_RDONLY ); if ( ifd == -1 ) @@ -363,506 +592,591 @@ get_npe(); // get the number of records from PROC_HPC_INFOS +#if 0 + { + register int i = 0; + while ( i <= npe ) + load[i++] = 0.0; + } +#else + memset( load , 0 , ( 1 + npe ) * sizeof( float ) ); +#endif + /* ** ok, start ncurses ** trap some signals in order to clear the screen before exit. */ - signal( SIGINT , (sig_t)onint ); + signal( SIGINT , (sig_t)onint ); signal( SIGQUIT , (sig_t)onint ); initscr(); noecho(); cbreak(); system( "stty cbreak -echo" ); - for ( i = 0 ; i <= npe ; i++ ) - load[i] = 0; + /* + ** trap also SIGWINCH since it could interrupt guess_by_recsz and confuse + ** the user with a "openMosix not configured" message. + ** Window change is handled by main() trough get_screen_size() and + ** resizeterm(). + */ + signal( SIGWINCH , SIG_IGN ); - while ( 1 ) // start neverending loop +} /* initialization */ + + + +/****************************************************************************** + *_____________________________ GET_SCREEN_SIZE _____________________________* + ******************************************************************************/ +#ifdef DEBUG +# define XY( msg ) \ + do { \ + DBGprint( "%10.10s %d x %d - %d x %d" \ + , #msg \ + , screen_cols , screen_rows \ + , COLS , LINES \ + ); \ + } while ( 0 ); +#else +# define XY(_) +#endif +void get_screen_size( void ) +{ + struct winsize ws ; /* window size structure (termios) */ + + if ( ioctl( STDOUT_FILENO , TIOCGWINSZ , &ws ) != -1 && + ws.ws_col > 0 && ws.ws_row > 0 ) { + screen_cols = ws.ws_col; + screen_rows = ws.ws_row; + XY( "ioctl" ); + } +#if 1 + else // use ncurses size + { + screen_cols = COLS; + screen_rows = LINES; + XY( "curses" ); + } +#else //{ + if ( screen_cols == 0 || screen_rows == 0 ) + { + screen_cols = tgetnum( "co" ); + screen_rows = tgetnum( "li" ); + XY( "tgetnum" ); + } - // if oM un/configured while we are running, recheck for recsz and npe. - if ( vernum == _UNKNOWN ) - vernum = guess_by_recsz( ifd ) , get_npe(); + if ( screen_cols == 0 || screen_rows == 0 ) + { + char *columns , *lines ; /* Unix98 environment variables */ + columns = getenv( "COLUMNS" ); + if ( columns && *columns ) + { + screen_cols = strtoi( columns ); + if ( errno == EINVAL || screen_cols == 0 ) + screen_cols = 80; + } + lines = getenv( "LINES" ); + if ( lines && *lines ) + { + screen_rows = strtoi( lines ); + if ( errno == EINVAL || screen_rows == 0 ) + screen_rows = 24; + } + XY( "getenv" ); + } +#endif //} - first_read = nread = 0; + if ( screen_cols == 0 || screen_rows == 0 ) + fprintf( stderr , "No luck! Screen size %dx%d\n" , screen_cols , screen_rows ) , onint( 0 ); - /* get the new (if changed) win size */ - if ( ioctl( STDIN_FILENO , TIOCGWINSZ , (char *)&ws ) == -1 ) - fprintf( stderr , "ioctl() failed: [%d] %m\n" , errno ) , onint( 1 ); +} /* get_screen_size */ +#undef XY - if ( ( COLS != ws.ws_col ) || ( LINES != ws.ws_row ) ) + + +/******************************************************************************* + *_____________________________ GET_TOTAL_COUNTS _____________________________* + *******************************************************************************/ +void get_total_counts( int * first_read , int * nread , int * tot_display , int * cpus_display , unsigned int turns ) +{ + register int i , j ; + + memset( &info[1] , 0 , npe * RECSZ_STD ); // clear records buffer + + (void)lseek( ifd , 0L , SEEK_SET ); // goto start of file + j = readstruct( ifd , &info[1] , npe ); // read the whole file content + DBGprint( "j = %d" , j ); + if ( j < npe ) + { + npe = j; + adjust_first(); + } + + *first_read = 1; + *nread = npe; + + /* + ** check for invalid records (dead nodes) + */ + for ( *tot_display = 0 , *cpus_display = 0 , i = 1 ; i <= npe ; i++ ) + { + if ( info[i].status & DS_MOSIX_UP ) { - initscr(); - need_count = 1; + (*tot_display)++; + (*cpus_display) += info[i].ncpus; + valid[i] = 1; + load[i] = -1; } - - if ( tflg ) + else if ( ( info[i].status & DS_MOSIX_DEF ) && + valid[i] > ( turns >= -MAX_SILENT ? MAX_SILENT : -(int64_t)turns ) ) { - memset( &info[1] , 0 , npe * RECSZ_STD ); // clear records buffer + (*tot_display)++; + (*cpus_display) += info[i].ncpus; + } + } - (void)lseek( ifd , 0L , SEEK_SET ); // goto start of file - j = readstruct( ifd , &info[1] , npe ); // read the whole file content - DBGprint( "j = %d" , j ); - if ( j < npe ) - { - npe = j; - adjust_first(); - } +} /* get_total_counts */ - first_read = 1; - nread = npe; - /* - ** check for invalid records (dead nodes) - */ - for ( tot_display = 0 , cpus_display = 0 , i = 1 ; i <= npe ; i++ ) - { - if ( info[i].status & DS_MOSIX_UP ) - { - tot_display++; - cpus_display += info[i].ncpus; - valid[i] = 1; - load[i] = -1; - } - else if ( - ( info[i].status & DS_MOSIX_DEF ) && - valid[i] > ( turns >= -MAX_SILENT ? MAX_SILENT : -(int64_t)turns ) - ) - { - tot_display++; - cpus_display += info[i].ncpus; - } - } - } - if ( need_count && ! vflg && ! wflg ) - { - get_npe(); - k = ( COLS - COL_FROM_0 - 1 ) + 1; - tot = 0; +/************************************************************************* + *_____________________________ GET_COUNTS _____________________________* + *************************************************************************/ +void get_counts( int * first_read , int * nread , int * tot , int dflg , int tflg ) +{ + register int i , j , k ; + int last ; - /* we only need to answer whether there are at least k - * nodes up ahead or not: once we have the answer, - * stop reading. Of course, with "tflg" we have already - * read everything */ + get_npe(); - first_read = first; + k = ( screen_cols - COL_FROM_0 - 1 ) + 1; - if ( ! tflg ) - nread = 0; + *tot = 0; - for ( i = first ; i <= npe && tot < k ; i += k ) - { - last = i + k - 1; - if ( last > npe ) - last = npe; - if ( ! tflg ) - { - (void)lseek( ifd , i - 1 , SEEK_SET ); - j = readstruct( ifd , &info[i] , ( last - i + 1 ) ); - if ( j < ( last - i + 1 ) ) - last = npe = i + j - 1; - nread = last + 1 - first; - } - for ( j = i ; j <= last && tot < k ; j++ ) - if ( info[j].status & ( dflg ? DS_MOSIX_DEF : DS_MOSIX_UP ) ) - tot++; - } + /* we only need to answer whether there are at least k + * nodes up ahead or not: once we have the answer, + * stop reading. Of course, with "tflg" we have already + * read everything */ - need_count = 0; - } + *first_read = first; - /* calculate the screen_width */ - wid = 1 + ( npe > 9 ) + ( npe > 99 ) + ( npe > 999 ) + ( npe > 9999 ); - k = ( COLS - COL_FROM_0 - 1 ) / ( wid + 1 ); + if ( ! tflg ) + *nread = 0; - if ( vflg ) + for ( i = first ; i <= npe && *tot < k ; i += k ) + { + last = i + k - 1; + if ( last > npe ) + last = npe; + if ( ! tflg ) { + (void)lseek( ifd , i - 1 , SEEK_SET ); + j = readstruct( ifd , &info[i] , ( last - i + 1 ) ); + if ( j < ( last - i + 1 ) ) + last = npe = i + j - 1; + *nread = last + 1 - first; + } + for ( j = i ; j <= last && *tot < k ; j++ ) + if ( info[j].status & ( dflg ? DS_MOSIX_DEF : DS_MOSIX_UP ) ) + (*tot)++; + } + +} /* get_counts */ + + + +/************************************************************************************* + *_____________________________ CALCULATE_SCREEN_WIDTH _____________________________* + *************************************************************************************/ +void calculate_screen_width( int * wid , int * ver , int vflg , int wflg , int tot ) +{ + int k ; + + /* calculate the screen_width */ + *wid = N_STRLEN( npe ); + k = ( screen_cols - COL_FROM_0 - 1 ) / ( *wid + 1 ); + + DBGprint( "-- %d -- %d -- %d -- %d --" , *wid , *ver , vflg , screen_width ); + + if ( vflg ) + { vert: - base = LINES - 2 - wid; - ver = 1; - if ( vflg == 2 ) - { - wid = 0; - screen_width = ( COLS - COL_FROM_0 - 1 ); - } - else - { - wid = 1; - screen_width = ( COLS - COL_FROM_0 - 1 ) / 2; - } - adjust_first(); - } - else if ( wflg || k >= tot || ( COLS - COL_FROM_0 - 1 ) < tot ) + base = screen_rows - 2 - *wid; + *ver = 1; + if ( vflg == 2 ) { - ver = 0; - screen_width = k; - base = LINES - 3; + *wid = 0; + screen_width = ( screen_cols - COL_FROM_0 - 1 ); } else - goto vert; + { + *wid = 1; + screen_width = ( screen_cols - COL_FROM_0 - 1 ) / 2; + } + adjust_first(); + } + else if ( wflg || k >= tot || ( screen_cols - COL_FROM_0 - 1 ) < tot ) + { + *ver = 0; + screen_width = k; + base = screen_rows - 3; + } + else + goto vert; + + DBGprint( "++ %d ++ %d ++ %d ++ %d ++" , *wid , *ver , vflg , screen_width ); - move( 0 , 0 ); - clrtobot(); +} /* calculate_screen_width */ - if ( item == D_GETMEM || item == D_GETBMEM ) + + +/***************************************************************************** + *_____________________________ DISPLAY_HEADER _____________________________* + *****************************************************************************/ +#define LONG_HEADER "openMosix monitor" +#define SHORT_HEADER "mosmon" +void display_header ( void ) +{ +// static const int lh = strlen( LONG_HEADER ); +// static const int sh = strlen( SHORT_HEADER ); +// sizeof() makes gcc happy (avoid "initializer element is not constant" warning) + static const int lh = sizeof( LONG_HEADER ) - 1 ; + static const int sh = sizeof( SHORT_HEADER ) - 1 ; + + int header = screen_cols - COL_FROM_0 - 1; + if ( header > lh ) + { + move( 0 , COL_FROM_0 + 1 + ( header >> 1 ) - ( lh >> 1 ) ); + addstr( LONG_HEADER ); + } + else if ( header > sh ) + { + move( 0 , COL_FROM_0 + 1 + ( header >> 1 ) - ( sh >> 1 ) ); + addstr( SHORT_HEADER ); + } +} /* display_header */ +#undef LONG_HEADER +#undef SHORT_HEADER + + + +/******************************************************************************** + *_____________________________ DISPLAY_ITEM_TEXT _____________________________* + ********************************************************************************/ +void display_item_text( void ) +{ + int i , j ; + const char * ylabel; + + move( 0 , 0 ); + clrtobot(); + + display_header(); + + if ( item == D_GETMEM || item == D_GETBMEM ) + { + if ( item == D_GETBMEM ) { - if ( item == D_GETBMEM ) - { - fmt = "Raw Used Memory"; - i = base / 2 - 8; - if ( i < 1 ) - i = 1; - } - else - { - fmt = "Used Memory"; - i = base / 2 - 6; - j = 1; - } - for ( ; *fmt ; i++ ) - { - move( i , 0 ); - addch( (chtype)*fmt++ ); - } - while ( i == base / 4 || i == base / 2 || i == base * 3 / 4 ) - i++; - if ( i < base ) - { - move( i , 2 ); - addstr( "(MB)" ); - } + ylabel = "Raw Used Memory"; + i = base / 2 - 8; + if ( i < 1 ) + i = 1; + } + else + { + ylabel = "Used Memory"; + i = base / 2 - 6; + j = 1; + } + for ( ; *ylabel ; i++ ) + { + move( i , 0 ); + addch( (chtype)*ylabel++ ); } - else if ( item == D_GETLOAD ) + while ( i == base / 4 || i == base / 2 || i == base * 3 / 4 ) + i++; + if ( i < base ) { + move( 0 , 2 ); + addstr( "(MB)" ); + } + } + else if ( item == D_GETLOAD ) + { #ifdef USE_LOG_LOAD - int n = ( log_load ) ? 7 : 3 ; - fmt = ( log_load ) ? "LOG LOAD" : "LOAD" ; + int n = ( log_load ) ? 7 : 3 ; + ylabel = ( log_load ) ? "LOG LOAD" : "LOAD" ; #else - int n = 3; - fmt = "LOAD"; + int n = 3; + ylabel = "LOAD"; #endif /* USE_LOG_LOAD */ - for ( i = base / 2 - n ; *fmt ; i += 2 ) - { - move( i , 0 ); - addch( (chtype)*fmt++ ); - } - } - else if ( item == D_GETSPEED ) + for ( i = base / 2 - n ; *ylabel ; i += 2 ) { - fmt = "SPEED"; - for ( i = base / 2 - 4 ; *fmt ; i += 2 ) - { - move( i , 0 ); - addch( (chtype)*fmt++ ); - } + move( i , 0 ); + addch( (chtype)*ylabel++ ); } - else + } + else if ( item == D_GETSPEED ) + { + ylabel = "SPEED"; + for ( i = base / 2 - 4 ; *ylabel ; i += 2 ) { - fmt = "Utilizability"; - for ( i = base / 2 - 7 ; *fmt ; i++ ) - { - move( i , 0 ); - addch( (chtype)*fmt++ ); - } + move( i , 0 ); + addch( (chtype)*ylabel++ ); } - - for ( i = 0 ; i < base ; i++ ) + } + else + { + ylabel = "Utilizability"; + for ( i = base / 2 - 7 ; *ylabel ; i++ ) { - move( i , COL_FROM_0 ); - addch( '|' ); + move( i , 0 ); + addch( (chtype)*ylabel++ ); } + } - move( base , COL_FROM_0 ); +} /* display_item_text */ + + +/*************************************************************************** + *_____________________________ DISPLAY_AXES _____________________________* + ***************************************************************************/ +void display_axes( int wid ) +{ + register int i; + int r; + + for ( i = 0 ; i < base ; i++ ) + { + move( i , COL_FROM_0 ); + addch( '|' ); + } + + for ( r = 1 ; r <= rows ; r++ ) + { + move( base - ROW_OFFSET( r ) , COL_FROM_0 ); for ( i = screen_width * ( wid + 1 ) + 1 ; i > 0 ; i-- ) addch( '-' ); + } - j = ( COLS - COL_FROM_0 - 8 ) / 2; - if ( j < COL_FROM_0 ) - j = COL_FROM_0; - else if ( j > 27 ) - j = 27; + move( screen_rows - 2 , 0 ); + addstr( "Node #" ); - move( LINES - 2 , 0 ); - addstr( "Node #" ); +} /* display_axes */ - if ( tflg ) - { - move( LINES - 1 , 0 ); - if ( tot_display ) - printw( "[Total %d] [CPUs %d]" , tot_display , cpus_display ); - else - printw( "[openMosix Not Configured]" ); - } - max = 0; - dead = 0; - turns++; +/********************************************************************************* + *_____________________________ DISPLAY_TOTAL_INFO _____________________________* + *********************************************************************************/ +void display_total_info( int tot_display , int cpus_display ) +{ + move( screen_rows - 1 , 0 ); - if ( ! tflg ) - (void)lseek( ifd , first - 1 , SEEK_SET ); + if ( tot_display ) + printw( "[Total %d] [CPUs %d]" , tot_display , cpus_display ); + else + printw( "[openMosix Not Configured]" ); - for ( i = first ; ( i < ( first + screen_width + dead ) ) && ( i <= npe ) ; i++ ) - { - /* if we receive 0 we don't remove the load of - the process completely: only divide it by two */ +} /* display_total_info */ - if ( ! ( ( i >= first_read ) && ( i < first_read + nread ) ) ) - { - /*try to compute optimal read-ahead (not easy)*/ - if ( ! nread ) - first_read = i; - /* guess same # of dead as already found */ - j = first + screen_width + dead + dead - i; - if ( j > npe - i + 1 ) - j = npe - i + 1; - j = readstruct( ifd , &info[i] , j ); - if ( j <= 0 ) - { - npe = i - 1; - break; - } - nread += j; - } - if ( info[i].status & DS_MOSIX_UP ) - { - valid[i] = 1; - switch ( item ) - { - case D_GETLOAD: -#ifdef USE_LOG_LOAD - load[i] = ( log_load ) - ? ( ( info[i].load > 0 ) ? log10( info[i].load ) : 0 ) - : ( info[i].load / 100.0 ) ; -#else - load[i] = info[i].load / 100.0; -#endif /* USE_LOG_LOAD */ - other[i] = info[i].ncpus; - break; - case D_GETMEM: - load[i] = info[i].tmem / 1048576.0; - other[i] = load[i] - info[i].mem / 1048576.0; - break; - case D_GETBMEM: - load[i] = info[i].tmem / 1048576.0; - other[i] = load[i] - info[i].rmem / 1048576.0; - break; - case D_GETSPEED: - load[i] = info[i].speed; - other[i] = info[i].ncpus; - break; - case D_GETUTIL: - load[i] = info[i].util / info[i].ncpus; - break; - } - } - else if ( ! ( info[i].status & DS_MOSIX_DEF ) ) - load[i] = valid[i] = VERY_DEAD; - else if ( valid[i] <= MAX_SILENT + 1 ) - load[i] = valid[i] = MAX_SILENT; - else - { - valid[i]--; - if ( load[i] < 0 ) - load[i] = 0; - } - if ( load[i] < 0 ) - { - load[i] = (valid[i] < 0) ? valid[i] : -1; - if ( load[i] <= ( dflg ? VERY_DEAD : MAX_SILENT ) ) - dead++; - } -#ifdef USE_LOG_LOAD -# if 0 - if ( load[i] > max ) - { - if ( log_load && item == D_GETLOAD ) - max = 4; - else - max = load[i]; - } -# else - if ( log_load && item == D_GETLOAD ) - max = 4; // when log_load max must be always 4 - else if ( load[i] > max ) - max = load[i]; -# endif -#else - if ( load[i] > max ) - max = load[i]; -#endif /* USE_LOG_LOAD */ - } +/********************************************************************************** + *_____________________________ COLLECT_NODES_STATS _____________________________* + **********************************************************************************/ +void collect_nodes_stats( int * dead , int first_read , int nread , int dflg , int tflg , float * max ) +{ + register int i , j ; - if ( tflg ) - { - for ( ; i <= npe ; i++ ) - if ( ! ( info[i].status & DS_MOSIX_DEF ) ) - valid[i] = VERY_DEAD; - else if ( valid[i] > MAX_SILENT && ! ( info[i].status & DS_MOSIX_UP ) ) - valid[i]--; + if ( ! tflg ) + (void)lseek( ifd , first - 1 , SEEK_SET ); - for ( i = first - 1 ; i > 0 ; i-- ) - if ( ! ( info[i].status & DS_MOSIX_DEF ) ) - valid[i] = VERY_DEAD; - else if ( valid[i] > MAX_SILENT && ! ( info[i].status & DS_MOSIX_UP ) ) - valid[i]--; - } + for ( i = first ; ( i < ( first + screen_width * rows + *dead ) ) && ( i <= npe ) ; i++ ) + { + /* if we receive 0 we don't remove the load of + the process completely: only divide it by two */ - if ( max < 1 ) + if ( ! ( ( i >= first_read ) && ( i < first_read + nread ) ) ) { - if ( max == 0 && item == D_GETLOAD ) /* idle */ + /* try to compute optimal read-ahead (not easy) */ + if ( ! nread ) + first_read = i; + /* guess same # of dead as already found */ + j = first + screen_width * rows + *dead + *dead - i; + if ( j > npe - i + 1 ) + j = npe - i + 1; + j = readstruct( ifd , &info[i] , j ); + if ( j <= 0 ) { - standout(); - move( base - 1 , 2 ); - addstr( "IDLE" ); - standend(); + npe = i - 1; + break; } - max = 1; + nread += j; } - if ( max >= curmax ) + + if ( info[i].status & DS_MOSIX_UP ) { - curmax = max; - cool = 0; + valid[i] = 1; + switch ( item ) + { + case D_GETLOAD: +#ifdef USE_LOG_LOAD + load[i] = ( log_load ) + ? ( ( info[i].load > 0 ) ? log10( info[i].load ) : 0 ) + : ( info[i].load / 100.0 ) ; +#else + load[i] = info[i].load / 100.0; +#endif /* USE_LOG_LOAD */ + other[i] = info[i].ncpus; + break; + case D_GETMEM: + load[i] = info[i].tmem / 1048576.0; + other[i] = load[i] - info[i].mem / 1048576.0; + break; + case D_GETBMEM: + load[i] = info[i].tmem / 1048576.0; + other[i] = load[i] - info[i].rmem / 1048576.0; + break; + case D_GETSPEED: + load[i] = info[i].speed; + other[i] = info[i].ncpus; + break; + case D_GETUTIL: + load[i] = info[i].util / info[i].ncpus; + break; + } } + else if ( ! ( info[i].status & DS_MOSIX_DEF ) ) + load[i] = valid[i] = VERY_DEAD; + else if ( valid[i] <= MAX_SILENT + 1 ) + load[i] = valid[i] = MAX_SILENT; else { - if ( cool++ >= 3 ) - curmax = max; - max = curmax; + valid[i]--; + if ( load[i] < 0 ) + load[i] = 0; } - if ( item == D_GETMEM ) + if ( load[i] < 0 ) { - /* typical values are very close to 1MB multiples, - * but not quite, causing distortions: - */ + load[i] = ( valid[i] < 0 ) ? valid[i] : -1; + if ( load[i] <= ( dflg ? VERY_DEAD : MAX_SILENT ) ) + (*dead)++; } - switch ( item ) +#ifdef USE_LOG_LOAD +# if 0 + if ( load[i] > *max ) { - case D_GETLOAD: - fmt = "%5.2f"; - break; - case D_GETSPEED: - fmt = "%5.0f"; - break; - case D_GETUTIL: - fmt = "%4.0f%%"; - break; - case D_GETMEM: - case D_GETBMEM: - fmt = ( max >= 999.0 ) ? "%5.0f" : "%5.3g" ; - break; + if ( log_load && item == D_GETLOAD ) + *max = 4; + else + *max = load[i]; } +# else + if ( log_load && item == D_GETLOAD ) + *max = 4; // when log_load max must be always 4 + else if ( load[i] > *max ) + *max = load[i]; +# endif +#else + if ( load[i] > *max ) + *max = load[i]; +#endif /* USE_LOG_LOAD */ + } - if ( max > 0 ) - { - move( 0 , 1 ); - printw( fmt , max ); - } - /*if ( max >= 3 )*/ - { - move( base / 4 , 1 ); - printw( fmt , max * 3 / 4 ); - move( base / 2 , 1 ); - printw( fmt , max / 2 ); - move( base * 3 / 4 , 1 ); - printw( fmt , max / 4 ); - } - move( base , 5 ); - addch( '0' ); + if ( tflg ) + { + for ( ; i <= npe ; i++ ) + if ( ! ( info[i].status & DS_MOSIX_DEF ) ) + valid[i] = VERY_DEAD; + else if ( valid[i] > MAX_SILENT && ! ( info[i].status & DS_MOSIX_UP ) ) + valid[i]--; + + for ( i = first - 1 ; i > 0 ; i-- ) + if ( ! ( info[i].status & DS_MOSIX_DEF ) ) + valid[i] = VERY_DEAD; + else if ( valid[i] > MAX_SILENT && ! ( info[i].status & DS_MOSIX_UP ) ) + valid[i]--; + } + +} /* collect_nodes_stats */ + + + +/****************************************************************************** + *_____________________________ CHECK_MAX_VALUE _____________________________* + ******************************************************************************/ +void check_max_value( float * max , float * curmax ) +{ + static int cool; - last = first + screen_width + dead - 1; - if ( npe < last ) - last = npe; - if ( wid == 0 && 2 * ( last - first + 1 - dead ) <= screen_width ) - wid = 1; - if ( wid == 0 ) - { - space = '|'; - rev = 0; - } - else + if ( *max < 1 ) + { + if ( *max == 0 && item == D_GETLOAD ) /* idle */ { - space = ' '; - rev = 1; + standout(); + move( base - 1 , 2 ); + addstr( "IDLE" ); + standend(); } - if ( rev ) - standout(); + *max = 1; + } + if ( *max >= *curmax ) + { + *curmax = *max; + cool = 0; + } + else + { + if ( cool++ >= 3 ) + *curmax = *max; + *max = *curmax; + } - dead = 0; /* number of not responding machines */ +} /* check_max_value */ - if ( max ) - { - for ( i = first ; i <= last ; i++ ) - { - if ( load[i] > 0 ) - { - col = COL_FROM_0 + 1 + ( wid != 0 ) + wid / 2 + - ( wid + 1 ) * ( i - first - dead ); - l = base - ( load[i] * base ) / max + 0.5; - if ( item == D_GETMEM || item == D_GETBMEM ) - { - k = base - ( other[i] * base ) / max + 0.5; - if ( rev ) - standend(); - for ( ; l < k ; l++ ) - { - move( l , col ); - addch( (chtype)( valid[i] > 0 ? '+' : '?' ) ); - } - if ( rev ) - standout(); - } - ospace = space; - if ( item == D_GETSPEED && other[i] > 1 ) - space = '0' + other[i]; - for ( ; l < base ; l++ ) - { - move( l , col ); - addch( (chtype)( valid[i] > 0 ? space : '?' ) ); - } - space = ospace; - } - else if ( load[i] < 0 ) - { - if ( load[i] <= ( dflg ? VERY_DEAD : MAX_SILENT ) ) - { - dead++; - continue; - } - col = COL_FROM_0 + 1 + ( wid != 0 ) + wid / 2 + - ( wid + 1 ) * ( i - first - dead ); - if ( rev ) - standend(); - move( base - 4 , col ); - addch( 'D' ); - move( base - 3 , col ); - addch( 'E' ); - move( base - 2 , col ); - addch( 'A' ); - move( base - 1 , col ); - addch( 'D' ); - if ( rev ) - standout(); - } - } - } +/****************************************************************************** + *_____________________________ GET_ITEM_FORMAT _____________________________* + ******************************************************************************/ +NCURSES_CONST char * get_item_format( float max ) +{ + switch ( item ) + { + case D_GETLOAD: return "%5.2f"; + case D_GETSPEED: return "%5.0f"; + case D_GETUTIL: return "%4.0f%%"; + case D_GETMEM: // fall through + case D_GETBMEM: return ( max >= 999.0 ) ? "%5.0f" : "%5.3g"; + default: return "%f"; // WTF! // should never happen + } +} /* get_item_format */ - if ( rev ) - standend(); + +/******************************************************************************* + *_____________________________ DISPLAY_X_LABELS _____________________________* + *******************************************************************************/ +void display_x_labels( int ver , int wid , int dflg ) +{ + register int i , j , k; + int r ; + int dead = 0 , prevdead = 0 ; + + for ( r = 1 ; r <= rows ; r++ ) + { if ( ver ) { - for ( j = 10 , k = LINES - 2 ; k > base ; k-- , j *= 10 ) + for ( j = 10 , k = screen_rows - 2 ; k > base ; k-- , j *= 10 ) { - move( k , COL_FROM_0 + 1 ); - for ( i = first ; i < ( first + screen_width + dead ) && i <= npe ; i++ ) + move( k - ROW_OFFSET( r ) , COL_FROM_0 + 1 ); + for ( i = first + screen_width * ( r - 1 ) + prevdead , dead = 0 ; + i < ( first + screen_width * r + dead + prevdead ) && i <= npe ; + i++ ) { if ( load[i] > ( dflg ? VERY_DEAD : MAX_SILENT ) ) { @@ -870,13 +1184,18 @@ addch( ' ' ); addch( (chtype)( '0' + i % j / ( j / 10 ) ) ); } + else + dead++; } } + prevdead += dead ; } else { - move( base + 1 ,COL_FROM_0 + 1 ); - for ( i = first ; i < ( first + screen_width + dead ) && i <= npe ; i++ ) + move( base + 1 - ROW_OFFSET( r ) , COL_FROM_0 + 1 ); + for ( i = first + screen_width * ( r - 1 ) + prevdead , dead = 0 ; + i < ( first + screen_width * r + dead + prevdead ) && i <= npe ; + i++ ) { if ( load[i] > ( dflg ? VERY_DEAD : MAX_SILENT ) ) { @@ -886,227 +1205,317 @@ printw( "%*s%d%*s" , wid / 2 , "" , i , wid / 2 - 2 , "" ); else { - j = wid - ( 1 + ( i > 9 ) + ( i > 99 ) + ( i > 999 ) + ( i > 9999 ) ); + j = wid - N_STRLEN( i ); printw( "%*s%d%*s" , j / 2 + 1 , "" , i , ( j + 1 ) / 2 , "" ); } } + else + dead++; } + prevdead += dead ; } + } + move( base , 79 ); + refresh(); - move( base , 79 ); - refresh(); +} /* display_x_labels */ - if ( turns % 60 == 0 ) - get_npe(); - /* - ** screen's out, check for interactive keys - */ - sleep_or_input( 1 ); - if ( is_input() ) - { - switch ( my_getch() ) - { - //-- - -- - -- - -- - -- - -- - - case '\2': - case KEY_HOME: -//#define __CB(m) cb(m,4,9) -#define __CB(m) cb_ctr(m) - __CB( "The openMosix Group" ); - __CB( " presents... " ); - __CB( PROGNAME " version " PROGVER "!" ); -#undef __CB - break; - case 'q': - case 'Q': - onint( 0 ); - case '\14': - case '\r': - case '\n': - clear(); - refresh(); - break; - case '?': - case 'h': - case 'H': - help(); - break; - //-- - -- - -- - -- - -- - -- - - case 'a': - case 'A': - wflg = vflg = 0; - need_count = 1; - break; - case 'v': - vflg = 1; - wflg = 0; - break; - case 'V': - vflg = 2; - wflg = 0; - break; - case 'w': - case 'W': - vflg = 0; - wflg = 1; - break; - //-- - -- - -- - -- - -- - -- - - case 't': - tflg = !tflg; - break; - case 'd': - case 'D': - dflg = !dflg; - break; - case 'y': - case 'Y': - yardstick(); - break; - //-- - -- - -- - -- - -- - -- - - case 's': - case 'S': - curmax = 0 ; - set_mode( D_GETSPEED ); - break; - case 'm': - case 'M': - curmax = 0 ; - set_mode( D_GETMEM ); - break; -#ifdef USE_LOG_LOAD - case 'L': - log_load = !log_load; - // fall through -#endif /* USE_LOG_LOAD */ - case 'l': - curmax = 0 ; - set_mode( D_GETLOAD ); - break; - case 'u': - case 'U': - curmax = 0 ; - set_mode( D_GETUTIL ); - break; - case 'r': - case 'R': - curmax = 0 ; - set_mode( D_GETBMEM ); - break; - //-- - -- - -- - -- - -- - -- - - case '+': - case KEY_RIGHT: - if ( first + screen_width - 1 < npe ) - first++; - break; - case '-': - case KEY_LEFT: - if ( first > 1 ) - { - need_count = 1; - first--; - } - break; - case 'n': //next - case 'N': - first += screen_width; - if ( first + screen_width - 1 > npe ) - { - first = npe + 1 - screen_width; - if ( first < 1 ) - first = 1; - } - break; - case 'p': //previous - case 'P': - case 'b': //back? - case 'B': - if ( first ) - need_count = 1; - if ( first > screen_width ) - first -= screen_width; - else - first = 1; - break; - //-- - -- - -- - -- - -- - -- - - case KEY_IC: - DBGprint( "interactive key INSERT, force update" ); - vernum = guess_by_recsz( ifd ) , get_npe(); - break; - //-- - -- - -- - -- - -- - -- - - default: - write( STDOUT_FILENO , "\a" , 1 ); - } +/******************************************************************************* + *_____________________________ DISPLAY_Y_LABELS _____________________________* + *******************************************************************************/ +void display_y_labels( int ver , float max ) +{ + NCURSES_CONST char * fmt = get_item_format( max ); - } /* is_input */ + int j ; + int ors ; /* One Row Size */ + int rbase ; + int vh; - } /* neverending loop */ + if ( rows == 1 ) + vh = 1 ; /* 1 row, no 'vh' space for nodes numbers is needed ... */ + else if ( ! ver ) + vh = 2 ; + else + vh = 1 + N_STRLEN( npe ); -} /* main */ + ors = base / rows - vh ; /* We need to consider a space 'vh' for nodes numbers */ + + for ( j = 1 ; j <= rows ; j++ ) + { + rbase = base - ROW_OFFSET( j ); + + if ( max > 0 ) + { +// move( rbase - ors + 1 , 1 ); + move( rbase - ors , 1 ); + printw( fmt , max ); + } + if ( ors > 4 && max > 0 ) + { + move( rbase - ( ors >> 1 ) , 1 ); + printw( fmt , max / 2 ); + } + if ( ors > 8 && max > 0 ) + { + move( rbase - ( ors >> 1 ) - ( ors >> 2 ) , 1 ); + printw( fmt , max * 3 / 4 ); + move( rbase - ( ors >> 1 ) + ( ors >> 2 ) , 1 ); + printw( fmt , max / 4 ); + } + move( rbase , 5 ); + addch( '0' ); + } +} /* display_y_labels */ -/******************************************************************** - *_____________________________ USAGE _____________________________* - ********************************************************************/ -/* -** ...does something useful -** should fit on 80x24 screen (error + help + prompt) -*/ -#define BELL { if ( isatty( STDERR_FILENO ) ) putc( '\a' , stderr ); } -void usage ( const char * errmsg , ... ) + +/*************************************************************************** + *_____________________________ DISPLAY_BARS _____________________________* + ***************************************************************************/ +void display_bars( int ver , int wid , int dflg , int rev , char space , float max ) { + register int i , k , ri ; + int col = 0 ; - if ( errmsg && *errmsg ) + int l , r , dead , prevdead = 0; + int rbase ; + int vh; + int disp_h; + + if ( rows == 1 ) + vh = 1 ; /* 1 row, no 'vh' space for nodes numbers is needed ... */ + else if ( ! ver ) + vh = 2 ; + else + vh = 1 + N_STRLEN( npe ); + + disp_h = base / rows - vh ; + + for ( r = 1 ; r <= rows ; r++ ) { - va_list args; - BELL; - fprintf( stderr , "*** Usage error: " ); - va_start( args , errmsg ); - vfprintf( stderr , errmsg , args ); - va_end( args ); - putc( '\n' , stderr ); + rbase = base - base * ( r - 1 ) / rows ; + dead = 0; + for ( i = first + screen_width * ( r - 1 ) + prevdead , ri = 0 ; + i < ( first + screen_width * r + dead + prevdead ) && i <= npe ; + i++ , ri++ ) + { + + if ( load[i] > 0 ) + { + col = COL_FROM_0 + 1 + ( wid != 0 ) + wid / 2 + ( wid + 1 ) * ri ; + + l = rbase - ( load[i] * ( base / rows - vh ) ) / max + 0.5; + + if ( item == D_GETMEM || item == D_GETBMEM ) + { + k = rbase - ( other[i] * ( rbase / rows - vh ) ) / max + 0.5; + if ( rev ) + standend(); + for ( ; l < k ; l++ ) + { + move( l , col ); + addch( (chtype)( valid[i] > 0 ? '+' : '?' ) ); + } + if ( rev ) + standout(); + } + if ( item == D_GETSPEED && other[i] > 1 ) + space = '0' + other[i]; + for ( ; l < rbase ; l++ ) + { + move( l , col ); + addch( (chtype)( valid[i] > 0 ? space : '?' ) ); + } + } + else if ( load[i] < 0 ) + { + if ( load[i] <= ( dflg ? VERY_DEAD : MAX_SILENT ) ) + { + dead++; + ri--; + continue; + } + col = COL_FROM_0 + 1 + ( wid != 0 ) + wid / 2 + ( wid + 1 ) * ri; + if ( rev ) + standend(); + if ( disp_h > 3 ) + { + move( rbase - 4 , col ); addch( 'D' ); + move( rbase - 3 , col ); addch( 'E' ); + move( rbase - 2 , col ); addch( 'A' ); + move( rbase - 1 , col ); addch( 'D' ); + } + else + { + move( rbase - 1 , col ); + addch( 'D' ); + } + if ( rev ) + standout(); + } + } + prevdead += dead ; } - fprintf ( stderr , - "\n" - "Usage: %s [options]\n" - "\n" - " -w horizontal (wide) numbering\n" - " -v vertical numbering\n" - " -V super-vertical (tight) numbering\n" - " -a automatic selection of numbering (default)\n" - "\n" - " -s show CPU speed (10,000 = 400MHz Pentium-2)\n" - " -m show memory (used out of total)\n" - " -r show memory (raw used/free out of total)\n" - " -u show utilizability (%%)\n" - " -l show load (default, 1.0 = 100%% standard CPU)\n" +} /* display_bars */ + + + +/************************************************************************** + *_____________________________ CHECK_INPUT _____________________________* + **************************************************************************/ +void check_input( disp_flag_s * flg , int * need_count , float * curmax ) +{ + if ( is_input() ) + { + int c = my_getch(); // must be int (KEY_* are greater than 255) + switch ( c ) + { + //-- - -- - -- - -- - -- - -- - + case '\2': + case KEY_HOME: +//#define __CB(m) cb(m,4,9) +#define __CB(m) cb_ctr(m) + __CB( "The openMosix Group" ); + __CB( " presents... " ); + __CB( PROGNAME " version " PROGVER "!" ); +#undef __CB + break; + case 'q': + case 'Q': + onint( 0 ); + case '\14': + case '\r': + case '\n': + clear(); + refresh(); + break; + case '?': + case 'h': + case 'H': + help(); + break; + //-- - -- - -- - -- - -- - -- - + case 'a': + case 'A': + flg->wide = flg->vert = 0; + *need_count = 1; + break; + case 'v': + flg->vert = 1; + flg->wide = 0; + break; + case 'V': + flg->vert = 2; + flg->wide = 0; + break; + case 'w': + case 'W': + flg->vert = 0; + flg->wide = 1; + break; + //-- - -- - -- - -- - -- - -- - + case 't': + flg->tot = !flg->tot; + break; + case 'd': + case 'D': + flg->dead = !flg->dead; + break; + case 'y': + case 'Y': + yardstick(); + break; + //-- - -- - -- - -- - -- - -- - + case '1': + case '2': + case '3': + case '4': + case '5': + rows = (char)c - '0' ; + break; + //-- - -- - -- - -- - -- - -- - + case 's': + case 'S': + *curmax = 0 ; + set_mode( D_GETSPEED ); + break; + case 'm': + case 'M': + *curmax = 0 ; + set_mode( D_GETMEM ); + break; #ifdef USE_LOG_LOAD - " -L show load (log scale, 2.0 = 100%% standard CPU)\n" + case 'L': + log_load = !log_load; + // fall through #endif /* USE_LOG_LOAD */ -// "\n" - " -d show dead nodes (configured but not-responding)\n" - " -t show total number of operational nodes\n" -// " (not recommended on very large clusters, will\n" -// " be very slow)\n" -// "\n" - " +NODE_NUMBER begin the display at a particular node-number\n" - "\n" - " -F KVER force kernel version instead of guessing record size\n" -// " (KVER = [2416|...|2419|2420|2421|2422|2423|...])\n" - "\n" - " -h|-H display this message\n" -// "\n" -// "Try 'man %s' for details.\n" - "\n" - , PROGNAME -// , PROGNAME - ); + case 'l': + *curmax = 0 ; + set_mode( D_GETLOAD ); + break; + case 'u': + case 'U': + *curmax = 0 ; + set_mode( D_GETUTIL ); + break; + case 'r': + case 'R': + *curmax = 0 ; + set_mode( D_GETBMEM ); + break; + //-- - -- - -- - -- - -- - -- - + case '+': + case KEY_RIGHT: + if ( first + screen_width - 1 < npe ) + first++; + break; + case '-': + case KEY_LEFT: + if ( first > 1 ) + { + *need_count = 1; + first--; + } + break; + case 'n': //next + case 'N': + first += screen_width; + if ( first + screen_width - 1 > npe ) + { + first = npe + 1 - screen_width; + if ( first < 1 ) + first = 1; + } + break; + case 'p': //previous + case 'P': + case 'b': //back? + case 'B': + if ( first ) + *need_count = 1; + if ( first > screen_width ) + first -= screen_width; + else + first = 1; + break; + //-- - -- - -- - -- - -- - -- - + case KEY_IC: + DBGprint( "interactive key INSERT, force update" ); + vernum = guess_by_recsz( ifd ) , get_npe(); + break; + //-- - -- - -- - -- - -- - -- - + default: + write( STDOUT_FILENO , "\a" , 1 ); + } - exit( errmsg ? 1 : 0 ); + } /* is_input */ -} /* usage */ +} /* check_input */ @@ -1391,6 +1800,12 @@ if ( readc_half_second() == '~' ) return( las_char = KEY_IC ); // INSERT = ESC[2~ break; + case '3': // otherwise trapped as key '3' (3 rows) + if ( readc_half_second() == '~' ) + return( las_char = KEY_DC ); // DELETE = ESC[3~ + break; + case '4': // otherwise trapped as key '4' (4 rows) + return ERR; case '5': case '6': if ( readc_half_second() == '~' ) @@ -1437,13 +1852,13 @@ w1 = newwin( 0 , 0 , 0 , 0 ); if ( w1 == NULL ) - printf( "error creating help.exiting..\n" ) , onint( 1 ); + printf( "error creating help. Exiting...\n" ) , onint( 1 ); waddstr( w1 , HELP_STR1 ); waddstr( w1 , "\nPress ESC to exit help or any other key to continue..." ); w2 = newwin( 0 , 0 , 0 , 0 ); if ( w2 == NULL ) - printf( "error creating help.exiting..\n") , onint( 1 ); + printf( "error creating help. Exiting...\n" ) , onint( 1 ); waddstr( w2 , HELP_STR2 ); waddstr( w2 , "\nPress any key to continue..." ); @@ -1527,13 +1942,13 @@ if ( mode == 0 ) /* create */ { - wn = newwin( LINES / 3 , COLS * 4 / 9 , LINES / 3 , COLS / 3 ); + wn = newwin( screen_rows / 3 , screen_cols * 4 / 9 , screen_rows / 3 , screen_cols / 3 ); if ( wn == NULL ) printf( "very bad\n" ) , onint( 1 ); mode = 1; } else - wclear(wn); + wclear( wn ); alarm( 0 ); clearok( wn , TRUE ); @@ -1559,10 +1974,10 @@ { static int mode = 0; static WINDOW *wn; - int nlines = ( LINES / 3 ); - int ncols = ( COLS * 4 / 9 ); - int begin_y = ( LINES / 3 ); - int begin_x = ( COLS / 3 ); + int nlines = ( screen_rows / 3 ); + int ncols = ( screen_cols * 4 / 9 ); + int begin_y = ( screen_rows / 3 ); + int begin_x = ( screen_cols / 3 ); if ( mode == 0 ) /* create */ { @@ -1572,12 +1987,12 @@ mode = 1; } else - wclear(wn); + wclear( wn ); alarm( 0 ); clearok( wn , TRUE ); box( wn , '|' , '-' ); - wmove( wn , (nlines/2) , (ncols/2)-(strlen(msg)/2) ); + wmove( wn , ( nlines / 2 ) , ( ncols / 2 ) - ( strlen( msg ) / 2 ) ); waddstr( wn , msg ); wrefresh( wn ); sleep( 1 ); @@ -1637,7 +2052,7 @@ echo(); nocbreak(); system( "stty -cbreak echo" ); - move( LINES - 1 , 0 ); + move( screen_rows - 1 , 0 ); refresh(); endwin(); ioctl( STDIN_FILENO , TCIOFLUSH , 0 );