example.c File Reference

This is an example component, it demos the component interface and implements three example counters. More...

Include dependency graph for example.c:

Go to the source code of this file.

Data Structures

struct  example_register_t
struct  example_native_event_entry_t
struct  example_reg_alloc_t
struct  example_control_state_t
struct  example_context_t

Defines

#define EXAMPLE_MAX_SIMULTANEOUS_COUNTERS   3
#define EXAMPLE_MAX_MULTIPLEX_COUNTERS   4
#define EXAMPLE_ZERO_REG   0
#define EXAMPLE_CONSTANT_REG   1
#define EXAMPLE_AUTOINC_REG   2
#define EXAMPLE_GLOBAL_AUTOINC_REG   3
#define EXAMPLE_TOTAL_EVENTS   4

Functions

static void example_hardware_reset (example_context_t *ctx)
static long long example_hardware_read (int which_one, example_context_t *ctx)
static int example_hardware_write (int which_one, example_context_t *ctx, long long value)
static int detect_example (void)
int _example_init_component (int cidx)
int _example_init_thread (hwd_context_t *ctx)
int _example_init_control_state (hwd_control_state_t *ctl)
int _example_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
int _example_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _example_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _example_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
int _example_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *events)
int _example_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _example_shutdown_component (void)
int _example_shutdown_thread (hwd_context_t *ctx)
int _example_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int _example_set_domain (hwd_control_state_t *cntrl, int domain)
int _example_ntv_enum_events (unsigned int *EventCode, int modifier)
int _example_ntv_code_to_name (unsigned int EventCode, char *name, int len)
int _example_ntv_code_to_descr (unsigned int EventCode, char *descr, int len)

Variables

papi_vector_t _example_vector
static
example_native_event_entry_t
example_native_table
static int num_events = 0
static long long example_global_autoinc_value = 0

Detailed Description

Author:
Joachim Protze joachim.protze@zih.tu-dresden.de
Vince Weaver vweaver1@eecs.utk.edu

Definition in file example.c.


Define Documentation

#define EXAMPLE_AUTOINC_REG   2

Definition at line 99 of file example.c.

#define EXAMPLE_CONSTANT_REG   1

Definition at line 98 of file example.c.

#define EXAMPLE_GLOBAL_AUTOINC_REG   3

Definition at line 100 of file example.c.

#define EXAMPLE_MAX_MULTIPLEX_COUNTERS   4

Definition at line 29 of file example.c.

#define EXAMPLE_MAX_SIMULTANEOUS_COUNTERS   3

This driver supports three counters counting at once

Definition at line 28 of file example.c.

#define EXAMPLE_TOTAL_EVENTS   4

Definition at line 102 of file example.c.

#define EXAMPLE_ZERO_REG   0

Definition at line 97 of file example.c.


Function Documentation

int _example_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)

This function sets various options in the component

Parameters:
[in] ctx -- hardware context
[in] code valid are PAPI_SET_DEFDOM, PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL and PAPI_SET_INHERIT
[in] option -- options to be set

Definition at line 461 of file example.c.

00462 {
00463 
00464         (void) ctx;
00465     (void) code;
00466     (void) option;
00467 
00468     SUBDBG( "example_ctl..." );
00469 
00470     return PAPI_OK;
00471 }

int _example_init_component ( int  cidx  ) 

Initialize hardware counters, setup the function vector table and get hardware information, this routine is called when the PAPI process is initialized (IE PAPI_library_init)

Definition at line 187 of file example.c.

00188 {
00189 
00190     SUBDBG( "_example_init_component..." );
00191 
00192    
00193         /* First, detect that our hardware is available */
00194         if (detect_example()!=PAPI_OK) {
00195        return PAPI_ECMP;
00196     }
00197    
00198     /* we know in advance how many events we want                       */
00199     /* for actual hardware this might have to be determined dynamically */
00200     num_events = EXAMPLE_TOTAL_EVENTS;
00201 
00202     /* Allocate memory for the our native event table */
00203     example_native_table =
00204         ( example_native_event_entry_t * )
00205         papi_calloc( sizeof(example_native_event_entry_t),num_events);
00206     if ( example_native_table == NULL ) {
00207         PAPIERROR( "malloc():Could not get memory for events table" );
00208         return PAPI_ENOMEM;
00209     }
00210 
00211     /* fill in the event table parameters */
00212     /* for complicated components this will be done dynamically */
00213     /* or by using an external library                          */
00214 
00215     strcpy( example_native_table[0].name, "EXAMPLE_ZERO" );
00216     strcpy( example_native_table[0].description,
00217             "This is an example counter, that always returns 0" );
00218     example_native_table[0].writable = 0;
00219 
00220     strcpy( example_native_table[1].name, "EXAMPLE_CONSTANT" );
00221     strcpy( example_native_table[1].description,
00222             "This is an example counter, that always returns a constant value of 42" );
00223     example_native_table[1].writable = 0;
00224 
00225     strcpy( example_native_table[2].name, "EXAMPLE_AUTOINC" );
00226     strcpy( example_native_table[2].description,
00227             "This is an example counter, that reports a per-thread  auto-incrementing value" );
00228     example_native_table[2].writable = 1;
00229 
00230     strcpy( example_native_table[3].name, "EXAMPLE_GLOBAL_AUTOINC" );
00231     strcpy( example_native_table[3].description,
00232             "This is an example counter, that reports a global auto-incrementing value" );
00233     example_native_table[3].writable = 1;
00234 
00235     /* Export the total number of events available */
00236     _example_vector.cmp_info.num_native_events = num_events;
00237 
00238     /* Export the component id */
00239     _example_vector.cmp_info.CmpIdx = cidx;
00240 
00241     
00242 
00243     return PAPI_OK;
00244 }

Here is the call graph for this function:

int _example_init_control_state ( hwd_control_state_t ctl  ) 

Setup a counter control state. In general a control state holds the hardware info for an EventSet.

Definition at line 268 of file example.c.

00269 {
00270    SUBDBG( "example_init_control_state... %p\n", ctl );
00271 
00272    example_control_state_t *example_ctl = ( example_control_state_t * ) ctl;
00273    memset( example_ctl, 0, sizeof ( example_control_state_t ) );
00274 
00275    return PAPI_OK;
00276 }

int _example_init_thread ( hwd_context_t ctx  ) 

This is called whenever a thread is initialized

Definition at line 248 of file example.c.

00249 {
00250 
00251         example_context_t *example_context = (example_context_t *)ctx;
00252 
00253         example_context->autoinc_value=0;
00254    
00255     SUBDBG( "_example_init_thread %p...", ctx );
00256 
00257     return PAPI_OK;
00258 }

int _example_ntv_code_to_descr ( unsigned int  EventCode,
char *  descr,
int  len 
)

Takes a native event code and passes back the event description

Parameters:
EventCode is the native event code
descr is a pointer for the description to be copied to
len is the size of the descr string

Definition at line 588 of file example.c.

00589 {
00590   int index;
00591   index = EventCode;
00592 
00593   /* make sure event is in range */
00594   if (index >= 0 && index < num_events) {
00595      strncpy( descr, example_native_table[index].description, len );
00596      return PAPI_OK;
00597   }
00598   
00599   return PAPI_ENOEVNT;
00600 }

int _example_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

Takes a native event code and passes back the name

Parameters:
EventCode is the native event code
name is a pointer for the name to be copied to
len is the size of the name string

Definition at line 567 of file example.c.

00568 {
00569   int index;
00570 
00571   index = EventCode;
00572 
00573   /* Make sure we are in range */
00574   if (index >= 0 && index < num_events) {
00575      strncpy( name, example_native_table[index].name, len );  
00576      return PAPI_OK;
00577   }
00578    
00579   return PAPI_ENOEVNT;
00580 }

int _example_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Enumerate Native Events

Parameters:
EventCode is the event of interest
modifier is one of PAPI_ENUM_FIRST, PAPI_ENUM_EVENTS If your component has attribute masks then these need to be handled here as well.

Definition at line 525 of file example.c.

00526 {
00527   int index;
00528 
00529 
00530   switch ( modifier ) {
00531 
00532         /* return EventCode of first event */
00533     case PAPI_ENUM_FIRST:
00534        /* return the first event that we support */
00535 
00536        *EventCode = 0;
00537        return PAPI_OK;
00538 
00539         /* return EventCode of next available event */
00540     case PAPI_ENUM_EVENTS:
00541        index = *EventCode;
00542 
00543        /* Make sure we have at least 1 more event after us */
00544        if ( index < num_events - 1 ) {
00545 
00546           /* This assumes a non-sparse mapping of the events */
00547           *EventCode = *EventCode + 1;
00548           return PAPI_OK;
00549        } else {
00550           return PAPI_ENOEVNT;
00551        }
00552        break;
00553     
00554     default:
00555        return PAPI_EINVAL;
00556   }
00557 
00558   return PAPI_EINVAL;
00559 }

int _example_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)

Triggered by PAPI_read()

Definition at line 356 of file example.c.

00358 {
00359 
00360    (void) flags;
00361 
00362    example_context_t *example_ctx = (example_context_t *) ctx;
00363    example_control_state_t *example_ctl = ( example_control_state_t *) ctl;   
00364 
00365    SUBDBG( "example_read... %p %d", ctx, flags );
00366 
00367    int i;
00368 
00369    /* Read counters into expected slot */
00370    for(i=0;i<example_ctl->num_events;i++) {
00371       example_ctl->counter[i] =
00372         example_hardware_read( example_ctl->which_counter[i], 
00373                        example_ctx );
00374    }
00375 
00376    /* return pointer to the values we read */
00377    *events = example_ctl->counter;
00378 
00379    return PAPI_OK;
00380 }

Here is the call graph for this function:

int _example_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Triggered by PAPI_reset() but only if the EventSet is currently running

Definition at line 411 of file example.c.

00412 {
00413         example_context_t *event_ctx = (example_context_t *)ctx;
00414     (void) ctl;
00415 
00416     SUBDBG( "example_reset ctx=%p ctrl=%p...", ctx, ctl );
00417 
00418     /* Reset the hardware */
00419     example_hardware_reset( event_ctx );
00420 
00421     return PAPI_OK;
00422 }

Here is the call graph for this function:

int _example_set_domain ( hwd_control_state_t cntrl,
int  domain 
)

This function has to set the bits needed to count different domains In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER By default return PAPI_EINVAL if none of those are specified and PAPI_OK with success PAPI_DOM_USER is only user context is counted PAPI_DOM_KERNEL is only the Kernel/OS context is counted PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses) PAPI_DOM_ALL is all of the domains

Definition at line 483 of file example.c.

00484 {
00485         (void) cntrl;
00486 
00487     int found = 0;
00488     SUBDBG( "example_set_domain..." );
00489 
00490     if ( PAPI_DOM_USER & domain ) {
00491         SUBDBG( " PAPI_DOM_USER " );
00492         found = 1;
00493     }
00494     if ( PAPI_DOM_KERNEL & domain ) {
00495         SUBDBG( " PAPI_DOM_KERNEL " );
00496         found = 1;
00497     }
00498     if ( PAPI_DOM_OTHER & domain ) {
00499         SUBDBG( " PAPI_DOM_OTHER " );
00500         found = 1;
00501     }
00502     if ( PAPI_DOM_ALL & domain ) {
00503         SUBDBG( " PAPI_DOM_ALL " );
00504         found = 1;
00505     }
00506     if ( !found )
00507         return ( PAPI_EINVAL );
00508 
00509     return PAPI_OK;
00510 }

int _example_shutdown_component ( void   ) 

Triggered by PAPI_shutdown()

Definition at line 426 of file example.c.

00427 {
00428 
00429     SUBDBG( "example_shutdown_component..." );
00430 
00431         /* Free anything we allocated */
00432    
00433     papi_free(example_native_table);
00434 
00435     return PAPI_OK;
00436 }

int _example_shutdown_thread ( hwd_context_t ctx  ) 

Called at thread shutdown

Definition at line 440 of file example.c.

00441 {
00442 
00443         (void) ctx;
00444 
00445     SUBDBG( "example_shutdown_thread... %p", ctx );
00446 
00447     /* Last chance to clean up thread */
00448 
00449     return PAPI_OK;
00450 }

int _example_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Triggered by PAPI_start()

Definition at line 315 of file example.c.

00316 {
00317 
00318         (void) ctx;
00319         (void) ctl;
00320 
00321     SUBDBG( "example_start %p %p...", ctx, ctl );
00322 
00323     /* anything that would need to be set at counter start time */
00324 
00325     /* reset counters? */
00326         /* For hardware that cannot reset counters, store initial        */
00327         /*     counter state to the ctl and subtract it off at read time */
00328      
00329     /* start the counting ?*/
00330 
00331     return PAPI_OK;
00332 }

int _example_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Triggered by PAPI_stop()

Definition at line 337 of file example.c.

00338 {
00339 
00340         (void) ctx;
00341         (void) ctl;
00342 
00343     SUBDBG( "example_stop %p %p...", ctx, ctl );
00344 
00345     /* anything that would need to be done at counter stop time */
00346 
00347     
00348 
00349     return PAPI_OK;
00350 }

int _example_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)

Triggered by eventset operations like add or remove

Definition at line 281 of file example.c.

00285 {
00286    
00287    (void) ctx;
00288    int i, index;
00289 
00290    example_control_state_t *example_ctl = ( example_control_state_t * ) ctl;   
00291 
00292    SUBDBG( "_example_update_control_state %p %p...", ctl, ctx );
00293 
00294    /* if no events, return */
00295    if (count==0) return PAPI_OK;
00296 
00297    for( i = 0; i < count; i++ ) {
00298       index = native[i].ni_event;
00299       
00300       /* Map counter #i to Measure Event "index" */
00301       example_ctl->which_counter[i]=index;
00302 
00303       /* We have no constraints on event position, so any event */
00304       /* can be in any slot.                                    */
00305       native[i].ni_position = i;
00306    }
00307 
00308    example_ctl->num_events=count;
00309 
00310    return PAPI_OK;
00311 }

int _example_write ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long *  events 
)

Triggered by PAPI_write(), but only if the counters are running

Definition at line 385 of file example.c.

00387 {
00388 
00389         example_context_t *example_ctx = (example_context_t *) ctx;
00390         example_control_state_t *example_ctl = ( example_control_state_t *) ctl;   
00391    
00392         int i;
00393    
00394     SUBDBG( "example_write... %p %p", ctx, ctl );
00395 
00396         /* Write counters into expected slot */
00397         for(i=0;i<example_ctl->num_events;i++) {
00398        example_hardware_write( example_ctl->which_counter[i],
00399                    example_ctx,
00400                    events[i] );
00401     }
00402    
00403     return PAPI_OK;
00404 }

Here is the call graph for this function:

static int detect_example ( void   )  [static]

Definition at line 172 of file example.c.

00172                      {
00173  
00174    return PAPI_OK;
00175 }

Here is the caller graph for this function:

static long long example_hardware_read ( int  which_one,
example_context_t ctx 
) [static]

Code that reads event values.

Definition at line 121 of file example.c.

00122 {
00123     long long old_value;
00124 
00125     switch ( which_one ) {
00126     case EXAMPLE_ZERO_REG:
00127         return 0;
00128     case EXAMPLE_CONSTANT_REG:
00129         return 42;
00130     case EXAMPLE_AUTOINC_REG:
00131         old_value = ctx->autoinc_value;
00132         ctx->autoinc_value++;
00133         return old_value;
00134     case EXAMPLE_GLOBAL_AUTOINC_REG:
00135         old_value = example_global_autoinc_value;
00136         example_global_autoinc_value++;
00137         return old_value;
00138     default:
00139             fprintf(stderr,"Invalid counter read %#x\n",which_one );
00140         return -1;
00141     }
00142 
00143     return 0;
00144 }

Here is the caller graph for this function:

static void example_hardware_reset ( example_context_t ctx  )  [static]

Code that resets the hardware.

Definition at line 108 of file example.c.

00109 {
00110    /* reset per-thread count */
00111    ctx->autoinc_value=0;
00112    /* reset global count */
00113    example_global_autoinc_value = 0;
00114 
00115 }

Here is the caller graph for this function:

static int example_hardware_write ( int  which_one,
example_context_t ctx,
long long  value 
) [static]

Code that writes event values.

Definition at line 148 of file example.c.

00151 {
00152 
00153     switch ( which_one ) {
00154     case EXAMPLE_ZERO_REG:
00155     case EXAMPLE_CONSTANT_REG:
00156         return PAPI_OK; /* can't be written */
00157     case EXAMPLE_AUTOINC_REG:
00158         ctx->autoinc_value=value;
00159         return PAPI_OK;
00160     case EXAMPLE_GLOBAL_AUTOINC_REG:
00161             example_global_autoinc_value=value;
00162         return PAPI_OK;
00163     default:
00164         perror( "Invalid counter write" );
00165         return -1;
00166     }
00167 
00168     return 0;
00169 }

Here is the caller graph for this function:


Variable Documentation

Vector that points to entry points for our component

Definition at line 33 of file example.c.

long long example_global_autoinc_value = 0 [static]

Definition at line 104 of file example.c.

This table contains the native events

Definition at line 87 of file example.c.

int num_events = 0 [static]

number of events in the table

Definition at line 90 of file example.c.


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1