PAPI  5.0.1.0
fork_exec_overflow.c
Go to the documentation of this file.
00001 /*
00002  *  Test PAPI with fork() and exec().
00003  */
00004 
00005 #include <sys/time.h>
00006 #include <sys/types.h>
00007 #include <sys/wait.h>
00008 #include <errno.h>
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <unistd.h>
00012 #include "papi.h"
00013 #include "papi_test.h"
00014 
00015 #define MAX_EVENTS  3
00016 
00017 int Event[MAX_EVENTS] = {
00018     PAPI_TOT_CYC,
00019     PAPI_FP_INS,
00020     PAPI_FAD_INS,
00021 };
00022 
00023 int Threshold[MAX_EVENTS] = {
00024     8000000,
00025     4000000,
00026     4000000,
00027 };
00028 
00029 int num_events = 1;
00030 int EventSet = PAPI_NULL;
00031 char *name = "unknown";
00032 struct timeval start, last;
00033 long count, total;
00034 
00035 void
00036 my_handler( int EventSet, void *pc, long long ovec, void *context )
00037 {
00038     ( void ) EventSet;
00039     ( void ) pc;
00040     ( void ) ovec;
00041     ( void ) context;
00042 
00043     count++;
00044     total++;
00045 }
00046 
00047 void
00048 zero_count( void )
00049 {
00050     gettimeofday( &start, NULL );
00051     last = start;
00052     count = 0;
00053     total = 0;
00054 }
00055 
00056 #define HERE(str)  printf("[%d] %s, %s\n", getpid(), name, str);
00057 
00058 void
00059 print_rate( char *str )
00060 {
00061     static int last_count = -1;
00062     struct timeval now;
00063     double st_secs, last_secs;
00064 
00065     gettimeofday( &now, NULL );
00066     st_secs = ( double ) ( now.tv_sec - start.tv_sec )
00067         + ( ( double ) ( now.tv_usec - start.tv_usec ) ) / 1000000.0;
00068     last_secs = ( double ) ( now.tv_sec - last.tv_sec )
00069         + ( ( double ) ( now.tv_usec - last.tv_usec ) ) / 1000000.0;
00070     if ( last_secs <= 0.001 )
00071         last_secs = 0.001;
00072 
00073     printf( "[%d] %s, time = %.3f, total = %ld, last = %ld, rate = %.1f/sec\n",
00074             getpid(  ), str, st_secs, total, count,
00075             ( ( double ) count ) / last_secs );
00076 
00077     if ( last_count != -1 ) {
00078         if ( count < .1 * last_count ) {
00079             test_fail( name, __LINE__, "Interrupt rate changed!", 1 );
00080             exit( 1 );
00081         }
00082     }
00083     last_count = ( int ) count;
00084     count = 0;
00085     last = now;
00086 }
00087 
00088 void
00089 do_cycles( int program_time )
00090 {
00091     struct timeval start, now;
00092     double x, sum;
00093 
00094     gettimeofday( &start, NULL );
00095 
00096     for ( ;; ) {
00097         sum = 1.0;
00098         for ( x = 1.0; x < 250000.0; x += 1.0 )
00099             sum += x;
00100         if ( sum < 0.0 )
00101             printf( "==>>  SUM IS NEGATIVE !!  <<==\n" );
00102 
00103         gettimeofday( &now, NULL );
00104         if ( now.tv_sec >= start.tv_sec + program_time )
00105             break;
00106     }
00107 }
00108 
00109 void
00110 my_papi_init( void )
00111 {
00112     if ( PAPI_library_init( PAPI_VER_CURRENT ) != PAPI_VER_CURRENT )
00113         test_fail( name, __LINE__, "PAPI_library_init failed", 1 );
00114 }
00115 
00116 void
00117 my_papi_start( void )
00118 {
00119     int ev;
00120 
00121     EventSet = PAPI_NULL;
00122 
00123     if ( PAPI_create_eventset( &EventSet ) != PAPI_OK )
00124         test_fail( name, __LINE__, "PAPI_create_eventset failed", 1 );
00125 
00126     for ( ev = 0; ev < num_events; ev++ ) {
00127         if ( PAPI_add_event( EventSet, Event[ev] ) != PAPI_OK )
00128             test_fail( name, __LINE__, "PAPI_add_event failed", 1 );
00129     }
00130 
00131     for ( ev = 0; ev < num_events; ev++ ) {
00132         if ( PAPI_overflow( EventSet, Event[ev], Threshold[ev], 0, my_handler )
00133              != PAPI_OK ) {
00134             test_fail( name, __LINE__, "PAPI_overflow failed", 1 );
00135         }
00136     }
00137 
00138     if ( PAPI_start( EventSet ) != PAPI_OK )
00139         test_fail( name, __LINE__, "PAPI_start failed", 1 );
00140 }
00141 
00142 void
00143 my_papi_stop( void )
00144 {
00145     if ( PAPI_stop( EventSet, NULL ) != PAPI_OK )
00146         test_fail( name, __LINE__, "PAPI_stop failed", 1 );
00147 }
00148 
00149 void
00150 run( char *str, int len )
00151 {
00152     int n;
00153 
00154     for ( n = 1; n <= len; n++ ) {
00155         do_cycles( 1 );
00156         print_rate( str );
00157     }
00158 }
00159 
00160 int
00161 main( int argc, char **argv )
00162 {
00163     char buf[100];
00164 
00165     if ( argc < 2 || sscanf( argv[1], "%d", &num_events ) < 1 )
00166         num_events = 1;
00167     if ( num_events < 0 || num_events > MAX_EVENTS )
00168         num_events = 1;
00169 
00170     tests_quiet( argc, argv );  /* Set TESTS_QUIET variable */
00171     do_cycles( 1 );
00172     zero_count(  );
00173     my_papi_init(  );
00174     name = argv[0];
00175     printf( "[%d] %s, num_events = %d\n", getpid(  ), name, num_events );
00176     sprintf( buf, "%d", num_events );
00177     my_papi_start(  );
00178     run( name, 3 );
00179 #if defined(PCHILD)
00180     HERE( "stop" );
00181     my_papi_stop(  );
00182     HERE( "end" );
00183     test_pass( name, NULL, 0 );
00184 #elif defined(PEXEC)
00185     HERE( "stop" );
00186     my_papi_stop(  );
00187     HERE( "exec(./child_overflow)" );
00188     if ( access( "./child_overflow", X_OK ) == 0 )
00189         execl( "./child_overflow", "./child_overflow",
00190                ( TESTS_QUIET ? "TESTS_QUIET" : NULL ), NULL );
00191     else if ( access( "./ctests/child_overflow", X_OK ) == 0 )
00192         execl( "./ctests/child_overflow", "./ctests/child_overflow",
00193                ( TESTS_QUIET ? "TESTS_QUIET" : NULL ), NULL );
00194     test_fail( name, __LINE__, "exec failed", 1 );
00195 #elif defined(SYSTEM)
00196     HERE( "system(./child_overflow)" );
00197     if ( access( "./child_overflow", X_OK ) == 0 )
00198         ( TESTS_QUIET ? system( "./child_overflow TESTS_QUIET" ) :
00199           system( "./child_overflow" ) );
00200     else if ( access( "./ctests/child_overflow", X_OK ) == 0 )
00201         ( TESTS_QUIET ? system( "./ctests/child_overflow TESTS_QUIET" ) :
00202           system( "./ctests/child_overflow" ) );
00203     test_pass( name, NULL, 0 );
00204 #elif defined(SYSTEM2)
00205     HERE( "system(./burn)" );
00206     if ( access( "./burn", X_OK ) == 0 )
00207         ( TESTS_QUIET ? system( "./burn TESTS_QUIET" ) : system( "./burn" ) );
00208     else if ( access( "./ctests/burn", X_OK ) == 0 )
00209         ( TESTS_QUIET ? system( "./ctests/burn TESTS_QUIET" ) :
00210           system( "./ctests/burn" ) );
00211     test_pass( name, NULL, 0 );
00212 #else
00213     HERE( "fork" );
00214     {
00215         int ret = fork(  );
00216         if ( ret < 0 )
00217             test_fail( name, __LINE__, "fork failed", 1 );
00218         if ( ret == 0 ) {
00219             /*
00220              * Child process.
00221              */
00222             zero_count(  );
00223             my_papi_init(  );
00224             my_papi_start(  );
00225             run( "child", 5 );
00226             HERE( "stop" );
00227             my_papi_stop(  );
00228             sleep( 3 );
00229             HERE( "end" );
00230             exit( 0 );
00231         }
00232         run( "main", 14 );
00233         my_papi_stop(  );
00234         {
00235             int status;
00236             wait( &status );
00237             HERE( "end" );
00238             if ( WEXITSTATUS( status ) != 0 )
00239                 test_fail( name, __LINE__, "child failed", 1 );
00240             else
00241                 test_pass( name, NULL, 0 );
00242         }
00243     }
00244 #endif
00245     exit( 0 );
00246 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines