PAPI  5.0.1.0
krentel_pthreads.c
Go to the documentation of this file.
00001 /*
00002  *  Test PAPI with multiple threads.
00003  */
00004 
00005 #include <pthread.h>
00006 #include <sys/time.h>
00007 #include "papi_test.h"
00008 
00009 #define EVENT  PAPI_TOT_CYC
00010 
00011 int program_time = 5;
00012 int threshold = 20000000;
00013 int num_threads = 3;
00014 
00015 long count[MAX_THREADS];
00016 long iter[MAX_THREADS];
00017 struct timeval last[MAX_THREADS];
00018 
00019 pthread_key_t key;
00020 
00021 struct timeval start;
00022 
00023 void
00024 my_handler( int EventSet, void *pc, long long ovec, void *context )
00025 {
00026     ( void ) EventSet;
00027     ( void ) pc;
00028     ( void ) ovec;
00029     ( void ) context;
00030 
00031     long num = ( long ) pthread_getspecific( key );
00032 
00033     if ( num < 0 || num > num_threads )
00034         test_fail( __FILE__, __LINE__, "getspecific failed", 1 );
00035     count[num]++;
00036 }
00037 
00038 void
00039 print_rate( long num )
00040 {
00041     struct timeval now;
00042     long st_secs;
00043     double last_secs;
00044 
00045     gettimeofday( &now, NULL );
00046     st_secs = now.tv_sec - start.tv_sec;
00047     last_secs = ( double ) ( now.tv_sec - last[num].tv_sec )
00048         + ( ( double ) ( now.tv_usec - last[num].tv_usec ) ) / 1000000.0;
00049     if ( last_secs <= 0.001 )
00050         last_secs = 0.001;
00051 
00052     printf( "[%ld] time = %ld, count = %ld, iter = %ld, "
00053             "rate = %.1f/Kiter\n",
00054             num, st_secs, count[num], iter[num],
00055             ( 1000.0 * ( double ) count[num] ) / ( double ) iter[num] );
00056 
00057     count[num] = 0;
00058     iter[num] = 0;
00059     last[num] = now;
00060 }
00061 
00062 void
00063 do_cycles( long num, int len )
00064 {
00065     struct timeval start, now;
00066     double x, sum;
00067 
00068     gettimeofday( &start, NULL );
00069 
00070     for ( ;; ) {
00071         sum = 1.0;
00072         for ( x = 1.0; x < 250000.0; x += 1.0 )
00073             sum += x;
00074         if ( sum < 0.0 )
00075             printf( "==>>  SUM IS NEGATIVE !!  <<==\n" );
00076 
00077         iter[num]++;
00078 
00079         gettimeofday( &now, NULL );
00080         if ( now.tv_sec >= start.tv_sec + len )
00081             break;
00082     }
00083 }
00084 
00085 void
00086 launch_timer( int *EventSet )
00087 {
00088     if ( PAPI_create_eventset( EventSet ) != PAPI_OK )
00089         test_fail( __FILE__, __LINE__, "PAPI_create_eventset failed", 1 );
00090 
00091     if ( PAPI_add_event( *EventSet, EVENT ) != PAPI_OK )
00092         test_fail( __FILE__, __LINE__, "PAPI_add_event failed", 1 );
00093 
00094     if ( PAPI_overflow( *EventSet, EVENT, threshold, 0, my_handler ) !=
00095          PAPI_OK )
00096         test_fail( __FILE__, __LINE__, "PAPI_overflow failed", 1 );
00097 
00098     if ( PAPI_start( *EventSet ) != PAPI_OK )
00099         test_fail( __FILE__, __LINE__, "PAPI_start failed", 1 );
00100 }
00101 
00102 void *
00103 my_thread( void *v )
00104 {
00105     long num = ( long ) v;
00106     int n;
00107     int EventSet = PAPI_NULL;
00108     long long value;
00109 
00110     int retval = PAPI_register_thread(  );
00111     if ( retval != PAPI_OK )
00112         test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval );
00113     pthread_setspecific( key, v );
00114 
00115     count[num] = 0;
00116     iter[num] = 0;
00117     last[num] = start;
00118 
00119     launch_timer( &EventSet );
00120     printf( "launched timer in thread %ld\n", num );
00121 
00122     for ( n = 1; n <= program_time; n++ ) {
00123         do_cycles( num, 1 );
00124         print_rate( num );
00125     }
00126 
00127     PAPI_stop( EventSet, &value );
00128     PAPI_remove_event( EventSet, EVENT );
00129     PAPI_destroy_eventset( &EventSet );
00130     retval = PAPI_unregister_thread(  );
00131     if ( retval != PAPI_OK )
00132         test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval );
00133     return ( NULL );
00134 }
00135 
00136 int
00137 main( int argc, char **argv )
00138 {
00139     pthread_t td;
00140     long n;
00141 
00142     tests_quiet( argc, argv );  /*Set TESTS_QUIET variable */
00143 
00144     if ( argc < 2 || sscanf( argv[1], "%d", &program_time ) < 1 )
00145         program_time = 6;
00146     if ( argc < 3 || sscanf( argv[2], "%d", &threshold ) < 1 )
00147         threshold = 20000000;
00148     if ( argc < 4 || sscanf( argv[3], "%d", &num_threads ) < 1 )
00149         num_threads = 3;
00150 
00151     printf( "program_time = %d, threshold = %d, num_threads = %d\n\n",
00152             program_time, threshold, num_threads );
00153 
00154     if ( PAPI_library_init( PAPI_VER_CURRENT ) != PAPI_VER_CURRENT )
00155         test_fail( __FILE__, __LINE__, "PAPI_library_init failed", 1 );
00156 
00157     if ( PAPI_thread_init( ( unsigned long ( * )( void ) ) ( pthread_self ) ) !=
00158          PAPI_OK )
00159         test_fail( __FILE__, __LINE__, "PAPI_thread_init failed", 1 );
00160 
00161     if ( pthread_key_create( &key, NULL ) != 0 )
00162         test_fail( __FILE__, __LINE__, "pthread key create failed", 1 );
00163 
00164     gettimeofday( &start, NULL );
00165 
00166     for ( n = 1; n <= num_threads; n++ ) {
00167         if ( pthread_create( &td, NULL, my_thread, ( void * ) n ) != 0 )
00168             test_fail( __FILE__, __LINE__, "pthread create failed", 1 );
00169     }
00170 
00171     my_thread( ( void * ) 0 );
00172 
00173     printf( "done\n" );
00174 
00175     test_pass( __FILE__, NULL, 0 );
00176     pthread_exit( NULL );
00177     return ( 0 );
00178 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines