PAPI  5.1.0.2
The Low Level API

Functions

int PAPI_accum (int EventSet, long long *values)
int PAPI_add_event (int EventSet, int Event)
int PAPI_add_named_event (int EventSet, char *EventName)
int PAPI_add_events (int EventSet, int *Events, int number)
int PAPI_assign_eventset_component (int EventSet, int cidx)
int PAPI_attach (int EventSet, unsigned long tid)
int PAPI_cleanup_eventset (int EventSet)
int PAPI_create_eventset (int *EventSet)
int PAPI_detach (int EventSet)
int PAPI_destroy_eventset (int *EventSet)
int PAPI_enum_event (int *EventCode, int modifier)
int PAPI_enum_cmp_event (int *EventCode, int modifier, int cidx)
int PAPI_event_code_to_name (int EventCode, char *out)
int PAPI_event_name_to_code (char *in, int *out)
int PAPI_get_dmem_info (PAPI_dmem_info_t *dest)
int PAPI_get_event_info (int EventCode, PAPI_event_info_t *info)
const PAPI_exe_info_tPAPI_get_executable_info (void)
const PAPI_hw_info_tPAPI_get_hardware_info (void)
const PAPI_component_info_tPAPI_get_component_info (int cidx)
int PAPI_get_multiplex (int EventSet)
int PAPI_get_opt (int option, PAPI_option_t *ptr)
int PAPI_get_cmp_opt (int option, PAPI_option_t *ptr, int cidx)
long long PAPI_get_real_cyc (void)
long long PAPI_get_real_nsec (void)
long long PAPI_get_real_usec (void)
const PAPI_shlib_info_tPAPI_get_shared_lib_info (void)
int PAPI_get_thr_specific (int tag, void **ptr)
int PAPI_get_overflow_event_index (int Eventset, long long overflow_vector, int *array, int *number)
long long PAPI_get_virt_cyc (void)
long long PAPI_get_virt_nsec (void)
long long PAPI_get_virt_usec (void)
int PAPI_is_initialized (void)
int PAPI_library_init (int version)
int PAPI_list_events (int EventSet, int *Events, int *number)
int PAPI_list_threads (unsigned long *tids, int *number)
int PAPI_lock (int)
int PAPI_multiplex_init (void)
int PAPI_num_cmp_hwctrs (int cidx)
int PAPI_num_events (int EventSet)
int PAPI_overflow (int EventSet, int EventCode, int threshold, int flags, PAPI_overflow_handler_t handler)
void PAPI_perror (char *msg)
int PAPI_profil (void *buf, unsigned bufsiz, caddr_t offset, unsigned scale, int EventSet, int EventCode, int threshold, int flags)
int PAPI_query_event (int EventCode)
int PAPI_query_named_event (char *EventName)
int PAPI_read (int EventSet, long long *values)
int PAPI_read_ts (int EventSet, long long *values, long long *cyc)
int PAPI_register_thread (void)
int PAPI_remove_event (int EventSet, int EventCode)
int PAPI_remove_named_event (int EventSet, char *EventName)
int PAPI_remove_events (int EventSet, int *Events, int number)
int PAPI_reset (int EventSet)
int PAPI_set_debug (int level)
int PAPI_set_cmp_domain (int domain, int cidx)
int PAPI_set_domain (int domain)
int PAPI_set_cmp_granularity (int granularity, int cidx)
int PAPI_set_granularity (int granularity)
int PAPI_set_multiplex (int EventSet)
int PAPI_set_opt (int option, PAPI_option_t *ptr)
int PAPI_set_thr_specific (int tag, void *ptr)
void PAPI_shutdown (void)
int PAPI_sprofil (PAPI_sprofil_t *prof, int profcnt, int EventSet, int EventCode, int threshold, int flags)
int PAPI_start (int EventSet)
int PAPI_state (int EventSet, int *status)
int PAPI_stop (int EventSet, long long *values)
char * PAPI_strerror (int)
unsigned long PAPI_thread_id (void)
int PAPI_thread_init (unsigned long(*id_fn)(void))
int PAPI_unlock (int)
int PAPI_unregister_thread (void)
int PAPI_write (int EventSet, long long *values)
int PAPI_get_event_component (int EventCode)
int PAPI_get_eventset_component (int EventSet)
int PAPI_get_component_index (char *name)
int PAPI_disable_component (int cidx)
int PAPI_disable_component_by_name (char *name)

Detailed Description


Function Documentation

int PAPI_accum ( int  EventSet,
long long *  values 
)

accumulate and reset hardware events from an event set

Definition at line 2671 of file papi.c.

{
    EventSetInfo_t *ESI;
    hwd_context_t *context;
    int i, cidx, retval;
    long long a, b, c;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 )
        papi_return( cidx );

    if ( values == NULL )
        papi_return( PAPI_EINVAL );

    if ( ESI->state & PAPI_RUNNING ) {
        if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
          retval = MPX_read( ESI->multiplex.mpx_evset, ESI->sw_stop, 0 );
        } else {
            /* get the context we should use for this event set */
            context = _papi_hwi_get_context( ESI, NULL );
            retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
        }
        if ( retval != PAPI_OK )
            papi_return( retval );
    }

    for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
        a = ESI->sw_stop[i];
        b = values[i];
        c = a + b;
        values[i] = c;
    }

    papi_return( PAPI_reset( EventSet ) );
}
int PAPI_add_event ( int  EventSet,
int  Event 
)

add single PAPI preset or native hardware event to an event set

Definition at line 1612 of file papi.c.

{
   APIDBG("Entry: EventSet: %d, EventCode: 0x%x\n", EventSet, EventCode);
    EventSetInfo_t *ESI;

    /* Is the EventSet already in existence? */

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    /* Check argument for validity */

    if ( ( ( EventCode & PAPI_PRESET_MASK ) == 0 ) &&
         ( EventCode & PAPI_NATIVE_MASK ) == 0 )
        papi_return( PAPI_EINVAL );

    /* Of course, it must be stopped in order to modify it. */

    if ( ESI->state & PAPI_RUNNING )
        papi_return( PAPI_EISRUN );

    /* Now do the magic. */

    papi_return( _papi_hwi_add_event( ESI, EventCode ) );
}
int PAPI_add_events ( int  EventSet,
int *  Events,
int  number 
)

add array of PAPI preset or native hardware events to an event set

Definition at line 5736 of file papi.c.

{
    int i, retval;

    if ( ( Events == NULL ) || ( number <= 0 ) )
        papi_return( PAPI_EINVAL );

    for ( i = 0; i < number; i++ ) {
        retval = PAPI_add_event( EventSet, Events[i] );
        if ( retval != PAPI_OK ) {
            if ( i == 0 )
                papi_return( retval );
            else
                return ( i );
        }
    }
    return ( PAPI_OK );
}
int PAPI_add_named_event ( int  EventSet,
char *  EventName 
)

add an event by name to a PAPI event set

Definition at line 1824 of file papi.c.

{
    int ret, code;
    
    ret = PAPI_event_name_to_code( EventName, &code );
    if ( ret == PAPI_OK ) ret = PAPI_add_event( EventSet, code );
    papi_return( ret );
}
int PAPI_assign_eventset_component ( int  EventSet,
int  cidx 
)

assign a component index to an existing but empty eventset

Definition at line 1475 of file papi.c.

{
    EventSetInfo_t *ESI;
    int retval;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

/* validate cidx */
    retval = valid_component( cidx );
    if ( retval < 0 )
        papi_return( retval );

/* cowardly refuse to reassign eventsets */ 
    if ( ESI->CmpIdx >= 0 )
      return PAPI_EINVAL;

    return ( _papi_hwi_assign_eventset( ESI, cidx ) );
}
int PAPI_attach ( int  EventSet,
unsigned long  tid 
)

attach specified event set to a specific process or thread id

Definition at line 3123 of file papi.c.

{
    return ( _papi_set_attach( PAPI_ATTACH, EventSet, tid ) );
}
int PAPI_cleanup_eventset ( int  EventSet)

remove all PAPI events from an event set

Definition at line 2813 of file papi.c.

{
    EventSetInfo_t *ESI;
    int i, cidx, total, retval;

    APIDBG("Attempting to cleanup Eventset %d\n",EventSet);

    /* Is the EventSet already in existence? */

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    /* if the eventset has no index and no events, return OK
       otherwise return NOCMP */
    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 ) {
        if ( ESI->NumberOfEvents )
            papi_return( cidx );
        papi_return( PAPI_OK );
    }

    /* Of course, it must be stopped in order to modify it. */

    if ( ESI->state & PAPI_RUNNING )
        papi_return( PAPI_EISRUN );

    /* clear overflow flag and turn off hardware overflow handler */
    if ( ESI->state & PAPI_OVERFLOWING ) {
        total = ESI->overflow.event_counter;
        for ( i = 0; i < total; i++ ) {
            retval = PAPI_overflow( EventSet,
                                    ESI->overflow.EventCode[0], 0, 0, NULL );
            if ( retval != PAPI_OK )
                papi_return( retval );
        }
    }

    /* clear profile flag and turn off hardware profile handler */
    if ( ( ESI->state & PAPI_PROFILING ) &&
         _papi_hwd[cidx]->cmp_info.hardware_intr &&
         !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
        total = ESI->profile.event_counter;
        for ( i = 0; i < total; i++ ) {
            retval =
                PAPI_sprofil( NULL, 0, EventSet, ESI->profile.EventCode[0], 0,
                              PAPI_PROFIL_POSIX );
            if ( retval != PAPI_OK )
                papi_return( retval );
        }
    }

    if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
        retval = MPX_cleanup( &ESI->multiplex.mpx_evset );
        if ( retval != PAPI_OK )
            papi_return( retval );
    }

    retval = _papi_hwd[cidx]->cleanup_eventset( ESI->ctl_state );
    if ( retval != PAPI_OK ) 
        papi_return( retval );

    /* Now do the magic */
    papi_return( _papi_hwi_cleanup_eventset( ESI ) );
}
int PAPI_create_eventset ( int *  EventSet)

create a new empty PAPI event set

Definition at line 1411 of file papi.c.

{
   APIDBG("Entry: EventSet: %p\n", EventSet);
    ThreadInfo_t *master;
    int retval;

    if ( init_level == PAPI_NOT_INITED )
        papi_return( PAPI_ENOINIT );
    retval = _papi_hwi_lookup_or_create_thread( &master, 0 );
    if ( retval )
        papi_return( retval );

    papi_return( _papi_hwi_create_eventset( EventSet, master ) );
}
int PAPI_destroy_eventset ( int *  EventSet)

deallocates memory associated with an empty PAPI event set

Definition at line 1952 of file papi.c.

{
    EventSetInfo_t *ESI;

    APIDBG("Destroying Eventset %d\n",*EventSet);

    /* check for pre-existing ESI */

    if ( EventSet == NULL )
        papi_return( PAPI_EINVAL );

    ESI = _papi_hwi_lookup_EventSet( *EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    if ( !( ESI->state & PAPI_STOPPED ) )
        papi_return( PAPI_EISRUN );

    if ( ESI->NumberOfEvents )
        papi_return( PAPI_EINVAL );

    _papi_hwi_remove_EventSet( ESI );
    *EventSet = PAPI_NULL;

    return PAPI_OK;
}
int PAPI_detach ( int  EventSet)

detach specified event set from a previously specified process or thread id

Definition at line 3182 of file papi.c.

{
    return ( _papi_set_attach( PAPI_DETACH, EventSet, 0 ) );
}
int PAPI_disable_component ( int  cidx)

Disables a component before init

Definition at line 6542 of file papi.c.

{

   const PAPI_component_info_t *cinfo;

   /* Can only run before PAPI_library_init() is called */
   if (init_level != PAPI_NOT_INITED) {
      return PAPI_ENOINIT;
   }
     
   cinfo=PAPI_get_component_info(cidx); 
   if (cinfo==NULL) return PAPI_ENOCMP;

   ((PAPI_component_info_t *)cinfo)->disabled=1;
   strcpy(((PAPI_component_info_t *)cinfo)->disabled_reason,
           "Disabled by PAPI_disable_component()");

   return PAPI_OK;
 
}
int PAPI_disable_component_by_name ( char *  name)

Disable, before library init, a component by name.

Definition at line 6592 of file papi.c.

{
    int cidx;

    /* I can only be called before init time */
    if (init_level!=PAPI_NOT_INITED) {
        return PAPI_ENOINIT;
    }

    cidx = PAPI_get_component_index(name);
    if (cidx>=0) {
        return PAPI_disable_component(cidx);
    } 

    return PAPI_ENOCMP;
}
int PAPI_enum_cmp_event ( int *  EventCode,
int  modifier,
int  cidx 
)

return the event code for the next available component event

Definition at line 1321 of file papi.c.

{
    int i = *EventCode;
    int retval;
    int event_code;

    if ( _papi_hwi_invalid_cmp(cidx) || ( (IS_PRESET(i)) && cidx > 0 ) ) {
        return PAPI_ENOCMP;
    }

    if ( IS_PRESET(i) ) {
        if ( modifier == PAPI_ENUM_FIRST ) {
            *EventCode = ( int ) PAPI_PRESET_MASK;
            return PAPI_OK;
        }
        i &= PAPI_PRESET_AND_MASK;
        while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
            if ( _papi_hwi_presets[i].symbol == NULL )
                return ( PAPI_ENOEVNT );    /* NULL pointer terminates list */
            if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
                if ( _papi_hwi_presets[i].count == 0 )
                    continue;
            }
            *EventCode = ( int ) ( i | PAPI_PRESET_MASK );
            return PAPI_OK;
        }
    } else if ( IS_NATIVE(i) ) {
//      if (!_papi_hwd[cidx]->cmp_info.disabled) {
//                return PAPI_ENOEVNT 
//            }
        /* Should we check against num native events here? */
        event_code=_papi_hwi_eventcode_to_native(*EventCode);
        retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );
        
            /* re-apply Component ID to the returned Event */
        *EventCode = _papi_hwi_native_to_eventcode(cidx,event_code);

        return retval;
    } 

    papi_return( PAPI_EINVAL );
}
int PAPI_enum_event ( int *  EventCode,
int  modifier 
)

return the event code for the next available preset or natvie event

Definition at line 1156 of file papi.c.

{
    int i = *EventCode;
    int retval;
    int cidx;
    int event_code;

    cidx = _papi_hwi_component_index( *EventCode );
    if (cidx < 0) return PAPI_ENOCMP;

    /* Do we handle presets in componets other than CPU? */
    /* if (( IS_PRESET(i) ) && cidx > 0 )) return PAPI_ENOCMP; */
        
    if ( IS_PRESET(i) ) {
        if ( modifier == PAPI_ENUM_FIRST ) {
            *EventCode = ( int ) PAPI_PRESET_MASK;
            return ( PAPI_OK );
        }
        i &= PAPI_PRESET_AND_MASK;
        while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
            if ( _papi_hwi_presets[i].symbol == NULL )
                return ( PAPI_ENOEVNT );    /* NULL pointer terminates list */
            if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
                if ( _papi_hwi_presets[i].count == 0 )
                    continue;
            }
            *EventCode = ( int ) ( i | PAPI_PRESET_MASK );
            return ( PAPI_OK );
        }
    } else if ( IS_NATIVE(i) ) {
        /* Should check against num native events here */

        event_code=_papi_hwi_eventcode_to_native((int)*EventCode);
        retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );

            /* re-apply Component ID to the returned Event */
        *EventCode = _papi_hwi_native_to_eventcode(cidx,event_code);

        return retval;
    } else if ( IS_USER_DEFINED(i) ) {
      if ( modifier == PAPI_ENUM_FIRST ) {
        *EventCode = (int) 0x0;
        return ( PAPI_OK );
      }

      i &= PAPI_UE_AND_MASK;
      ++i;

      if ( (int)_papi_user_events_count <= i )
        *EventCode = i;
      return ( PAPI_OK );
    }

    papi_return( PAPI_EINVAL );
}
int PAPI_event_code_to_name ( int  EventCode,
char *  out 
)

translate an integer PAPI event code into an ASCII PAPI preset or native name

Definition at line 926 of file papi.c.

{
    if ( out == NULL )
        papi_return( PAPI_EINVAL );

    if ( IS_PRESET(EventCode) ) {
        EventCode &= PAPI_PRESET_AND_MASK;
        if ( ( EventCode >= PAPI_MAX_PRESET_EVENTS )
             || ( _papi_hwi_presets[EventCode].symbol == NULL ) )
            papi_return( PAPI_ENOTPRESET );

        strncpy( out, _papi_hwi_presets[EventCode].symbol,
                 PAPI_MAX_STR_LEN );
        papi_return( PAPI_OK );
    }

    if ( IS_NATIVE(EventCode) ) {
        return ( _papi_hwi_native_code_to_name
                 ( ( unsigned int ) EventCode, out, PAPI_MAX_STR_LEN ) );
    }

    if ( IS_USER_DEFINED(EventCode) ) {
      EventCode &= PAPI_UE_AND_MASK;

      if ( EventCode < 0 || EventCode > (int)_papi_user_events_count )
        papi_return( PAPI_EINVAL );

      strncpy( out, _papi_user_events[EventCode].symbol,
          PAPI_MIN_STR_LEN);
      papi_return( PAPI_OK );
    }

    papi_return( PAPI_ENOEVNT );
}
int PAPI_event_name_to_code ( char *  in,
int *  out 
)

translate an ASCII PAPI preset or native name into an integer PAPI event code

Definition at line 1013 of file papi.c.

{
   APIDBG("Entry: in: %p, name: %s, out: %p\n", in, in, out);
    int i;

    if ( ( in == NULL ) || ( out == NULL ) )
        papi_return( PAPI_EINVAL );

    if ( init_level == PAPI_NOT_INITED )
        papi_return( PAPI_ENOINIT );

    /* All presets start with "PAPI_" so no need to */
    /* do an exhaustive search if that's not there  */
    if (strncmp(in, "PAPI_", 5) == 0) {
       for(i = 0; i < PAPI_MAX_PRESET_EVENTS; i++ ) {
          if ( ( _papi_hwi_presets[i].symbol )
           && ( strcasecmp( _papi_hwi_presets[i].symbol, in ) == 0) ) {
         *out = ( int ) ( i | PAPI_PRESET_MASK );
         papi_return( PAPI_OK );
          }
       }
    }

    for ( i=0; i < (int)_papi_user_events_count; i++ ) {
      if ( strcasecmp( _papi_user_events[i].symbol, in ) == 0 ) {
        *out = (int) ( i | PAPI_UE_MASK );
        papi_return( PAPI_OK );
      }
    }

    papi_return( _papi_hwi_native_name_to_code( in, out ) );
}
int PAPI_get_cmp_opt ( int  option,
PAPI_option_t ptr,
int  cidx 
)

query the component specific option settings of a specific event set

Definition at line 4247 of file papi.c.

{

  if (_papi_hwi_invalid_cmp(cidx)) {
     return PAPI_ECMP;
  }

    switch ( option ) {
        /* For now, MAX_HWCTRS and MAX CTRS are identical.
           At some future point, they may map onto different values.
         */
    case PAPI_MAX_HWCTRS:
        return ( _papi_hwd[cidx]->cmp_info.num_cntrs );
    case PAPI_MAX_MPX_CTRS:
        return ( _papi_hwd[cidx]->cmp_info.num_mpx_cntrs );
    case PAPI_DEFDOM:
        return ( _papi_hwd[cidx]->cmp_info.default_domain );
    case PAPI_DEFGRN:
        return ( _papi_hwd[cidx]->cmp_info.default_granularity );
    case PAPI_SHLIBINFO:
    {
        int retval;
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        retval = _papi_os_vector.update_shlib_info( &_papi_hwi_system_info );
        ptr->shlib_info = &_papi_hwi_system_info.shlib_info;
        papi_return( retval );
    }
    case PAPI_COMPONENTINFO:
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ptr->cmp_info = &( _papi_hwd[cidx]->cmp_info );
        return PAPI_OK;
    default:
      papi_return( PAPI_EINVAL );
    }
    return PAPI_OK;
}
int PAPI_get_component_index ( char *  name)

Return component index for component with matching name

Definition at line 6486 of file papi.c.

{
  int cidx;

  const PAPI_component_info_t *cinfo;

  for(cidx=0;cidx<papi_num_components;cidx++) {

     cinfo=PAPI_get_component_info(cidx); 
     if (cinfo==NULL) return PAPI_ENOCMP;

     if (!strncmp(name,cinfo->name,strlen(cinfo->name))) {
        return cidx;
     }
  }

  return PAPI_ENOCMP;
}

get information about the component features

Definition at line 810 of file papi.c.

{
    if ( _papi_hwi_invalid_cmp( cidx ) )
        return ( NULL );
    else
        return ( &( _papi_hwd[cidx]->cmp_info ) );
}

get dynamic memory usage information

Definition at line 5936 of file papi.c.

{
    if ( dest == NULL )
        return PAPI_EINVAL;

    memset( ( void * ) dest, 0x0, sizeof ( PAPI_dmem_info_t ) );
    return ( _papi_os_vector.get_dmem_info( dest ) );
}
int PAPI_get_event_component ( int  EventCode)

return which component an EventCode belongs to

Definition at line 6460 of file papi.c.

{
    return _papi_hwi_component_index( EventCode);
}
int PAPI_get_event_info ( int  EventCode,
PAPI_event_info_t info 
)

get the name and descriptions for a given preset or native event code

Definition at line 848 of file papi.c.

{
        int i;

    if ( info == NULL )
       papi_return( PAPI_EINVAL );

    if ( IS_PRESET(EventCode) ) {
           i = EventCode & PAPI_PRESET_AND_MASK;
       if ( i >= PAPI_MAX_PRESET_EVENTS )
          papi_return( PAPI_ENOTPRESET );
       papi_return( _papi_hwi_get_preset_event_info( EventCode, info ) );
    }

    if ( IS_NATIVE(EventCode) ) {
       papi_return( _papi_hwi_get_native_event_info
              ( ( unsigned int ) EventCode, info ) );
    }

    if ( IS_USER_DEFINED(EventCode) ) {
       papi_return( PAPI_OK );
    }
    papi_return( PAPI_ENOTPRESET );
}
int PAPI_get_eventset_component ( int  EventSet)

return which component an EventSet is assigned to

Definition at line 1518 of file papi.c.

{
    EventSetInfo_t *ESI;
    int retval;

/* validate eventset */
    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

/* check if a component has been assigned */ 
    if ( ESI->CmpIdx < 0 )
      papi_return( PAPI_ENOCMP );

/* validate CmpIdx */
    retval = valid_component( ESI->CmpIdx );
    if ( retval < 0 )
        papi_return( retval );

/* return the index */
    return ( ESI->CmpIdx );
}

get the executable's address space information

Definition at line 5990 of file papi.c.

{
    PAPI_option_t ptr;
    int retval;

    memset( &ptr, 0, sizeof ( ptr ) );
    retval = PAPI_get_opt( PAPI_EXEINFO, &ptr );
    if ( retval == PAPI_OK )
        return ( ptr.exe_info );
    else
        return ( NULL );
}

get information about the system hardware

Definition at line 6061 of file papi.c.

{
    PAPI_option_t ptr;
    int retval;

    memset( &ptr, 0, sizeof ( ptr ) );
    retval = PAPI_get_opt( PAPI_HWINFO, &ptr );
    if ( retval == PAPI_OK )
        return ( ptr.hw_info );
    else
        return ( NULL );
}
int PAPI_get_multiplex ( int  EventSet)

get the multiplexing status of specified event set

Definition at line 3942 of file papi.c.

{
    PAPI_option_t popt;
    int retval;

    popt.multiplex.eventset = EventSet;
    retval = PAPI_get_opt( PAPI_MULTIPLEX, &popt );
    if ( retval < 0 )
        retval = 0;
    return retval;
}
int PAPI_get_opt ( int  option,
PAPI_option_t ptr 
)

query the option settings of the PAPI library or a specific event set

Definition at line 4056 of file papi.c.

{
    EventSetInfo_t *ESI;

    if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
        papi_return( PAPI_ENOINIT );

    switch ( option ) {
    case PAPI_DETACH:
    {
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );
        ptr->attach.tid = ESI->attach.tid;
        return ( ( ESI->state & PAPI_ATTACHED ) == 0 );
    }
    case PAPI_ATTACH:
    {
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );
        ptr->attach.tid = ESI->attach.tid;
        return ( ( ESI->state & PAPI_ATTACHED ) != 0 );
    }
    case PAPI_CPU_ATTACH:
    {
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );
        ptr->cpu.cpu_num = ESI->CpuInfo->cpu_num;
        return ( ( ESI->state & PAPI_CPU_ATTACHED ) != 0 );
    }
    case PAPI_DEF_MPX_NS:
    {
        /* xxxx for now, assume we only check against cpu component */
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ptr->multiplex.ns = _papi_os_info.itimer_ns;
        return ( PAPI_OK );
    }
    case PAPI_DEF_ITIMER_NS:
    {
        /* xxxx for now, assume we only check against cpu component */
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ptr->itimer.ns = _papi_os_info.itimer_ns;
        return ( PAPI_OK );
    }
    case PAPI_DEF_ITIMER:
    {
        /* xxxx for now, assume we only check against cpu component */
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ptr->itimer.itimer_num = _papi_os_info.itimer_num;
        ptr->itimer.itimer_sig = _papi_os_info.itimer_sig;
        ptr->itimer.ns = _papi_os_info.itimer_ns;
        ptr->itimer.flags = 0;
        return ( PAPI_OK );
    }
    case PAPI_MULTIPLEX:
    {
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );
        ptr->multiplex.ns = ESI->multiplex.ns;
        ptr->multiplex.flags = ESI->multiplex.flags;
        return ( ESI->state & PAPI_MULTIPLEXING ) != 0;
    }
    case PAPI_PRELOAD:
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        memcpy( &ptr->preload, &_papi_hwi_system_info.preload_info,
                sizeof ( PAPI_preload_info_t ) );
        break;
    case PAPI_DEBUG:
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ptr->debug.level = _papi_hwi_error_level;
        ptr->debug.handler = _papi_hwi_debug_handler;
        break;
    case PAPI_CLOCKRATE:
        return ( ( int ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
    case PAPI_MAX_CPUS:
        return ( _papi_hwi_system_info.hw_info.ncpu );
        /* For now, MAX_HWCTRS and MAX CTRS are identical.
           At some future point, they may map onto different values.
         */
    case PAPI_INHERIT:
    {
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );
        ptr->inherit.inherit = ESI->inherit.inherit;
        return ( PAPI_OK );
    }
    case PAPI_GRANUL:
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ESI = _papi_hwi_lookup_EventSet( ptr->granularity.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );
        ptr->granularity.granularity = ESI->granularity.granularity;
        break;
    case PAPI_EXEINFO:
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ptr->exe_info = &_papi_hwi_system_info.exe_info;
        break;
    case PAPI_HWINFO:
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ptr->hw_info = &_papi_hwi_system_info.hw_info;
        break;

    case PAPI_DOMAIN:
        if ( ptr == NULL )
            papi_return( PAPI_EINVAL );
        ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );
        ptr->domain.domain = ESI->domain.domain;
        return ( PAPI_OK );
    case PAPI_LIB_VERSION:
        return ( PAPI_VERSION );
/* The following cases all require a component index 
    and are handled by PAPI_get_cmp_opt() with cidx == 0*/
    case PAPI_MAX_HWCTRS:
    case PAPI_MAX_MPX_CTRS:
    case PAPI_DEFDOM:
    case PAPI_DEFGRN:
    case PAPI_SHLIBINFO:
    case PAPI_COMPONENTINFO:
        return ( PAPI_get_cmp_opt( option, ptr, 0 ) );
    default:
        papi_return( PAPI_EINVAL );
    }
    return ( PAPI_OK );
}
int PAPI_get_overflow_event_index ( int  Eventset,
long long  overflow_vector,
int *  array,
int *  number 
)

# decomposes an overflow_vector into an event index array

Definition at line 6395 of file papi.c.

{
    EventSetInfo_t *ESI;
    int set_bit, j, pos;
    int count = 0, k;

    if ( overflow_vector == ( long long ) 0 )
        papi_return( PAPI_EINVAL );

    if ( ( array == NULL ) || ( number == NULL ) )
        papi_return( PAPI_EINVAL );

    if ( *number < 1 )
        papi_return( PAPI_EINVAL );

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    /* in case the eventset is empty */
    if ( ESI->NumberOfEvents == 0 )
        papi_return( PAPI_EINVAL );

    while ( ( set_bit = ffsll( overflow_vector ) ) ) {
        set_bit -= 1;
        overflow_vector ^= ( long long ) 1 << set_bit;
        for ( j = 0; j < ESI->NumberOfEvents; j++ ) {
            for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0; k++ ) {
                pos = ESI->EventInfoArray[j].pos[k];
                if ( ( set_bit == pos ) &&
                     ( ( ESI->EventInfoArray[j].derived == NOT_DERIVED ) ||
                       ( ESI->EventInfoArray[j].derived == DERIVED_CMPD ) ) ) {
                    array[count++] = j;
                    if ( count == *number )
                        return PAPI_OK;

                    break;
                }
            }
        }
    }
    *number = count;
    return PAPI_OK;
}
long long PAPI_get_real_cyc ( void  )

return the total number of cycles since some arbitrary starting point

Definition at line 6093 of file papi.c.

{
    return ( _papi_os_vector.get_real_cycles(  ) );
}
long long PAPI_get_real_nsec ( void  )

return the total number of nanoseconds since some arbitrary starting point

Definition at line 6113 of file papi.c.

{
  return ( ( _papi_os_vector.get_real_nsec(  )));

}
long long PAPI_get_real_usec ( void  )

return the total number of microseconds since some arbitrary starting point

Definition at line 6140 of file papi.c.

{
    return ( _papi_os_vector.get_real_usec(  ) );
}

get information about the shared libraries used by the process

Definition at line 6020 of file papi.c.

{
    PAPI_option_t ptr;
    int retval;

    memset( &ptr, 0, sizeof ( ptr ) );
    retval = PAPI_get_opt( PAPI_SHLIBINFO, &ptr );
    if ( retval == PAPI_OK )
        return ( ptr.shlib_info );
    else
        return ( NULL );
}
int PAPI_get_thr_specific ( int  tag,
void **  ptr 
)

return a pointer to a thread specific stored data structure

Definition at line 360 of file papi.c.

{
    ThreadInfo_t *thread;
    int doall = 0, retval = PAPI_OK;

    if ( init_level == PAPI_NOT_INITED )
        papi_return( PAPI_ENOINIT );
    if ( tag & PAPI_TLS_ALL_THREADS ) {
        tag = tag ^ PAPI_TLS_ALL_THREADS;
        doall = 1;
    }
    if ( ( tag < 0 ) || ( tag > PAPI_TLS_NUM ) )
        papi_return( PAPI_EINVAL );

    if ( doall )
        papi_return( _papi_hwi_gather_all_thrspec_data
                     ( tag, ( PAPI_all_thr_spec_t * ) ptr ) );

    retval = _papi_hwi_lookup_or_create_thread( &thread, 0 );
    if ( retval == PAPI_OK )
        *ptr = thread->thread_storage[tag];
    else
        papi_return( retval );

    return ( PAPI_OK );
}
long long PAPI_get_virt_cyc ( void  )

return the process cycles since some arbitrary starting point

Definition at line 6176 of file papi.c.

{

    return ( ( long long ) _papi_os_vector.get_virt_cycles( ) );
}
long long PAPI_get_virt_nsec ( void  )

return the process nanoseconds since some arbitrary starting point

Definition at line 6206 of file papi.c.

{

  return ( ( _papi_os_vector.get_virt_nsec()));

}
long long PAPI_get_virt_usec ( void  )

return the process microseconds since some arbitrary starting point

Definition at line 6248 of file papi.c.

{

    return ( ( long long ) _papi_os_vector.get_virt_usec() );
}
int PAPI_is_initialized ( void  )

return the initialized state of the PAPI library

Definition at line 6341 of file papi.c.

{
    return ( init_level );
}
int PAPI_library_init ( int  version)

initialize the PAPI library

Definition at line 498 of file papi.c.

{
    char *filename;
    int tmp = 0, tmpel;

    /* This is a poor attempt at a lock. 
       For 3.1 this should be replaced with a 
       true UNIX semaphore. We cannot use PAPI
       locks here because they are not initialized yet */
    static int _in_papi_library_init_cnt = 0;
#ifdef DEBUG
    char *var;
#endif
    _papi_hwi_init_errors();

    if ( version != PAPI_VER_CURRENT )
        papi_return( PAPI_EINVAL );

    ++_in_papi_library_init_cnt;
    while ( _in_papi_library_init_cnt > 1 ) {
        PAPIERROR( "Multiple callers of PAPI_library_init" );
        sleep( 1 );
    }

    /* This checks to see if we have forked or called init more than once.
       If we have forked, then we continue to init. If we have not forked, 
       we check to see the status of initialization. */

    APIDBG( "Initializing library: current PID %d, old PID %d\n", 
                getpid(  ), _papi_hwi_system_info.pid );

    if ( _papi_hwi_system_info.pid == getpid(  ) ) {
        /* If the magic environment variable PAPI_ALLOW_STOLEN is set,
           we call shutdown if PAPI has been initialized. This allows
           tools that use LD_PRELOAD to run on applications that use PAPI.
           In this circumstance, PAPI_ALLOW_STOLEN will be set to 'stolen'
           so the tool can check for this case. */

        if ( getenv( "PAPI_ALLOW_STOLEN" ) ) {
            char buf[PAPI_HUGE_STR_LEN];
            if ( init_level != PAPI_NOT_INITED )
                PAPI_shutdown(  );
            sprintf( buf, "%s=%s", "PAPI_ALLOW_STOLEN", "stolen" );
            putenv( buf );
        }

        /* If the library has been successfully initialized *OR*
           the library attempted initialization but failed. */

        else if ( ( init_level != PAPI_NOT_INITED ) ||
                  ( init_retval != DEADBEEF ) ) {
            _in_papi_library_init_cnt--;
            if ( init_retval < PAPI_OK )
                papi_return( init_retval );
            else
                return ( init_retval );
        }

        APIDBG( "system_info was initialized, but init did not succeed\n" );
    }
#ifdef DEBUG
    var = ( char * ) getenv( "PAPI_DEBUG" );
    _papi_hwi_debug = 0;

    if ( var != NULL ) {
        if ( strlen( var ) != 0 ) {
            if ( strstr( var, "SUBSTRATE" ) )
                _papi_hwi_debug |= DEBUG_SUBSTRATE;
            if ( strstr( var, "API" ) )
                _papi_hwi_debug |= DEBUG_API;
            if ( strstr( var, "INTERNAL" ) )
                _papi_hwi_debug |= DEBUG_INTERNAL;
            if ( strstr( var, "THREADS" ) )
                _papi_hwi_debug |= DEBUG_THREADS;
            if ( strstr( var, "MULTIPLEX" ) )
                _papi_hwi_debug |= DEBUG_MULTIPLEX;
            if ( strstr( var, "OVERFLOW" ) )
                _papi_hwi_debug |= DEBUG_OVERFLOW;
            if ( strstr( var, "PROFILE" ) )
                _papi_hwi_debug |= DEBUG_PROFILE;
            if ( strstr( var, "MEMORY" ) )
                _papi_hwi_debug |= DEBUG_MEMORY;
            if ( strstr( var, "LEAK" ) )
                _papi_hwi_debug |= DEBUG_LEAK;
            if ( strstr( var, "ALL" ) )
                _papi_hwi_debug |= DEBUG_ALL;
        }

        if ( _papi_hwi_debug == 0 )
            _papi_hwi_debug |= DEBUG_API;
    }
#endif

    /* Be verbose for now */

    tmpel = _papi_hwi_error_level;
    _papi_hwi_error_level = PAPI_VERB_ECONT;

    /* Initialize internal globals */
    if ( _papi_hwi_init_global_internal(  ) != PAPI_OK ) {
        _in_papi_library_init_cnt--;
        _papi_hwi_error_level = tmpel;
        papi_return( PAPI_EINVAL );
    }

    /* Initialize OS */
    tmp = _papi_hwi_init_os();
    if ( tmp ) {
       init_retval = tmp;
       _papi_hwi_shutdown_global_internal(  );
       _in_papi_library_init_cnt--;
       _papi_hwi_error_level = tmpel;
       papi_return( init_retval );
    }

    /* Initialize component globals */

    tmp = _papi_hwi_init_global(  );
    if ( tmp ) {
        init_retval = tmp;
        _papi_hwi_shutdown_global_internal(  );
        _in_papi_library_init_cnt--;
        _papi_hwi_error_level = tmpel;
        papi_return( init_retval );
    }
    
    /* Initialize thread globals, including the main threads  */

    tmp = _papi_hwi_init_global_threads(  );
    if ( tmp ) {
        int i;
        init_retval = tmp;
        _papi_hwi_shutdown_global_internal(  );
        for ( i = 0; i < papi_num_components; i++ ) {
            if (!_papi_hwd[i]->cmp_info.disabled) {
                       _papi_hwd[i]->shutdown_component(  );
            }
        }
        _in_papi_library_init_cnt--;
        _papi_hwi_error_level = tmpel;
        papi_return( init_retval );
    }

    init_level = PAPI_LOW_LEVEL_INITED;
    _in_papi_library_init_cnt--;
    _papi_hwi_error_level = tmpel;

#ifdef STATIC_USER_EVENTS
    _papi_user_defined_events_setup(NULL);
#endif

    if ( (filename = getenv( "PAPI_USER_EVENTS_FILE" )) != NULL ) {
      _papi_user_defined_events_setup(filename);
    }

    return ( init_retval = PAPI_VER_CURRENT );
}
int PAPI_list_events ( int  EventSet,
int *  Events,
int *  number 
)

list the events that are members of an event set

Definition at line 5883 of file papi.c.

{
    EventSetInfo_t *ESI;
    int i, j;

    if ( ( Events == NULL ) || ( *number <= 0 ) )
        papi_return( PAPI_EINVAL );

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( !ESI )
        papi_return( PAPI_ENOEVST );

    for ( i = 0, j = 0; j < ESI->NumberOfEvents; i++ ) {
        if ( ( int ) ESI->EventInfoArray[i].event_code != PAPI_NULL ) {
            Events[j] = ( int ) ESI->EventInfoArray[i].event_code;
            j++;
            if ( j == *number )
                break;
        }
    }

    *number = j;

    return ( PAPI_OK );
}
int PAPI_list_threads ( unsigned long *  tids,
int *  number 
)

list the thread ids currently known to PAPI

Definition at line 284 of file papi.c.

{
    PAPI_all_thr_spec_t tmp;
    int retval;

    /* If tids == NULL, then just count the threads, don't gather a list. */
    /* If tids != NULL, then we need the length of the tids array in num. */

    if ( ( number == NULL ) || ( tids && ( *number <= 0 ) ) )
        papi_return( PAPI_EINVAL );

    memset( &tmp, 0x0, sizeof ( tmp ) );

    /* data == NULL, since we don't want the thread specific pointers. */
    /* tids may be NULL, if the user doesn't want the thread IDs. */

    tmp.num = *number;
    tmp.id = tids;
    tmp.data = NULL;

    retval = _papi_hwi_gather_all_thrspec_data( 0, &tmp );
    if ( retval == PAPI_OK )
        *number = tmp.num;

    papi_return( retval );
}
int PAPI_lock ( int  )

lock one of two PAPI internal user mutex variables

Definition at line 6279 of file papi.c.

{
    if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
        papi_return( PAPI_EINVAL );

    papi_return( _papi_hwi_lock( lck ) );
}
int PAPI_multiplex_init ( void  )

initialize multiplex support in the PAPI library

Definition at line 2907 of file papi.c.

{
    int retval;

    retval = mpx_init( _papi_os_info.itimer_ns );
    papi_return( retval );
}
int PAPI_num_cmp_hwctrs ( int  cidx)

return the number of hardware counters for a specified component

Definition at line 3880 of file papi.c.

{
    return ( PAPI_get_cmp_opt( PAPI_MAX_HWCTRS, NULL, cidx ) );
}
int PAPI_num_events ( int  EventSet)

return the number of events in an event set

Definition at line 4338 of file papi.c.

{
    EventSetInfo_t *ESI;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( !ESI )
        papi_return( PAPI_ENOEVST );

#ifdef DEBUG
    /* Not necessary */
    if ( ESI->NumberOfEvents == 0 )
        papi_return( PAPI_EINVAL );
#endif

    return ( ESI->NumberOfEvents );
}
int PAPI_overflow ( int  EventSet,
int  EventCode,
int  threshold,
int  flags,
PAPI_overflow_handler_t  handler 
)

set up an event set to begin registering overflows

< Using Hardware

< Force using Software

Definition at line 4684 of file papi.c.

{
    int retval, cidx, index, i;
    EventSetInfo_t *ESI;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL ) {
        OVFDBG("No EventSet\n");
        papi_return( PAPI_ENOEVST );
        }

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 ) {
        OVFDBG("Component Error\n");
        papi_return( cidx );
    }

    if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
        OVFDBG("Already running\n");
        papi_return( PAPI_EISRUN );
    }

    if ( ESI->state & PAPI_ATTACHED ) {
        OVFDBG("Attached\n");
        papi_return( PAPI_EINVAL );
    }
    
    if ( ESI->state & PAPI_CPU_ATTACHED ) {
        OVFDBG("CPU attached\n");
        papi_return( PAPI_EINVAL );
    }
    
    if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
                        ( unsigned int ) EventCode ) ) < 0 ) {
        papi_return( PAPI_ENOEVNT );
    }

    if ( threshold < 0 ) {
        OVFDBG("Threshold below zero\n");
        papi_return( PAPI_EINVAL );
    }

    /* We do not support derived events in overflow */
    /* Unless it's DERIVED_CMPD in which no calculations are done */

    if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) && threshold != 0 &&
         ( ESI->EventInfoArray[index].derived ) &&
         ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) ) {
        OVFDBG("Derived event in overflow\n");
        papi_return( PAPI_EINVAL );
    }

    /* the first time to call PAPI_overflow function */

    if ( !( ESI->state & PAPI_OVERFLOWING ) ) {
        if ( handler == NULL ) {
            OVFDBG("NULL handler\n");
            papi_return( PAPI_EINVAL );
        }
        if ( threshold == 0 ) {
            OVFDBG("Zero threshold\n");
            papi_return( PAPI_EINVAL );
        }
    }
    if ( threshold > 0 &&
         ESI->overflow.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs )
        papi_return( PAPI_ECNFLCT );

    if ( threshold == 0 ) {
        for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
            if ( ESI->overflow.EventCode[i] == EventCode )
                break;
        }
        /* EventCode not found */
        if ( i == ESI->overflow.event_counter )
            papi_return( PAPI_EINVAL );
        /* compact these arrays */
        while ( i < ESI->overflow.event_counter - 1 ) {
            ESI->overflow.deadline[i] = ESI->overflow.deadline[i + 1];
            ESI->overflow.threshold[i] = ESI->overflow.threshold[i + 1];
            ESI->overflow.EventIndex[i] = ESI->overflow.EventIndex[i + 1];
            ESI->overflow.EventCode[i] = ESI->overflow.EventCode[i + 1];
            i++;
        }
        ESI->overflow.deadline[i] = 0;
        ESI->overflow.threshold[i] = 0;
        ESI->overflow.EventIndex[i] = 0;
        ESI->overflow.EventCode[i] = 0;
        ESI->overflow.event_counter--;
    } else {
        if ( ESI->overflow.event_counter > 0 ) {
            if ( ( flags & PAPI_OVERFLOW_FORCE_SW ) &&
                 ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) )
                papi_return( PAPI_ECNFLCT );
            if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) &&
                 ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) )
                papi_return( PAPI_ECNFLCT );
        }
        for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
            if ( ESI->overflow.EventCode[i] == EventCode )
                break;
        }
        /* A new entry */
        if ( i == ESI->overflow.event_counter ) {
            ESI->overflow.EventCode[i] = EventCode;
            ESI->overflow.event_counter++;
        }
        /* New or existing entry */
        ESI->overflow.deadline[i] = threshold;
        ESI->overflow.threshold[i] = threshold;
        ESI->overflow.EventIndex[i] = index;
        ESI->overflow.flags = flags;

    }

    /* If overflowing is already active, we should check to
       make sure that we don't specify a different handler
       or different flags here. You can't mix them. */

    ESI->overflow.handler = handler;

    /* Set up the option structure for the low level.
       If we have hardware interrupts and we are not using
       forced software emulated interrupts */

    if ( _papi_hwd[cidx]->cmp_info.hardware_intr &&
         !( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) ) {
        retval = _papi_hwd[cidx]->set_overflow( ESI, index, threshold );
        if ( retval == PAPI_OK )
            ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
        else {
            papi_return( retval );  /* We should undo stuff here */
        }
    } else {
        /* Make sure hardware overflow is not set */
        ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
    }

    APIDBG( "Overflow using: %s\n",
            ( ESI->overflow.
              flags & PAPI_OVERFLOW_HARDWARE ? "[Hardware]" : ESI->overflow.
              flags & PAPI_OVERFLOW_FORCE_SW ? "[Forced Software]" :
              "[Software]" ) );

    /* Toggle the overflow flags and ESI state */

    if ( ESI->overflow.event_counter >= 1 )
        ESI->state |= PAPI_OVERFLOWING;
    else {
        ESI->state ^= PAPI_OVERFLOWING;
        ESI->overflow.flags = 0;
        ESI->overflow.handler = NULL;
    }

    return PAPI_OK;
}
void PAPI_perror ( char *  msg)

Print a PAPI error message

Definition at line 4548 of file papi.c.

{
    char *foo;

    foo = PAPI_strerror( _papi_hwi_errno );
    if ( foo == NULL )
        return;

    if ( msg )
        if ( *msg )
                fprintf( stderr, "%s: ", msg );

    fprintf( stderr, "%s\n", foo );
}
int PAPI_profil ( void *  buf,
unsigned  bufsiz,
caddr_t  offset,
unsigned  scale,
int  EventSet,
int  EventCode,
int  threshold,
int  flags 
)

generate PC histogram data where hardware counter overflow occurs

Definition at line 5332 of file papi.c.

{
    EventSetInfo_t *ESI;
    int i;
    int retval;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    /* scale factors are checked for validity in PAPI_sprofil */

    if ( threshold > 0 ) {
        PAPI_sprofil_t *prof;

        for ( i = 0; i < ESI->profile.event_counter; i++ ) {
            if ( ESI->profile.EventCode[i] == EventCode )
                break;
        }

        if ( i == ESI->profile.event_counter ) {
            prof =
                ( PAPI_sprofil_t * ) papi_malloc( sizeof ( PAPI_sprofil_t ) );
            memset( prof, 0x0, sizeof ( PAPI_sprofil_t ) );
            prof->pr_base = buf;
            prof->pr_size = bufsiz;
            prof->pr_off = offset;
            prof->pr_scale = scale;

            retval =
                PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );

            if ( retval != PAPI_OK )
                papi_free( prof );
        } else {
            prof = ESI->profile.prof[i];
            prof->pr_base = buf;
            prof->pr_size = bufsiz;
            prof->pr_off = offset;
            prof->pr_scale = scale;
            retval =
                PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
        }
        papi_return( retval );
    }

    for ( i = 0; i < ESI->profile.event_counter; i++ ) {
        if ( ESI->profile.EventCode[i] == EventCode )
            break;
    }
    /* EventCode not found */
    if ( i == ESI->profile.event_counter )
        papi_return( PAPI_EINVAL );

    papi_free( ESI->profile.prof[i] );
    ESI->profile.prof[i] = NULL;

    papi_return( PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, flags ) );
}
int PAPI_query_event ( int  EventCode)

query if a PAPI event exists

Definition at line 700 of file papi.c.

{
    if ( IS_PRESET(EventCode) ) {
        EventCode &= PAPI_PRESET_AND_MASK;
        if ( EventCode >= PAPI_MAX_PRESET_EVENTS )
            papi_return( PAPI_ENOTPRESET );

        if ( _papi_hwi_presets[EventCode].count )
                papi_return (PAPI_OK);
        else
            return PAPI_ENOEVNT;
    }

    if ( IS_NATIVE(EventCode) ) {
        papi_return( _papi_hwi_query_native_event
                     ( ( unsigned int ) EventCode ) );
    }

    if ( IS_USER_DEFINED(EventCode) ) {
      EventCode &= PAPI_UE_AND_MASK;
      if ( EventCode < 0 || EventCode > (int)_papi_user_events_count)
        return ( PAPI_EINVAL );

      papi_return( PAPI_OK );
    }

    papi_return( PAPI_ENOEVNT );
}
int PAPI_query_named_event ( char *  EventName)

query if a named PAPI event exists

Definition at line 770 of file papi.c.

{
    int ret, code;
    
    ret = PAPI_event_name_to_code( EventName, &code );
    if ( ret == PAPI_OK ) ret = PAPI_query_event( code );
    papi_return( ret);
}
int PAPI_read ( int  EventSet,
long long *  values 
)

read hardware events from an event set with no reset

Definition at line 2485 of file papi.c.

{
    EventSetInfo_t *ESI;
    hwd_context_t *context;
    int cidx, retval = PAPI_OK;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 )
        papi_return( cidx );

    if ( values == NULL )
        papi_return( PAPI_EINVAL );

    if ( ESI->state & PAPI_RUNNING ) {
        if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
          retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
        } else {
            /* get the context we should use for this event set */
            context = _papi_hwi_get_context( ESI, NULL );
            retval = _papi_hwi_read( context, ESI, values );
        }
        if ( retval != PAPI_OK )
            papi_return( retval );
    } else {
        memcpy( values, ESI->sw_stop,
                ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
    }

#if defined(DEBUG)
    if ( ISLEVEL( DEBUG_API ) ) {
        int i;
        for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
            APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
        }
    }
#endif

    APIDBG( "PAPI_read returns %d\n", retval );
    return ( PAPI_OK );
}
int PAPI_read_ts ( int  EventSet,
long long *  values,
long long *  cyc 
)

read from an eventset with a real-time cycle timestamp

Definition at line 2575 of file papi.c.

{
    EventSetInfo_t *ESI;
    hwd_context_t *context;
    int cidx, retval = PAPI_OK;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 )
        papi_return( cidx );

    if ( values == NULL )
        papi_return( PAPI_EINVAL );

    if ( ESI->state & PAPI_RUNNING ) {
        if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
          retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
        } else {
            /* get the context we should use for this event set */
            context = _papi_hwi_get_context( ESI, NULL );
            retval = _papi_hwi_read( context, ESI, values );
        }
        if ( retval != PAPI_OK )
            papi_return( retval );
    } else {
        memcpy( values, ESI->sw_stop,
                ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
    }

    *cycles = _papi_os_vector.get_real_cycles(  );

#if defined(DEBUG)
    if ( ISLEVEL( DEBUG_API ) ) {
        int i;
        for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
            APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
        }
    }
#endif

    APIDBG( "PAPI_read_ts returns %d\n", retval );
    return PAPI_OK;
}
int PAPI_register_thread ( void  )

inform PAPI of the existence of a new thread

Definition at line 204 of file papi.c.

int PAPI_remove_event ( int  EventSet,
int  EventCode 
)

remove a hardware event from a PAPI event set

Definition at line 1707 of file papi.c.

{
    EventSetInfo_t *ESI;
    int i,retval;

    /* check for pre-existing ESI */

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    /* Check argument for validity */

    if ( ( !IS_PRESET(EventCode) ) &&
        ( !IS_NATIVE(EventCode) ) &&
        ( !IS_USER_DEFINED(EventCode) ))
        papi_return( PAPI_EINVAL );

    /* Of course, it must be stopped in order to modify it. */

    if ( !( ESI->state & PAPI_STOPPED ) )
        papi_return( PAPI_EISRUN );

    /* if the state is PAPI_OVERFLOWING, you must first call
       PAPI_overflow with threshold=0 to remove the overflow flag */

    /* Turn off the event that is overflowing */
    if ( ESI->state & PAPI_OVERFLOWING ) {
       for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
           if ( ESI->overflow.EventCode[i] == EventCode ) {
          retval = PAPI_overflow( EventSet, EventCode, 0, 0,
                      ESI->overflow.handler );
          if (retval!=PAPI_OK) return retval;
          break;
           }
       }
    }

    /* force the user to call PAPI_profil to clear the PAPI_PROFILING flag */
    if ( ESI->state & PAPI_PROFILING ) {
        for ( i = 0; i < ESI->profile.event_counter; i++ ) {
            if ( ESI->profile.EventCode[i] == EventCode ) {
                PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, 0 );
                break;
            }
        }
    }

    /* Now do the magic. */

    papi_return( _papi_hwi_remove_event( ESI, EventCode ) );
}
int PAPI_remove_events ( int  EventSet,
int *  Events,
int  number 
)

remove an array of hardware events from a PAPI event set

Definition at line 5823 of file papi.c.

{
    int i, retval;

    if ( ( Events == NULL ) || ( number <= 0 ) )
        papi_return( PAPI_EINVAL );

    for ( i = 0; i < number; i++ ) {
        retval = PAPI_remove_event( EventSet, Events[i] );
        if ( retval != PAPI_OK ) {
            if ( i == 0 )
                papi_return( retval );
            else
                return ( i );
        }
    }
    return ( PAPI_OK );
}
int PAPI_remove_named_event ( int  EventSet,
char *  EventName 
)

remove a named event from a PAPI event set

Definition at line 1901 of file papi.c.

{
    int ret, code;
    
    ret = PAPI_event_name_to_code( EventName, &code );
    if ( ret == PAPI_OK ) ret = PAPI_remove_event( EventSet, code );
    papi_return( ret );
}
int PAPI_reset ( int  EventSet)

reset the hardware event counts in an event set

Definition at line 2384 of file papi.c.

{
    int retval = PAPI_OK;
    EventSetInfo_t *ESI;
    hwd_context_t *context;
    int cidx;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 )
        papi_return( cidx );

    if ( ESI->state & PAPI_RUNNING ) {
        if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
            retval = MPX_reset( ESI->multiplex.mpx_evset );
        } else {
            /* If we're not the only one running, then just
               read the current values into the ESI->start
               array. This holds the starting value for counters
               that are shared. */
            /* get the context we should use for this event set */
            context = _papi_hwi_get_context( ESI, NULL );
            retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
        }
    } else {
#ifdef __bgp__
        //  For BG/P, we always want to reset the 'real' hardware counters.  The counters
        //  can be controlled via multiple interfaces, and we need to ensure that the values
        //  are truly zero...
        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( ESI, NULL );
        retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
#endif
        memset( ESI->sw_stop, 0x00,
                ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
    }

    APIDBG( "PAPI_reset returns %d\n", retval );
    papi_return( retval );
}
int PAPI_set_cmp_domain ( int  domain,
int  cidx 
)

set the component specific default execution domain for new event sets

Definition at line 5651 of file papi.c.

{
    PAPI_option_t ptr;

    memset( &ptr, 0, sizeof ( ptr ) );
    ptr.defdomain.def_cidx = cidx;
    ptr.defdomain.domain = domain;
    papi_return( PAPI_set_opt( PAPI_DEFDOM, &ptr ) );
}
int PAPI_set_cmp_granularity ( int  granularity,
int  cidx 
)

set the component specific default granularity for new event sets

Definition at line 5515 of file papi.c.

{
    PAPI_option_t ptr;

    memset( &ptr, 0, sizeof ( ptr ) );
    ptr.defgranularity.def_cidx = cidx;
    ptr.defgranularity.granularity = granularity;
    papi_return( PAPI_set_opt( PAPI_DEFGRN, &ptr ) );
}
int PAPI_set_debug ( int  level)

set the current debug level for PAPI

Definition at line 3047 of file papi.c.

{
    PAPI_option_t option;

    memset( &option, 0x0, sizeof ( option ) );
    option.debug.level = level;
    option.debug.handler = _papi_hwi_debug_handler;
    return ( PAPI_set_opt( PAPI_DEBUG, &option ) );
}
int PAPI_set_domain ( int  domain)

set the default execution domain for new event sets

Definition at line 5581 of file papi.c.

{
    return ( PAPI_set_cmp_domain( domain, 0 ) );
}
int PAPI_set_granularity ( int  granularity)

set the default granularity for new event sets

Definition at line 5450 of file papi.c.

{
    return ( PAPI_set_cmp_granularity( granularity, 0 ) );
}
int PAPI_set_multiplex ( int  EventSet)

convert a standard event set to a multiplexed event set

Definition at line 3256 of file papi.c.

{
    PAPI_option_t mpx;
    EventSetInfo_t *ESI;
    int cidx;
    int ret;

    /* Is the EventSet already in existence? */

    ESI = _papi_hwi_lookup_EventSet( EventSet );

    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    /* if the eventset has no index return NOCMP */
    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 )
        papi_return( cidx );

    if ( ( ret = mpx_check( EventSet ) ) != PAPI_OK )
        papi_return( ret );

    memset( &mpx, 0x0, sizeof ( mpx ) );
    mpx.multiplex.eventset = EventSet;
    mpx.multiplex.flags = PAPI_MULTIPLEX_DEFAULT;
    mpx.multiplex.ns = _papi_os_info.itimer_ns;
    return ( PAPI_set_opt( PAPI_MULTIPLEX, &mpx ) );
}
int PAPI_set_opt ( int  option,
PAPI_option_t ptr 
)

change the option settings of the PAPI library or a specific event set

Definition at line 3386 of file papi.c.

{
    APIDBG("Entry:  option: %d, ptr: %p\n", option, ptr);

    _papi_int_option_t internal;
    int retval = PAPI_OK;
    hwd_context_t *context;
    int cidx;

    if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
        papi_return( PAPI_ENOINIT );
    if ( ptr == NULL )
        papi_return( PAPI_EINVAL );

    memset( &internal, 0x0, sizeof ( _papi_int_option_t ) );

    switch ( option ) {
    case PAPI_DETACH:
    {
        internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
        if ( internal.attach.ESI == NULL )
            papi_return( PAPI_ENOEVST );

        cidx = valid_ESI_component( internal.attach.ESI );
        if ( cidx < 0 )
            papi_return( cidx );

        if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
            papi_return( PAPI_ECMP );

        /* if attached to a cpu, return an error */
        if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
            papi_return( PAPI_ECMP );

        if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
            papi_return( PAPI_EISRUN );

        if ( ( internal.attach.ESI->state & PAPI_ATTACHED ) == 0 )
            papi_return( PAPI_EINVAL );

        internal.attach.tid = internal.attach.ESI->attach.tid;
        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( internal.attach.ESI, NULL );
        retval = _papi_hwd[cidx]->ctl( context, PAPI_DETACH, &internal );
        if ( retval != PAPI_OK )
            papi_return( retval );

        internal.attach.ESI->state ^= PAPI_ATTACHED;
        internal.attach.ESI->attach.tid = 0;
        return ( PAPI_OK );
    }
    case PAPI_ATTACH:
    {
        internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
        if ( internal.attach.ESI == NULL )
            papi_return( PAPI_ENOEVST );

        cidx = valid_ESI_component( internal.attach.ESI );
        if ( cidx < 0 )
            papi_return( cidx );

        if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
            papi_return( PAPI_ECMP );

        if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
            papi_return( PAPI_EISRUN );

        if ( internal.attach.ESI->state & PAPI_ATTACHED )
            papi_return( PAPI_EINVAL );

        /* if attached to a cpu, return an error */
        if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
            papi_return( PAPI_ECMP );

        internal.attach.tid = ptr->attach.tid;
        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( internal.attach.ESI, NULL );
        retval = _papi_hwd[cidx]->ctl( context, PAPI_ATTACH, &internal );
        if ( retval != PAPI_OK )
            papi_return( retval );

        internal.attach.ESI->state |= PAPI_ATTACHED;
        internal.attach.ESI->attach.tid = ptr->attach.tid;

        papi_return (_papi_hwi_lookup_or_create_thread( 
                      &(internal.attach.ESI->master), ptr->attach.tid ));
    }
    case PAPI_CPU_ATTACH:
    {
        APIDBG("eventset: %d, cpu_num: %d\n", ptr->cpu.eventset, ptr->cpu.cpu_num);
        internal.cpu.ESI = _papi_hwi_lookup_EventSet( ptr->cpu.eventset );
        if ( internal.cpu.ESI == NULL )
            papi_return( PAPI_ENOEVST );

        internal.cpu.cpu_num = ptr->cpu.cpu_num;
        APIDBG("internal: %p, ESI: %p, cpu_num: %d\n", &internal, internal.cpu.ESI, internal.cpu.cpu_num);

        cidx = valid_ESI_component( internal.cpu.ESI );
        if ( cidx < 0 )
            papi_return( cidx );

        if ( _papi_hwd[cidx]->cmp_info.cpu == 0 )
            papi_return( PAPI_ECMP );

        // can not attach to a cpu if already attached to a process or 
        // counters set to be inherited by child processes
        if ( internal.cpu.ESI->state & (PAPI_ATTACHED | PAPI_INHERIT) )
            papi_return( PAPI_EINVAL );

        if ( ( internal.cpu.ESI->state & PAPI_STOPPED ) == 0 )
            papi_return( PAPI_EISRUN );

        retval = _papi_hwi_lookup_or_create_cpu(&internal.cpu.ESI->CpuInfo, internal.cpu.cpu_num);
        if( retval != PAPI_OK) {
            papi_return( retval );
        }

        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
        retval = _papi_hwd[cidx]->ctl( context, PAPI_CPU_ATTACH, &internal );
        if ( retval != PAPI_OK )
            papi_return( retval );

        /* set to show this event set is attached to a cpu not a thread */
        internal.cpu.ESI->state |= PAPI_CPU_ATTACHED;
        return ( PAPI_OK );
    }
    case PAPI_DEF_MPX_NS:
    {
        cidx = 0;            /* xxxx for now, assume we only check against cpu component */
        if ( ptr->multiplex.ns < 0 )
            papi_return( PAPI_EINVAL );
        /* We should check the resolution here with the system, either
           component if kernel multiplexing or PAPI if SW multiplexing. */
        internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
        /* Low level just checks/adjusts the args for this component */
        retval = _papi_hwd[cidx]->ctl( context, PAPI_DEF_MPX_NS, &internal );
        if ( retval == PAPI_OK ) {
            _papi_os_info.itimer_ns = ( int ) internal.multiplex.ns;
            ptr->multiplex.ns = ( int ) internal.multiplex.ns;
        }
        papi_return( retval );
    }
    case PAPI_DEF_ITIMER_NS:
    {
        cidx = 0;            /* xxxx for now, assume we only check against cpu component */
        if ( ptr->itimer.ns < 0 )
            papi_return( PAPI_EINVAL );
        internal.itimer.ns = ptr->itimer.ns;
        /* Low level just checks/adjusts the args for this component */
        retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER_NS, &internal );
        if ( retval == PAPI_OK ) {
            _papi_os_info.itimer_ns = internal.itimer.ns;
            ptr->itimer.ns = internal.itimer.ns;
        }
        papi_return( retval );
    }
    case PAPI_DEF_ITIMER:
    {
        cidx = 0;            /* xxxx for now, assume we only check against cpu component */
        if ( ptr->itimer.ns < 0 )
            papi_return( PAPI_EINVAL );
        memcpy( &internal.itimer, &ptr->itimer,
                sizeof ( PAPI_itimer_option_t ) );
        /* Low level just checks/adjusts the args for this component */
        retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER, &internal );
        if ( retval == PAPI_OK ) {
            _papi_os_info.itimer_num = ptr->itimer.itimer_num;
            _papi_os_info.itimer_sig = ptr->itimer.itimer_sig;
            if ( ptr->itimer.ns > 0 )
                _papi_os_info.itimer_ns = ptr->itimer.ns;
            /* flags are currently ignored, eventually the flags will be able
               to specify whether or not we use POSIX itimers (clock_gettimer) */
        }
        papi_return( retval );
    }
    case PAPI_MULTIPLEX:
    {
        EventSetInfo_t *ESI;
        ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
       
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );

        cidx = valid_ESI_component( ESI );
        if ( cidx < 0 )
            papi_return( cidx );
       
        if ( !( ESI->state & PAPI_STOPPED ) )
            papi_return( PAPI_EISRUN );
        if ( ESI->state & PAPI_MULTIPLEXING )
            papi_return( PAPI_EINVAL );

        if ( ptr->multiplex.ns < 0 )
            papi_return( PAPI_EINVAL );
        internal.multiplex.ESI = ESI;
        internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
        internal.multiplex.flags = ptr->multiplex.flags;
        if ( ( _papi_hwd[cidx]->cmp_info.kernel_multiplex ) &&
             ( ( ptr->multiplex.flags & PAPI_MULTIPLEX_FORCE_SW ) == 0 ) ) {
            /* get the context we should use for this event set */
            context = _papi_hwi_get_context( ESI, NULL );
            retval = _papi_hwd[cidx]->ctl( context, PAPI_MULTIPLEX, &internal );
        }
        /* Kernel or PAPI may have changed this value so send it back out to the user */
        ptr->multiplex.ns = ( int ) internal.multiplex.ns;
        if ( retval == PAPI_OK )
            papi_return( _papi_hwi_convert_eventset_to_multiplex
                         ( &internal.multiplex ) );
        return ( retval );
    }
    case PAPI_DEBUG:
    {
        int level = ptr->debug.level;
        switch ( level ) {
        case PAPI_QUIET:
        case PAPI_VERB_ESTOP:
        case PAPI_VERB_ECONT:
            _papi_hwi_error_level = level;
            break;
        default:
            papi_return( PAPI_EINVAL );
        }
        _papi_hwi_debug_handler = ptr->debug.handler;
        return ( PAPI_OK );
    }
    case PAPI_DEFDOM:
    {
        int dom = ptr->defdomain.domain;
        if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
            papi_return( PAPI_EINVAL );

        /* Change the global structure. The _papi_hwd_init_control_state function 
           in the components gets information from the global structure instead of
           per-thread information. */
        cidx = valid_component( ptr->defdomain.def_cidx );
        if ( cidx < 0 )
            papi_return( cidx );

        /* Check what the component supports */

        if ( dom == PAPI_DOM_ALL )
            dom = _papi_hwd[cidx]->cmp_info.available_domains;

        if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
            papi_return( PAPI_EINVAL );

        _papi_hwd[cidx]->cmp_info.default_domain = dom;

        return ( PAPI_OK );
    }
    case PAPI_DOMAIN:
    {
        int dom = ptr->domain.domain;
        if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
            papi_return( PAPI_EINVAL_DOM );

        internal.domain.ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
        if ( internal.domain.ESI == NULL )
            papi_return( PAPI_ENOEVST );

        cidx = valid_ESI_component( internal.domain.ESI );
        if ( cidx < 0 )
            papi_return( cidx );

        /* Check what the component supports */

        if ( dom == PAPI_DOM_ALL )
            dom = _papi_hwd[cidx]->cmp_info.available_domains;

        if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
            papi_return( PAPI_EINVAL_DOM );

        if ( !( internal.domain.ESI->state & PAPI_STOPPED ) )
            papi_return( PAPI_EISRUN );

        /* Try to change the domain of the eventset in the hardware */
        internal.domain.domain = dom;
        internal.domain.eventset = ptr->domain.eventset;
        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( internal.domain.ESI, NULL );
        retval = _papi_hwd[cidx]->ctl( context, PAPI_DOMAIN, &internal );
        if ( retval < PAPI_OK )
            papi_return( retval );

        /* Change the domain of the eventset in the library */

        internal.domain.ESI->domain.domain = dom;

        return ( retval );
    }
    case PAPI_DEFGRN:
    {
        int grn = ptr->defgranularity.granularity;
        if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
            papi_return( PAPI_EINVAL );

        cidx = valid_component( ptr->defgranularity.def_cidx );
        if ( cidx < 0 )
            papi_return( cidx );

        /* Change the component structure. The _papi_hwd_init_control_state function 
           in the components gets information from the global structure instead of
           per-thread information. */

        /* Check what the component supports */

        if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
            papi_return( PAPI_EINVAL );

        /* Make sure there is only 1 set. */
        if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
            papi_return( PAPI_EINVAL );

        _papi_hwd[cidx]->cmp_info.default_granularity = grn;

        return ( PAPI_OK );
    }
    case PAPI_GRANUL:
    {
        int grn = ptr->granularity.granularity;

        if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
            papi_return( PAPI_EINVAL );

        internal.granularity.ESI =
            _papi_hwi_lookup_EventSet( ptr->granularity.eventset );
        if ( internal.granularity.ESI == NULL )
            papi_return( PAPI_ENOEVST );

        cidx = valid_ESI_component( internal.granularity.ESI );
        if ( cidx < 0 )
            papi_return( cidx );

        /* Check what the component supports */

        if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
            papi_return( PAPI_EINVAL );

        /* Make sure there is only 1 set. */
        if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
            papi_return( PAPI_EINVAL );

        internal.granularity.granularity = grn;
        internal.granularity.eventset = ptr->granularity.eventset;
        retval = _papi_hwd[cidx]->ctl( NULL, PAPI_GRANUL, &internal );
        if ( retval < PAPI_OK )
            return ( retval );

        internal.granularity.ESI->granularity.granularity = grn;
        return ( retval );
    }
    case PAPI_INHERIT:
    {
        EventSetInfo_t *ESI;
        ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );

        cidx = valid_ESI_component( ESI );
        if ( cidx < 0 )
            papi_return( cidx );

        if ( _papi_hwd[cidx]->cmp_info.inherit == 0 )
            papi_return( PAPI_ECMP );

        if ( ( ESI->state & PAPI_STOPPED ) == 0 )
            papi_return( PAPI_EISRUN );

        /* if attached to a cpu, return an error */
        if (ESI->state & PAPI_CPU_ATTACHED)
            papi_return( PAPI_ECMP );

        internal.inherit.ESI = ESI;
        internal.inherit.inherit = ptr->inherit.inherit;

        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( internal.inherit.ESI, NULL );
        retval = _papi_hwd[cidx]->ctl( context, PAPI_INHERIT, &internal );
        if ( retval < PAPI_OK )
            return ( retval );

        ESI->inherit.inherit = ptr->inherit.inherit;
        return ( retval );
    }
    case PAPI_DATA_ADDRESS:
    case PAPI_INSTR_ADDRESS:
    {

        EventSetInfo_t *ESI;

        ESI = _papi_hwi_lookup_EventSet( ptr->addr.eventset );
        if ( ESI == NULL )
            papi_return( PAPI_ENOEVST );

        cidx = valid_ESI_component( ESI );
        if ( cidx < 0 )
            papi_return( cidx );

        internal.address_range.ESI = ESI;

        if ( !( internal.address_range.ESI->state & PAPI_STOPPED ) )
            papi_return( PAPI_EISRUN );

        /*set domain to be PAPI_DOM_USER */
        internal.address_range.domain = PAPI_DOM_USER;

        internal.address_range.start = ptr->addr.start;
        internal.address_range.end = ptr->addr.end;
        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( internal.address_range.ESI, NULL );
        retval = _papi_hwd[cidx]->ctl( context, option, &internal );
        ptr->addr.start_off = internal.address_range.start_off;
        ptr->addr.end_off = internal.address_range.end_off;
        papi_return( retval );
    }
    case PAPI_USER_EVENTS_FILE:
    {
      SUBDBG("Filename is -%s-\n", ptr->events_file);
      _papi_user_defined_events_setup(ptr->events_file);
      return( PAPI_OK );
    }
    default:
        papi_return( PAPI_EINVAL );
    }
}
int PAPI_set_thr_specific ( int  tag,
void *  ptr 
)

save a pointer as a thread specific stored data structure

Definition at line 436 of file papi.c.

{
    ThreadInfo_t *thread;
    int retval = PAPI_OK;

    if ( init_level == PAPI_NOT_INITED )
        papi_return( PAPI_ENOINIT );
    if ( ( tag < 0 ) || ( tag > PAPI_NUM_TLS ) )
        papi_return( PAPI_EINVAL );

    retval = _papi_hwi_lookup_or_create_thread( &thread, 0 );
    if ( retval == PAPI_OK ) {
       _papi_hwi_lock( THREADS_LOCK );
       thread->thread_storage[tag] = ptr;
       _papi_hwi_unlock( THREADS_LOCK );
    }
    else
        return ( retval );

    return ( PAPI_OK );
}
void PAPI_shutdown ( void  )

finish using PAPI and free all related resources

Definition at line 4372 of file papi.c.

{
        EventSetInfo_t *ESI;
        ThreadInfo_t *master;
        DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
        int i, j = 0, retval;


    APIDBG( "Enter\n" );
    if ( init_retval == DEADBEEF ) {
        PAPIERROR( PAPI_SHUTDOWN_str );
        return;
    }

    MPX_shutdown(  );

    /* Free all EventSets for this thread */

   master = _papi_hwi_lookup_thread( 0 );

      /* Count number of running EventSets AND */
      /* Stop any running EventSets in this thread */

#ifdef DEBUG
again:
#endif
   for( i = 0; i < map->totalSlots; i++ ) {
      ESI = map->dataSlotArray[i];
      if ( ESI ) {
     if ( ESI->master == master ) {
        if ( ESI->state & PAPI_RUNNING ) {
           retval=PAPI_stop( i, NULL );
        }
        retval=PAPI_cleanup_eventset( i );
        if (retval!=PAPI_OK) PAPIERROR("Error during cleanup.\n");
        _papi_hwi_free_EventSet( ESI );
     } 
         else {
            if ( ESI->state & PAPI_RUNNING ) {
           j++;
        }
     }
      }
   }

    /* No locking required, we're just waiting for the others
       to call shutdown or stop their eventsets. */

#ifdef DEBUG
    if ( j != 0 ) {
        PAPIERROR( PAPI_SHUTDOWN_SYNC_str );
        sleep( 1 );
        j = 0;
        goto again;
    }
#endif

    /* Shutdown the entire component */

    _papi_cleanup_user_events();

    _papi_hwi_shutdown_highlevel(  );
    _papi_hwi_shutdown_global_internal(  );
    _papi_hwi_shutdown_global_threads(  );
    for( i = 0; i < papi_num_components; i++ ) {
       if (!_papi_hwd[i]->cmp_info.disabled) {
              _papi_hwd[i]->shutdown_component(  );
       }
    }

    /* Now it is safe to call re-init */

    init_retval = DEADBEEF;
    init_level = PAPI_NOT_INITED;
    _papi_mem_cleanup_all(  );
}
int PAPI_sprofil ( PAPI_sprofil_t prof,
int  profcnt,
int  EventSet,
int  EventCode,
int  threshold,
int  flags 
)

generate hardware counter profiles from multiple code regions

Definition at line 4939 of file papi.c.

{
   EventSetInfo_t *ESI;
   int retval, index, i, buckets;
   int forceSW = 0;
   int cidx;

   /* Check to make sure EventSet exists */
   ESI = _papi_hwi_lookup_EventSet( EventSet );
   if ( ESI == NULL ) {
      papi_return( PAPI_ENOEVST );
   }

   /* Check to make sure EventSet is stopped */
   if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
      papi_return( PAPI_EISRUN );
   }

   /* We cannot profile if attached */
   if ( ESI->state & PAPI_ATTACHED ) {
      papi_return( PAPI_EINVAL );
   }

   /* We cannot profile if cpu attached */
   if ( ESI->state & PAPI_CPU_ATTACHED ) {
      papi_return( PAPI_EINVAL );
   }

   /* Get component for EventSet */
   cidx = valid_ESI_component( ESI );
   if ( cidx < 0 ) {
      papi_return( cidx );
   }

   /* Get index of the Event we want to profile */
   if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
                      (unsigned int) EventCode ) ) < 0 ) {
      papi_return( PAPI_ENOEVNT );
   }

   /* We do not support derived events in overflow */
   /* Unless it's DERIVED_CMPD in which no calculations are done */
   if ( ( ESI->EventInfoArray[index].derived ) &&
    ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) &&
    !( flags & PAPI_PROFIL_FORCE_SW ) ) {
      papi_return( PAPI_EINVAL );
   }

   /* If no prof structures, then make sure count is 0 */
   if ( prof == NULL ) {
      profcnt = 0;
   }

   /* check all profile regions for valid scale factors of:
      2 (131072/65536),
      1 (65536/65536),
      or < 1 (65535 -> 2) as defined in unix profil()
      2/65536 is reserved for single bucket profiling
      {0,1}/65536 are traditionally used to terminate profiling
      but are unused here since PAPI uses threshold instead
    */
   for( i = 0; i < profcnt; i++ ) {
      if ( !( ( prof[i].pr_scale == 131072 ) ||
       ( ( prof[i].pr_scale <= 65536 && prof[i].pr_scale > 1 ) ) ) ) {
     APIDBG( "Improper scale factor: %d\n", prof[i].pr_scale );
     papi_return( PAPI_EINVAL );
      }
   }

   /* Make sure threshold is valid */
   if ( threshold < 0 ) {
      papi_return( PAPI_EINVAL );
   }

   /* the first time to call PAPI_sprofil */
   if ( !( ESI->state & PAPI_PROFILING ) ) {
      if ( threshold == 0 ) {
     papi_return( PAPI_EINVAL );
      }
   }

   /* ??? */
   if ( (threshold > 0) &&
    (ESI->profile.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs) ) {
      papi_return( PAPI_ECNFLCT );
   }

   if ( threshold == 0 ) {
      for( i = 0; i < ESI->profile.event_counter; i++ ) {
     if ( ESI->profile.EventCode[i] == EventCode ) {
        break;
     }
      }
        
      /* EventCode not found */
      if ( i == ESI->profile.event_counter ) {
     papi_return( PAPI_EINVAL );
      }

      /* compact these arrays */
      while ( i < ESI->profile.event_counter - 1 ) {
         ESI->profile.prof[i] = ESI->profile.prof[i + 1];
     ESI->profile.count[i] = ESI->profile.count[i + 1];
     ESI->profile.threshold[i] = ESI->profile.threshold[i + 1];
     ESI->profile.EventIndex[i] = ESI->profile.EventIndex[i + 1];
     ESI->profile.EventCode[i] = ESI->profile.EventCode[i + 1];
     i++;
      }
      ESI->profile.prof[i] = NULL;
      ESI->profile.count[i] = 0;
      ESI->profile.threshold[i] = 0;
      ESI->profile.EventIndex[i] = 0;
      ESI->profile.EventCode[i] = 0;
      ESI->profile.event_counter--;
   } else {
      if ( ESI->profile.event_counter > 0 ) {
     if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
          !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
        papi_return( PAPI_ECNFLCT );
     }
     if ( !( flags & PAPI_PROFIL_FORCE_SW ) &&
          ( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
        papi_return( PAPI_ECNFLCT );
     }
      }

      for( i = 0; i < ESI->profile.event_counter; i++ ) {
     if ( ESI->profile.EventCode[i] == EventCode ) {
        break;
     }
      }

      if ( i == ESI->profile.event_counter ) {
     i = ESI->profile.event_counter;
     ESI->profile.event_counter++;
     ESI->profile.EventCode[i] = EventCode;
      }
      ESI->profile.prof[i] = prof;
      ESI->profile.count[i] = profcnt;
      ESI->profile.threshold[i] = threshold;
      ESI->profile.EventIndex[i] = index;
   }

   APIDBG( "Profile event counter is %d\n", ESI->profile.event_counter );

   /* Clear out old flags */
   if ( threshold == 0 ) {
      flags |= ESI->profile.flags;
   }

   /* make sure no invalid flags are set */
   if ( flags &
    ~( PAPI_PROFIL_POSIX | PAPI_PROFIL_RANDOM | PAPI_PROFIL_WEIGHTED |
       PAPI_PROFIL_COMPRESS | PAPI_PROFIL_BUCKETS | PAPI_PROFIL_FORCE_SW |
       PAPI_PROFIL_INST_EAR | PAPI_PROFIL_DATA_EAR ) ) {
      papi_return( PAPI_EINVAL );
   }

   /* if we have kernel-based profiling, then we're just asking for 
      signals on interrupt. */
   /* if we don't have kernel-based profiling, then we're asking for 
      emulated PMU interrupt */
   if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
    ( _papi_hwd[cidx]->cmp_info.kernel_profile == 0 ) ) {
      forceSW = PAPI_OVERFLOW_FORCE_SW;
   }

   /* make sure one and only one bucket size is set */
   buckets = flags & PAPI_PROFIL_BUCKETS;
   if ( !buckets ) {
      flags |= PAPI_PROFIL_BUCKET_16;   /* default to 16 bit if nothing set */
   }
   else {
      /* return error if more than one set */
      if ( !( ( buckets == PAPI_PROFIL_BUCKET_16 ) ||
          ( buckets == PAPI_PROFIL_BUCKET_32 ) ||
          ( buckets == PAPI_PROFIL_BUCKET_64 ) ) ) {
     papi_return( PAPI_EINVAL );
      }
   }

   /* Set up the option structure for the low level */
   ESI->profile.flags = flags;

   if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
    !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
      retval = _papi_hwd[cidx]->set_profile( ESI, index, threshold );
      if ( ( retval == PAPI_OK ) && ( threshold > 0 ) ) {
     /* We need overflowing because we use the overflow dispatch handler */
     ESI->state |= PAPI_OVERFLOWING;
     ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
      }
   } else {
      retval = PAPI_overflow( EventSet, EventCode, threshold, forceSW,
                  _papi_hwi_dummy_handler );
   }
    
   if ( retval < PAPI_OK ) {
      papi_return( retval );    /* We should undo stuff here */
   }

   /* Toggle the profiling flags and ESI state */

   if ( ESI->profile.event_counter >= 1 ) {
      ESI->state |= PAPI_PROFILING;
   }
   else {
      ESI->state ^= PAPI_PROFILING;
      ESI->profile.flags = 0;
   }

   return PAPI_OK;
}
int PAPI_start ( int  EventSet)

start counting hardware events in an event set

Definition at line 2034 of file papi.c.

{
    APIDBG("Entry: EventSet: %d\n", EventSet);
    int is_dirty=0;
    int retval;
    EventSetInfo_t *ESI;
    ThreadInfo_t *thread = NULL;
    CpuInfo_t *cpu = NULL;
    hwd_context_t *context;
    int cidx;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL ) {
       papi_return( PAPI_ENOEVST );
    }

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 ) {
       papi_return( cidx );
    }

    /* only one event set per thread/cpu can be running at any time, */
    /* so if another event set is running, the user must stop that   */
        /* event set explicitly */

        thread = ESI->master;
    cpu = ESI->CpuInfo;

    /* check cpu attached case first */
    if (ESI->state & PAPI_CPU_ATTACHED) {
       if ( cpu->running_eventset[cidx] ) {
          papi_return( PAPI_EISRUN );
       }
    } else {
        if ( thread->running_eventset[cidx] ) {
           papi_return( PAPI_EISRUN );
        }
    } 
    
    /* Check that there are added events */
    if ( ESI->NumberOfEvents < 1 ) {
       papi_return( PAPI_EINVAL );
    }

    /* If multiplexing is enabled for this eventset,
       call John May's code. */

    if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
       retval = MPX_start( ESI->multiplex.mpx_evset );
       if ( retval != PAPI_OK ) {
          papi_return( retval );
       }

       /* Update the state of this EventSet */
       ESI->state ^= PAPI_STOPPED;
       ESI->state |= PAPI_RUNNING;

       return PAPI_OK;
    }

    /* get the context we should use for this event set */
    context = _papi_hwi_get_context( ESI, &is_dirty );
    if (is_dirty) {
       /* we need to reset the context state because it was last used   */
       /* for some other event set and does not contain the information */
           /* for our events.                                               */
       retval = _papi_hwd[ESI->CmpIdx]->update_control_state( 
                                                        ESI->ctl_state,
                            ESI->NativeInfoArray,
                            ESI->NativeCount,
                            context);
       if ( retval != PAPI_OK ) {
          papi_return( retval );
       }
        
       /* now that the context contains this event sets information,    */
       /* make sure the position array in the EventInfoArray is correct */

       /* We have to do this because ->update_control_state() can */
       /* in theory re-order the native events out from under us. */
       _papi_hwi_map_events_to_native( ESI );

    }

    /* If overflowing is enabled, turn it on */
    if ( ( ESI->state & PAPI_OVERFLOWING ) &&
         !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
       retval = _papi_hwi_start_signal( _papi_os_info.itimer_sig, 
                        NEED_CONTEXT, cidx );
       if ( retval != PAPI_OK ) {
          papi_return( retval );
       }

       /* Update the state of this EventSet and thread */
       /* before to avoid races                        */
       ESI->state ^= PAPI_STOPPED;
       ESI->state |= PAPI_RUNNING;
           /* can not be attached to thread or cpu if overflowing */
       thread->running_eventset[cidx] = ESI;

       retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
       if ( retval != PAPI_OK ) {
          _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
          ESI->state ^= PAPI_RUNNING;
          ESI->state |= PAPI_STOPPED;
          thread->running_eventset[cidx] = NULL;
          papi_return( retval );
       }

       retval = _papi_hwi_start_timer( _papi_os_info.itimer_num,
                       _papi_os_info.itimer_sig,
                       _papi_os_info.itimer_ns );
       if ( retval != PAPI_OK ) {
          _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
          _papi_hwd[cidx]->stop( context, ESI->ctl_state );
          ESI->state ^= PAPI_RUNNING;
          ESI->state |= PAPI_STOPPED;
          thread->running_eventset[cidx] = NULL;
          papi_return( retval );
       }
    } else {
       /* Update the state of this EventSet and thread before */
       /* to avoid races                                      */
       ESI->state ^= PAPI_STOPPED;
       ESI->state |= PAPI_RUNNING;
        
       /* if not attached to cpu or another process */
       if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
          if ( !( ESI->state & PAPI_ATTACHED ) ) {
         thread->running_eventset[cidx] = ESI;
          }
       } else {
          cpu->running_eventset[cidx] = ESI;
       }

       retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
       if ( retval != PAPI_OK ) {
          _papi_hwd[cidx]->stop( context, ESI->ctl_state );
          ESI->state ^= PAPI_RUNNING;
          ESI->state |= PAPI_STOPPED;
          if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
         if ( !( ESI->state & PAPI_ATTACHED ) ) 
            thread->running_eventset[cidx] = NULL;
          } else {
         cpu->running_eventset[cidx] = NULL;
          }
          papi_return( retval );
       }
    }

    return retval;
}
int PAPI_state ( int  EventSet,
int *  status 
)

return the counting state of an event set

Definition at line 2976 of file papi.c.

{
    EventSetInfo_t *ESI;

    if ( status == NULL )
        papi_return( PAPI_EINVAL );

    /* check for good EventSetIndex value */

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    /*read status FROM ESI->state */

    *status = ESI->state;

    return ( PAPI_OK );
}
int PAPI_stop ( int  EventSet,
long long *  values 
)

stop counting hardware events in an event set and return current events

Definition at line 2239 of file papi.c.

{
   APIDBG("Entry: EventSet: %d, values: %p\n", EventSet, values);
    EventSetInfo_t *ESI;
    hwd_context_t *context;
    int cidx, retval;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 )
        papi_return( cidx );

    if ( !( ESI->state & PAPI_RUNNING ) )
        papi_return( PAPI_ENOTRUN );

    /* If multiplexing is enabled for this eventset, turn if off */

    if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
        retval = MPX_stop( ESI->multiplex.mpx_evset, values );
        if ( retval != PAPI_OK )
            papi_return( retval );

        /* Update the state of this EventSet */

        ESI->state ^= PAPI_RUNNING;
        ESI->state |= PAPI_STOPPED;

        return ( PAPI_OK );
    }

    /* get the context we should use for this event set */
    context = _papi_hwi_get_context( ESI, NULL );
    /* Read the current counter values into the EventSet */
    retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
    if ( retval != PAPI_OK )
        papi_return( retval );

    /* Remove the control bits from the active counter config. */
    retval = _papi_hwd[cidx]->stop( context, ESI->ctl_state );
    if ( retval != PAPI_OK )
        papi_return( retval );
    if ( values )
        memcpy( values, ESI->sw_stop,
                ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );

    /* If kernel profiling is in use, flush and process the kernel buffer */

    if ( ESI->state & PAPI_PROFILING ) {
        if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
             !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
            retval = _papi_hwd[cidx]->stop_profiling( ESI->master, ESI );
            if ( retval < PAPI_OK )
                papi_return( retval );
        }
    }

    /* If overflowing is enabled, turn it off */

    if ( ESI->state & PAPI_OVERFLOWING ) {
        if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
            retval = _papi_hwi_stop_timer( _papi_os_info.itimer_num,
                               _papi_os_info.itimer_sig );
            if ( retval != PAPI_OK )
                papi_return( retval );
            _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
        }
    }

    /* Update the state of this EventSet */

    ESI->state ^= PAPI_RUNNING;
    ESI->state |= PAPI_STOPPED;

    /* Update the running event set for this thread */
    if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
        if ( !( ESI->state & PAPI_ATTACHED ))
            ESI->master->running_eventset[cidx] = NULL;
    } else {
        ESI->CpuInfo->running_eventset[cidx] = NULL;
    }
    
#if defined(DEBUG)
    if ( _papi_hwi_debug & DEBUG_API ) {
        int i;
        for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
            APIDBG( "PAPI_stop ESI->sw_stop[%d]:\t%llu\n", i, ESI->sw_stop[i] );
        }
    }
#endif

    return ( PAPI_OK );
}
char* PAPI_strerror ( int  )

return a pointer to the error name corresponding to a specified error code

Definition at line 4498 of file papi.c.

{
    if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) )
        return ( NULL );

    return ( _papi_errlist[-errorCode] );
}
unsigned long PAPI_thread_id ( void  )

get the thread identifier of the current thread

Definition at line 156 of file papi.c.

{
    if ( _papi_hwi_thread_id_fn != NULL )
        return ( ( *_papi_hwi_thread_id_fn ) (  ) );
    else
#ifdef DEBUG
    if ( _papi_hwi_debug_handler )
        return ( unsigned long ) _papi_hwi_debug_handler( PAPI_EMISC );
#endif
    return ( unsigned long ) PAPI_EMISC;
}
int PAPI_thread_init ( unsigned long(*)(void)  id_fn)

initialize thread support in the PAPI library

int PAPI_unlock ( int  )

unlock one of two PAPI internal user mutex variables

Definition at line 6299 of file papi.c.

{
    if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
        papi_return( PAPI_EINVAL );

    papi_return( _papi_hwi_unlock( lck ) );
}
int PAPI_unregister_thread ( void  )

inform PAPI that a previously registered thread is disappearing

Definition at line 240 of file papi.c.

int PAPI_write ( int  EventSet,
long long *  values 
)

write counter values into counters

Definition at line 2738 of file papi.c.

{
    int cidx, retval = PAPI_OK;
    EventSetInfo_t *ESI;
    hwd_context_t *context;

    ESI = _papi_hwi_lookup_EventSet( EventSet );
    if ( ESI == NULL )
        papi_return( PAPI_ENOEVST );

    cidx = valid_ESI_component( ESI );
    if ( cidx < 0 )
        papi_return( cidx );

    if ( values == NULL )
        papi_return( PAPI_EINVAL );

    if ( ESI->state & PAPI_RUNNING ) {
        /* get the context we should use for this event set */
        context = _papi_hwi_get_context( ESI, NULL );
        retval = _papi_hwd[cidx]->write( context, ESI->ctl_state, values );
        if ( retval != PAPI_OK )
            return ( retval );
    }

    memcpy( ESI->hw_start, values,
            ( size_t ) _papi_hwd[cidx]->cmp_info.num_cntrs *
            sizeof ( long long ) );

    return ( retval );
}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines