PAPI  5.0.1.0
attach3.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 #include <limits.h>
00020 
00021 #ifdef _AIX
00022 #define _LINUX_SOURCE_COMPAT
00023 #endif
00024 
00025 #if defined(__FreeBSD__)
00026 # define PTRACE_ATTACH PT_ATTACH
00027 # define PTRACE_CONT PT_CONTINUE
00028 #endif
00029 
00030 int
00031 wait_for_attach_and_loop( void )
00032 {
00033   char *path;
00034   char newpath[PATH_MAX];
00035   path = getenv("PATH");
00036 
00037   sprintf(newpath, "PATH=./:%s", (path)?path:'\0' );
00038   putenv(newpath);
00039 
00040   if (ptrace(PTRACE_TRACEME, 0, 0, 0) == 0) {
00041     execlp("attach_target","attach_target","100000000",NULL); 
00042     perror("execl(attach_target) failed");
00043   }
00044   perror("PTRACE_TRACEME");
00045   return ( 1 );
00046 }
00047 
00048 int
00049 main( int argc, char **argv )
00050 {
00051     int status, retval, num_tests = 1, tmp;
00052     int EventSet1 = PAPI_NULL;
00053     long long **values;
00054     long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc;
00055     char event_name[PAPI_MAX_STR_LEN];;
00056     const PAPI_hw_info_t *hw_info;
00057     const PAPI_component_info_t *cmpinfo;
00058     pid_t pid;
00059 
00060     /* Fork before doing anything with the PMU */
00061 
00062     setbuf(stdout,NULL);
00063     pid = fork(  );
00064     if ( pid < 0 )
00065         test_fail( __FILE__, __LINE__, "fork()", PAPI_ESYS );
00066     if ( pid == 0 )
00067         exit( wait_for_attach_and_loop(  ) );
00068 
00069     tests_quiet( argc, argv );  /* Set TESTS_QUIET variable */
00070 
00071 
00072     /* Master only process below here */
00073 
00074     retval = PAPI_library_init( PAPI_VER_CURRENT );
00075     if ( retval != PAPI_VER_CURRENT )
00076         test_fail_exit( __FILE__, __LINE__, "PAPI_library_init", retval );
00077 
00078     if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL )
00079         test_fail_exit( __FILE__, __LINE__, "PAPI_get_component_info", 0 );
00080 
00081     if ( cmpinfo->attach == 0 )
00082         test_skip( __FILE__, __LINE__, "Platform does not support attaching",
00083                    0 );
00084 
00085     hw_info = PAPI_get_hardware_info(  );
00086     if ( hw_info == NULL )
00087         test_fail_exit( __FILE__, __LINE__, "PAPI_get_hardware_info", 0 );
00088 
00089     /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or
00090        PAPI_TOT_INS, depending on the availability of the event on the
00091        platform */
00092     retval = PAPI_create_eventset(&EventSet1);
00093     if ( retval != PAPI_OK )
00094         test_fail_exit( __FILE__, __LINE__, "PAPI_attach", retval );
00095 
00096     /* Force addition of component */
00097 
00098     retval = PAPI_assign_eventset_component( EventSet1, 0 );
00099     if ( retval != PAPI_OK )
00100         test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
00101                    retval );
00102 
00103     /* The following call causes this test to fail for perf_events */
00104 
00105     retval = PAPI_attach( EventSet1, ( unsigned long ) pid );
00106     if ( retval != PAPI_OK )
00107         test_fail_exit( __FILE__, __LINE__, "PAPI_attach", retval );
00108 
00109     sprintf(event_name,"PAPI_TOT_CYC");
00110 
00111     retval = PAPI_add_event(EventSet1, PAPI_TOT_CYC);
00112     if ( retval != PAPI_OK )
00113         test_fail_exit( __FILE__, __LINE__, "PAPI_add_event", retval );
00114     retval = PAPI_add_event(EventSet1, PAPI_FP_INS);
00115     if ( retval == PAPI_ENOEVNT ) {
00116         test_warn( __FILE__, __LINE__, "PAPI_FP_INS", retval);
00117     } else if ( retval != PAPI_OK ) {
00118         test_fail_exit( __FILE__, __LINE__, "PAPI_add_event", retval );
00119     }
00120     
00121     values = allocate_test_space( 1, 2);
00122 
00123     elapsed_us = PAPI_get_real_usec(  );
00124 
00125     elapsed_cyc = PAPI_get_real_cyc(  );
00126 
00127     elapsed_virt_us = PAPI_get_virt_usec(  );
00128 
00129     elapsed_virt_cyc = PAPI_get_virt_cyc(  );
00130 
00131     printf("must_ptrace is %d\n",cmpinfo->attach_must_ptrace);
00132     pid_t  child = wait( &status );
00133     printf( "Debugger exited wait() with %d\n",child );
00134       if (WIFSTOPPED( status ))
00135         {
00136           printf( "Child has stopped due to signal %d (%s)\n",
00137               WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
00138         }
00139       if (WIFSIGNALED( status ))
00140         {
00141           printf( "Child %ld received signal %d (%s)\n",
00142               (long)child,
00143               WTERMSIG(status) , strsignal(WTERMSIG( status )) );
00144         }
00145     printf("After %d\n",retval);
00146 
00147     retval = PAPI_start( EventSet1 );
00148     if ( retval != PAPI_OK )
00149         test_fail_exit( __FILE__, __LINE__, "PAPI_start", retval );
00150 
00151     printf("Continuing\n");
00152     if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00153       perror( "ptrace(PTRACE_CONT)" );
00154       return 1;
00155     }
00156 
00157 
00158     do {
00159       child = wait( &status );
00160       printf( "Debugger exited wait() with %d\n", child);
00161       if (WIFSTOPPED( status ))
00162         {
00163           printf( "Child has stopped due to signal %d (%s)\n",
00164               WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
00165         }
00166       if (WIFSIGNALED( status ))
00167         {
00168           printf( "Child %ld received signal %d (%s)\n",
00169               (long)child,
00170               WTERMSIG(status) , strsignal(WTERMSIG( status )) );
00171         }
00172     } while (!WIFEXITED( status ));
00173 
00174     printf("Child exited with value %d\n",WEXITSTATUS(status));
00175     if (WEXITSTATUS(status) != 0) 
00176       test_fail_exit( __FILE__, __LINE__, "Exit status of child to attach to", PAPI_EMISC);
00177 
00178     retval = PAPI_stop( EventSet1, values[0] );
00179     if ( retval != PAPI_OK )
00180       test_fail_exit( __FILE__, __LINE__, "PAPI_stop", retval );
00181 
00182     elapsed_virt_us = PAPI_get_virt_usec(  ) - elapsed_virt_us;
00183 
00184     elapsed_virt_cyc = PAPI_get_virt_cyc(  ) - elapsed_virt_cyc;
00185 
00186     elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
00187 
00188     elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
00189 
00190     retval = PAPI_cleanup_eventset(EventSet1);
00191     if (retval != PAPI_OK)
00192       test_fail_exit( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
00193 
00194     retval = PAPI_destroy_eventset(&EventSet1);
00195     if (retval != PAPI_OK)
00196       test_fail_exit( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
00197 
00198     printf( "Test case: 3rd party attach start, stop.\n" );
00199     printf( "-----------------------------------------------\n" );
00200     tmp = PAPI_get_opt( PAPI_DEFDOM, NULL );
00201     printf( "Default domain is: %d (%s)\n", tmp, stringify_all_domains( tmp ) );
00202     tmp = PAPI_get_opt( PAPI_DEFGRN, NULL );
00203     printf( "Default granularity is: %d (%s)\n", tmp,
00204             stringify_granularity( tmp ) );
00205     printf( "Using %d iterations of c += a*b\n", NUM_FLOPS );
00206     printf
00207         ( "-------------------------------------------------------------------------\n" );
00208 
00209     printf( "Test type    : \t           1\n" );
00210 
00211     printf( TAB1, "PAPI_TOT_CYC : \t", ( values[0] )[0] );
00212     printf( TAB1, "PAPI_FP_INS  : \t", ( values[0] )[1] );
00213     printf( TAB1, "Real usec    : \t", elapsed_us );
00214     printf( TAB1, "Real cycles  : \t", elapsed_cyc );
00215     printf( TAB1, "Virt usec    : \t", elapsed_virt_us );
00216     printf( TAB1, "Virt cycles  : \t", elapsed_virt_cyc );
00217 
00218     printf
00219         ( "-------------------------------------------------------------------------\n" );
00220 
00221     printf( "Verification: none\n" );
00222 
00223     test_pass( __FILE__, values, num_tests );
00224     exit( 1 );
00225 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines