multiattach.c File Reference

Include dependency graph for multiattach.c:

Go to the source code of this file.

Functions

int wait_for_attach_and_loop (int num)
int main (int argc, char **argv)

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 40 of file multiattach.c.

00041 {
00042     int status, retval, num_tests = 2, tmp;
00043     int EventSet1 = PAPI_NULL, EventSet2 = PAPI_NULL;
00044     int PAPI_event, PAPI_event2, mask1, mask2;
00045     int num_events1, num_events2;
00046     long long **values;
00047     long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc;
00048     char event_name[PAPI_MAX_STR_LEN], add_event_str[PAPI_MAX_STR_LEN];
00049     const PAPI_component_info_t *cmpinfo;
00050     pid_t pid, pid2;
00051     double ratio1,ratio2;
00052 
00053     /* Set TESTS_QUIET variable */
00054     tests_quiet( argc, argv );
00055 
00056     /* Initialize the library */
00057     retval = PAPI_library_init( PAPI_VER_CURRENT );
00058     if ( retval != PAPI_VER_CURRENT ) {
00059        test_fail_exit( __FILE__, __LINE__, "PAPI_library_init", retval );
00060     }
00061 
00062     /* get the component info and check if we support attach */
00063     if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL ) {
00064        test_fail_exit( __FILE__, __LINE__, "PAPI_get_component_info", 0 );
00065     }
00066 
00067     if ( cmpinfo->attach == 0 ) {
00068        test_skip( __FILE__, __LINE__, 
00069               "Platform does not support attaching", 0 );
00070     }
00071 
00072     /* fork off first child */
00073     pid = fork(  );
00074     if ( pid < 0 ) {
00075        test_fail_exit( __FILE__, __LINE__, "fork()", PAPI_ESYS );
00076     }
00077     if ( pid == 0 ) {
00078        exit( wait_for_attach_and_loop( 1 ) );
00079     }
00080 
00081     /* fork off second child, does twice as much */
00082     pid2 = fork(  );
00083     if ( pid2 < 0 ) {
00084        test_fail_exit( __FILE__, __LINE__, "fork()", PAPI_ESYS );
00085     }
00086     if ( pid2 == 0 ) {
00087        exit( wait_for_attach_and_loop( 2 ) );
00088     }
00089 
00090     /* add PAPI_TOT_CYC and one of the events in 
00091            PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, 
00092            depending on the availability of the event 
00093            on the platform                            */
00094     EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 );
00095     EventSet2 = add_two_events( &num_events2, &PAPI_event2, &mask2 );
00096 
00097     if ( cmpinfo->attach_must_ptrace ) {
00098        if ( ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
00099           perror( "ptrace(PTRACE_ATTACH)" );
00100           return 1 ;
00101        }
00102        if ( waitpid( pid, &status, 0 ) == -1 ) {
00103           perror( "waitpid()" );
00104           exit( 1 );
00105        }
00106        if ( WIFSTOPPED( status ) == 0 ) {
00107           test_fail( __FILE__, __LINE__,
00108             "Child process didnt return true to WIFSTOPPED", 0 );
00109        }
00110        
00111        if ( ptrace( PTRACE_ATTACH, pid2, NULL, NULL ) == -1 ) {
00112           perror( "ptrace(PTRACE_ATTACH)" );
00113           return 1;
00114        }
00115        if ( waitpid( pid2, &status, 0 ) == -1 ) {
00116           perror( "waitpid()" );
00117           exit( 1 );
00118        }
00119        if ( WIFSTOPPED( status ) == 0 ) {
00120           test_fail( __FILE__, __LINE__,
00121             "Child process didnt return true to WIFSTOPPED", 0 );
00122        }
00123     }
00124 
00125     retval = PAPI_attach( EventSet1, ( unsigned long ) pid );
00126     if ( retval != PAPI_OK ) {
00127        test_fail( __FILE__, __LINE__, "PAPI_attach", retval ); 
00128     }
00129 
00130     retval = PAPI_attach( EventSet2, ( unsigned long ) pid2 );
00131     if ( retval != PAPI_OK ) {
00132        test_fail( __FILE__, __LINE__, "PAPI_attach", retval ); 
00133     }
00134 
00135     retval = PAPI_event_code_to_name( PAPI_event, event_name );
00136     if ( retval != PAPI_OK ) {
00137        test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
00138     }
00139     sprintf( add_event_str, "PAPI_add_event[%s]", event_name );
00140 
00141     /* num_events1 is greater than num_events2 so don't worry. */
00142 
00143     values = allocate_test_space( num_tests, num_events1 );
00144 
00145     /* Gather before values */
00146     elapsed_us = PAPI_get_real_usec(  );
00147     elapsed_cyc = PAPI_get_real_cyc(  );
00148     elapsed_virt_us = PAPI_get_virt_usec(  );
00149     elapsed_virt_cyc = PAPI_get_virt_cyc(  );
00150 
00151     /* Wait for the SIGSTOP. */
00152     if ( cmpinfo->attach_must_ptrace ) {
00153        if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00154           perror( "ptrace(PTRACE_CONT)" );
00155           return 1;
00156        }
00157        if ( waitpid( pid, &status, 0 ) == -1 ) {
00158           perror( "waitpid()" );
00159           exit( 1 );
00160        }
00161        if ( WIFSTOPPED( status ) == 0 ) {
00162           test_fail( __FILE__, __LINE__,
00163             "Child process didn't return true to WIFSTOPPED", 0 );
00164        }
00165        if ( WSTOPSIG( status ) != SIGSTOP ) {
00166           test_fail( __FILE__, __LINE__,
00167             "Child process didn't stop on SIGSTOP", 0 );
00168        }
00169 
00170        if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
00171           perror( "ptrace(PTRACE_CONT)" );
00172           return 1;
00173        }
00174        if ( waitpid( pid2, &status, 0 ) == -1 ) {
00175           perror( "waitpid()" );
00176           exit( 1 );
00177        }
00178        if ( WIFSTOPPED( status ) == 0 ) {
00179           test_fail( __FILE__, __LINE__,
00180             "Child process didn't return true to WIFSTOPPED", 0 );
00181        }
00182        if ( WSTOPSIG( status ) != SIGSTOP ) {
00183           test_fail( __FILE__, __LINE__,
00184             "Child process didn't stop on SIGSTOP", 0 );
00185        }
00186     }
00187 
00188     /* start first child */
00189     retval = PAPI_start( EventSet1 );
00190     if ( retval != PAPI_OK ) {
00191         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00192     }
00193 
00194     /* start second child */
00195     retval = PAPI_start( EventSet2 );
00196     if ( retval != PAPI_OK ) {
00197         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00198     }
00199 
00200     /* Wait for the SIGSTOP. */
00201     if ( cmpinfo->attach_must_ptrace ) {
00202        if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00203           perror( "ptrace(PTRACE_ATTACH)" );
00204           return 1;
00205        }
00206        if ( waitpid( pid, &status, 0 ) == -1 ) {
00207           perror( "waitpid()" );
00208           exit( 1 );
00209        }
00210        if ( WIFSTOPPED( status ) == 0 ) {
00211           test_fail( __FILE__, __LINE__,
00212             "Child process didn't return true to WIFSTOPPED", 0 );
00213        }
00214        if ( WSTOPSIG( status ) != SIGSTOP ) {
00215           test_fail( __FILE__, __LINE__,
00216             "Child process didn't stop on SIGSTOP", 0 );
00217        }
00218 
00219        if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
00220            perror( "ptrace(PTRACE_ATTACH)" );
00221            return 1;
00222        }
00223        if ( waitpid( pid2, &status, 0 ) == -1 ) {
00224           perror( "waitpid()" );
00225           exit( 1 );
00226        }
00227        if ( WIFSTOPPED( status ) == 0 ) {
00228           test_fail( __FILE__, __LINE__,
00229             "Child process didn't return true to WIFSTOPPED", 0 );
00230        }
00231        if ( WSTOPSIG( status ) != SIGSTOP ) {
00232           test_fail( __FILE__, __LINE__,
00233             "Child process didn't stop on SIGSTOP", 0 );
00234        }
00235     }
00236 
00237     elapsed_virt_us = PAPI_get_virt_usec(  ) - elapsed_virt_us;
00238     elapsed_virt_cyc = PAPI_get_virt_cyc(  ) - elapsed_virt_cyc;
00239     elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
00240     elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
00241 
00242     /* stop first child */
00243     retval = PAPI_stop( EventSet1, values[0] );
00244     if ( retval != PAPI_OK ) {
00245        printf( "Warning: PAPI_stop returned error %d, probably ok.\n",
00246                 retval );
00247     }
00248 
00249     /* stop second child */
00250     retval = PAPI_stop( EventSet2, values[1] );
00251     if ( retval != PAPI_OK ) {
00252        printf( "Warning: PAPI_stop returned error %d, probably ok.\n",
00253                 retval );
00254     }
00255 
00256     remove_test_events( &EventSet1, mask1 );
00257     remove_test_events( &EventSet2, mask2 );
00258 
00259     if ( cmpinfo->attach_must_ptrace ) {
00260        if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00261           perror( "ptrace(PTRACE_CONT)" );
00262           return 1;
00263        }
00264        if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
00265           perror( "ptrace(PTRACE_CONT)" );
00266           return 1;
00267        }
00268     }
00269 
00270     if ( waitpid( pid, &status, 0 ) == -1 ) {
00271        perror( "waitpid()" );
00272        exit( 1 );
00273     }
00274     if ( WIFEXITED( status ) == 0 ) {
00275        test_fail( __FILE__, __LINE__,
00276              "Child process didn't return true to WIFEXITED", 0 );
00277     }
00278 
00279     if ( waitpid( pid2, &status, 0 ) == -1 ) {
00280        perror( "waitpid()" );
00281        exit( 1 );
00282     }
00283     if ( WIFEXITED( status ) == 0 ) {
00284         test_fail( __FILE__, __LINE__,
00285               "Child process didn't return true to WIFEXITED", 0 );
00286     }
00287 
00288     /* This code isn't necessary as we know the child has exited, */
00289     /* it *may* return an error if the component so chooses. You  */
00290         /* should use read() instead. */
00291 
00292     printf( "Test case: multiple 3rd party attach start, stop.\n" );
00293     printf( "-----------------------------------------------\n" );
00294     tmp = PAPI_get_opt( PAPI_DEFDOM, NULL );
00295     printf( "Default domain is: %d (%s)\n", tmp, 
00296         stringify_all_domains( tmp ) );
00297     tmp = PAPI_get_opt( PAPI_DEFGRN, NULL );
00298     printf( "Default granularity is: %d (%s)\n", tmp,
00299             stringify_granularity( tmp ) );
00300     printf( "Using %d iterations of c += a*b\n", NUM_FLOPS );
00301     printf( "-------------------------------------------------------------------------\n" );
00302 
00303     sprintf( add_event_str, "(PID %jd) %-12s : \t", ( intmax_t ) pid,
00304              event_name );
00305     printf( TAB1, add_event_str, values[0][1] );
00306     sprintf( add_event_str, "(PID %jd) PAPI_TOT_CYC : \t", 
00307          ( intmax_t ) pid );
00308     printf( TAB1, add_event_str, values[0][0] );
00309     sprintf( add_event_str, "(PID %jd) %-12s : \t", ( intmax_t ) pid2,
00310              event_name );
00311     printf( TAB1, add_event_str,values[1][1] );
00312     sprintf( add_event_str, "(PID %jd) PAPI_TOT_CYC : \t", 
00313          ( intmax_t ) pid2 );
00314     printf( TAB1, add_event_str, values[1][0] );
00315     printf( TAB1, "Real usec    : \t", elapsed_us );
00316     printf( TAB1, "Real cycles  : \t", elapsed_cyc );
00317     printf( TAB1, "Virt usec    : \t", elapsed_virt_us );
00318     printf( TAB1, "Virt cycles  : \t", elapsed_virt_cyc );
00319 
00320     printf
00321         ( "-------------------------------------------------------------------------\n" );
00322 
00323     printf("Verification: pid %d results should be twice pid %d\n",pid2,pid );
00324 
00325     ratio1=(double)values[1][0]/(double)values[0][0];
00326     ratio2=(double)values[1][1]/(double)values[0][1];
00327 
00328     printf("\t%lld/%lld = %lf\n",values[1][0],values[0][0],ratio1);
00329     
00330 
00331     if ((ratio1 >2.15 ) || (ratio1 < 1.85)) {
00332       printf("Ratio out of range, should be ~2.0 not %lf\n",ratio1);
00333       test_fail( __FILE__, __LINE__,
00334             "Error: Counter ratio not two", 0 );
00335     }
00336 
00337     printf("\t%lld/%lld = %lf\n",values[1][1],values[0][1],ratio2);
00338 
00339     if ((ratio2 >2.75 ) || (ratio2 < 1.25)) {
00340       printf("Ratio out of range, should be ~2.0, not %lf\n",ratio2);
00341       test_fail( __FILE__, __LINE__,
00342             "Known issue: Counter ratio not two", 0 );
00343     }
00344 
00345     test_pass( __FILE__, values, num_tests );
00346     return 0;
00347 }

Here is the call graph for this function:

int wait_for_attach_and_loop ( int  num  ) 

Definition at line 31 of file multiattach.c.

00032 {
00033     kill( getpid(  ), SIGSTOP );
00034     do_flops( NUM_FLOPS * num );
00035     kill( getpid(  ), SIGSTOP );
00036     return ( 0 );
00037 }

Here is the call graph for this function:


Generated on 8 Sep 2016 for PAPI by  doxygen 1.6.1