PAPI  5.0.1.0
attach2.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_create_eventset", retval );
00095 
00096     /* Here we are testing that this does not cause a fail */
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     retval = PAPI_attach( EventSet1, ( unsigned long ) pid );
00104     if ( retval != PAPI_OK )
00105         test_fail_exit( __FILE__, __LINE__, "PAPI_attach", retval );
00106 
00107     sprintf(event_name,"PAPI_TOT_CYC");
00108 
00109     retval = PAPI_add_event(EventSet1, PAPI_TOT_CYC);
00110     if ( retval != PAPI_OK )
00111         test_fail_exit( __FILE__, __LINE__, "PAPI_add_event", retval );
00112 
00113     retval = PAPI_add_event(EventSet1, PAPI_FP_INS);
00114     if ( retval == PAPI_ENOEVNT ) {
00115         test_warn( __FILE__, __LINE__, "PAPI_FP_INS", retval);
00116     } else if ( retval != PAPI_OK ) {
00117         test_fail_exit( __FILE__, __LINE__, "PAPI_add_event", retval );
00118     }
00119     
00120     values = allocate_test_space( 1, 2);
00121 
00122     elapsed_us = PAPI_get_real_usec(  );
00123 
00124     elapsed_cyc = PAPI_get_real_cyc(  );
00125 
00126     elapsed_virt_us = PAPI_get_virt_usec(  );
00127 
00128     elapsed_virt_cyc = PAPI_get_virt_cyc(  );
00129 
00130     printf("must_ptrace is %d\n",cmpinfo->attach_must_ptrace);
00131     pid_t  child = wait( &status );
00132     printf( "Debugger exited wait() with %d\n",child );
00133       if (WIFSTOPPED( status ))
00134         {
00135           printf( "Child has stopped due to signal %d (%s)\n",
00136               WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
00137         }
00138       if (WIFSIGNALED( status ))
00139         {
00140           printf( "Child %ld received signal %d (%s)\n",
00141               (long)child,
00142               WTERMSIG(status) , strsignal(WTERMSIG( status )) );
00143         }
00144     printf("After %d\n",retval);
00145 
00146     retval = PAPI_start( EventSet1 );
00147     if ( retval != PAPI_OK )
00148         test_fail_exit( __FILE__, __LINE__, "PAPI_start", retval );
00149 
00150     printf("Continuing\n");
00151     if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
00152       perror( "ptrace(PTRACE_CONT)" );
00153       return 1;
00154     }
00155 
00156 
00157     do {
00158       child = wait( &status );
00159       printf( "Debugger exited wait() with %d\n", child);
00160       if (WIFSTOPPED( status ))
00161         {
00162           printf( "Child has stopped due to signal %d (%s)\n",
00163               WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
00164         }
00165       if (WIFSIGNALED( status ))
00166         {
00167           printf( "Child %ld received signal %d (%s)\n",
00168               (long)child,
00169               WTERMSIG(status) , strsignal(WTERMSIG( status )) );
00170         }
00171     } while (!WIFEXITED( status ));
00172 
00173     printf("Child exited with value %d\n",WEXITSTATUS(status));
00174     if (WEXITSTATUS(status) != 0) 
00175       test_fail_exit( __FILE__, __LINE__, "Exit status of child to attach to", PAPI_EMISC);
00176 
00177     retval = PAPI_stop( EventSet1, values[0] );
00178     if ( retval != PAPI_OK )
00179       test_fail_exit( __FILE__, __LINE__, "PAPI_stop", retval );
00180 
00181     elapsed_virt_us = PAPI_get_virt_usec(  ) - elapsed_virt_us;
00182 
00183     elapsed_virt_cyc = PAPI_get_virt_cyc(  ) - elapsed_virt_cyc;
00184 
00185     elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
00186 
00187     elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
00188     
00189     retval = PAPI_cleanup_eventset(EventSet1);
00190     if (retval != PAPI_OK)
00191       test_fail_exit( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
00192 
00193     retval = PAPI_destroy_eventset(&EventSet1);
00194     if (retval != PAPI_OK)
00195       test_fail_exit( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
00196 
00197     printf( "Test case: 3rd party attach start, stop.\n" );
00198     printf( "-----------------------------------------------\n" );
00199     tmp = PAPI_get_opt( PAPI_DEFDOM, NULL );
00200     printf( "Default domain is: %d (%s)\n", tmp, stringify_all_domains( tmp ) );
00201     tmp = PAPI_get_opt( PAPI_DEFGRN, NULL );
00202     printf( "Default granularity is: %d (%s)\n", tmp,
00203             stringify_granularity( tmp ) );
00204     printf( "Using %d iterations of c += a*b\n", NUM_FLOPS );
00205     printf
00206         ( "-------------------------------------------------------------------------\n" );
00207 
00208     printf( "Test type    : \t           1\n" );
00209 
00210     printf( TAB1, "PAPI_TOT_CYC : \t", ( values[0] )[0] );
00211     printf( TAB1, "PAPI_FP_INS  : \t", ( values[0] )[1] );
00212     printf( TAB1, "Real usec    : \t", elapsed_us );
00213     printf( TAB1, "Real cycles  : \t", elapsed_cyc );
00214     printf( TAB1, "Virt usec    : \t", elapsed_virt_us );
00215     printf( TAB1, "Virt cycles  : \t", elapsed_virt_cyc );
00216 
00217     printf
00218         ( "-------------------------------------------------------------------------\n" );
00219 
00220     printf( "Verification: none\n" );
00221 
00222     test_pass( __FILE__, values, num_tests );
00223     exit( 1 );
00224 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines