//------------------------------------------------------------------- // activity.cpp // // This application continuously reads the volatile kernel data // that is stored in a pseudo-file (named '/proc/activity') and // displays it on the screen until the key is pressed. // The 'data' consists of an array of 256 counters representing // invocations of the kernel's 256 interrupt service routines. // // This program employs the 'curses' programming interface, and // is compiled using the command: // // $ g++ activity.cpp -lncurses -o activity // // It requires that an accompanying module (named 'activity.c') // has already been compiled and installed. // // This program also makes use of the 'select()' system-call to // allow efficient handling of the multiplexed program input. // // NOTE: Developed and tested with Linux kernel version 2.4.18. // // programmer: ALLAN CRUSE // written on: 22 MAR 2003 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), write(), close() #include // for initscr(), endwin() #define KEY_ESCAPE 27 // ASCII code for ESCAPE-key #define FILENAME "/proc/activity" // name of input pseudo-file int main( void ) { // open the pseudo-file for reading int fd = open( FILENAME, O_RDONLY ); if ( fd < 0 ) { fprintf( stderr, "could not find \'%s\' \n", FILENAME ); exit(1); } // initialize file-descriptor bitmap for 'select()' fd_set permset; FD_ZERO( &permset ); FD_SET( STDIN_FILENO, &permset ); FD_SET( fd, &permset ); // initialize the 'curses' screen-display initscr(); noecho(); clear(); raw(); // draw the screen's title, headline and sideline int i, ndev = 1+fd, row = 2, col = 27; mvprintw( row, col, "INTERRUPT ACTIVITY MONITOR" ); for (i = 0; i < 16; i++) { row = i+6; col = 6; mvprintw( row, col, "%02X:", i*16 ); row = 5; col = i*4 + 12; mvprintw( row, col, "%X", i ); } refresh(); // main loop: continuously responds to multiplexed input for(;;) { // sleep until some new data is ready to be read fd_set readset = permset; if ( select( ndev, &readset, NULL, NULL, NULL ) < 0 ) break; // process new data read from the keyboard char inch; if ( FD_ISSET( STDIN_FILENO, &readset ) ) if ( read( STDIN_FILENO, &inch, 1 ) > 0 ) if ( inch == KEY_ESCAPE ) break; // process new data read from the pseudo-file if ( FD_ISSET( fd, &readset ) ) { unsigned long counter[ 256 ] = {0}; lseek( fd, 0, SEEK_SET ); if ( read( fd, counter, 1024 ) < 1024 ) break; for (i = 0; i < 256; i++) { int row = ( i / 16 ) + 6; int col = ( i % 16 ) * 4 + 10; unsigned long what = counter[ i ] % 1000; if ( !counter[i] ) mvprintw( row, col, "---" ); else mvprintw( row, col, "%03d", what ); } row = 23; col = 0; move( row, col ); } refresh(); } // close the pseudo-file and restore the standard user-interface close( fd ); endwin(); }