|
PAPI
5.0.1.0
|
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 }