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

Definition at line 100 of file example.c.

Definition at line 29 of file example.c.

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]codevalid 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.

{

        (void) ctx;
    (void) code;
    (void) option;

    SUBDBG( "example_ctl..." );

    return PAPI_OK;
}
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.

{

    SUBDBG( "_example_init_component..." );

   
        /* First, detect that our hardware is available */
        if (detect_example()!=PAPI_OK) {
       return PAPI_ECMP;
    }
   
    /* we know in advance how many events we want                       */
    /* for actual hardware this might have to be determined dynamically */
    num_events = EXAMPLE_TOTAL_EVENTS;

    /* Allocate memory for the our native event table */
    example_native_table =
        ( example_native_event_entry_t * )
        papi_calloc( sizeof(example_native_event_entry_t),num_events);
    if ( example_native_table == NULL ) {
        PAPIERROR( "malloc():Could not get memory for events table" );
        return PAPI_ENOMEM;
    }

    /* fill in the event table parameters */
    /* for complicated components this will be done dynamically */
    /* or by using an external library                          */

    strcpy( example_native_table[0].name, "EXAMPLE_ZERO" );
    strcpy( example_native_table[0].description,
            "This is an example counter, that always returns 0" );
    example_native_table[0].writable = 0;

    strcpy( example_native_table[1].name, "EXAMPLE_CONSTANT" );
    strcpy( example_native_table[1].description,
            "This is an example counter, that always returns a constant value of 42" );
    example_native_table[1].writable = 0;

    strcpy( example_native_table[2].name, "EXAMPLE_AUTOINC" );
    strcpy( example_native_table[2].description,
            "This is an example counter, that reports a per-thread  auto-incrementing value" );
    example_native_table[2].writable = 1;

    strcpy( example_native_table[3].name, "EXAMPLE_GLOBAL_AUTOINC" );
    strcpy( example_native_table[3].description,
            "This is an example counter, that reports a global auto-incrementing value" );
    example_native_table[3].writable = 1;

    /* Export the total number of events available */
    _example_vector.cmp_info.num_native_events = num_events;

    /* Export the component id */
    _example_vector.cmp_info.CmpIdx = cidx;

    

    return PAPI_OK;
}

Here is the call graph for this function:

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.

{
   SUBDBG( "example_init_control_state... %p\n", ctl );

   example_control_state_t *example_ctl = ( example_control_state_t * ) ctl;
   memset( example_ctl, 0, sizeof ( example_control_state_t ) );

   return PAPI_OK;
}

This is called whenever a thread is initialized

Definition at line 248 of file example.c.

{

        example_context_t *example_context = (example_context_t *)ctx;

        example_context->autoinc_value=0;
   
    SUBDBG( "_example_init_thread %p...", ctx );

    return PAPI_OK;
}
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:
EventCodeis the native event code
descris a pointer for the description to be copied to
lenis the size of the descr string

Definition at line 588 of file example.c.

{
  int index;
  index = EventCode;

  /* make sure event is in range */
  if (index >= 0 && index < num_events) {
     strncpy( descr, example_native_table[index].description, len );
     return PAPI_OK;
  }
  
  return PAPI_ENOEVNT;
}
int _example_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

Takes a native event code and passes back the name

Parameters:
EventCodeis the native event code
nameis a pointer for the name to be copied to
lenis the size of the name string

Definition at line 567 of file example.c.

{
  int index;

  index = EventCode;

  /* Make sure we are in range */
  if (index >= 0 && index < num_events) {
     strncpy( name, example_native_table[index].name, len );  
     return PAPI_OK;
  }
   
  return PAPI_ENOEVNT;
}
int _example_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Enumerate Native Events

Parameters:
EventCodeis the event of interest
modifieris 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.

{
  int index;


  switch ( modifier ) {

        /* return EventCode of first event */
    case PAPI_ENUM_FIRST:
       /* return the first event that we support */

       *EventCode = 0;
       return PAPI_OK;

        /* return EventCode of next available event */
    case PAPI_ENUM_EVENTS:
       index = *EventCode;

       /* Make sure we have at least 1 more event after us */
       if ( index < num_events - 1 ) {

          /* This assumes a non-sparse mapping of the events */
          *EventCode = *EventCode + 1;
          return PAPI_OK;
       } else {
          return PAPI_ENOEVNT;
       }
       break;
    
    default:
       return PAPI_EINVAL;
  }

  return PAPI_EINVAL;
}
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.

{

   (void) flags;

   example_context_t *example_ctx = (example_context_t *) ctx;
   example_control_state_t *example_ctl = ( example_control_state_t *) ctl;   

   SUBDBG( "example_read... %p %d", ctx, flags );

   int i;

   /* Read counters into expected slot */
   for(i=0;i<example_ctl->num_events;i++) {
      example_ctl->counter[i] =
        example_hardware_read( example_ctl->which_counter[i], 
                       example_ctx );
   }

   /* return pointer to the values we read */
   *events = example_ctl->counter;

   return PAPI_OK;
}

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.

{
        example_context_t *event_ctx = (example_context_t *)ctx;
    (void) ctl;

    SUBDBG( "example_reset ctx=%p ctrl=%p...", ctx, ctl );

    /* Reset the hardware */
    example_hardware_reset( event_ctx );

    return PAPI_OK;
}

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.

{
        (void) cntrl;

    int found = 0;
    SUBDBG( "example_set_domain..." );

    if ( PAPI_DOM_USER & domain ) {
        SUBDBG( " PAPI_DOM_USER " );
        found = 1;
    }
    if ( PAPI_DOM_KERNEL & domain ) {
        SUBDBG( " PAPI_DOM_KERNEL " );
        found = 1;
    }
    if ( PAPI_DOM_OTHER & domain ) {
        SUBDBG( " PAPI_DOM_OTHER " );
        found = 1;
    }
    if ( PAPI_DOM_ALL & domain ) {
        SUBDBG( " PAPI_DOM_ALL " );
        found = 1;
    }
    if ( !found )
        return ( PAPI_EINVAL );

    return PAPI_OK;
}

Triggered by PAPI_shutdown()

Definition at line 426 of file example.c.

{

    SUBDBG( "example_shutdown_component..." );

        /* Free anything we allocated */
   
    papi_free(example_native_table);

    return PAPI_OK;
}

Called at thread shutdown

Definition at line 440 of file example.c.

{

        (void) ctx;

    SUBDBG( "example_shutdown_thread... %p", ctx );

    /* Last chance to clean up thread */

    return PAPI_OK;
}
int _example_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Triggered by PAPI_start()

Definition at line 315 of file example.c.

{

        (void) ctx;
        (void) ctl;

    SUBDBG( "example_start %p %p...", ctx, ctl );

    /* anything that would need to be set at counter start time */

    /* reset counters? */
        /* For hardware that cannot reset counters, store initial        */
        /*     counter state to the ctl and subtract it off at read time */
     
    /* start the counting ?*/

    return PAPI_OK;
}
int _example_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Triggered by PAPI_stop()

Definition at line 337 of file example.c.

{

        (void) ctx;
        (void) ctl;

    SUBDBG( "example_stop %p %p...", ctx, ctl );

    /* anything that would need to be done at counter stop time */

    

    return PAPI_OK;
}
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.

{
   
   (void) ctx;
   int i, index;

   example_control_state_t *example_ctl = ( example_control_state_t * ) ctl;   

   SUBDBG( "_example_update_control_state %p %p...", ctl, ctx );

   /* if no events, return */
   if (count==0) return PAPI_OK;

   for( i = 0; i < count; i++ ) {
      index = native[i].ni_event;
      
      /* Map counter #i to Measure Event "index" */
      example_ctl->which_counter[i]=index;

      /* We have no constraints on event position, so any event */
      /* can be in any slot.                                    */
      native[i].ni_position = i;
   }

   example_ctl->num_events=count;

   return PAPI_OK;
}
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.

{

        example_context_t *example_ctx = (example_context_t *) ctx;
        example_control_state_t *example_ctl = ( example_control_state_t *) ctl;   
   
        int i;
   
    SUBDBG( "example_write... %p %p", ctx, ctl );

        /* Write counters into expected slot */
        for(i=0;i<example_ctl->num_events;i++) {
       example_hardware_write( example_ctl->which_counter[i],
                   example_ctx,
                   events[i] );
    }
   
    return PAPI_OK;
}

Here is the call graph for this function:

static int detect_example ( void  ) [static]

Definition at line 172 of file example.c.

                     {
 
   return PAPI_OK;
}

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.

{
    long long old_value;

    switch ( which_one ) {
    case EXAMPLE_ZERO_REG:
        return 0;
    case EXAMPLE_CONSTANT_REG:
        return 42;
    case EXAMPLE_AUTOINC_REG:
        old_value = ctx->autoinc_value;
        ctx->autoinc_value++;
        return old_value;
    case EXAMPLE_GLOBAL_AUTOINC_REG:
        old_value = example_global_autoinc_value;
        example_global_autoinc_value++;
        return old_value;
    default:
            fprintf(stderr,"Invalid counter read %x\n",which_one );
        return -1;
    }

    return 0;
}

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.

{
   /* reset per-thread count */
   ctx->autoinc_value=0;
   /* reset global count */
   example_global_autoinc_value = 0;

}

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.

{

    switch ( which_one ) {
    case EXAMPLE_ZERO_REG:
    case EXAMPLE_CONSTANT_REG:
        return PAPI_OK; /* can't be written */
    case EXAMPLE_AUTOINC_REG:
        ctx->autoinc_value=value;
        return PAPI_OK;
    case EXAMPLE_GLOBAL_AUTOINC_REG:
            example_global_autoinc_value=value;
        return PAPI_OK;
    default:
        perror( "Invalid counter write" );
        return -1;
    }

    return 0;
}

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.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines