/** * \fn void main (void) * \brief Création du compteur "nom_compteur" dans /opt/productivity_link * \return EXIT_SUCCESS code de statut : ok. * */ int main (void) { /** Le type uuid permet de donner un identificateur au compteur */ uuid_t uuid; unsigned long long nombre=0 ; int pld = PL_INVALID_DESCRIPTOR; /** Le nom du compteur est stocké * dans une constante de pointeur de chaine de caractères * const char *counter[]. */ const char *counter[] = {"grandeur_a_analyser"}; /// Ouverture et test du compteur. if ((pld = pl_open("nom_compteur",1,counter,&uuid)) != PL_INVALID_DESCRIPTOR){ /// Incrémentation de "nombre" jusqu'à 21. while (nombre<=21){ pl_write(pld,&nombre,0); nombre++; sleep(1); } /// Décrémentation de "nombre" jusqu'à 5. while (nombre>5){ nombre--; pl_write(pld,&nombre,0); sleep(1); } /// Fermeture du compteur pl_close(pld); } return EXIT_SUCCESS; }
//----------------------------------------------------------------------------- // Program entry point - main //----------------------------------------------------------------------------- int main(int argc, char *argv[]) { //------------------------------------------------------------------------- // Generic variables. //------------------------------------------------------------------------- int i = 0; int ret = PL_FAILURE; #ifdef __PL_WINDOWS__ BOOL b_ret = FALSE; size_t st_ret = 0; #ifdef __PL_FILESYSTEM_LESS__ DWORD dw_ret = 0; #endif // __PL_FILESYSTEM_LESS__ #endif // __PL_WINDOWS__ //------------------------------------------------------------------------- // PL management variables. //------------------------------------------------------------------------- int pld = PL_INVALID_DESCRIPTOR; //------------------------------------------------------------------------- // File operation management variables. //------------------------------------------------------------------------- char file[PL_MAX_PATH]; #if defined (__PL_WINDOWS__) && !defined (__PL_FILESYSTEM_LESS__) OPENFILENAME ofn; TCHAR t_file[PL_MAX_PATH]; #endif // __PL_WINDOWS__ && !__PL_FILESYSTEM_LESS__ //------------------------------------------------------------------------- // Counter data management variables. //------------------------------------------------------------------------- #ifdef __PL_WINDOWS__ ULONGLONG performance = 0; ULONGLONG work_units = 0; #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) unsigned long long performance = 0; unsigned long long work_units = 0; #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ //------------------------------------------------------------------------- #if defined (__PL_WINDOWS__) && !defined (__PL_FILESYSTEM_LESS__) //------------------------------------------------------------------------- // Open a file selection dialog box. //------------------------------------------------------------------------- ZeroMemory( t_file, sizeof(t_file) ); ZeroMemory( &ofn, sizeof(ofn) ); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = NULL; ofn.lpstrFile = t_file; ofn.nMaxFile = sizeof(t_file); ofn.lpstrFilter = _T("Productivity Link Configuration File\0*.INI\0"); ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = PL_FOLDER; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; b_ret = GetOpenFileName(&ofn); if(!b_ret) { return(1); // signal error } ZeroMemory( file, sizeof(file) ); wcstombs_s( &st_ret, file, sizeof(file), ofn.lpstrFile, _TRUNCATE ); #endif // __PL_WINDOWS__ && !__PL_FILESYSTEM_LESS__ //------------------------------------------------------------------------- // Check input arguments count and retrive file name (no checks on name). //------------------------------------------------------------------------- #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) if(argc != 2) { fprintf( stderr, "\nUsage: %s <pl_config_file>\n\n", argv[0] ); exit(1); // signal error } memset( file, 0, sizeof(file) ); strncpy( file, argv[1], strlen(argv[1]) ); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ #if defined (__PL_WINDOWS__) && defined (__PL_FILESYSTEM_LESS__) if(argc != 2) { fprintf( stderr, "\nUsage: %s <pl_config_file>\n\n", argv[0] ); exit(1); // signal error } memset( file, 0, sizeof(file) ); strncpy( file, argv[1], strlen(argv[1]) ); #endif // __PL_WINDOWS__ && __PL_FILESYSTEM_LESS__ //------------------------------------------------------------------------- // Display PL directory. //------------------------------------------------------------------------- printf("\n*******************************************************\n"); printf("Using productivity link directory: %s\n", file); printf("*******************************************************\n\n"); //------------------------------------------------------------------------- // Attach to PL. //------------------------------------------------------------------------- pld = pl_attach(file); if(pld == PL_INVALID_DESCRIPTOR) { #ifdef __PL_WINDOWS__ fprintf( stdout, "pl_attach() error: [%d]d - [%x]h\n", GetLastError(), GetLastError() ); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || defined (__PL_SOLARIS__) || (__PL_MACOSX__) fprintf( stdout, "pl_attach() error: [%d]d - [%x]h\n", errno, errno ); fflush(stdout); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ assert(0); } //------------------------------------------------------------------------- // Read PL counters ITERATIONS times. //------------------------------------------------------------------------- for(i = 0; i < ITERATIONS; i++) { printf( "Iteration %d\t", i ); #ifndef __PL_BLOCKING_COUNTER_FILE_LOCK__ ret = pl_read( pld, &performance, PERFORMANCE ); check(ret); ret = pl_read( pld, &work_units, WORK_UNITS ); check(ret); #else // __PL_BLOCKING_COUNTER_FILE_LOCK__ ret = pl_read( pld, &performance, PERFORMANCE ); if(ret != PL_SUCCESS) { #ifdef __PL_WINDOWS__ fprintf( stdout, "pl_read() error: [%d]d - [%x]h\n", GetLastError(), GetLastError() ); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || defined (__PL_SOLARIS__) || (__PL_MACOSX__) fprintf( stdout, "pl_read() error: [%d]d - [%x]h\n", errno, errno ); fflush(stdout); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ assert(0); } ret = pl_read( pld, &work_units, WORK_UNITS ); assert(ret == PL_SUCCESS); #endif // __PL_BLOCKING_COUNTER_FILE_LOCK__ //------------------------------------------------------------------------- // Pause and echo counters values. //------------------------------------------------------------------------- #ifdef __PL_WINDOWS__ Sleep(PAUSE); printf( "performance: %I64u, work_units: %I64u\n", performance, work_units ); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) sleep(PAUSE); printf( "performance: %lld, work_units: %lld\n", performance, work_units ); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ } // for i //------------------------------------------------------------------------- // Clean-up. //------------------------------------------------------------------------- ret = pl_close(pld); if(ret != PL_SUCCESS) { #ifdef __PL_WINDOWS__ fprintf( stdout, "pl_close() error: [%d]d - [%x]h\n", GetLastError(), GetLastError() ); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || defined (__PL_SOLARIS__) || (__PL_MACOSX__) fprintf( stdout, "pl_close() error: [%d]d - [%x]h\n", errno, errno ); fflush(stdout); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ assert(0); } else { pld = PL_INVALID_DESCRIPTOR; } return(0); }
//----------------------------------------------------------------------------- // program entry point. //----------------------------------------------------------------------------- int main(int argc, char *argv[], char *envp[]) { //------------------------------------------------------------------------- // Generic variables. //------------------------------------------------------------------------- int ret = -1; PENERGY_DATA p = NULL; PL_STATUS plret = PL_FAILURE; unsigned long long value = 0; char buffer[ENERGY_INPUT_LINE_MAX_SIZE] = { '\0' }; #ifdef __PL_WINDOWS__ BOOL bret = FALSE; #endif // __PL_WINDOWS__ //------------------------------------------------------------------------- // ESRV instance handling variables. //------------------------------------------------------------------------- char esrv_config_file_name_buffer[PL_MAX_PATH] = { '\0' }; int f_esrv_guid = 0; int f_esrv_pid = 0; char *env = NULL; //------------------------------------------------------------------------- // Variables used to build ESRV start command -- if we have to. //------------------------------------------------------------------------- char esrv_command_buffer[PL_MAX_PATH] = { '\0' }; //------------------------------------------------------------------------- // Variables used to remove ESRV PL after use -- if we started it. //------------------------------------------------------------------------- char esrv_pl_path_name[PL_MAX_PATH] = { '\0' }; #ifdef __PL_WINDOWS__ char current_path_name[PL_MAX_PATH] = { '\0' }; char esrv_pl_config_file_name[PL_MAX_PATH] = { '\0' }; struct _finddata_t find_files; intptr_t file = 0; #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) DIR *directory = NULL; struct dirent *file = NULL; char file_name[PL_MAX_PATH] = { '\0' }; #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ //------------------------------------------------------------------------- // Variables used to read ESRV's sartup output -- used to get the GUID //------------------------------------------------------------------------- char *pc = NULL; char *token = NULL; int input_line_count = 0; char esrv_guid[ENERGY_GUID_LENGHT_IN_CHARACTERS + 1] = { '\0' }; #ifdef __PL_WINDOWS__ DWORD esrv_pid = 0; HANDLE esrv_handle = NULL; DWORD bytes_read = 0; #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) pid_t esrv_pid = 0; #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ //------------------------------------------------------------------------- // Signal handler variables. //------------------------------------------------------------------------- #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) struct sigaction sa; #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ //-------------------------------------------------------------------------- //------------------------------------------------------------------------- // Retrive the energy structure address. //------------------------------------------------------------------------- p = &energy_data; assert(p != NULL); //------------------------------------------------------------------------- // Initialize the energy data structure. //------------------------------------------------------------------------- memset(p, 0, sizeof(ENERGY_DATA)); p->argc = argc; p->argv = argv; p->channel = ENERGY_DEFAULT_CHANNEL; p->esrv_pld = PL_INVALID_DESCRIPTOR; p->esrv_status = ESRV_STATUS_NOT_RUNNING; //------------------------------------------------------------------------- // Parse user input. //------------------------------------------------------------------------- plret = parser(&energy_data); if(plret != PL_SUCCESS) { _ERROR("Unable to make sense of user input."); } else { if((p->f_help == 1) || (p->f_version == 1)) { goto done; } } //------------------------------------------------------------------------- // Check for inconsistent user input. //------------------------------------------------------------------------- if( ( (p->f_guid == 1) && (p->f_guid_shell_variable) ) ) { _ERROR( "Incompatible ESRV instance designation. Please use --guid or --guid_shell_variable option." ); } if(p->f_command == 0) { _ERROR( "You need to specify a command. Use energy --help for details." ); } //------------------------------------------------------------------------- // Select the ESRV instance to use. // Note: // If no ESRV id is provided, then an instance is started and ended // by the program. // Note: // If GUID is provided, build the pl_config.ini full path name for the // attach. // Note: // If CONFIG is provided, then do nothing, we are ready to attach. //------------------------------------------------------------------------- memset( esrv_config_file_name_buffer, 0, sizeof(esrv_config_file_name_buffer) ); if(p->f_guid == 1) { memcpy( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_ROOT, strlen(ENERGY_ESRV_PL_CONFIG_FILE_ROOT) ); strncat( esrv_config_file_name_buffer, ESRV_APPLICATION_NAME, strlen(ESRV_APPLICATION_NAME) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE, strlen(ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE) ); strncat( esrv_config_file_name_buffer, p->esrv_guid, strlen(p->esrv_guid) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_NAME, strlen(ENERGY_ESRV_PL_CONFIG_FILE_NAME) ); goto attach_to_esrv; } if(p->f_guid_shell_variable == 1) { memcpy( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_ROOT, strlen(ENERGY_ESRV_PL_CONFIG_FILE_ROOT) ); strncat( esrv_config_file_name_buffer, ESRV_APPLICATION_NAME, strlen(ESRV_APPLICATION_NAME) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE, strlen(ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE) ); strncat( esrv_config_file_name_buffer, p->esrv_guid_shell_variable_value, strlen(p->esrv_guid_shell_variable_value) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_NAME, strlen(ENERGY_ESRV_PL_CONFIG_FILE_NAME) ); goto attach_to_esrv; } //------------------------------------------------------------------------- // Because it is easier to type energy -- command than energy --guid xxx -- // command, we check for the existence of a ENERGY_ESRV_DEFAULT_GUID_SHELL_- // -VARIABLE shell variable. If it exist and has a valid GUID, then it is // used. If no such variable exist, then energy continues by starting its // own instance of ESRV. //------------------------------------------------------------------------- env = getenv(ENERGY_ESRV_DEFAULT_GUID_SHELL_VARIABLE); if(env != NULL) { ret = plh_filter_uuid_string(env); if(ret != PL_FAILURE) { memcpy( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_ROOT, strlen(ENERGY_ESRV_PL_CONFIG_FILE_ROOT) ); strncat( esrv_config_file_name_buffer, ESRV_APPLICATION_NAME, strlen(ESRV_APPLICATION_NAME) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE, strlen(ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE) ); strncat( esrv_config_file_name_buffer, env, strlen(env) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_NAME, strlen(ENERGY_ESRV_PL_CONFIG_FILE_NAME) ); goto attach_to_esrv; } } //------------------------------------------------------------------------- // Build ESRV binary name and command line // Note: // cli_buffer holds the ESRV binary name and the command line options. // if the command and the arguments are provided separately to // CreateProcess then the argv count is erroneous in the started // process and ESRV fails the cli parsing. //------------------------------------------------------------------------- memset( esrv_command_buffer, 0, sizeof(esrv_command_buffer) ); strncpy( esrv_command_buffer, ENERGY_ESRV_BINARY_NAME, strlen(ENERGY_ESRV_BINARY_NAME) ); if(p->f_esrv_options == 1) { strncat( esrv_command_buffer, p->esrv_options, strlen(p->esrv_options) ); } else { strncat( esrv_command_buffer, ENERGY_ESRV_DEFAULT_OPTIONS, strlen(ENERGY_ESRV_DEFAULT_OPTIONS) ); } strncat( esrv_command_buffer, ENERGY_ESRV_SHELL_OPTION, strlen(ENERGY_ESRV_SHELL_OPTION) ); //------------------------------------------------------------------------- // Start an ESRV instance in a child process. //------------------------------------------------------------------------- #ifdef __PL_WINDOWS__ p->fp_esrv = _popen( esrv_command_buffer, "rt" ); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) p->fp_esrv = popen( esrv_command_buffer, "r" ); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ if(p->fp_esrv == NULL) { _ERROR("Unable to start ESRV."); } //------------------------------------------------------------------------- // Retrieve the ESRV's instance PID and GUID. //------------------------------------------------------------------------- do { pc = fgets( buffer, sizeof(buffer), p->fp_esrv ); if(pc != NULL) { switch(++input_line_count) { case ENERGY_ESRV_GUID_LINE: //--------------------------------------------------------- // extract ESRV's GUID and save it //--------------------------------------------------------- token = strtok( buffer, ENERGY_ESRV_GUID_TOKEN_SEPARATORS ); while(token != NULL) { if(strncmp( token, ENERGY_ESRV_PRE_GUID_TOKEN, strlen(ENERGY_ESRV_PRE_GUID_TOKEN) ) == 0) { token = strtok( NULL, ENERGY_ESRV_GUID_TOKEN_TERMINATOR ); memset( esrv_guid, 0, sizeof(esrv_guid) ); strncpy( esrv_guid, token, strlen(token) ); f_esrv_guid = 1; break; } token = strtok( NULL, ENERGY_ESRV_GUID_TOKEN_SEPARATORS ); } break; case ENERGY_ESRV_PID_LINE: //--------------------------------------------------------- // extract ESRV's PID and save it. //--------------------------------------------------------- token = strtok( buffer, ENERGY_ESRV_PID_TOKEN_SEPARATORS ); while(token != NULL) { if(strncmp( token, ENERGY_ESRV_PRE_PID_TOKEN, strlen(ENERGY_ESRV_PRE_PID_TOKEN) ) == 0) { token = strtok( NULL, ENERGY_ESRV_PID_TOKEN_TERMINATOR ); #ifdef __PL_WINDOWS__ esrv_pid = (DWORD)atoi(token); #endif // __Pl_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) esrv_pid = (pid_t)atoi(token); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ assert(esrv_pid != 0); f_esrv_pid = 1; goto pid_found; } token = strtok( NULL, ENERGY_ESRV_GUID_TOKEN_SEPARATORS ); } break; default: break; } } else { //----------------------------------------------------------------- // Likely the ESRV launch has failed, let's signal this error. //----------------------------------------------------------------- _ERROR("ESRV likely failed to start."); } } while(pc != NULL); //------------------------------------------------------------------------- // Likely the ESRV launch has failed, let's signal this error. //------------------------------------------------------------------------- _ERROR("ESRV likely failed to start."); pid_found: //------------------------------------------------------------------------- // Check and build the pl_config.ini file to attach to. //------------------------------------------------------------------------- assert((f_esrv_guid == 1) && (f_esrv_pid == 1)); memset( esrv_config_file_name_buffer, 0, sizeof(esrv_config_file_name_buffer) ); memcpy( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_ROOT, strlen(ENERGY_ESRV_PL_CONFIG_FILE_ROOT) ); strncat( esrv_config_file_name_buffer, ESRV_APPLICATION_NAME, strlen(ESRV_APPLICATION_NAME) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE, strlen(ENERGY_ESRV_PL_CONFIG_FILE_UNDERSCORE) ); strncat( esrv_config_file_name_buffer, esrv_guid, strlen(esrv_guid) ); memset( esrv_pl_path_name, 0, sizeof(esrv_pl_path_name) ); strncpy( esrv_pl_path_name, esrv_config_file_name_buffer, strlen(esrv_config_file_name_buffer) ); strncat( esrv_config_file_name_buffer, ENERGY_ESRV_PL_CONFIG_FILE_NAME, strlen(ENERGY_ESRV_PL_CONFIG_FILE_NAME) ); attach_to_esrv: //------------------------------------------------------------------------- // Attach to the identified instance of ESRV and read settings. //------------------------------------------------------------------------- p->esrv_pld = pl_attach(esrv_config_file_name_buffer); if(p->esrv_pld == PL_INVALID_DESCRIPTOR) { _ERROR("Unable to attach to the specified ESRV instance."); } //------------------------------------------------------------------------- // read-in esrv's configuration: // - ESRV Status (running or not) // - ESRV Channel count // - ESRV Version (not used) // - ESRV energy in joule counter's precision // Note: // since each channel holds esrv's configuration counters, we read the // first channel to read the channel count. ESRV has always at least // one channel, so the read is safe // Note: // Channel count is zero count, therefore the --. //------------------------------------------------------------------------- plret = pl_read( p->esrv_pld, &p->channels, ESRV_COUNTER_CHANNELS_INDEX ); if(plret != PL_SUCCESS) { _ERROR("Unable to read the ESRV channels count counter."); } if(p->channel > p->channels) { WARNING( "The requested channel does not exist in the specified ESRV instance. Will use default channel (1)." ); p->channel = 1; } p->channel--; //------------------------------------------------------------------------- // Now that the channels count is known, we can read the requested ESRV channel //------------------------------------------------------------------------- plret = pl_read( p->esrv_pld, &p->status, (p->channel * ESRV_BASE_COUNTERS_COUNT) + ESRV_COUNTER_STATUS_INDEX ); if(plret != PL_SUCCESS) { _ERROR("Unable to read the ESRV status counter."); } if(p->status != ESRV_STATUS_RUNNING) { _ERROR("The specified ESRV instance doesn't seem to be alive."); } plret = pl_read( p->esrv_pld, &p->version, (p->channel * ESRV_BASE_COUNTERS_COUNT) + ESRV_COUNTER_VERSION_INDEX ); if(plret != PL_SUCCESS) { _ERROR("Unable to read the ESRV version counter."); } plret = pl_read( p->esrv_pld, &value, (p->channel * ESRV_BASE_COUNTERS_COUNT) + ESRV_COUNTER_ENERGY_JOULES_DECIMALS_INDEX ); if(plret != PL_SUCCESS) { _ERROR( "Unable to read the ESRV energy in Joule(s) counter's .decimal suffix counter." ); } p->energy_data_multiplier = pow( 10.0, (double)value ); //------------------------------------------------------------------------- // Install signal handler. //------------------------------------------------------------------------- #ifdef __PL_WINDOWS__ bret = SetConsoleCtrlHandler( (PHANDLER_ROUTINE)signal_handler, TRUE ); if(bret == 0) { #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; ret = sigaction( SIGINT, &sa, NULL ); if(ret == -1) { #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ _ERROR("Unable to install the signal handler."); } //------------------------------------------------------------------------- // Read start energy. //------------------------------------------------------------------------- plret = pl_read( p->esrv_pld, &p->start_energy_data, (p->channel * ESRV_BASE_COUNTERS_COUNT) + ESRV_COUNTER_ENERGY_JOULES_INDEX ); if(plret != PL_SUCCESS) { _ERROR("Unable to read start energy value."); } //------------------------------------------------------------------------- // Run command. //------------------------------------------------------------------------- #ifdef __PL_WINDOWS__ p->fp = _popen( p->command, "rt" ); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) p->fp = popen( p->command, "r" ); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ if(p->fp == NULL) { _ERROR("Unable to execute command."); } //------------------------------------------------------------------------- // Echo command output to stdout. // Note: // With some verbose commands, the extra processing on the output may // consume extra energy (buffer[strlen(buffer) - 1] = '\0';). Remove // this cosmetic processing if this becomes an issue. //------------------------------------------------------------------------- while(p->f_interrupted == 0) { pc = fgets( buffer, sizeof(buffer), p->fp ); if(pc != NULL) { buffer[strlen(buffer) - 1] = '\0'; puts(buffer); } else { break; } } //------------------------------------------------------------------------- // Read end energy and close ESRV PL. //------------------------------------------------------------------------- plret = pl_read( p->esrv_pld, &p->end_energy_data, (p->channel * ESRV_BASE_COUNTERS_COUNT) + ESRV_COUNTER_ENERGY_JOULES_INDEX ); if(plret != PL_SUCCESS) { _ERROR("Unable to read end energy value."); } plret = pl_close(p->esrv_pld); if(plret != PL_SUCCESS) { _ERROR("Unable to close ESRV instance's PL."); } //------------------------------------------------------------------------- // End command. //------------------------------------------------------------------------- if(p->f_interrupted == 0) { if(feof(p->fp)) { #ifdef __PL_WINDOWS__ _pclose(p->fp); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) pclose(p->fp); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ } else { _ERROR("Unable to completely read command's output."); } } //------------------------------------------------------------------------- // Compute energy consumed. //------------------------------------------------------------------------- p->consumed_energy_in_joules = (double)( p->end_energy_data - p->start_energy_data ) / p->energy_data_multiplier ; p->consumed_energy_in_kwhs = p->consumed_energy_in_joules / ONE_KWH_IN_JOULES ; //------------------------------------------------------------------------- // Report consumed energy. //------------------------------------------------------------------------- fprintf( stdout, "\nEnergy: [%g] Joule(s) - [%g] kWh(s).\n", p->consumed_energy_in_joules, p->consumed_energy_in_kwhs ); //------------------------------------------------------------------------- // close the ESRV instance's process and remove its PL //------------------------------------------------------------------------- if( (f_esrv_guid == 1) && (f_esrv_pid == 1) ) { #ifdef __PL_WINDOWS__ esrv_handle = OpenProcess( PROCESS_TERMINATE, FALSE, esrv_pid ); assert(esrv_handle != NULL); bret = TerminateProcess( esrv_handle, 0 ); assert(bret != FALSE); //--------------------------------------------------------------------- // reset last ESRV instance's flags and ids //--------------------------------------------------------------------- esrv_handle = NULL; #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) ret = kill( esrv_pid, SIGTERM ); assert(ret != -1); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ f_esrv_guid = 0; f_esrv_pid = 0; esrv_pid = 0; //--------------------------------------------------------------------- // close last ESRV instance's output stream //--------------------------------------------------------------------- #ifdef __PL_WINDOWS__ _pclose(p->fp_esrv); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) pclose(p->fp_esrv); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ //--------------------------------------------------------------------- // Delete ESRV instance's PL. //--------------------------------------------------------------------- #ifdef __PL_WINDOWS__ pc = _getcwd( current_path_name, sizeof(current_path_name) ); assert(pc != NULL); ret = _chdir(esrv_pl_path_name); assert(ret != -1); file = _findfirst( "*", &find_files ); do { if( ( strcmp( find_files.name, "." ) != 0 ) && ( strcmp( find_files.name, ".." ) != 0 ) ) { ret = -1; do { ret = remove(find_files.name); } while(ret == -1); } } while( _findnext( file, &find_files ) == 0); ret = _findclose(file); assert(ret != -1); ret = _chdir(current_path_name); assert(ret != -1); ret = -1; do { ret = _rmdir(esrv_pl_path_name); } while(ret == -1); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) directory = opendir(esrv_pl_path_name); assert(directory != NULL); file = readdir(directory); while(file != NULL) { if( ( strcmp( file->d_name, "." ) != 0 ) && ( strcmp( file->d_name, ".." ) != 0 ) ) { memset( file_name, 0, sizeof(file_name) ); strncat( file_name, esrv_pl_path_name, strlen(esrv_pl_path_name) ); strncat( file_name, "/", strlen("/") ); strncat( file_name, file->d_name, strlen(file->d_name) ); ret = -1; do { ret = unlink(file_name); } while(ret != -1); } file = readdir(directory); } closedir(directory); ret = -1; do { ret = rmdir(esrv_pl_path_name); } while(ret != -1); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ } done: return(PL_SUCCESS); error: return(PL_FAILURE); } /*----------------------------------------------------------------------------- Function: parser Purpose : parse user input to set energy data structure In : pointer to energy data structure Out : updated energy data structure Return : status History ------------------------------------------------------------------------------- Date : Author Modification ------------------------------------------------------------------------------- 01/28/2010 Jamel Tayeb Creation. */ int parser(PENERGY_DATA p) { //------------------------------------------------------------------------- // Parsing variables. //------------------------------------------------------------------------- int i = 0; int j = 0; int value = 0; char buffer[PL_MAX_PATH] = { '\0' }; char *options[OPTION_STRINGS_COUNT] = { OPTION_STRINGS }; #ifdef __PL_WINDOWS__ size_t st_ret = 0; #endif // __PL_WINDOWS__ PL_STATUS ret = PL_FAILURE; //------------------------------------------------------------------------- // String to upper case variables. //------------------------------------------------------------------------- #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) size_t k = 0; size_t l = 0; char *pc = NULL; char c = '\0'; #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ assert(p != NULL); for(i = 1; i < p->argc; i++) { memset(buffer, 0, sizeof(buffer)); strncpy(buffer, p->argv[i], sizeof(buffer)); #ifdef __PL_WINDOWS__ _strupr(buffer); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) pc = buffer; l = strlen(buffer); for(k = 0; k < l; k++) { c = *pc; *pc++ = (char)toupper(c); } #endif// __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ for(j = 0; j < OPTION_STRINGS_COUNT; j++) { if(strncmp(buffer, options[j], strlen(options[j])) == 0) { switch(j) { //--------------------------------------------------------- // [-H] option. //--------------------------------------------------------- case H_ID: case HELP_ID: fprintf( stdout, HELP_STRING, ENERGY_APPLICATION_NAME, ENERGY_APPLICATION_NAME, ENERGY_APPLICATION_NAME, ENERGY_ESRV_DEFAULT_GUID_SHELL_VARIABLE, ENERGY_APPLICATION_NAME, ENERGY_APPLICATION_NAME, ENERGY_APPLICATION_NAME ); p->f_help = 1; goto parser_done; break; //--------------------------------------------------------- // [-V] option. //--------------------------------------------------------- case V_ID: case VERSION_ID: p->f_version = 1; fprintf( stdout, "%s: version %s.%s.%s\n", ENERGY_APPLICATION_NAME, ENERGY_VERSION_MAJOR, ENERGY_VERSION_MINOR, ENERGY_VERSION_REVISION ); fprintf( stdout, "Using PL helper version %s.%s.%s\n", PL_HELPER_VERSION_MAJOR, PL_HELPER_VERSION_MINOR, PL_HELPER_VERSION_REVISION ); fprintf( stdout, "Using PL version %s.%s.%s(%s)", PL_VERSION_MAJOR, PL_VERSION_MINOR, PL_VERSION_REVISION, PL_VERSION_OS ); fprintf(stdout, "\n"); goto parser_done; break; //--------------------------------------------------------- // [-G <string>] option. //--------------------------------------------------------- case G_ID: case GUID_ID: if(i + 1 >= p->argc) { ERROR_INDEX( "Missing argument after token [%s] in position [%d].", p->argv[i], i + 1 ); } p->f_guid = 1; i++; p->esrv_guid = p->argv[i]; ret = plh_filter_uuid_string(p->esrv_guid); if(ret == PL_FAILURE) { memset(buffer, 0, sizeof(buffer)); sprintf( buffer, "Guid [%s] does not seem to be a valig guid.", p->esrv_guid ); _ERROR(buffer); } goto parser_skip; break; //--------------------------------------------------------- // [-X <string>] option. //--------------------------------------------------------- case X_ID: case GUID_SHELL_VARIABLE_ID: if(i + 1 >= p->argc) { ERROR_INDEX( "Missing argument after token [%s] in position [%d].", p->argv[i], i + 1 ); } p->f_guid_shell_variable = 1; i++; p->esrv_guid_shell_variable = p->argv[i]; p->esrv_guid_shell_variable_value = getenv(p->esrv_guid_shell_variable); if(p->esrv_guid_shell_variable_value == NULL) { memset(buffer, 0, sizeof(buffer)); sprintf( buffer, "Environment variable [%s] does not exist.", p->esrv_guid_shell_variable ); _ERROR(buffer); } else { ret = plh_filter_uuid_string(p->esrv_guid_shell_variable_value); if(ret == PL_FAILURE) { memset(buffer, 0, sizeof(buffer)); sprintf( buffer, "Environment variable [%s] value [%s] does not seem to be a valig guid.", p->esrv_guid_shell_variable, p->esrv_guid_shell_variable_value ); _ERROR(buffer); } } goto parser_skip; break; //--------------------------------------------------------- // [-N <integer>] option. //--------------------------------------------------------- case N_ID: case CHANNEL_ID: if(i + 1 >= p->argc) { ERROR_INDEX( "Missing argument after token [%s] in position [%d].", p->argv[i], i + 1 ); } i++; p->channel = (unsigned int)atoi(p->argv[i]); if(value == 0) { value = ENERGY_DEFAULT_CHANNEL; } p->f_channel = 1; goto parser_skip; break; //--------------------------------------------------------- // [-E <string>] option. //--------------------------------------------------------- case E_ID: case ESRV_OPTIONS_ID: if(i + 1 >= p->argc) { ERROR_INDEX( "Missing argument after token [%s] in position [%d].", p->argv[i], i + 1 ); } p->f_esrv_options = 1; i++; p->esrv_options = p->argv[i]; goto parser_skip; break; //--------------------------------------------------------- // -- separator id. //--------------------------------------------------------- case SEPARATOR_ID: if(i + 1 >= p->argc) { ERROR_INDEX( "Missing argument after token [%s] in position [%d].", p->argv[i], i + 1 ); } i++; memset(p->command, 0, sizeof(p->command)); strncpy(p->command, p->argv[i], strlen(p->argv[i])); while(++i < p->argc) { strncat(p->command, " ", strlen(" ")); strncat(p->command, p->argv[i], strlen(p->argv[i])); } p->f_command = 1; goto parser_done; break; //--------------------------------------------------------- // Unknown option. //--------------------------------------------------------- default: ERROR_INDEX( "Unable to make sense of token [%s] in position [%d].", buffer, j ); } } } // for j _ERROR("Unable to make sense of options. Use --help option for help."); goto error; parser_skip: ; } // for i parser_done: //------------------------------------------------------------------------- // Return status. //------------------------------------------------------------------------- return(PL_SUCCESS); error: return(PL_FAILURE); }
/*--------------------------------------------------------------------------- Function: main Purpose : benchmark entry point In : none Out : none Return : status History ---------------------------------------------------------------------------- Date : Author Modification ---------------------------------------------------------------------------- 04/16/2009 Jamel Tayeb Creation. */ int main(void) { //---------------------------------------------------------------------- // timing data //---------------------------------------------------------------------- #ifdef __PL_WINDOWS__ __int64 start_counter = 0; __int64 stop_counter = 0; __int64 average_counter = 0; __int64 base_average_cycles = 0; __int64 pl_write_average_cycles = 0; __int64 pl_read_average_cycles = 0; #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) unsigned long long start_counter = 0; unsigned long long stop_counter = 0; unsigned long long average_counter = 0; unsigned long long base_average_cycles = 0; unsigned long long pl_write_average_cycles = 0; unsigned long long pl_read_average_cycles = 0; #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ //---------------------------------------------------------------------- // Test PL data //---------------------------------------------------------------------- PL_STATUS ret = PL_FAILURE; int pld = PL_INVALID_DESCRIPTOR; uuid_t uuid; char application_name[] = "benchmark"; const char *counter_names[] = { "test_counter" }; unsigned int counter_count = 1; unsigned long long i = 0; unsigned long long x = 0; int j = 0; //----------------------------------------------------------------------- // open test PL //----------------------------------------------------------------------- fprintf(stdout, "\n"); fprintf(stdout, "************************************************************\n"); fprintf(stdout, "* This micro-benchmark uses RDTSC / _IA64_REG_AR_ITC to *\n"); fprintf(stdout, "* evaluate the processor cycles required to carry-out the *\n"); fprintf(stdout, "* pl_write() and pl_read() Productivity Link API calls *\n"); #ifdef __PL_WINDOWS__ fprintf(stdout, "* (%12I64u write and read operations are performed *\n", (unsigned long long)(MAX_ITERATIONS * MAX_OPERATIONS)); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) fprintf(stdout, "* (%12llu write and read operations are performed *\n", (unsigned long long)(MAX_ITERATIONS * MAX_OPERATIONS)); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ fprintf(stdout, "* in sequence). *\n"); fprintf(stdout, "* *\n"); fprintf(stdout, "* This method is imperfect as it will catch cycles *\n"); fprintf(stdout, "* consumed by interrupt routines. Therefore, consider *\n"); fprintf(stdout, "* numbers as indications, not exact values. *\n"); fprintf(stdout, "* When running the benchmark, stop all other applications. *\n"); fprintf(stdout, "* *\n"); fprintf(stdout, "* When compiling the benchmark, deactivate all compiler *\n"); fprintf(stdout, "* optimizations. Run in single processor configuration. *\n"); fprintf(stdout, "* Deactivate all frequency and voltage adjustment *\n"); fprintf(stdout, "* features before running this micro-benchmark. *\n"); fprintf(stdout, "************************************************************\n"); fprintf(stdout, "\n"); fprintf(stdout, "Opening Test PL:\n"); pld = pl_open(application_name, counter_count, counter_names, &uuid); assert(pld != PL_INVALID_DESCRIPTOR); //-- test zone ---------------------------------------------------------- /* @@@@@ @@ @@@@ @@@@@@ @@@@@ @@@@@@ @@@@ @@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@ @ @ @@@@ @@@@@@ @ @@@@@@ @@@@ @ @ @ @@@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@ @ @ @@@@@ @@@@@@ @ @@@@@@ @@@@@ @ */ //----------------------------------------------------------------------- // reference loop //----------------------------------------------------------------------- init_average(); fprintf(stdout, "Measuring Base Data : "); for(j = 0; j < MAX_ITERATIONS; j++) { fprintf(stdout, "*"); start_timer(); for(i = 0; i < MAX_OPERATIONS; i++) { ; } stop_timer(); x = i; // consume i in case optimization is activated sum_average(); } print_timer(); fprintf(stdout, "\n"); compute_average(MAX_ITERATIONS * MAX_OPERATIONS); base_average_cycles = average_counter; /* @ @ @@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@ @@@@ @@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@ @ @ @@@@@@ @ @@@@@@ @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@ @ @@@@@@ @ @@@@@@ @@@@@ @ */ //---------------------------------------------------------------------- // write loop //---------------------------------------------------------------------- init_average(); fprintf(stdout, "Measuring pl_write() Data : "); for(j = 0; j < MAX_ITERATIONS; j++) { fprintf(stdout, "*"); start_timer(); for(i = 0; i < MAX_OPERATIONS; i++) { pl_write(pld, &i, 0); } stop_timer(); sum_average(); } print_timer(); fprintf(stdout, "\n"); compute_average(MAX_ITERATIONS * MAX_OPERATIONS); pl_write_average_cycles = average_counter; /* @@@@@ @@@@@@ @@ @@@@@ @@@@@ @@@@@@ @@@@ @@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@ @@@@@@ @ @ @ @ @ @@@@@@ @@@@ @ @ @ @ @@@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@@ @ @ @@@@@ @ @@@@@@ @@@@@ @ */ //---------------------------------------------------------------------- // read loop //---------------------------------------------------------------------- init_average(); fprintf(stdout, "Measuring pl_read() Data : "); for(j = 0; j < MAX_ITERATIONS; j++) { fprintf(stdout, "*"); start_timer(); for(i = 0; i < MAX_OPERATIONS; i++) { pl_read(pld, &x, 0); } stop_timer(); sum_average(); } print_timer(); fprintf(stdout, "\n"); compute_average(MAX_ITERATIONS * MAX_OPERATIONS); pl_read_average_cycles = average_counter; //-- end test zone ----------------------------------------------------- //---------------------------------------------------------------------- // close test PL //---------------------------------------------------------------------- fprintf(stdout, "Closing Test PL.\n"); ret = pl_close(pld); assert(ret == PL_SUCCESS); //---------------------------------------------------------------------- // report test results //---------------------------------------------------------------------- fprintf(stdout, "\n"); fprintf(stdout, "Test Report:\n"); fprintf(stdout, "=============\n"); fprintf(stdout, "\n"); #ifdef __PL_WINDOWS__ fprintf(stdout, "Average CPU cycles per pl_write() call : %12I64u.\n", pl_write_average_cycles); fprintf(stdout, "Average CPU cycles per pl_read() call : %12I64u.\n", pl_read_average_cycles); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) fprintf(stdout, "Average CPU cycles per pl_write() call : %12llu.\n", pl_write_average_cycles); fprintf(stdout, "Average CPU cycles per pl_read() call : %12llu.\n", pl_read_average_cycles); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ fprintf(stdout, "\n"); fprintf(stdout, "Notes:\n"); fprintf(stdout, "======\n"); fprintf(stdout, " * A 2.0 GHz processor with two cores processes ~4 billion\n"); fprintf(stdout, "instructions per second (~2 billion per core). Allocation\n"); fprintf(stdout, "of system CPU cycles under the following conditions:\n"); #ifdef __PL_WINDOWS__ fprintf(stdout, "1000 pl_write() calls per second: ~%1.3f%%\n", (double)pl_write_average_cycles / 40000.0); fprintf(stdout, "1000 pl_read() calls per second: ~%1.3f%%\n", (double)pl_read_average_cycles / 40000.0); #endif // __PL_WINDOWS__ #if defined (__PL_LINUX__) || (__PL_SOLARIS__) || (__PL_MACOSX__) fprintf(stdout, "1000 pl_write() calls per second: ~%1.3f%%\n", (double)pl_write_average_cycles / 40000.0); fprintf(stdout, "1000 pl_read() calls per second: ~%1.3f%%\n", (double)pl_read_average_cycles / 40000.0); #endif // __PL_LINUX__ || __PL_SOLARIS__ || __PL_MACOSX__ fprintf(stdout, "\n"); fprintf(stdout, "\n"); fprintf(stdout, " * 1.0 GHz cycle = 1.0 nanosecond = 1.0 x 10-9 second.\n"); fprintf(stdout, " 10 nanoseconds = 1.0 x 10-5 millisecond.\n"); fprintf(stdout, " 100 nanoseconds = 0.0001 millisecond.\n"); fprintf(stdout, " 1,000 nanoseconds = 0.001 millisecond.\n"); fprintf(stdout, " 10,000 nanoseconds = 0.01 millisecond.\n"); fprintf(stdout, " 100,000 nanoseconds = 0.1 millisecond.\n"); fprintf(stdout, " 1,000,000 nanoseconds = 1 millisecond.\n"); fprintf(stdout, "\n"); fprintf(stdout, "************************************************************\n"); fprintf(stdout, "* End of micro-benchmark *\n"); fprintf(stdout, "************************************************************\n"); fprintf(stdout, "\n"); return(PL_SUCCESS); }
/*--------------------------------------------------------------------------- Function: main Purpose : statistic collector entry point In : none Out : none Return : status History ---------------------------------------------------------------------------- Date : Author Modification ---------------------------------------------------------------------------- 07/08/2009 Jamel Tayeb Creation. */ int main(void) { int f_load = 0; int f_cpu = 0; int bret = -1; ssize_t sret = 0; char separators_load[] = " /\t\n"; char separators_cpu[] = " \t\n"; char buffer[BUFFER_SIZE] = { '\0' }; char *token = NULL; unsigned long long value = 0; struct sigaction sa; char *startup[STARTUP_MESSAGE_LINES_COUNT] = { STARTUP_MESSAGE_LINES }; unsigned long long samples = 0; int chars_displayed = 0; int i = 0; unsigned long long user_last = 0; unsigned long long nice_last = 0; unsigned long long system_last = 0; unsigned long long idle_last = 0; unsigned long long io_wait_last = 0; unsigned long long soft_irq_last = 0; unsigned long long hard_irq_last = 0; unsigned long long steal_last = 0; unsigned long long user = 0; unsigned long long nice = 0; unsigned long long system = 0; unsigned long long idle = 0; unsigned long long io_wait = 0; unsigned long long soft_irq = 0; unsigned long long hard_irq = 0; unsigned long long steal = 0; unsigned long long usage_percentage = 0; long double usage_time = 0; long double total_time = 0; PL_STATUS ret = PL_FAILURE; int pld = PL_INVALID_DESCRIPTOR; uuid_t uuid; char application_name[] = APPLICATION_NAME; const char *counters_names[COUNTERS_COUNT] = { CPU_USAGE_COUNTERS, LOAD_COUNTERS, CPU_COUNTERS, }; enum counters_indexes { CPU_USAGE_PERCENTAGE_INDEX = 0, CPU_USAGE_PERCENTAGE_DECIMALS_INDEX, CPU_AND_IO_UTILIZATION_OF_THE_LAST_MINUTE_PERIOD_INDEX, CPU_AND_IO_UTILIZATION_OF_THE_LAST_MINUTE_PERIOD_DECIMALS_INDEX, CPU_AND_IO_UTILIZATION_OF_THE_LAST_FIVE_MINUTES_PERIOD_INDEX, CPU_AND_IO_UTILIZATION_OF_THE_LAST_FIVE_MINUTES_PERIOD_DECIMALS_INDEX, CPU_AND_IO_UTILIZATION_OF_THE_LAST_TEN_MINUTES_PERIOD_INDEX, CPU_AND_IO_UTILIZATION_OF_THE_LAST_TEN_MINUTES_PERIOD_DECIMALS_INDEX, NUMBER_OF_CURRENTLY_RUNNING_PROCESSES_INDEX, TOTAL_NUMBER_OF_PROCESSES_INDEX, LAST_PROCESS_ID_USED_INDEX, JIFFIES_IN_USER_MODE_INDEX, JIFFIES_IN_LOW_PRIORITY_USER_MODE_INDEX, JIFFIES_IN_SYSTEM_MODE_MODE_INDEX, JIFFIES_IN_IDLE_TASK_MODE_INDEX, JIFFIES_IN_IO_WAIT_INDEX, JIFFIES_IN_HARDIRQ_INDEX, JIFFIES_IN_SOFTIRQ_INDEX, JIFFIES_IN_STEAL_INDEX }; //------------------------------------------------------------------------ // print startup message to stdout //------------------------------------------------------------------------ for(i = 0; i < STARTUP_MESSAGE_LINES_COUNT; i++) { fprintf(stdout, "%s", startup[i]); } //------------------------------------------------------------------------ // instal signal handler //------------------------------------------------------------------------ sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; bret = sigaction(SIGINT, &sa, NULL); assert(bret != -1); //------------------------------------------------------------------------ // open PL //------------------------------------------------------------------------ pld = pl_open(application_name, COUNTERS_COUNT, counters_names, &uuid); assert(pld != PL_INVALID_DESCRIPTOR); //------------------------------------------------------------------------ // print PL and use message to stdout //------------------------------------------------------------------------ memset(buffer, 0, sizeof(buffer)); uuid_unparse(uuid, buffer); fprintf(stdout, "Using PL.........: [%s]\n", buffer); fprintf(stdout, "Exporting........:\n"); for(i = 0; i < COUNTERS_COUNT; i++) { fprintf(stdout, ".................: [%s]\n", counters_names[i]); } fprintf(stdout, "To Stop Logging : [<CRTL>+<C>]\n"); //------------------------------------------------------------------------ // write static PL counters //------------------------------------------------------------------------ value = 2; ret = pl_write(pld, &value, CPU_USAGE_PERCENTAGE_DECIMALS_INDEX); ASSERT; ret = pl_write(pld, &value, CPU_AND_IO_UTILIZATION_OF_THE_LAST_MINUTE_PERIOD_DECIMALS_INDEX); ASSERT; ret = pl_write(pld, &value, CPU_AND_IO_UTILIZATION_OF_THE_LAST_FIVE_MINUTES_PERIOD_DECIMALS_INDEX); ASSERT; ret = pl_write(pld, &value, CPU_AND_IO_UTILIZATION_OF_THE_LAST_TEN_MINUTES_PERIOD_DECIMALS_INDEX); ASSERT; //------------------------------------------------------------------------ // read and export data every second //------------------------------------------------------------------------ while(stop == 0) { //-------------------------------------------------------------------- // start with load data //-------------------------------------------------------------------- f_load = open(DATA_SOURCE_LOAD, O_RDONLY); assert(f_load != -1); memset(buffer, 0, BUFFER_SIZE); sret = read(f_load, buffer, BUFFER_SIZE); assert(sret != -1); // last minute load token = strtok(buffer, separators_load); if(token != NULL) { value = (unsigned long long)(atof(token) * SCALING); ret = pl_write(pld, &value, CPU_AND_IO_UTILIZATION_OF_THE_LAST_MINUTE_PERIOD_INDEX); ASSERT; } // last five minutes load token = strtok(NULL, separators_load); if(token != NULL) { value = (unsigned long long)(atof(token) * SCALING); ret = pl_write(pld, &value, CPU_AND_IO_UTILIZATION_OF_THE_LAST_FIVE_MINUTES_PERIOD_INDEX); ASSERT; } // last ten minutes load token = strtok(NULL, separators_load); if(token != NULL) { value = (unsigned long long)(atof(token) * SCALING); ret = pl_write(pld, &value, CPU_AND_IO_UTILIZATION_OF_THE_LAST_TEN_MINUTES_PERIOD_INDEX); ASSERT; } // running processes token = strtok(NULL, separators_load); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, NUMBER_OF_CURRENTLY_RUNNING_PROCESSES_INDEX); ASSERT; } // total number of precesses token = strtok(NULL, separators_load); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, TOTAL_NUMBER_OF_PROCESSES_INDEX); ASSERT; } // last process id used token = strtok(NULL, separators_load); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, LAST_PROCESS_ID_USED_INDEX); ASSERT; } bret = close(f_load); assert(bret != -1); //-------------------------------------------------------------------- // continue with cpu data //-------------------------------------------------------------------- f_cpu = open(DATA_SOURCE_CPU, O_RDONLY); assert(f_cpu != -1); memset(buffer, 0, BUFFER_SIZE); sret = read(f_cpu, buffer, BUFFER_SIZE); assert(sret != -1); token = strtok(buffer, separators_cpu); while(token != NULL) { if(strcmp(token, CPU_TO_MONITOR) == 0) { // jiffies in user mode token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_USER_MODE_INDEX); ASSERT; user_last = user; user = value; } // jiffies in low priority user mode - nice token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_LOW_PRIORITY_USER_MODE_INDEX); ASSERT; nice_last = nice; nice = value; } // jiffies in system mode mode token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_SYSTEM_MODE_MODE_INDEX); ASSERT; system_last = system; system = value; } // jiffies in idle task mode token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_IDLE_TASK_MODE_INDEX); ASSERT; idle_last = idle; idle = value; } // jiffies in IO wait token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_IO_WAIT_INDEX); ASSERT; io_wait_last = io_wait; io_wait = value; } // jiffies in IRQ - hardirq token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_HARDIRQ_INDEX); ASSERT; hard_irq_last = hard_irq; hard_irq = value; } // jiffies in IRQ - softirq token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_SOFTIRQ_INDEX); ASSERT; soft_irq_last = soft_irq; soft_irq = value; } // jiffies in steal token = strtok(NULL, separators_cpu); if(token != NULL) { value = (unsigned long long)atoi(token); ret = pl_write(pld, &value, JIFFIES_IN_STEAL_INDEX); ASSERT; steal_last = steal; steal = value; } goto found; } token = strtok(NULL, separators_cpu); } found: bret = close(f_cpu); assert(bret != -1); //------------------------------------------------------------------- // compute cpu utilization % //------------------------------------------------------------------- usage_time = (long double)( (user - user_last) + (nice - nice_last) + (system - system_last) + (soft_irq - soft_irq_last) + (hard_irq - hard_irq_last) + (steal - steal_last) ); total_time = (long double)( usage_time + (idle - idle_last) + (io_wait - io_wait_last) ); usage_percentage = (unsigned long long)(100.0 * usage_time / total_time) * 100; ret = pl_write(pld, &usage_percentage, CPU_USAGE_PERCENTAGE_INDEX); ASSERT; //------------------------------------------------------------------- // increment sample(s) count //------------------------------------------------------------------- samples++; //------------------------------------------------------------------- // print to stdout the sample count //------------------------------------------------------------------- chars_displayed = fprintf(stdout, "Samples : [%llu]", samples); fflush(stdout); for(i = 0; i < chars_displayed; i++) { fprintf(stdout, "\b"); } //------------------------------------------------------------------- // sleep for a second //------------------------------------------------------------------- sleep(1); } //------------------------------------------------------------------------ // close PL //------------------------------------------------------------------------ ret = pl_close(pld); ASSERT; return(PL_SUCCESS); }