PAPI  5.0.1.0
zero_attach.c
Go to the documentation of this file.
00001 /* This file performs the following test: start, stop and timer functionality for
00002    attached processes.
00003 
00004    - It attempts to use the following two counters. It may use less depending on
00005      hardware counter resource limitations. These are counted in the default counting
00006      domain and default granularity, depending on the platform. Usually this is 
00007      the user domain (PAPI_DOM_USER) and thread context (PAPI_GRN_THR).
00008      + PAPI_FP_INS
00009      + PAPI_TOT_CYC
00010    - Get us.
00011    - Start counters
00012    - Do flops
00013    - Stop and read counters
00014    - Get us.
00015 */
00016 
00017 #include "papi_test.h"
00018 #include <sys/ptrace.h>
00019 
00020 #ifdef _AIX
00021 #define _LINUX_SOURCE_COMPAT
00022 #endif
00023 
00024 #if defined(__FreeBSD__)
00025 # define PTRACE_ATTACH PT_ATTACH
00026 # define PTRACE_CONT PT_CONTINUE
00027 #endif
00028 
00029 int
00030 wait_for_attach_and_loop( void )
00031 {
00032     kill( getpid(  ), SIGSTOP );
00033     do_flops( NUM_FLOPS );
00034     kill( getpid(  ), SIGSTOP );
00035     return 0;
00036 }
00037 
00038 int
00039 main( int argc, char **argv )
00040 {
00041     int status, retval, num_tests = 1, tmp;
00042     int EventSet1 = PAPI_NULL;
00043     int PAPI_event, mask1;
00044     int num_events1;
00045     long long **values;
00046     long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc;
00047     char event_name[PAPI_MAX_STR_LEN], add_event_str[PAPI_MAX_STR_LEN];
00048     const PAPI_component_info_t *cmpinfo;
00049     pid_t pid;
00050 
00051     /* Set TESTS_QUIET variable */
00052     tests_quiet( argc, argv );
00053 
00054     /* Initialize the PAPI library */
00055     retval = PAPI_library_init( PAPI_VER_CURRENT );
00056     if ( retval != PAPI_VER_CURRENT ) {
00057        test_fail_exit( __FILE__, __LINE__, "PAPI_library_init", retval );
00058     }
00059 
00060     if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL ) {
00061        test_fail_exit( __FILE__, __LINE__, "PAPI_get_component_info", 0 );
00062     }
00063 
00064     if ( cmpinfo->attach == 0 ) {
00065        test_skip( __FILE__, __LINE__, 
00066               "Platform does not support attaching", 0 );
00067     }
00068 
00069     pid = fork(  );
00070     if ( pid < 0 ) {
00071        test_fail( __FILE__, __LINE__, "fork()", PAPI_ESYS );
00072     }
00073     if ( pid == 0 ) {
00074        exit( wait_for_attach_and_loop(  ) );
00075     }
00076 
00077     /* add PAPI_TOT_CYC and one of the events in 
00078        PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, 
00079        depending on the availability of the event 
00080        on the platform                            */
00081     EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 );
00082 
00083     if ( cmpinfo->attach_must_ptrace ) {
00084         if ( ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
00085             perror( "ptrace(PTRACE_ATTACH)" );
00086             return 1;
00087         }
00088         if ( waitpid( pid, &status, 0 ) == -1 ) {
00089             perror( "waitpid()" );
00090             exit( 1 );
00091         }
00092         if ( WIFSTOPPED( status ) == 0 )
00093             test_fail( __FILE__, __LINE__,
00094                        "Child process didnt return true to WIFSTOPPED", 0 );
00095     }
00096 
00097     retval = PAPI_attach( EventSet1, ( unsigned long ) pid );
00098     if ( retval != PAPI_OK )
00099         test_fail( __FILE__, __LINE__, "PAPI_attach", retval );
00100 
00101     retval = PAPI_event_code_to_name( PAPI_event, event_name );
00102     if ( retval != PAPI_OK )
00103         test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
00104     sprintf( add_event_str, "PAPI_add_event[%s]", event_name );
00105 
00106     /* num_events1 is greater than num_events2 so don't worry. */
00107 
00108     values = allocate_test_space( num_tests, num_events1 );
00109 
00110     elapsed_us = PAPI_get_real_usec(  );
00111     elapsed_cyc = PAPI_get_real_cyc(  );
00112     elapsed_virt_us = PAPI_get_virt_usec(  );
00113     elapsed_virt_cyc = PAPI_get_virt_cyc(  );
00114 
00115     /* Wait for the SIGSTOP. */
00116     if ( cmpinfo->attach_must_ptrace ) {
00117         if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00118             perror( "ptrace(PTRACE_CONT)" );
00119             return 1;
00120         }
00121         if ( waitpid( pid, &status, 0 ) == -1 ) {
00122             perror( "waitpid()" );
00123             exit( 1 );
00124         }
00125         if ( WIFSTOPPED( status ) == 0 ) {
00126             test_fail( __FILE__, __LINE__,
00127                        "Child process didn't return true to WIFSTOPPED", 0 );
00128         }
00129         if ( WSTOPSIG( status ) != SIGSTOP ) {
00130             test_fail( __FILE__, __LINE__,
00131                        "Child process didn't stop on SIGSTOP", 0 );
00132         }
00133     }
00134 
00135     retval = PAPI_start( EventSet1 );
00136     if ( retval != PAPI_OK ) {
00137         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00138     }
00139 
00140     /* Wait for the SIGSTOP. */
00141     if ( cmpinfo->attach_must_ptrace ) {
00142         if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00143             perror( "ptrace(PTRACE_CONT)" );
00144             return 1;
00145         }
00146         if ( waitpid( pid, &status, 0 ) == -1 ) {
00147             perror( "waitpid()" );
00148             exit( 1 );
00149         }
00150         if ( WIFSTOPPED( status ) == 0 ) {
00151             test_fail( __FILE__, __LINE__,
00152                        "Child process didn't return true to WIFSTOPPED", 0 );
00153         }
00154         if ( WSTOPSIG( status ) != SIGSTOP ) {
00155             test_fail( __FILE__, __LINE__,
00156                        "Child process didn't stop on SIGSTOP", 0 );
00157         }
00158     }
00159 
00160     elapsed_virt_us = PAPI_get_virt_usec(  ) - elapsed_virt_us;
00161     elapsed_virt_cyc = PAPI_get_virt_cyc(  ) - elapsed_virt_cyc;
00162     elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
00163     elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
00164 
00165     retval = PAPI_stop( EventSet1, values[0] );
00166     if ( retval != PAPI_OK ) {
00167         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00168     }
00169 
00170     remove_test_events( &EventSet1, mask1 );
00171 
00172     if ( cmpinfo->attach_must_ptrace ) {
00173         if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00174             perror( "ptrace(PTRACE_CONT)" );
00175             return 1;
00176         }
00177     }
00178 
00179     if ( waitpid( pid, &status, 0 ) == -1 ) {
00180         perror( "waitpid()" );
00181         exit( 1 );
00182     }
00183     if ( WIFEXITED( status ) == 0 )
00184         test_fail( __FILE__, __LINE__,
00185                    "Child process didn't return true to WIFEXITED", 0 );
00186 
00187 
00188     printf( "Test case: 3rd party attach start, stop.\n" );
00189     printf( "-----------------------------------------------\n" );
00190     tmp = PAPI_get_opt( PAPI_DEFDOM, NULL );
00191     printf( "Default domain is: %d (%s)\n", tmp, 
00192         stringify_all_domains( tmp ) );
00193     tmp = PAPI_get_opt( PAPI_DEFGRN, NULL );
00194     printf( "Default granularity is: %d (%s)\n", tmp,
00195             stringify_granularity( tmp ) );
00196     printf( "Using %d iterations of c += a*b\n", NUM_FLOPS );
00197     printf( "-------------------------------------------------------------------------\n" );
00198 
00199     printf( "Test type    : \t           1\n" );
00200 
00201     sprintf( add_event_str, "%-12s : \t", event_name );
00202     printf( TAB1, add_event_str, values[0][1] );
00203     printf( TAB1, "PAPI_TOT_CYC : \t", values[0][0] );
00204     printf( TAB1, "Real usec    : \t", elapsed_us );
00205     printf( TAB1, "Real cycles  : \t", elapsed_cyc );
00206     printf( TAB1, "Virt usec    : \t", elapsed_virt_us );
00207     printf( TAB1, "Virt cycles  : \t", elapsed_virt_cyc );
00208 
00209     printf( "-------------------------------------------------------------------------\n" );
00210 
00211     printf( "Verification: none\n" );
00212 
00213     test_pass( __FILE__, values, num_tests );
00214     
00215     return 0;
00216 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines