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