|
PAPI
5.0.1.0
|
00001 /* 00002 * File: multiplex1_pthreads.c 00003 * Author: Rick Kufrin 00004 * rkufrin@ncsa.uiuc.edu 00005 * Mods: Philip Mucci 00006 * mucci@cs.utk.edu 00007 */ 00008 00009 /* This file really bangs on the multiplex pthread functionality */ 00010 00011 #include <pthread.h> 00012 #include "papi_test.h" 00013 00014 int *events; 00015 int numevents = 0; 00016 int max_events=0; 00017 00018 double 00019 loop( long n ) 00020 { 00021 long i; 00022 double a = 0.0012; 00023 00024 for ( i = 0; i < n; i++ ) { 00025 a += 0.01; 00026 } 00027 return a; 00028 } 00029 00030 void * 00031 thread( void *arg ) 00032 { 00033 ( void ) arg; /*unused */ 00034 int eventset = PAPI_NULL; 00035 long long *values; 00036 00037 int ret = PAPI_register_thread( ); 00038 if ( ret != PAPI_OK ) 00039 test_fail( __FILE__, __LINE__, "PAPI_register_thread", ret ); 00040 ret = PAPI_create_eventset( &eventset ); 00041 if ( ret != PAPI_OK ) 00042 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", ret ); 00043 00044 values=calloc(max_events,sizeof(long long)); 00045 00046 printf( "Event set %d created\n", eventset ); 00047 00048 /* In Component PAPI, EventSets must be assigned a component index 00049 before you can fiddle with their internals. 00050 0 is always the cpu component */ 00051 ret = PAPI_assign_eventset_component( eventset, 0 ); 00052 if ( ret != PAPI_OK ) { 00053 test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component", ret ); 00054 } 00055 00056 ret = PAPI_set_multiplex( eventset ); 00057 if ( ret == PAPI_ENOSUPP) { 00058 test_skip( __FILE__, __LINE__, "Multiplexing not supported", 1 ); 00059 } 00060 else if ( ret != PAPI_OK ) { 00061 test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", ret ); 00062 } 00063 00064 ret = PAPI_add_events( eventset, events, numevents ); 00065 if ( ret < PAPI_OK ) { 00066 test_fail( __FILE__, __LINE__, "PAPI_add_events", ret ); 00067 } 00068 00069 ret = PAPI_start( eventset ); 00070 if ( ret != PAPI_OK ) { 00071 test_fail( __FILE__, __LINE__, "PAPI_start", ret ); 00072 } 00073 00074 do_stuff( ); 00075 00076 ret = PAPI_stop( eventset, values ); 00077 if ( ret != PAPI_OK ) { 00078 test_fail( __FILE__, __LINE__, "PAPI_stop", ret ); 00079 } 00080 00081 ret = PAPI_cleanup_eventset( eventset ); 00082 if ( ret != PAPI_OK ) { 00083 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", ret ); 00084 } 00085 00086 ret = PAPI_destroy_eventset( &eventset ); 00087 if ( ret != PAPI_OK ) { 00088 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", ret ); 00089 } 00090 00091 ret = PAPI_unregister_thread( ); 00092 if ( ret != PAPI_OK ) 00093 test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", ret ); 00094 return ( NULL ); 00095 } 00096 00097 int 00098 main( int argc, char **argv ) 00099 { 00100 int nthreads = 8, ret, i; 00101 PAPI_event_info_t info; 00102 pthread_t *threads; 00103 const PAPI_hw_info_t *hw_info; 00104 00105 tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ 00106 00107 if ( !TESTS_QUIET ) { 00108 if ( argc > 1 ) { 00109 int tmp = atoi( argv[1] ); 00110 if ( tmp >= 1 ) 00111 nthreads = tmp; 00112 } 00113 } 00114 00115 ret = PAPI_library_init( PAPI_VER_CURRENT ); 00116 if ( ret != PAPI_VER_CURRENT ) { 00117 test_fail( __FILE__, __LINE__, "PAPI_library_init", ret ); 00118 } 00119 00120 hw_info = PAPI_get_hardware_info( ); 00121 if ( hw_info == NULL ) 00122 test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); 00123 00124 if ( strcmp( hw_info->model_string, "POWER6" ) == 0 ) { 00125 ret = PAPI_set_domain( PAPI_DOM_ALL ); 00126 if ( ret != PAPI_OK ) { 00127 test_fail( __FILE__, __LINE__, "PAPI_set_domain", ret ); 00128 } 00129 } 00130 00131 ret = PAPI_thread_init( ( unsigned long ( * )( void ) ) pthread_self ); 00132 if ( ret != PAPI_OK ) { 00133 test_fail( __FILE__, __LINE__, "PAPI_thread_init", ret ); 00134 } 00135 00136 ret = PAPI_multiplex_init( ); 00137 if ( ret != PAPI_OK ) { 00138 test_fail( __FILE__, __LINE__, "PAPI_multiplex_init", ret ); 00139 } 00140 00141 if ((max_events = PAPI_get_cmp_opt(PAPI_MAX_MPX_CTRS,NULL,0)) <= 0) { 00142 test_fail( __FILE__, __LINE__, "PAPI_get_cmp_opt", max_events ); 00143 } 00144 00145 if ((events = calloc(max_events,sizeof(int))) == NULL) { 00146 test_fail( __FILE__, __LINE__, "calloc", PAPI_ESYS ); 00147 } 00148 00149 /* Fill up the event set with as many non-derived events as we can */ 00150 00151 i = PAPI_PRESET_MASK; 00152 do { 00153 if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) { 00154 if ( info.count == 1 ) { 00155 events[numevents++] = ( int ) info.event_code; 00156 printf( "Added %s\n", info.symbol ); 00157 } else { 00158 printf( "Skipping derived event %s\n", info.symbol ); 00159 } 00160 } 00161 } while ( ( PAPI_enum_event( &i, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK ) 00162 && ( numevents < max_events ) ); 00163 00164 printf( "Found %d events\n", numevents ); 00165 00166 do_stuff( ); 00167 00168 printf( "Creating %d threads:\n", nthreads ); 00169 00170 threads = 00171 ( pthread_t * ) malloc( ( size_t ) nthreads * sizeof ( pthread_t ) ); 00172 if ( threads == NULL ) { 00173 test_fail( __FILE__, __LINE__, "malloc", PAPI_ENOMEM ); 00174 } 00175 00176 /* Create the threads */ 00177 for ( i = 0; i < nthreads; i++ ) { 00178 ret = pthread_create( &threads[i], NULL, thread, NULL ); 00179 if ( ret != 0 ) { 00180 test_fail( __FILE__, __LINE__, "pthread_create", PAPI_ESYS ); 00181 } 00182 } 00183 00184 /* Wait for thread completion */ 00185 for ( i = 0; i < nthreads; i++ ) { 00186 ret = pthread_join( threads[i], NULL ); 00187 if ( ret != 0 ) { 00188 test_fail( __FILE__, __LINE__, "pthread_join", PAPI_ESYS ); 00189 } 00190 } 00191 00192 printf( "Done." ); 00193 test_pass( __FILE__, NULL, 0 ); 00194 pthread_exit( NULL ); 00195 exit( 0 ); 00196 }