PAPI  5.0.1.0
zero_pthreads.c
Go to the documentation of this file.
00001 /* This file performs the following test: start, stop and timer
00002 functionality for 2 slave pthreads
00003 
00004    - It attempts to use the following two counters. It may use less
00005 depending on hardware counter resource limitations. These are counted
00006 in the default counting domain and default granularity, depending on
00007 the platform. Usually this is the user domain (PAPI_DOM_USER) and
00008 thread context (PAPI_GRN_THR).
00009 
00010      + PAPI_FP_INS
00011      + PAPI_TOT_CYC
00012 
00013 Each of 2 slave pthreads:
00014    - Get cyc.
00015    - Get us.
00016    - Start counters
00017    - Do flops
00018    - Stop and read counters
00019    - Get us.
00020    - Get cyc.
00021 
00022 Master pthread:
00023    - Get us.
00024    - Get cyc.
00025    - Fork threads
00026    - Wait for threads to exit
00027    - Get us.
00028    - Get cyc.
00029 */
00030 
00031 #include <pthread.h>
00032 
00033 #include "papi_test.h"
00034 
00035 void *
00036 Thread( void *arg )
00037 {
00038     int retval, num_tests = 1;
00039     int EventSet1 = PAPI_NULL;
00040     int PAPI_event, mask1;
00041     int num_events1;
00042     long long **values;
00043     long long elapsed_us, elapsed_cyc;
00044     char event_name[PAPI_MAX_STR_LEN];
00045 
00046     retval = PAPI_register_thread(  );
00047     if ( retval != PAPI_OK ) {
00048        test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval );
00049     }
00050 
00051     printf( "Thread 0x%x started\n", ( int ) pthread_self(  ) );
00052 
00053     /* add PAPI_TOT_CYC and one of the events in 
00054        PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, 
00055        depending on the availability of the event 
00056        on the platform                              */
00057     EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 );
00058 
00059     retval = PAPI_event_code_to_name( PAPI_event, event_name );
00060     if ( retval != PAPI_OK ) {
00061        test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
00062     }
00063 
00064     values = allocate_test_space( num_tests, num_events1 );
00065 
00066     elapsed_us = PAPI_get_real_usec(  );
00067     elapsed_cyc = PAPI_get_real_cyc(  );
00068 
00069     retval = PAPI_start( EventSet1 );
00070     if ( retval != PAPI_OK ) {
00071         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00072     }
00073 
00074     do_flops( *( int * ) arg );
00075 
00076     retval = PAPI_stop( EventSet1, values[0] );
00077     if ( retval != PAPI_OK ) {
00078         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00079     }
00080 
00081     elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
00082     elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
00083 
00084     remove_test_events( &EventSet1, mask1 );
00085 
00086     if ( !TESTS_QUIET ) {
00087        printf( "Thread 0x%x %-12s : \t%lld\n", ( int ) pthread_self(  ),
00088                 event_name, values[0][1] );
00089        printf( "Thread 0x%x PAPI_TOT_CYC : \t%lld\n", (int) pthread_self(),
00090                 values[0][0] );
00091        printf( "Thread 0x%x Real usec    : \t%lld\n", 
00092             ( int ) pthread_self(  ),
00093                 elapsed_us );
00094        printf( "Thread 0x%x Real cycles  : \t%lld\n", (int) pthread_self(),
00095                 elapsed_cyc );
00096     }
00097 
00098     free_test_space( values, num_tests );
00099 
00100     retval = PAPI_unregister_thread(  );
00101     if ( retval != PAPI_OK )
00102         test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval );
00103     return NULL;
00104 }
00105 
00106 int
00107 main( int argc, char **argv )
00108 {
00109     pthread_t e_th, f_th, g_th, h_th;
00110     int flops1, flops2, flops3, flops4;
00111     int retval, rc;
00112     pthread_attr_t attr;
00113     long long elapsed_us, elapsed_cyc;
00114 
00115     /* Set TESTS_QUIET variable */
00116     tests_quiet( argc, argv );
00117 
00118     /* Init PAPI library */
00119     retval = PAPI_library_init( PAPI_VER_CURRENT );
00120     if ( retval != PAPI_VER_CURRENT ) {
00121        test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
00122     }
00123 
00124     retval = PAPI_thread_init( ( unsigned long ( * )( void ) ) 
00125                    ( pthread_self ) );
00126     if ( retval != PAPI_OK ) {
00127        if ( retval == PAPI_ECMP ) {
00128           test_skip( __FILE__, __LINE__, "PAPI_thread_init", retval );
00129        }
00130        else {
00131           test_fail( __FILE__, __LINE__, "PAPI_thread_init", retval );
00132        }
00133     }
00134 
00135     elapsed_us = PAPI_get_real_usec(  );
00136 
00137     elapsed_cyc = PAPI_get_real_cyc(  );
00138 
00139     pthread_attr_init( &attr );
00140 #ifdef PTHREAD_CREATE_UNDETACHED
00141     pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_UNDETACHED );
00142 #endif
00143 #ifdef PTHREAD_SCOPE_SYSTEM
00144     retval = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
00145     if ( retval != 0 )
00146         test_skip( __FILE__, __LINE__, "pthread_attr_setscope", retval );
00147 #endif
00148 
00149     flops1 = 1000000;
00150     rc = pthread_create( &e_th, &attr, Thread, ( void * ) &flops1 );
00151     if ( rc ) {
00152         retval = PAPI_ESYS;
00153         test_fail( __FILE__, __LINE__, "pthread_create", retval );
00154     }
00155     flops2 = 2000000;
00156     rc = pthread_create( &f_th, &attr, Thread, ( void * ) &flops2 );
00157     if ( rc ) {
00158         retval = PAPI_ESYS;
00159         test_fail( __FILE__, __LINE__, "pthread_create", retval );
00160     }
00161 
00162     flops3 = 4000000;
00163     rc = pthread_create( &g_th, &attr, Thread, ( void * ) &flops3 );
00164     if ( rc ) {
00165         retval = PAPI_ESYS;
00166         test_fail( __FILE__, __LINE__, "pthread_create", retval );
00167     }
00168 
00169     flops4 = 8000000;
00170     rc = pthread_create( &h_th, &attr, Thread, ( void * ) &flops4 );
00171     if ( rc ) {
00172         retval = PAPI_ESYS;
00173         test_fail( __FILE__, __LINE__, "pthread_create", retval );
00174     }
00175 
00176     pthread_attr_destroy( &attr );
00177     flops1 = 500000;
00178     Thread( &flops1 );
00179     pthread_join( h_th, NULL );
00180     pthread_join( g_th, NULL );
00181     pthread_join( f_th, NULL );
00182     pthread_join( e_th, NULL );
00183 
00184     elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
00185     elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
00186 
00187     if ( !TESTS_QUIET ) {
00188         printf( "Master real usec   : \t%lld\n", elapsed_us );
00189         printf( "Master real cycles : \t%lld\n", elapsed_cyc );
00190     }
00191 
00192     test_pass( __FILE__, NULL, 0 );
00193     pthread_exit( NULL );
00194     exit( 1 );
00195 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines