|
PAPI
5.0.1.0
|
00001 /* 00002 * File: multiplex1_pthreads.c 00003 * Author: Philip Mucci 00004 * mucci@cs.utk.edu 00005 * Mods: <your name here> 00006 * <your email address> 00007 */ 00008 00009 /* This file tests the multiplex pthread functionality */ 00010 00011 #include <pthread.h> 00012 #include "papi_test.h" 00013 00014 #define TOTAL_EVENTS 10 00015 00016 int solaris_preset_PAPI_events[TOTAL_EVENTS] = { 00017 PAPI_BR_MSP, PAPI_TOT_CYC, PAPI_L2_TCM, PAPI_L1_ICM, 0 00018 }; 00019 int power6_preset_PAPI_events[TOTAL_EVENTS] = { 00020 PAPI_FP_INS, PAPI_TOT_CYC, PAPI_L1_DCM, PAPI_L1_ICM, 0 00021 }; 00022 int preset_PAPI_events[TOTAL_EVENTS] = { 00023 PAPI_FP_INS, PAPI_TOT_INS, PAPI_L1_DCM, PAPI_L1_ICM, 0 00024 }; 00025 static int PAPI_events[TOTAL_EVENTS] = { 0, }; 00026 static int PAPI_events_len = 0; 00027 00028 #define CPP_TEST_FAIL(string, retval) test_fail(__FILE__, __LINE__, string, retval) 00029 00030 void 00031 init_papi_pthreads( int *out_events, int *len ) 00032 { 00033 int retval; 00034 int i, real_len = 0; 00035 int *in_events = preset_PAPI_events; 00036 const PAPI_hw_info_t *hw_info; 00037 00038 /* Initialize the library */ 00039 retval = PAPI_library_init( PAPI_VER_CURRENT ); 00040 if ( retval != PAPI_VER_CURRENT ) 00041 CPP_TEST_FAIL( "PAPI_library_init", retval ); 00042 00043 hw_info = PAPI_get_hardware_info( ); 00044 if ( hw_info == NULL ) 00045 test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); 00046 00047 if ( strstr( hw_info->model_string, "UltraSPARC" ) ) { 00048 in_events = solaris_preset_PAPI_events; 00049 } 00050 00051 if ( strcmp( hw_info->model_string, "POWER6" ) == 0 ) { 00052 in_events = power6_preset_PAPI_events; 00053 retval = PAPI_set_domain( PAPI_DOM_ALL ); 00054 if ( retval != PAPI_OK ) 00055 CPP_TEST_FAIL( "PAPI_set_domain", retval ); 00056 } 00057 00058 retval = PAPI_multiplex_init( ); 00059 if ( retval == PAPI_ENOSUPP) { 00060 test_skip(__FILE__, __LINE__, "Multiplex not supported", 1); 00061 } 00062 else if ( retval != PAPI_OK ) { 00063 CPP_TEST_FAIL( "PAPI_multiplex_init", retval ); 00064 } 00065 00066 if ( ( retval = 00067 PAPI_thread_init( ( unsigned 00068 long ( * )( void ) ) ( pthread_self ) ) ) != 00069 PAPI_OK ) { 00070 if ( retval == PAPI_ECMP ) 00071 test_skip( __FILE__, __LINE__, "PAPI_thread_init", retval ); 00072 else 00073 test_fail( __FILE__, __LINE__, "PAPI_thread_init", retval ); 00074 } 00075 00076 for ( i = 0; in_events[i] != 0; i++ ) { 00077 char out[PAPI_MAX_STR_LEN]; 00078 /* query and set up the right instruction to monitor */ 00079 retval = PAPI_query_event( in_events[i] ); 00080 if ( retval == PAPI_OK ) { 00081 out_events[real_len++] = in_events[i]; 00082 PAPI_event_code_to_name( in_events[i], out ); 00083 if ( real_len == *len ) 00084 break; 00085 } else { 00086 PAPI_event_code_to_name( in_events[i], out ); 00087 if ( !TESTS_QUIET ) 00088 printf( "%s does not exist\n", out ); 00089 } 00090 } 00091 if ( real_len < 1 ) 00092 CPP_TEST_FAIL( "No counters available", 0 ); 00093 *len = real_len; 00094 } 00095 00096 int 00097 do_pthreads( void *( *fn ) ( void * ) ) 00098 { 00099 int i, rc, retval; 00100 pthread_attr_t attr; 00101 pthread_t id[NUM_THREADS]; 00102 00103 pthread_attr_init( &attr ); 00104 #ifdef PTHREAD_CREATE_UNDETACHED 00105 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_UNDETACHED ); 00106 #endif 00107 #ifdef PTHREAD_SCOPE_SYSTEM 00108 retval = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); 00109 if ( retval != 0 ) 00110 test_skip( __FILE__, __LINE__, "pthread_attr_setscope", retval ); 00111 #endif 00112 00113 for ( i = 0; i < NUM_THREADS; i++ ) { 00114 rc = pthread_create( &id[i], &attr, fn, NULL ); 00115 if ( rc ) 00116 return ( FAILURE ); 00117 } 00118 for ( i = 0; i < NUM_THREADS; i++ ) 00119 pthread_join( id[i], NULL ); 00120 00121 pthread_attr_destroy( &attr ); 00122 00123 return ( SUCCESS ); 00124 } 00125 00126 /* Tests that PAPI_multiplex_init does not mess with normal operation. */ 00127 00128 void * 00129 case1_pthreads( void *arg ) 00130 { 00131 ( void ) arg; /*unused */ 00132 int retval, i, EventSet = PAPI_NULL; 00133 long long values[2]; 00134 00135 if ( ( retval = PAPI_register_thread( ) ) != PAPI_OK ) 00136 test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval ); 00137 00138 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00139 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00140 00141 for ( i = 0; i < PAPI_events_len; i++ ) { 00142 char out[PAPI_MAX_STR_LEN]; 00143 00144 retval = PAPI_add_event( EventSet, PAPI_events[i] ); 00145 if ( retval != PAPI_OK ) 00146 CPP_TEST_FAIL( "PAPI_add_event", retval ); 00147 PAPI_event_code_to_name( PAPI_events[i], out ); 00148 if ( !TESTS_QUIET ) 00149 printf( "Added %s\n", out ); 00150 } 00151 00152 do_stuff( ); 00153 00154 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00155 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00156 00157 do_stuff( ); 00158 00159 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00160 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00161 00162 if ( !TESTS_QUIET ) { 00163 printf( "case1 thread %4x:", ( unsigned ) pthread_self( ) ); 00164 test_print_event_header( "", EventSet ); 00165 printf( "case1 thread %4x:", ( unsigned ) pthread_self( ) ); 00166 printf( TAB2, "", values[0], values[1] ); 00167 } 00168 00169 if ( ( retval = PAPI_cleanup_eventset( EventSet ) ) != PAPI_OK ) /* JT */ 00170 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00171 00172 if ( ( retval = PAPI_destroy_eventset( &EventSet) ) != PAPI_OK ) 00173 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); 00174 00175 if ( ( retval = PAPI_unregister_thread( ) ) != PAPI_OK ) 00176 test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval ); 00177 00178 return ( ( void * ) SUCCESS ); 00179 } 00180 00181 /* Tests that PAPI_set_multiplex() works before adding events */ 00182 00183 void * 00184 case2_pthreads( void *arg ) 00185 { 00186 ( void ) arg; /*unused */ 00187 int retval, i, EventSet = PAPI_NULL; 00188 long long values[2]; 00189 00190 if ( ( retval = PAPI_register_thread( ) ) != PAPI_OK ) 00191 test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval ); 00192 00193 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00194 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00195 00196 /* In Component PAPI, EventSets must be assigned a component index 00197 before you can fiddle with their internals. 00198 0 is always the cpu component */ 00199 retval = PAPI_assign_eventset_component( EventSet, 0 ); 00200 if ( retval != PAPI_OK ) 00201 CPP_TEST_FAIL( "PAPI_assign_eventset_component", retval ); 00202 00203 if ( ( retval = PAPI_set_multiplex( EventSet ) ) != PAPI_OK ) { 00204 if ( retval == PAPI_ENOSUPP) { 00205 test_skip(__FILE__, __LINE__, "Multiplex not supported", 1); 00206 } 00207 test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval ); 00208 } 00209 printf( "++case2 thread %4x:", ( unsigned ) pthread_self( ) ); 00210 00211 for ( i = 0; i < PAPI_events_len; i++ ) { 00212 char out[PAPI_MAX_STR_LEN]; 00213 00214 retval = PAPI_add_event( EventSet, PAPI_events[i] ); 00215 if ( retval != PAPI_OK ) 00216 CPP_TEST_FAIL( "PAPI_add_event", retval ); 00217 PAPI_event_code_to_name( PAPI_events[i], out ); 00218 if ( !TESTS_QUIET ) 00219 printf( "Added %s\n", out ); 00220 } 00221 00222 do_stuff( ); 00223 00224 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00225 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00226 00227 do_stuff( ); 00228 00229 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00230 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00231 00232 if ( !TESTS_QUIET ) { 00233 printf( "case2 thread %4x:", ( unsigned ) pthread_self( ) ); 00234 test_print_event_header( "", EventSet ); 00235 printf( "case2 thread %4x:", ( unsigned ) pthread_self( ) ); 00236 printf( TAB2, "", values[0], values[1] ); 00237 } 00238 00239 if ( ( retval = PAPI_cleanup_eventset( EventSet ) ) != PAPI_OK ) /* JT */ 00240 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00241 00242 if ( ( retval = PAPI_destroy_eventset( &EventSet) ) != PAPI_OK ) 00243 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); 00244 00245 if ( ( retval = PAPI_unregister_thread( ) ) != PAPI_OK ) 00246 test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval ); 00247 00248 return ( ( void * ) SUCCESS ); 00249 } 00250 00251 /* Tests that PAPI_set_multiplex() works after adding events */ 00252 00253 void * 00254 case3_pthreads( void *arg ) 00255 { 00256 ( void ) arg; /*unused */ 00257 int retval, i, EventSet = PAPI_NULL; 00258 long long values[2]; 00259 00260 if ( ( retval = PAPI_register_thread( ) ) != PAPI_OK ) 00261 test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval ); 00262 00263 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00264 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00265 00266 for ( i = 0; i < PAPI_events_len; i++ ) { 00267 char out[PAPI_MAX_STR_LEN]; 00268 00269 retval = PAPI_add_event( EventSet, PAPI_events[i] ); 00270 if ( retval != PAPI_OK ) 00271 CPP_TEST_FAIL( "PAPI_add_event", retval ); 00272 PAPI_event_code_to_name( PAPI_events[i], out ); 00273 if ( !TESTS_QUIET ) 00274 printf( "Added %s\n", out ); 00275 } 00276 00277 if ( ( retval = PAPI_set_multiplex( EventSet ) ) != PAPI_OK ) { 00278 if ( retval == PAPI_ENOSUPP) { 00279 test_skip(__FILE__, __LINE__, "Multiplex not supported", 1); 00280 } 00281 test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval ); 00282 } 00283 do_stuff( ); 00284 00285 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00286 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00287 00288 do_stuff( ); 00289 00290 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00291 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00292 00293 if ( !TESTS_QUIET ) { 00294 printf( "case3 thread %4x:", ( unsigned ) pthread_self( ) ); 00295 test_print_event_header( "", EventSet ); 00296 printf( "case3 thread %4x:", ( unsigned ) pthread_self( ) ); 00297 printf( TAB2, "", values[0], values[1] ); 00298 } 00299 00300 if ( ( retval = PAPI_cleanup_eventset( EventSet ) ) != PAPI_OK ) /* JT */ 00301 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00302 00303 if ( ( retval = PAPI_destroy_eventset( &EventSet) ) != PAPI_OK ) 00304 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); 00305 00306 if ( ( retval = PAPI_unregister_thread( ) ) != PAPI_OK ) 00307 test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval ); 00308 00309 return ( ( void * ) SUCCESS ); 00310 } 00311 00312 /* Tests that PAPI_set_multiplex() works before/after adding events */ 00313 00314 void * 00315 case4_pthreads( void *arg ) 00316 { 00317 ( void ) arg; /*unused */ 00318 int retval, i, EventSet = PAPI_NULL; 00319 long long values[4]; 00320 char out[PAPI_MAX_STR_LEN]; 00321 00322 if ( ( retval = PAPI_register_thread( ) ) != PAPI_OK ) 00323 test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval ); 00324 00325 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00326 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00327 00328 i = 0; 00329 retval = PAPI_add_event( EventSet, PAPI_events[i] ); 00330 if ( retval != PAPI_OK ) 00331 CPP_TEST_FAIL( "PAPI_add_event", retval ); 00332 PAPI_event_code_to_name( PAPI_events[i], out ); 00333 printf( "Added %s\n", out ); 00334 00335 if ( ( retval = PAPI_set_multiplex( EventSet ) ) != PAPI_OK ) { 00336 if ( retval == PAPI_ENOSUPP) { 00337 test_skip(__FILE__, __LINE__, "Multiplex not supported", 1); 00338 } 00339 00340 test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval ); 00341 } 00342 i = 1; 00343 retval = PAPI_add_event( EventSet, PAPI_events[i] ); 00344 if ( retval != PAPI_OK ) 00345 CPP_TEST_FAIL( "PAPI_add_event", retval ); 00346 PAPI_event_code_to_name( PAPI_events[i], out ); 00347 printf( "Added %s\n", out ); 00348 00349 do_stuff( ); 00350 00351 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00352 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00353 00354 do_stuff( ); 00355 00356 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00357 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00358 00359 if ( !TESTS_QUIET ) { 00360 printf( "case4 thread %4x:", ( unsigned ) pthread_self( ) ); 00361 test_print_event_header( "", EventSet ); 00362 printf( "case4 thread %4x:", ( unsigned ) pthread_self( ) ); 00363 printf( TAB2, "", values[0], values[1] ); 00364 } 00365 00366 if ( ( retval = PAPI_cleanup_eventset( EventSet ) ) != PAPI_OK ) /* JT */ 00367 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00368 00369 if ( ( retval = PAPI_destroy_eventset( &EventSet) ) != PAPI_OK ) 00370 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); 00371 00372 if ( ( retval = PAPI_unregister_thread( ) ) != PAPI_OK ) 00373 test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval ); 00374 00375 return ( ( void * ) SUCCESS ); 00376 } 00377 00378 int 00379 case1( void ) 00380 { 00381 int retval; 00382 00383 PAPI_events_len = 2; 00384 init_papi_pthreads( PAPI_events, &PAPI_events_len ); 00385 00386 retval = do_pthreads( case1_pthreads ); 00387 00388 PAPI_shutdown( ); 00389 00390 return ( retval ); 00391 } 00392 00393 int 00394 case2( void ) 00395 { 00396 int retval; 00397 00398 PAPI_events_len = 2; 00399 init_papi_pthreads( PAPI_events, &PAPI_events_len ); 00400 00401 retval = do_pthreads( case2_pthreads ); 00402 00403 PAPI_shutdown( ); 00404 00405 return ( retval ); 00406 } 00407 00408 int 00409 case3( void ) 00410 { 00411 int retval; 00412 00413 PAPI_events_len = 2; 00414 init_papi_pthreads( PAPI_events, &PAPI_events_len ); 00415 00416 retval = do_pthreads( case3_pthreads ); 00417 00418 PAPI_shutdown( ); 00419 00420 return ( retval ); 00421 } 00422 00423 int 00424 case4( void ) 00425 { 00426 int retval; 00427 00428 PAPI_events_len = 2; 00429 init_papi_pthreads( PAPI_events, &PAPI_events_len ); 00430 00431 retval = do_pthreads( case4_pthreads ); 00432 00433 PAPI_shutdown( ); 00434 00435 return ( retval ); 00436 } 00437 00438 int 00439 main( int argc, char **argv ) 00440 { 00441 int retval; 00442 00443 tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ 00444 00445 printf( "%s: Using %d threads\n\n", argv[0], NUM_THREADS ); 00446 00447 printf 00448 ( "case1: Does PAPI_multiplex_init() not break regular operation?\n" ); 00449 if ( case1( ) != SUCCESS ) 00450 test_fail( __FILE__, __LINE__, "case1", PAPI_ESYS ); 00451 00452 printf( "case2: Does setmpx/add work?\n" ); 00453 if ( case2( ) != SUCCESS ) 00454 test_fail( __FILE__, __LINE__, "case2", PAPI_ESYS ); 00455 00456 printf( "case3: Does add/setmpx work?\n" ); 00457 if ( case3( ) != SUCCESS ) 00458 test_fail( __FILE__, __LINE__, "case3", PAPI_ESYS ); 00459 00460 printf( "case4: Does add/setmpx/add work?\n" ); 00461 if ( case4( ) != SUCCESS ) 00462 test_fail( __FILE__, __LINE__, "case4", PAPI_ESYS ); 00463 00464 retval = PAPI_library_init( PAPI_VER_CURRENT ); 00465 if ( retval != PAPI_VER_CURRENT ) 00466 CPP_TEST_FAIL( "PAPI_library_init", retval ); 00467 00468 test_pass( __FILE__, NULL, 0 ); 00469 exit( 1 ); 00470 }