/* * Test PAPI with fork() and exec(). */ #include #include #include #include #include #include #include #include "papi.h" #include "papi_test.h" #define MAX_EVENTS 3 static int Event[MAX_EVENTS] = { PAPI_TOT_CYC, PAPI_FP_INS, PAPI_FAD_INS, }; static int Threshold[MAX_EVENTS] = { 8000000, 4000000, 4000000, }; static int num_events = 1; static int EventSet = PAPI_NULL; static const char *name = "unknown"; static struct timeval start, last; static long count, total; static void my_handler( int EventSet, void *pc, long long ovec, void *context ) { ( void ) EventSet; ( void ) pc; ( void ) ovec; ( void ) context; count++; total++; } static void zero_count( void ) { gettimeofday( &start, NULL ); last = start; count = 0; total = 0; } static void print_here( const char *str) { if (!TESTS_QUIET) printf("[%d] %s, %s\n", getpid(), name, str); } static void print_rate( const char *str ) { static int last_count = -1; struct timeval now; double st_secs, last_secs; gettimeofday( &now, NULL ); st_secs = ( double ) ( now.tv_sec - start.tv_sec ) + ( ( double ) ( now.tv_usec - start.tv_usec ) ) / 1000000.0; last_secs = ( double ) ( now.tv_sec - last.tv_sec ) + ( ( double ) ( now.tv_usec - last.tv_usec ) ) / 1000000.0; if ( last_secs <= 0.001 ) last_secs = 0.001; if (!TESTS_QUIET) { printf( "[%d] %s, time = %.3f, total = %ld, last = %ld, rate = %.1f/sec\n", getpid( ), str, st_secs, total, count, ( ( double ) count ) / last_secs ); } if ( last_count != -1 ) { if ( count < .1 * last_count ) { test_fail( name, __LINE__, "Interrupt rate changed!", 1 ); exit( 1 ); } } last_count = ( int ) count; count = 0; last = now; } static void do_cycles( int program_time ) { struct timeval start, now; double x, sum; gettimeofday( &start, NULL ); for ( ;; ) { sum = 1.0; for ( x = 1.0; x < 250000.0; x += 1.0 ) sum += x; if ( sum < 0.0 ) printf( "==>> SUM IS NEGATIVE !! <<==\n" ); gettimeofday( &now, NULL ); if ( now.tv_sec >= start.tv_sec + program_time ) break; } } static void my_papi_start( void ) { int ev; EventSet = PAPI_NULL; if ( PAPI_create_eventset( &EventSet ) != PAPI_OK ) test_fail( name, __LINE__, "PAPI_create_eventset failed", 1 ); for ( ev = 0; ev < num_events; ev++ ) { if ( PAPI_add_event( EventSet, Event[ev] ) != PAPI_OK ) { if (!TESTS_QUIET) printf("Trouble adding event\n"); test_skip( name, __LINE__, "PAPI_add_event failed", 1 ); } } for ( ev = 0; ev < num_events; ev++ ) { if ( PAPI_overflow( EventSet, Event[ev], Threshold[ev], 0, my_handler ) != PAPI_OK ) { test_fail( name, __LINE__, "PAPI_overflow failed", 1 ); } } if ( PAPI_start( EventSet ) != PAPI_OK ) test_fail( name, __LINE__, "PAPI_start failed", 1 ); } static void run( const char *str, int len ) { int n; for ( n = 1; n <= len; n++ ) { do_cycles( 1 ); print_rate( str ); } } int main( int argc, char **argv ) { char buf[100]; int quiet,retval; /* Used to be able to set this via command line */ num_events=1; /* Set TESTS_QUIET variable */ quiet=tests_quiet( argc, argv ); do_cycles( 1 ); zero_count( ); retval=PAPI_library_init( PAPI_VER_CURRENT ); if (retval!=PAPI_VER_CURRENT) { test_fail( name, __LINE__, "PAPI_library_init failed", 1 ); } name = argv[0]; if (!quiet) printf( "[%d] %s, num_events = %d\n", getpid( ), name, num_events ); sprintf( buf, "%d", num_events ); my_papi_start( ); run( name, 3 ); print_here( "system(./burn)" ); if ( access( "./burn", X_OK ) == 0 ) ( quiet ? system( "./burn TESTS_QUIET" ) : system( "./burn" ) ); else if ( access( "./ctests/burn", X_OK ) == 0 ) ( quiet ? system( "./ctests/burn TESTS_QUIET" ) : system( "./ctests/burn" ) ); test_pass(__FILE__); return 0; }