PAPI  5.0.1.0
appio.c
Go to the documentation of this file.
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: */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines