|
PAPI
5.0.1.0
|
00001 /****************************/ 00002 /* THIS IS OPEN SOURCE CODE */ 00003 /****************************/ 00004 00029 #include <stdlib.h> 00030 #include <ctype.h> 00031 #include <string.h> 00032 #include <errno.h> 00033 #include <sys/select.h> 00034 00035 /* Headers required by PAPI */ 00036 #include "papi.h" 00037 #include "papi_internal.h" 00038 #include "papi_vector.h" 00039 #include "papi_memory.h" 00040 00041 #include "appio.h" 00042 00043 // The PIC test implies it's built for shared linkage 00044 #ifdef PIC 00045 # include "dlfcn.h" 00046 #endif 00047 00048 /* 00049 #pragma weak dlerror 00050 static void *_dlsym_fake(void *handle, const char* symbol) { (void) handle; (void) symbol; return NULL; } 00051 void *dlsym(void *handle, const char* symbol) __attribute__ ((weak, alias ("_dlsym_fake"))); 00052 */ 00053 00054 papi_vector_t _appio_vector; 00055 00056 /********************************************************************* 00057 * Private 00058 ********************************************************************/ 00059 00060 //#define APPIO_FOO 1 00061 00062 static APPIO_native_event_entry_t * _appio_native_events; 00063 00064 00065 /* If you modify the appio_stats_t below, you MUST update APPIO_MAX_COUNTERS */ 00066 static __thread long long _appio_register_current[APPIO_MAX_COUNTERS]; 00067 typedef enum { 00068 READ_BYTES = 0, 00069 READ_CALLS, 00070 READ_ERR, 00071 READ_INTERRUPTED, 00072 READ_WOULD_BLOCK, 00073 READ_SHORT, 00074 READ_EOF, 00075 READ_BLOCK_SIZE, 00076 READ_USEC, 00077 WRITE_BYTES, 00078 WRITE_CALLS, 00079 WRITE_ERR, 00080 WRITE_SHORT, 00081 WRITE_WOULD_BLOCK, 00082 WRITE_BLOCK_SIZE, 00083 WRITE_USEC, 00084 OPEN_CALLS, 00085 OPEN_ERR, 00086 OPEN_FDS, 00087 SELECT_USEC, 00088 RECV_BYTES, 00089 RECV_CALLS, 00090 RECV_ERR, 00091 RECV_INTERRUPTED, 00092 RECV_WOULD_BLOCK, 00093 RECV_SHORT, 00094 RECV_EOF, 00095 RECV_BLOCK_SIZE, 00096 RECV_USEC 00097 } _appio_stats_t ; 00098 00099 static const struct appio_counters { 00100 const char *name; 00101 const char *description; 00102 } _appio_counter_info[APPIO_MAX_COUNTERS] = { 00103 { "READ_BYTES", "Bytes read"}, 00104 { "READ_CALLS", "Number of read calls"}, 00105 { "READ_ERR", "Number of read calls that resulted in an error"}, 00106 { "READ_INTERRUPTED","Number of read calls that timed out or were interruped"}, 00107 { "READ_WOULD_BLOCK","Number of read calls that would have blocked"}, 00108 { "READ_SHORT", "Number of read calls that returned less bytes than requested"}, 00109 { "READ_EOF", "Number of read calls that returned an EOF"}, 00110 { "READ_BLOCK_SIZE", "Average block size of reads"}, 00111 { "READ_USEC", "Real microseconds spent in reads"}, 00112 { "WRITE_BYTES", "Bytes written"}, 00113 { "WRITE_CALLS", "Number of write calls"}, 00114 { "WRITE_ERR", "Number of write calls that resulted in an error"}, 00115 { "WRITE_SHORT", "Number of write calls that wrote less bytes than requested"}, 00116 { "WRITE_WOULD_BLOCK","Number of write calls that would have blocked"}, 00117 { "WRITE_BLOCK_SIZE","Mean block size of writes"}, 00118 { "WRITE_USEC", "Real microseconds spent in writes"}, 00119 { "OPEN_CALLS", "Number of open calls"}, 00120 { "OPEN_ERR", "Number of open calls that resulted in an error"}, 00121 { "OPEN_FDS", "Number of currently open descriptors"}, 00122 { "SELECT_USEC", "Real microseconds spent in select calls"}, 00123 { "RECV_BYTES", "Bytes read in recv/recvmsg/recvfrom"}, 00124 { "RECV_CALLS", "Number of recv/recvmsg/recvfrom calls"}, 00125 { "RECV_ERR", "Number of recv/recvmsg/recvfrom calls that resulted in an error"}, 00126 { "RECV_INTERRUPTED","Number of recv/recvmsg/recvfrom calls that timed out or were interruped"}, 00127 { "RECV_WOULD_BLOCK","Number of recv/recvmsg/recvfrom calls that would have blocked"}, 00128 { "RECV_SHORT", "Number of recv/recvmsg/recvfrom calls that returned less bytes than requested"}, 00129 { "RECV_EOF", "Number of recv/recvmsg/recvfrom calls that returned an EOF"}, 00130 { "RECV_BLOCK_SIZE", "Average block size of recv/recvmsg/recvfrom"}, 00131 { "RECV_USEC", "Real microseconds spent in recv/recvmsg/recvfrom"} 00132 }; 00133 00134 00135 /********************************************************************* 00136 *** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT **** 00137 ********************************************************************/ 00138 00139 int __close(int fd); 00140 int close(int fd) { 00141 int retval; 00142 SUBDBG("appio: intercepted close(%d)\n", fd); 00143 retval = __close(fd); 00144 if ((retval == 0) && (_appio_register_current[OPEN_FDS]>0)) _appio_register_current[OPEN_FDS]--; 00145 return retval; 00146 } 00147 00148 int __open(const char *pathname, int flags, mode_t mode); 00149 int open(const char *pathname, int flags, mode_t mode) { 00150 int retval; 00151 SUBDBG("appio: intercepted open(%s,%d,%d)\n", pathname, flags, mode); 00152 retval = __open(pathname,flags,mode); 00153 _appio_register_current[OPEN_CALLS]++; 00154 if (retval < 0) _appio_register_current[OPEN_ERR]++; 00155 else _appio_register_current[OPEN_FDS]++; 00156 return retval; 00157 } 00158 00159 /* we use timeval as a zero value timeout to select in read/write 00160 for polling if the operation would block */ 00161 struct timeval zerotv; /* this has to be zero, so define it here */ 00162 00163 int __select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 00164 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { 00165 int retval; 00166 SUBDBG("appio: intercepted select(%d,%p,%p,%p,%p)\n", nfds,readfds,writefds,exceptfds,timeout); 00167 long long start_ts = PAPI_get_real_usec(); 00168 retval = __select(nfds,readfds,writefds,exceptfds,timeout); 00169 long long duration = PAPI_get_real_usec() - start_ts; 00170 _appio_register_current[SELECT_USEC] += duration; 00171 return retval; 00172 } 00173 00174 extern int errno; 00175 ssize_t __read(int fd, void *buf, size_t count); 00176 ssize_t read(int fd, void *buf, size_t count) { 00177 int retval; 00178 SUBDBG("appio: intercepted read(%d,%p,%lu)\n", fd, buf, (unsigned long)count); 00179 00180 // check if read would block on descriptor 00181 fd_set readfds; 00182 FD_ZERO(&readfds); 00183 FD_SET(fd, &readfds); 00184 int ready = __select(fd+1, &readfds, NULL, NULL, &zerotv); 00185 if (ready == 0) _appio_register_current[READ_WOULD_BLOCK]++; 00186 00187 long long start_ts = PAPI_get_real_usec(); 00188 retval = __read(fd,buf, count); 00189 long long duration = PAPI_get_real_usec() - start_ts; 00190 int n = _appio_register_current[READ_CALLS]++; // read calls 00191 if (retval > 0) { 00192 _appio_register_current[READ_BLOCK_SIZE]= (n * _appio_register_current[READ_BLOCK_SIZE] + count)/(n+1); // mean size 00193 _appio_register_current[READ_BYTES] += retval; // read bytes 00194 if (retval < (int)count) _appio_register_current[READ_SHORT]++; // read short 00195 _appio_register_current[READ_USEC] += duration; 00196 } 00197 if (retval < 0) { 00198 _appio_register_current[READ_ERR]++; // read err 00199 if (EINTR == errno) 00200 _appio_register_current[READ_INTERRUPTED]++; // signal interrupted the read 00201 if ((EAGAIN == errno) || (EWOULDBLOCK == errno)) 00202 _appio_register_current[READ_WOULD_BLOCK]++; //read would block on descriptor marked as non-blocking 00203 } 00204 if (retval == 0) _appio_register_current[READ_EOF]++; // read eof 00205 return retval; 00206 } 00207 00208 size_t _IO_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 00209 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { 00210 size_t retval; 00211 SUBDBG("appio: intercepted fread(%p,%lu,%lu,%p)\n", ptr, (unsigned long) size, (unsigned long) nmemb, (void*) stream); 00212 long long start_ts = PAPI_get_real_usec(); 00213 retval = _IO_fread(ptr,size,nmemb,stream); 00214 long long duration = PAPI_get_real_usec() - start_ts; 00215 int n = _appio_register_current[READ_CALLS]++; // read calls 00216 if (retval > 0) { 00217 _appio_register_current[READ_BLOCK_SIZE]= (n * _appio_register_current[READ_BLOCK_SIZE]+ size*nmemb)/(n+1);//mean size 00218 _appio_register_current[READ_BYTES]+= retval * size; // read bytes 00219 if (retval < nmemb) _appio_register_current[READ_SHORT]++; // read short 00220 _appio_register_current[READ_USEC] += duration; 00221 } 00222 00223 /* A value of zero returned means one of two things..*/ 00224 if (retval == 0) { 00225 if (feof(stream)) _appio_register_current[READ_EOF]++; // read eof 00226 else _appio_register_current[READ_ERR]++; // read err 00227 } 00228 return retval; 00229 } 00230 00231 ssize_t __write(int fd, const void *buf, size_t count); 00232 ssize_t write(int fd, const void *buf, size_t count) { 00233 int retval; 00234 SUBDBG("appio: intercepted write(%d,%p,%lu)\n", fd, buf, (unsigned long)count); 00235 00236 // check if write would block on descriptor 00237 fd_set writefds; 00238 FD_ZERO(&writefds); 00239 FD_SET(fd, &writefds); 00240 int ready = __select(fd+1, NULL, &writefds, NULL, &zerotv); 00241 if (ready == 0) _appio_register_current[WRITE_WOULD_BLOCK]++; 00242 00243 long long start_ts = PAPI_get_real_usec(); 00244 retval = __write(fd,buf, count); 00245 long long duration = PAPI_get_real_usec() - start_ts; 00246 int n = _appio_register_current[WRITE_CALLS]++; // write calls 00247 if (retval >= 0) { 00248 _appio_register_current[WRITE_BLOCK_SIZE]= (n * _appio_register_current[WRITE_BLOCK_SIZE] + count)/(n+1); // mean size 00249 _appio_register_current[WRITE_BYTES]+= retval; // write bytes 00250 if (retval < (int)count) _appio_register_current[WRITE_SHORT]++; // short write 00251 _appio_register_current[WRITE_USEC] += duration; 00252 } 00253 if (retval < 0) _appio_register_current[WRITE_ERR]++; // err 00254 return retval; 00255 } 00256 00257 // The PIC test implies it's built for shared linkage 00258 #ifdef PIC 00259 static ssize_t (*__recv)(int sockfd, void *buf, size_t len, int flags) = NULL; 00260 ssize_t recv(int sockfd, void *buf, size_t len, int flags) { 00261 int retval; 00262 SUBDBG("appio: intercepted recv(%d,%p,%lu,%d)\n", sockfd, buf, (unsigned long)len, flags); 00263 if (!__recv) __recv = dlsym(RTLD_NEXT, "recv"); 00264 if (!__recv) { 00265 fprintf(stderr, "appio,c Internal Error: Could not obtain handle for real recv\n"); 00266 exit(1); 00267 } 00268 // check if recv would block on descriptor 00269 fd_set readfds; 00270 FD_ZERO(&readfds); 00271 FD_SET(sockfd, &readfds); 00272 int ready = __select(sockfd+1, &readfds, NULL, NULL, &zerotv); 00273 if (ready == 0) _appio_register_current[RECV_WOULD_BLOCK]++; 00274 00275 long long start_ts = PAPI_get_real_usec(); 00276 retval = __recv(sockfd, buf, len, flags); 00277 long long duration = PAPI_get_real_usec() - start_ts; 00278 int n = _appio_register_current[RECV_CALLS]++; // read calls 00279 if (retval > 0) { 00280 _appio_register_current[RECV_BLOCK_SIZE]= (n * _appio_register_current[RECV_BLOCK_SIZE] + len)/(n+1); // mean size 00281 _appio_register_current[RECV_BYTES] += retval; // read bytes 00282 if (retval < (int)len) _appio_register_current[RECV_SHORT]++; // read short 00283 _appio_register_current[RECV_USEC] += duration; 00284 } 00285 if (retval < 0) { 00286 _appio_register_current[RECV_ERR]++; // read err 00287 if (EINTR == errno) 00288 _appio_register_current[RECV_INTERRUPTED]++; // signal interrupted the read 00289 if ((EAGAIN == errno) || (EWOULDBLOCK == errno)) 00290 _appio_register_current[RECV_WOULD_BLOCK]++; //read would block on descriptor marked as non-blocking 00291 } 00292 if (retval == 0) _appio_register_current[RECV_EOF]++; // read eof 00293 return retval; 00294 } 00295 #endif /* PIC */ 00296 00297 size_t _IO_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 00298 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { 00299 size_t retval; 00300 SUBDBG("appio: intercepted fwrite(%p,%lu,%lu,%p)\n", ptr, (unsigned long) size, (unsigned long) nmemb, (void*) stream); 00301 long long start_ts = PAPI_get_real_usec(); 00302 retval = _IO_fwrite(ptr,size,nmemb,stream); 00303 long long duration = PAPI_get_real_usec() - start_ts; 00304 int n = _appio_register_current[WRITE_CALLS]++; // write calls 00305 if (retval > 0) { 00306 _appio_register_current[WRITE_BLOCK_SIZE]= (n * _appio_register_current[WRITE_BLOCK_SIZE] + size*nmemb)/(n+1); // mean block size 00307 _appio_register_current[WRITE_BYTES]+= retval * size; // write bytes 00308 if (retval < nmemb) _appio_register_current[WRITE_SHORT]++; // short write 00309 _appio_register_current[WRITE_USEC] += duration; 00310 } 00311 if (retval == 0) _appio_register_current[WRITE_ERR]++; // err 00312 return retval; 00313 } 00314 00315 00316 /********************************************************************* 00317 *************** BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS ********* 00318 *********************************************************************/ 00319 00320 /* 00321 * This is called whenever a thread is initialized 00322 */ 00323 int 00324 _appio_init_thread( hwd_context_t *ctx ) 00325 { 00326 ( void ) ctx; 00327 SUBDBG("_appio_init_thread %p\n", ctx); 00328 return PAPI_OK; 00329 } 00330 00331 00332 /* Initialize hardware counters, setup the function vector table 00333 * and get hardware information, this routine is called when the 00334 * PAPI process is initialized (IE PAPI_library_init) 00335 */ 00336 int 00337 _appio_init_component( int cidx ) 00338 { 00339 00340 SUBDBG("_appio_component %d\n", cidx); 00341 _appio_native_events = (APPIO_native_event_entry_t *) papi_calloc(sizeof(APPIO_native_event_entry_t), APPIO_MAX_COUNTERS); 00342 00343 if (_appio_native_events == NULL ) { 00344 PAPIERROR( "malloc():Could not get memory for events table" ); 00345 return PAPI_ENOMEM; 00346 } 00347 int i; 00348 for (i=0; i<APPIO_MAX_COUNTERS; i++) { 00349 _appio_native_events[i].name = _appio_counter_info[i].name; 00350 _appio_native_events[i].description = _appio_counter_info[i].description; 00351 _appio_native_events[i].resources.selector = i + 1; 00352 } 00353 00354 /* Export the total number of events available */ 00355 _appio_vector.cmp_info.num_native_events = APPIO_MAX_COUNTERS;; 00356 00357 /* Export the component id */ 00358 _appio_vector.cmp_info.CmpIdx = cidx; 00359 00360 return PAPI_OK; 00361 } 00362 00363 00364 /* 00365 * Control of counters (Reading/Writing/Starting/Stopping/Setup) 00366 * functions 00367 */ 00368 int 00369 _appio_init_control_state( hwd_control_state_t *ctl ) 00370 { 00371 ( void ) ctl; 00372 00373 return PAPI_OK; 00374 } 00375 00376 00377 int 00378 _appio_start( hwd_context_t *ctx, hwd_control_state_t *ctl ) 00379 { 00380 ( void ) ctx; 00381 00382 SUBDBG("_appio_start %p %p\n", ctx, ctl); 00383 APPIO_control_state_t *appio_ctl = (APPIO_control_state_t *) ctl; 00384 00385 /* this memset needs to move to thread_init */ 00386 memset(_appio_register_current, 0, APPIO_MAX_COUNTERS * sizeof(_appio_register_current[0])); 00387 00388 /* set initial values to 0 */ 00389 memset(appio_ctl->values, 0, APPIO_MAX_COUNTERS*sizeof(appio_ctl->values[0])); 00390 00391 return PAPI_OK; 00392 } 00393 00394 00395 int 00396 _appio_read( hwd_context_t *ctx, hwd_control_state_t *ctl, 00397 long long ** events, int flags ) 00398 { 00399 (void) flags; 00400 (void) ctx; 00401 00402 SUBDBG("_appio_read %p %p\n", ctx, ctl); 00403 APPIO_control_state_t *appio_ctl = (APPIO_control_state_t *) ctl; 00404 int i; 00405 00406 for ( i=0; i<appio_ctl->num_events; i++ ) { 00407 int index = appio_ctl->counter_bits[i]; 00408 SUBDBG("event=%d, index=%d, val=%lld\n", i, index, _appio_register_current[index]); 00409 appio_ctl->values[index] = _appio_register_current[index]; 00410 } 00411 *events = appio_ctl->values; 00412 00413 return PAPI_OK; 00414 } 00415 00416 00417 int 00418 _appio_stop( hwd_context_t *ctx, hwd_control_state_t *ctl ) 00419 { 00420 (void) ctx; 00421 00422 SUBDBG("_appio_stop ctx=%p ctl=%p\n", ctx, ctl); 00423 APPIO_control_state_t *appio_ctl = (APPIO_control_state_t *) ctl; 00424 int i; 00425 for ( i=0; i<appio_ctl->num_events; i++ ) { 00426 int index = appio_ctl->counter_bits[i]; 00427 SUBDBG("event=%d, index=%d, val=%lld\n", i, index, _appio_register_current[index]); 00428 appio_ctl->values[i] = _appio_register_current[index]; 00429 } 00430 00431 return PAPI_OK; 00432 } 00433 00434 00435 /* 00436 * Thread shutdown 00437 */ 00438 int 00439 _appio_shutdown_thread( hwd_context_t *ctx ) 00440 { 00441 ( void ) ctx; 00442 00443 return PAPI_OK; 00444 } 00445 00446 00447 /* 00448 * Clean up what was setup in appio_init_component(). 00449 */ 00450 int 00451 _appio_shutdown_component( void ) 00452 { 00453 return PAPI_OK; 00454 } 00455 00456 00457 /* This function sets various options in the component 00458 * The valid codes being passed in are PAPI_SET_DEFDOM, 00459 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL and 00460 * PAPI_SET_INHERIT 00461 */ 00462 int 00463 _appio_ctl( hwd_context_t *ctx, int code, _papi_int_option_t *option ) 00464 { 00465 ( void ) ctx; 00466 ( void ) code; 00467 ( void ) option; 00468 00469 return PAPI_OK; 00470 } 00471 00472 00473 int 00474 _appio_update_control_state( hwd_control_state_t *ctl, 00475 NativeInfo_t *native, int count, hwd_context_t *ctx ) 00476 { 00477 ( void ) ctx; 00478 ( void ) ctl; 00479 00480 SUBDBG("_appio_update_control_state ctx=%p ctl=%p num_events=%d\n", ctx, ctl, count); 00481 int i, index; 00482 APPIO_control_state_t *appio_ctl = (APPIO_control_state_t *) ctl; 00483 (void) ctx; 00484 00485 for ( i = 0; i < count; i++ ) { 00486 index = native[i].ni_event; 00487 appio_ctl->counter_bits[i] = index; 00488 native[i].ni_position = index; 00489 } 00490 appio_ctl->num_events = count; 00491 00492 return PAPI_OK; 00493 } 00494 00495 00496 /* 00497 * This function has to set the bits needed to count different domains 00498 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER 00499 * By default return PAPI_EINVAL if none of those are specified 00500 * and PAPI_OK with success 00501 * PAPI_DOM_USER is only user context is counted 00502 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted 00503 * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses) 00504 * PAPI_DOM_ALL is all of the domains 00505 */ 00506 int 00507 _appio_set_domain( hwd_control_state_t *ctl, int domain ) 00508 { 00509 ( void ) ctl; 00510 00511 int found = 0; 00512 00513 if ( PAPI_DOM_USER & domain ) found = 1; 00514 if ( PAPI_DOM_KERNEL & domain ) found = 1; 00515 if ( PAPI_DOM_OTHER & domain ) found = 1; 00516 00517 if ( !found ) 00518 return PAPI_EINVAL; 00519 00520 return PAPI_OK; 00521 } 00522 00523 00524 int 00525 _appio_reset( hwd_context_t *ctx, hwd_control_state_t *ctl ) 00526 { 00527 ( void ) ctx; 00528 ( void ) ctl; 00529 00530 return PAPI_OK; 00531 } 00532 00533 00534 /* 00535 * Native Event functions 00536 */ 00537 int 00538 _appio_ntv_enum_events( unsigned int *EventCode, int modifier ) 00539 { 00540 int index; 00541 00542 switch ( modifier ) { 00543 case PAPI_ENUM_FIRST: 00544 *EventCode = 0; 00545 return PAPI_OK; 00546 break; 00547 00548 case PAPI_ENUM_EVENTS: 00549 index = *EventCode; 00550 if ( index < APPIO_MAX_COUNTERS - 1 ) { 00551 *EventCode = *EventCode + 1; 00552 return PAPI_OK; 00553 } else { 00554 return PAPI_ENOEVNT; 00555 } 00556 break; 00557 00558 default: 00559 return PAPI_EINVAL; 00560 break; 00561 } 00562 return PAPI_EINVAL; 00563 } 00564 00565 00566 /* 00567 * 00568 */ 00569 int 00570 _appio_ntv_name_to_code( char *name, unsigned int *EventCode ) 00571 { 00572 int i; 00573 00574 for ( i=0; i<APPIO_MAX_COUNTERS; i++) { 00575 if (strcmp(name, _appio_counter_info[i].name) == 0) { 00576 *EventCode = i; 00577 return PAPI_OK; 00578 } 00579 } 00580 00581 return PAPI_ENOEVNT; 00582 } 00583 00584 00585 /* 00586 * 00587 */ 00588 int 00589 _appio_ntv_code_to_name( unsigned int EventCode, char *name, int len ) 00590 { 00591 int index = EventCode; 00592 00593 if ( index >= 0 && index < APPIO_MAX_COUNTERS ) { 00594 strncpy( name, _appio_counter_info[index].name, len ); 00595 return PAPI_OK; 00596 } 00597 00598 return PAPI_ENOEVNT; 00599 } 00600 00601 00602 /* 00603 * 00604 */ 00605 int 00606 _appio_ntv_code_to_descr( unsigned int EventCode, char *desc, int len ) 00607 { 00608 int index = EventCode; 00609 00610 if ( index >= 0 && index < APPIO_MAX_COUNTERS ) { 00611 strncpy(desc, _appio_counter_info[index].description, len ); 00612 return PAPI_OK; 00613 } 00614 00615 return PAPI_ENOEVNT; 00616 } 00617 00618 00619 /* 00620 * 00621 */ 00622 int 00623 _appio_ntv_code_to_bits( unsigned int EventCode, hwd_register_t *bits ) 00624 { 00625 int index = EventCode; 00626 00627 if ( index >= 0 && index < APPIO_MAX_COUNTERS ) { 00628 memcpy( ( APPIO_register_t * ) bits, 00629 &( _appio_native_events[index].resources ), 00630 sizeof ( APPIO_register_t ) ); 00631 return PAPI_OK; 00632 } 00633 00634 return PAPI_ENOEVNT; 00635 } 00636 00637 00638 /* 00639 * 00640 */ 00641 papi_vector_t _appio_vector = { 00642 .cmp_info = { 00643 /* default component information (unspecified values are initialized to 0) */ 00644 .name = "appio", 00645 .short_name = "appio", 00646 .version = "1.1.2.4", 00647 .CmpIdx = 0, /* set by init_component */ 00648 .num_mpx_cntrs = APPIO_MAX_COUNTERS, 00649 .num_cntrs = APPIO_MAX_COUNTERS, 00650 .default_domain = PAPI_DOM_USER, 00651 //.available_domains = PAPI_DOM_USER, 00652 .default_granularity = PAPI_GRN_THR, 00653 .available_granularities = PAPI_GRN_THR, 00654 .hardware_intr_sig = PAPI_INT_SIGNAL, 00655 00656 /* component specific cmp_info initializations */ 00657 .fast_real_timer = 0, 00658 .fast_virtual_timer = 0, 00659 .attach = 0, 00660 .attach_must_ptrace = 0, 00661 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL, 00662 }, 00663 00664 /* sizes of framework-opaque component-private structures */ 00665 .size = { 00666 .context = sizeof ( APPIO_context_t ), 00667 .control_state = sizeof ( APPIO_control_state_t ), 00668 .reg_value = sizeof ( APPIO_register_t ), 00669 .reg_alloc = sizeof ( APPIO_reg_alloc_t ), 00670 }, 00671 00672 /* function pointers in this component */ 00673 .init_thread = _appio_init_thread, 00674 .init_component = _appio_init_component, 00675 .init_control_state = _appio_init_control_state, 00676 .start = _appio_start, 00677 .stop = _appio_stop, 00678 .read = _appio_read, 00679 .shutdown_thread = _appio_shutdown_thread, 00680 .shutdown_component = _appio_shutdown_component, 00681 .ctl = _appio_ctl, 00682 00683 .update_control_state = _appio_update_control_state, 00684 .set_domain = _appio_set_domain, 00685 .reset = _appio_reset, 00686 00687 .ntv_enum_events = _appio_ntv_enum_events, 00688 .ntv_name_to_code = _appio_ntv_name_to_code, 00689 .ntv_code_to_name = _appio_ntv_code_to_name, 00690 .ntv_code_to_descr = _appio_ntv_code_to_descr, 00691 .ntv_code_to_bits = _appio_ntv_code_to_bits 00692 /* .ntv_bits_to_info = NULL, */ 00693 }; 00694 00695 /* vim:set ts=4 sw=4 sts=4 et: */