|
PAPI
5.0.1.0
|
00001 /* This file performs the following test: start, stop and timer functionality for 00002 an attached process as well as itself. 00003 00004 - It attempts to use the following two counters. It may use less depending on 00005 hardware counter resource limitations. These are counted in the default counting 00006 domain and default granularity, depending on the platform. Usually this is 00007 the user domain (PAPI_DOM_USER) and thread context (PAPI_GRN_THR). 00008 + PAPI_FP_INS 00009 + PAPI_TOT_CYC 00010 - Get us. 00011 - Start counters 00012 - Do flops 00013 - Stop and read counters 00014 - Get us. 00015 */ 00016 00017 #include "papi_test.h" 00018 #include <sys/ptrace.h> 00019 #include <inttypes.h> 00020 00021 #ifdef _AIX 00022 #define _LINUX_SOURCE_COMPAT 00023 #endif 00024 00025 #if defined(__FreeBSD__) 00026 # define PTRACE_ATTACH PT_ATTACH 00027 # define PTRACE_CONT PT_CONTINUE 00028 #endif 00029 00030 int 00031 wait_for_attach_and_loop( int num ) 00032 { 00033 kill( getpid( ), SIGSTOP ); 00034 do_flops( NUM_FLOPS * num ); 00035 kill( getpid( ), SIGSTOP ); 00036 return 0; 00037 } 00038 00039 int 00040 main( int argc, char **argv ) 00041 { 00042 int status, retval, num_tests = 2, tmp; 00043 int EventSet1 = PAPI_NULL, EventSet2 = PAPI_NULL; 00044 int PAPI_event, PAPI_event2, mask1, mask2; 00045 int num_events1, num_events2; 00046 long long **values; 00047 long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc; 00048 char event_name[PAPI_MAX_STR_LEN], add_event_str[PAPI_MAX_STR_LEN]; 00049 const PAPI_component_info_t *cmpinfo; 00050 pid_t pid; 00051 00052 /* Set TESTS_QUIET variable */ 00053 tests_quiet( argc, argv ); 00054 00055 /* init the library */ 00056 retval = PAPI_library_init( PAPI_VER_CURRENT ); 00057 if ( retval != PAPI_VER_CURRENT ) { 00058 test_fail_exit( __FILE__, __LINE__, "PAPI_library_init", retval ); 00059 } 00060 00061 /* get component info */ 00062 if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL ) { 00063 test_fail_exit( __FILE__, __LINE__, "PAPI_get_component_info", 0 ); 00064 } 00065 00066 /* see if we support attach */ 00067 if ( cmpinfo->attach == 0 ) { 00068 test_skip( __FILE__, __LINE__, 00069 "Platform does not support attaching",0 ); 00070 } 00071 00072 /* fork! */ 00073 pid = fork( ); 00074 if ( pid < 0 ) { 00075 test_fail_exit( __FILE__, __LINE__, "fork()", PAPI_ESYS ); 00076 } 00077 00078 /* if child, wait_for_attach_and_loop */ 00079 if ( pid == 0 ) { 00080 exit( wait_for_attach_and_loop( 2 ) ); 00081 } 00082 00083 /* add PAPI_TOT_CYC and one of the events in 00084 PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, 00085 depending on the availability of the event 00086 on the platform */ 00087 EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 ); 00088 EventSet2 = add_two_events( &num_events2, &PAPI_event2, &mask2 ); 00089 00090 if ( cmpinfo->attach_must_ptrace ) { 00091 if ( ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) { 00092 perror( "ptrace(PTRACE_ATTACH)" ); 00093 return 1; 00094 } 00095 if ( waitpid( pid, &status, 0 ) == -1 ) { 00096 perror( "waitpid()" ); 00097 exit( 1 ); 00098 } 00099 if ( WIFSTOPPED( status ) == 0 ) { 00100 test_fail( __FILE__, __LINE__, 00101 "Child process didnt return true to WIFSTOPPED", 0 ); 00102 } 00103 } 00104 00105 retval = PAPI_attach( EventSet2, ( unsigned long ) pid ); 00106 if ( retval != PAPI_OK ) { 00107 test_fail( __FILE__, __LINE__, "PAPI_attach", retval ); 00108 } 00109 00110 retval = PAPI_event_code_to_name( PAPI_event, event_name ); 00111 if ( retval != PAPI_OK ) { 00112 test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); 00113 } 00114 sprintf( add_event_str, "PAPI_add_event[%s]", event_name ); 00115 00116 /* num_events1 is greater than num_events2 so don't worry. */ 00117 00118 values = allocate_test_space( num_tests, num_events1 ); 00119 00120 /* get before values */ 00121 elapsed_us = PAPI_get_real_usec( ); 00122 elapsed_cyc = PAPI_get_real_cyc( ); 00123 elapsed_virt_us = PAPI_get_virt_usec( ); 00124 elapsed_virt_cyc = PAPI_get_virt_cyc( ); 00125 00126 /* Wait for the SIGSTOP. */ 00127 if ( cmpinfo->attach_must_ptrace ) { 00128 if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) { 00129 perror( "ptrace(PTRACE_CONT)" ); 00130 return 1; 00131 } 00132 if ( waitpid( pid, &status, 0 ) == -1 ) { 00133 perror( "waitpid()" ); 00134 exit( 1 ); 00135 } 00136 if ( WIFSTOPPED( status ) == 0 ) { 00137 test_fail( __FILE__, __LINE__, 00138 "Child process didn't return true to WIFSTOPPED", 0 ); 00139 } 00140 if ( WSTOPSIG( status ) != SIGSTOP ) { 00141 test_fail( __FILE__, __LINE__, 00142 "Child process didn't stop on SIGSTOP", 0 ); 00143 } 00144 } 00145 00146 retval = PAPI_start( EventSet1 ); 00147 if ( retval != PAPI_OK ) { 00148 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00149 } 00150 00151 retval = PAPI_start( EventSet2 ); 00152 if ( retval != PAPI_OK ) { 00153 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00154 } 00155 00156 /* Wait for the SIGSTOP. */ 00157 if ( cmpinfo->attach_must_ptrace ) { 00158 if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) { 00159 perror( "ptrace(PTRACE_ATTACH)" ); 00160 return 1; 00161 } 00162 if ( waitpid( pid, &status, 0 ) == -1 ) { 00163 perror( "waitpid()" ); 00164 exit( 1 ); 00165 } 00166 if ( WIFSTOPPED( status ) == 0 ) { 00167 test_fail( __FILE__, __LINE__, 00168 "Child process didn't return true to WIFSTOPPED", 0 ); 00169 } 00170 if ( WSTOPSIG( status ) != SIGSTOP ) { 00171 test_fail( __FILE__, __LINE__, 00172 "Child process didn't stop on SIGSTOP", 0 ); 00173 } 00174 } 00175 00176 elapsed_virt_us = PAPI_get_virt_usec( ) - elapsed_virt_us; 00177 elapsed_virt_cyc = PAPI_get_virt_cyc( ) - elapsed_virt_cyc; 00178 elapsed_us = PAPI_get_real_usec( ) - elapsed_us; 00179 elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; 00180 00181 retval = PAPI_stop( EventSet1, values[0] ); 00182 if ( retval != PAPI_OK ) { 00183 printf( "Warning: PAPI_stop returned error %d, probably ok.\n", 00184 retval ); 00185 } 00186 00187 retval = PAPI_stop( EventSet2, values[1] ); 00188 if ( retval != PAPI_OK ) { 00189 printf( "Warning: PAPI_stop returned error %d, probably ok.\n", 00190 retval ); 00191 } 00192 00193 remove_test_events( &EventSet1, mask1 ); 00194 remove_test_events( &EventSet2, mask2 ); 00195 00196 if ( cmpinfo->attach_must_ptrace ) { 00197 if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) { 00198 perror( "ptrace(PTRACE_CONT)" ); 00199 return 1; 00200 } 00201 } 00202 00203 if ( waitpid( pid, &status, 0 ) == -1 ) { 00204 perror( "waitpid()" ); 00205 exit( 1 ); 00206 } 00207 if ( WIFEXITED( status ) == 0 ) { 00208 test_fail( __FILE__, __LINE__, 00209 "Child process didn't return true to WIFEXITED", 0 ); 00210 } 00211 00212 /* This code isn't necessary as we know the child has exited, 00213 it *may* return an error if the component so chooses. 00214 You should use read() instead. */ 00215 00216 printf( "Test case: multiple 3rd party attach start, stop.\n" ); 00217 printf( "-----------------------------------------------\n" ); 00218 tmp = PAPI_get_opt( PAPI_DEFDOM, NULL ); 00219 printf( "Default domain is: %d (%s)\n", tmp, stringify_all_domains( tmp ) ); 00220 tmp = PAPI_get_opt( PAPI_DEFGRN, NULL ); 00221 printf( "Default granularity is: %d (%s)\n", tmp, 00222 stringify_granularity( tmp ) ); 00223 printf( "Using %d iterations of c += a*b\n", NUM_FLOPS ); 00224 printf( "-------------------------------------------------------------------------\n" ); 00225 00226 sprintf( add_event_str, "(PID self) %-12s : \t", 00227 event_name ); 00228 printf( TAB1, add_event_str, values[0][1] ); 00229 sprintf( add_event_str, "(PID self) PAPI_TOT_CYC : \t" ); 00230 printf( TAB1, add_event_str, values[0][0] ); 00231 sprintf( add_event_str, "(PID %jd) %-12s : \t", ( intmax_t ) pid, 00232 event_name ); 00233 printf( TAB1, add_event_str, values[1][1] ); 00234 sprintf( add_event_str, "(PID %jd) PAPI_TOT_CYC : \t", 00235 ( intmax_t ) pid ); 00236 printf( TAB1, add_event_str, values[1][0] ); 00237 printf( TAB1, "Real usec : \t", elapsed_us ); 00238 printf( TAB1, "Real cycles : \t", elapsed_cyc ); 00239 printf( TAB1, "Virt usec : \t", elapsed_virt_us ); 00240 printf( TAB1, "Virt cycles : \t", elapsed_virt_cyc ); 00241 00242 printf( "-------------------------------------------------------------------------\n" ); 00243 00244 printf( "Verification: none\n" ); 00245 00246 test_pass( __FILE__, values, num_tests ); 00247 00248 return 0; 00249 }