void Construct_Socket_Information_in_GUI(unsigned int *numCPUs) { int socket_0_num=0, socket_1_num=1; socket_0.max_cpu=0; socket_0.socket_num=0; int i; for(i=0;i < 8; i++) socket_0.processor_num[i]=-1; socket_1.max_cpu=0; socket_1.socket_num=1; for(i=0;i < 8; i++) socket_1.processor_num[i]=-1; construct_CPU_Hierarchy_info(&chi); construct_sibling_list(&chi); // print_CPU_Hierarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); // print_socket_information(&socket_0); // print_socket_information(&socket_1); *numCPUs = socket_0.num_physical_cores + socket_1.num_physical_cores; //// FOR DEBUGGING DUAL SOCKET CODE ON SINGLE SOCKET, UNCOMMENT BELOW 2 lines // memcpy(&socket_1, &socket_0, sizeof(struct cpu_socket_info)); // socket_1.socket_num=0; // print_socket_information(&socket_0); // print_socket_information(&socket_1); *numCPUs = socket_0.num_physical_cores + socket_1.num_physical_cores; // printf("My Widget: Num Processors %d\n",*numCPUs); int k, ii; k=0; for (ii = 0; ii < socket_0.num_physical_cores ; ii++) { if ( socket_0.processor_num[ii] != -1) { core_list[k] = socket_0.processor_num[ii]; socket_list[k] = 0; k++; } } for (ii = 0; ii < socket_1.num_physical_cores ; ii++) { if ( socket_1.processor_num[ii] != -1) { core_list[k] = socket_1.processor_num[ii]; socket_list[k] = 1; k++; } } }
int main (int argc, char **argv) { atexit(atexit_runsttysane); char log_file_name[MAX_FILENAME_LENGTH], log_file_name2[MAX_FILENAME_LENGTH+3]; prog_options.logging=0; //0=no logging, 1=logging, 2=appending struct cpu_hierarchy_info chi; struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; //////////////////// GET ARGUMENTS ////////////////////// int c; //char *cvalue = NULL; //static bool logging_val_append=false, logging_val_replace=false; bool presupplied_socket_info = false; bool only_display_version=false; static struct option long_options[]= { {"write", required_argument, 0, 'w'}, {"version", no_argument, 0, 'v'}, {"socket0", required_argument, 0, 'z'}, {"socket1", required_argument, 0, 'y'}, {"logfile", required_argument, 0, 'l'}, {"help", no_argument, 0, 'h'}, {"nogui", no_argument, 0, 'n'}, {0, 0, 0, 0} }; prog_options.logging = 0; while(1) { int option_index = 0; c = getopt_long(argc, argv,"w:vz:y:l:hn", long_options, &option_index); if (c==-1) break; switch(c) { case 'z': socket_0_num = atoi(optarg); presupplied_socket_info = true; printf("Socket_0 information will be about socket %d\n", socket_0.socket_num); break; case 'y': socket_1_num = atoi(optarg); presupplied_socket_info = true; printf("Socket_1 information will be about socket %d\n", socket_1.socket_num); break; case 'w': //printf("write options specified %s\n", optarg); if (strcmp("l",optarg)==0) { prog_options.logging = 1; printf("Logging is ON and set to replace\n"); } if (strcmp("a",optarg)==0) { prog_options.logging = 2; printf("Logging is ON and set to append\n"); } break; case 'v': only_display_version=true; break; case 'l': strncpy(log_file_name, optarg, MAX_FILENAME_LENGTH-3); strcpy(log_file_name2, log_file_name); strcat(log_file_name2, "_%d"); CPU_FREQUENCY_LOGGING_FILE_single = log_file_name; CPU_FREQUENCY_LOGGING_FILE_dual = log_file_name2; printf("Logging frequencies to %s for single sockets, %s for dual sockets(0,1 for multiple sockets)\n", CPU_FREQUENCY_LOGGING_FILE_single, CPU_FREQUENCY_LOGGING_FILE_dual); break; case 'n': use_ncurses = false; printf("Not Spawning the GUI\n"); break; case 'h': printf("\ni7z Tool Supports the following functions:\n"); printf("Display version information only and exit: "); printf("%c[%d;%d;%dm./i7z --version ", 0x1B,1,31,40); printf("%c[%dm[OR] ",0x1B,0); printf("%c[%d;%d;%dm./i7z -v \n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("Append to a log file: "); printf("%c[%d;%d;%dm./i7z --write a ", 0x1B,1,31,40); printf("%c[%dm[OR] ",0x1B,0); printf("%c[%d;%d;%dm./i7z -w a\n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("Replacement instead of Append: "); printf("%c[%d;%d;%dm./i7z --write l ", 0x1B,1,31,40); printf("%c[%dm[OR]", 0x1B,0); printf(" %c[%d;%d;%dm./i7z -w l\n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("Default log file name is %s (single socket) or %s (dual socket)\n", CPU_FREQUENCY_LOGGING_FILE_single, CPU_FREQUENCY_LOGGING_FILE_dual); printf("Specifying a different log file: "); printf("%c[%d;%d;%dm./i7z --logfile filename ", 0x1B,1,31,40); printf("%c[%dm[OR] ", 0x1B,0); printf("%c[%d;%d;%dm./i7z -l filename\n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("Specifying a particular socket to print: %c[%d;%d;%dm./i7z --socket0 X \n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("In order to print to a second socket use: %c[%d;%d;%dm./i7z --socket1 X \n", 0x1B,1,31,40); printf("%c[%dm",0x1B,0); printf("To turn the ncurses GUI off use: %c[%d;%d;%dm./i7z --nogui\n", 0x1B, 1, 31, 40); printf("%c[%dm",0x1B,0); printf("Example: To print for two sockets and also change the log file %c[%d;%d;%dm./i7z --socket0 0 --socket1 1 -logfile /tmp/logfilei7z -w l\n", 0x1B, 1, 31, 40); printf("%c[%dm",0x1B,0); exit(0); break; } } Print_Version_Information(); Print_Information_Processor (&prog_options.i7_version.nehalem, &prog_options.i7_version.sandy_bridge, &prog_options.i7_version.ivy_bridge, &prog_options.i7_version.haswell); if (only_display_version) exit(0); // printf("nehalem %d, sandy bridge %d\n", prog_options.i7_version.nehalem, prog_options.i7_version.sandy_bridge); Test_Or_Make_MSR_DEVICE_FILES (); modprobing_msr(); /* prog_options.logging = 0; if (logging_val_replace){ prog_options.logging = 1; printf("Logging is ON and set to replace\n"); } if (logging_val_append){ prog_options.logging = 2; printf("Logging is ON and set to append\n"); } */ /* while( (c=getopt(argc,argv,"w:")) !=-1){ cvalue = optarg; //printf("argument %c\n",c); if(cvalue == NULL){ printf("With -w option, requires an argument for append or logging\n"); exit(1); }else{ //printf(" %s\n",cvalue); if(strcmp(cvalue,"a")==0){ printf("Appending frequencies to %s (single_socket) or cpu_freq_log_dual_(%d/%d).txt (dual socket)\n", CPU_FREQUENCY_LOGGING_FILE_single,0,1); prog_options.logging=2; }else if(strcmp(cvalue,"l")==0){ printf("Logging frequencies to %s (single socket) or cpu_freq_log_dual_(%d/%d).txt (dual socket) \n", CPU_FREQUENCY_LOGGING_FILE_single,0,1); prog_options.logging=1; }else{ printf("Unknown Option, ignoring -w option.\n"); prog_options.logging=0; } sleep(3); } } */ /////////////////////////////////////////////////////////// construct_CPU_Hierarchy_info(&chi); construct_sibling_list(&chi); print_CPU_Hierarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); print_socket_information(&socket_0); print_socket_information(&socket_1); if (!use_ncurses){ printf("GUI has been Turned OFF\n"); //print_options(prog_options); } else { printf("GUI has been Turned ON\n"); init_ncurses(); //print_options(prog_options); /* if (prog_options.logging ==0) { printf("Logging is OFF\n"); } else { printf("Logging is ON\n"); if (prog_options.cstatelogging) { printf("Cstate logging is enabled\n"); } if (prog_options.templogging) { printf("temp logging is enabled\n"); } } */ } if (!presupplied_socket_info){ if (socket_0.max_cpu>0 && socket_1.max_cpu>0) { //Path for Dual Socket Code printf("i7z DEBUG: Dual Socket Detected\n\r"); //Dual_Socket(&prog_options); Dual_Socket(); } else { //Path for Single Socket Code printf("i7z DEBUG: Single Socket Detected\n\r"); //Single_Socket(&prog_options); Single_Socket(); } } else { Dual_Socket(); } return(1); }
void print_i7z_single () { struct cpu_heirarchy_info chi; struct cpu_socket_info socket_0={.max_cpu=0, .socket_num=0, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; struct cpu_socket_info socket_1={.max_cpu=0, .socket_num=1, .processor_num={-1,-1,-1,-1,-1,-1,-1,-1}}; construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); // print_CPU_Heirarchy(chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); // print_socket_information(&socket_0); // print_socket_information(&socket_1); int printw_offset = (0) * 14; //Make an array size max 8 (to accomdate Nehalem-EXEX -lol) to store the core-num that are candidates for a given socket //removing it from here as it is already allocated in the function //int *core_list, core_list_size_phy, core_list_size_log; //iterator int i; //turbo_mode enabled/disabled flag char TURBO_MODE; double cpu_freq_cpuinfo; cpu_freq_cpuinfo = cpufreq_info (); //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); //Print a slew of information on the ncurses window //I already print that in the loop so.. mvprintw (0, 0, "WAIT .... "); //estimate the freq using the estimate_MHz() code that is almost mhz accurate cpu_freq_cpuinfo = estimate_MHz (); mvprintw (3, 0, "True Frequency (without accounting Turbo) %0.0f MHz\n", cpu_freq_cpuinfo); //MSR number and hi:low bit of that MSR //This msr contains a lot of stuff, per socket wise //one can pass any core number and then get in multiplier etc int PLATFORM_INFO_MSR = 206; //CE 15:8 int PLATFORM_INFO_MSR_low = 8; int PLATFORM_INFO_MSR_high = 15; unsigned long long int old_val_CORE[2][numCPUs_max], new_val_CORE[2][numCPUs_max]; unsigned long long int old_val_REF[2][numCPUs_max], new_val_REF[2][numCPUs_max]; unsigned long long int old_val_C3[2][numCPUs_max], new_val_C3[2][numCPUs_max]; unsigned long long int old_val_C6[2][numCPUs_max], new_val_C6[2][numCPUs_max]; unsigned long long int old_val_C7[2][numCPUs_max], new_val_C7[2][numCPUs_max]; unsigned long long int old_TSC[2][numCPUs_max], new_TSC[2][numCPUs_max]; long double C0_time[2][numCPUs_max], C1_time[2][numCPUs_max], C3_time[2][numCPUs_max], C6_time[2][numCPUs_max], C7_time[2][numCPUs_max]; double _FREQ[2][numCPUs_max], _MULT[2][numCPUs_max]; struct timeval tvstart[2][numCPUs_max], tvstop[2][numCPUs_max]; struct timespec one_second_sleep; one_second_sleep.tv_sec = 0; one_second_sleep.tv_nsec = 499999999; // 500msec //Get turbo mode status by reading msr within turbo_status TURBO_MODE = turbo_status (); //Flags and other things about HT. int HT_ON; char HT_ON_str[30]; int kk_1 = 11; //below variables is used to monitor if any cores went offline etc. int online_cpus[MAX_PROCESSORS]; //Max 2 x Nehalem-EX with total 32 threads double estimated_mhz=0; int socket_num; //below variables stores how many cpus were observed till date for the socket int max_cpus_observed=0; for (;;) { construct_CPU_Heirarchy_info(&chi); construct_sibling_list(&chi); construct_socket_information(&chi, &socket_0, &socket_1, socket_0_num, socket_1_num); //HT enabled if num logical > num physical cores if (chi.HT==1) { strncpy (HT_ON_str, "Hyper Threading ON\0", 30); HT_ON = 1; } else { strncpy (HT_ON_str, "Hyper Threading OFF\0", 30); HT_ON = 0; } refresh (); SET_ONLINE_ARRAY_PLUS1(online_cpus) //In the function calls below socket_num is set to the socket to print for //printw_offset is the offset gap between the printing of the two sockets //kk_1 and kk_2 are the variables that have to be set, i have to use them internally //so in future if there are more sockets to be printed, add more kk_* socket_num=0; printw_offset=0; //printf("socket0 max cpu %d\n",socket_0.max_cpu); //printf("socket1 max cpu %d\n",socket_0.max_cpu); //below code in (else case) is to handle when for 2 sockets system, cpu1 is populated and cpu0 is empty. //single socket code but in an intelligent manner and not assuming that cpu0 is always populated before cpu1 if(socket_0.max_cpu>1){ socket_num=0; print_i7z_socket_single(socket_0, printw_offset, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, online_cpus, cpu_freq_cpuinfo, one_second_sleep, TURBO_MODE, HT_ON_str, &kk_1, old_val_CORE[socket_num], old_val_REF[socket_num], old_val_C3[socket_num], old_val_C6[socket_num],old_val_C7[socket_num], old_TSC[socket_num], estimated_mhz, new_val_CORE[socket_num], new_val_REF[socket_num], new_val_C3[socket_num], new_val_C6[socket_num],new_val_C7[socket_num], new_TSC[socket_num], _FREQ[socket_num], _MULT[socket_num], C0_time[socket_num], C1_time[socket_num], C3_time[socket_num], C6_time[socket_num],C7_time[socket_num], tvstart[socket_num], tvstop[socket_num], &max_cpus_observed); }else{ socket_num=1; print_i7z_socket_single(socket_1, printw_offset, PLATFORM_INFO_MSR, PLATFORM_INFO_MSR_high, PLATFORM_INFO_MSR_low, online_cpus, cpu_freq_cpuinfo, one_second_sleep, TURBO_MODE, HT_ON_str, &kk_1, old_val_CORE[socket_num], old_val_REF[socket_num], old_val_C3[socket_num], old_val_C6[socket_num],old_val_C7[socket_num], old_TSC[socket_num], estimated_mhz, new_val_CORE[socket_num], new_val_REF[socket_num], new_val_C3[socket_num], new_val_C6[socket_num],new_val_C7[socket_num], new_TSC[socket_num], _FREQ[socket_num], _MULT[socket_num], C0_time[socket_num], C1_time[socket_num], C3_time[socket_num], C6_time[socket_num],C7_time[socket_num], tvstart[socket_num], tvstop[socket_num], &max_cpus_observed); } } }