PAPI  5.0.1.0
linux-L2unit.c File Reference

This file has the source code for a component that enables PAPI-C to access hardware monitoring counters for BG/Q through the bgpm library. More...

Include dependency graph for linux-L2unit.c:

Go to the source code of this file.

Functions

int L2UNIT_init_thread (hwd_context_t *ctx)
int L2UNIT_init_component (int cidx)
int L2UNIT_init_control_state (hwd_control_state_t *ptr)
int L2UNIT_start (hwd_context_t *ctx, hwd_control_state_t *ptr)
int L2UNIT_stop (hwd_context_t *ctx, hwd_control_state_t *ptr)
int L2UNIT_read (hwd_context_t *ctx, hwd_control_state_t *ptr, long_long **events, int flags)
int L2UNIT_shutdown_thread (hwd_context_t *ctx)
void user_signal_handler_L2UNIT (int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext)
int L2UNIT_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
int L2UNIT_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int L2UNIT_cleanup_eventset (hwd_control_state_t *ctrl)
int L2UNIT_update_control_state (hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
int L2UNIT_set_domain (hwd_control_state_t *cntrl, int domain)
int L2UNIT_reset (hwd_context_t *ctx, hwd_control_state_t *ptr)
int L2UNIT_ntv_enum_events (unsigned int *EventCode, int modifier)
int L2UNIT_ntv_name_to_code (char *name, unsigned int *event_code)
int L2UNIT_ntv_code_to_name (unsigned int EventCode, char *name, int len)
int L2UNIT_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
int L2UNIT_ntv_code_to_bits (unsigned int EventCode, hwd_register_t *bits)

Variables

papi_vector_t _L2unit_vector

Detailed Description

Author:
Heike Jagode jagode@eecs.utk.edu Mods: <your name="" here>=""> <your email="" address>=""> BGPM / L2unit component

Tested version of bgpm (early access)

Definition in file linux-L2unit.c.


Function Documentation

Definition at line 380 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_cleanup_eventset\n" );
#endif
    
    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ctrl;
    
    // create a new empty bgpm eventset
    // reason: bgpm doesn't permit to remove events from an eventset; 
    // hence we delete the old eventset and create a new one
    _common_deleteRecreate( &this_state->EventGroup ); 
    
    // set BGPM eventGroup flag back to NOT applied yet (0)
    this_state->bgpm_eventset_applied = 0;

    
    return ( PAPI_OK );
}

Here is the call graph for this function:

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

Definition at line 362 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_ctl\n" );
#endif
    
    ( void ) ctx;
    ( void ) code;
    ( void ) option;
    return ( PAPI_OK );
}
int L2UNIT_init_component ( int  cidx)

Definition at line 49 of file linux-L2unit.c.

{ 
#ifdef DEBUG_BGQ
    printf( "L2UNIT_init_component\n" );
#endif
    
    _L2unit_vector.cmp_info.CmpIdx = cidx;
#ifdef DEBUG_BGQ
    printf( "L2UNIT_init_component cidx = %d\n", cidx );
#endif
    
    return ( PAPI_OK );
}

Definition at line 69 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_init_control_state\n" );
#endif

    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
    
    this_state->EventGroup = Bgpm_CreateEventSet();
    CHECK_BGPM_ERROR( this_state->EventGroup, "Bgpm_CreateEventSet" );
    
    // initialized BGPM eventGroup flag to NOT applied yet (0)
    this_state->bgpm_eventset_applied = 0;

    return PAPI_OK;
}

Definition at line 33 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_init_thread\n" );
#endif
    
    ( void ) ctx;
    return PAPI_OK;
}
int L2UNIT_ntv_code_to_bits ( unsigned int  EventCode,
hwd_register_t bits 
)

Definition at line 626 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    //printf( "L2UNIT_ntv_code_to_bits\n" );
#endif

    return ( PAPI_OK );
}
int L2UNIT_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 606 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    //printf( "L2UNIT_ntv_code_to_descr\n" );
#endif
    int retval, index;
    
    index = ( EventCode ) + OFFSET;
    
    retval = Bgpm_GetLongDesc( index, name, &len );
    CHECK_BGPM_ERROR( retval, "Bgpm_GetLongDesc" );                      

    return ( PAPI_OK );
}
int L2UNIT_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 577 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    //printf( "L2UNIT_ntv_code_to_name\n" );
#endif
    int index;
    
    index = ( EventCode ) + OFFSET;

    if ( index >= MAX_COUNTERS )
        return PAPI_ENOEVNT;

    strncpy( name, Bgpm_GetEventIdLabel( index ), len );
    
    if ( name == NULL ) {
#ifdef DEBUG_BGPM
        printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" );
#endif
        return PAPI_ENOEVNT;
    }
    
    return ( PAPI_OK );
}
int L2UNIT_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Definition at line 511 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    //printf( "L2UNIT_ntv_enum_events, EventCode = %x\n", *EventCode );
#endif

    switch ( modifier ) {
    case PAPI_ENUM_FIRST:
        *EventCode = 0;

        return ( PAPI_OK );
        break;

    case PAPI_ENUM_EVENTS:
    {
        int index = ( *EventCode ) + OFFSET;

        if ( index < L2UNIT_MAX_COUNTERS ) {
            *EventCode = *EventCode + 1;
            return ( PAPI_OK );
        } else
            return ( PAPI_ENOEVNT );

        break;
    }
    default:
        return ( PAPI_EINVAL );
    }
    return ( PAPI_EINVAL );
}
int L2UNIT_ntv_name_to_code ( char *  name,
unsigned int *  event_code 
)

Definition at line 547 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_ntv_name_to_code\n" );
#endif
    int ret;
    
    /* Return event id matching a given event label string */
    ret = Bgpm_GetEventIdFromLabel ( name );
    
    if ( ret <= 0 ) {
#ifdef DEBUG_BGPM
        printf ("Error: ret value is %d for BGPM API function '%s'.\n",
                ret, "Bgpm_GetEventIdFromLabel" );
#endif
        return PAPI_ENOEVNT;
    }
    else if ( ret < OFFSET || ret > L2UNIT_MAX_COUNTERS ) // not a L2Unit event
        return PAPI_ENOEVNT;
    else
        *event_code = ( ret - OFFSET );

    return PAPI_OK;
}
int L2UNIT_read ( hwd_context_t ctx,
hwd_control_state_t ptr,
long_long **  events,
int  flags 
)

Definition at line 139 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_read\n" );
#endif
    ( void ) ctx;
    ( void ) flags;
    int i, numEvts;
    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
    
    numEvts = Bgpm_NumEvents( this_state->EventGroup );
    if ( numEvts == 0 ) {
#ifdef DEBUG_BGPM
        printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
#endif
        //return ( EXIT_FAILURE );
    }

    for ( i = 0; i < numEvts; i++ )
        this_state->counters[i] = _common_getEventValue( i, this_state->EventGroup );
    
    *events = this_state->counters;
    
    return ( PAPI_OK );
}

Here is the call graph for this function:

int L2UNIT_reset ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 484 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_reset\n" );
#endif
    ( void ) ctx;
    int retval;
    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;

    /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 
     restriction that an EventSet has to be stopped before resetting is
     possible. However, BGPM does have this restriction. 
     Hence we need to stop, reset and start */
    retval = Bgpm_Stop( this_state->EventGroup );
    CHECK_BGPM_ERROR( retval, "Bgpm_Stop" );
    
    retval = Bgpm_ResetStart( this_state->EventGroup );
    CHECK_BGPM_ERROR( retval, "Bgpm_ResetStart" );
    
    return ( PAPI_OK );
}
int L2UNIT_set_domain ( hwd_control_state_t cntrl,
int  domain 
)

Definition at line 456 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_set_domain\n" );
#endif
    int found = 0;
    ( void ) cntrl;

    if ( PAPI_DOM_USER & domain )
        found = 1;

    if ( PAPI_DOM_KERNEL & domain )
        found = 1;

    if ( PAPI_DOM_OTHER & domain )
        found = 1;

    if ( !found )
        return ( PAPI_EINVAL );

    return ( PAPI_OK );
}
int L2UNIT_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)

Definition at line 278 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf("BEGIN L2UNIT_set_overflow\n");
#endif
    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ESI->ctl_state;
    int retval;
    int evt_idx;
    uint64_t threshold_for_bgpm;
    
    /*
     * In case an BGPM eventGroup HAS BEEN applied or attached before
     * overflow is set, delete the eventGroup and create an new empty one,
     * and rebuild as it was prior to deletion
     */
#ifdef DEBUG_BGQ
    printf( "L2UNIT_set_overflow: bgpm_eventset_applied = %d\n",
           this_state->bgpm_eventset_applied );
#endif  
    if ( 1 == this_state->bgpm_eventset_applied ) {
        _common_deleteRecreate( &this_state->EventGroup );
        _common_rebuildEventgroup( this_state->count,
                                  this_state->EventGroup_local,
                                  &this_state->EventGroup );
        
        /* set BGPM eventGroup flag back to NOT applied yet (0) 
         * because the eventGroup has been recreated from scratch */
        this_state->bgpm_eventset_applied = 0;
    }
    
    /* convert threadhold value assigned by PAPI user to value that is
     * programmed into the counter. This value is required by Bgpm_SetOverflow() */ 
    threshold_for_bgpm = BGPM_PERIOD2THRES( threshold );
    
    evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
    SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
           evt_idx, EventIndex, threshold );
#ifdef DEBUG_BGQ
    printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
           evt_idx, EventIndex, threshold );
#endif
    /* If this counter isn't set to overflow, it's an error */
    if ( threshold == 0 ) {
        /* Remove the signal handler */
        retval = _papi_hwi_stop_signal( _L2unit_vector.cmp_info.hardware_intr_sig );
        if ( retval != PAPI_OK )
            return ( retval );
    }
    else {
#ifdef DEBUG_BGQ
        printf( "L2UNIT_set_overflow: Enable the signal handler\n" );
#endif
        /* Enable the signal handler */
        retval = _papi_hwi_start_signal( _L2unit_vector.cmp_info.hardware_intr_sig, 
                                        NEED_CONTEXT, 
                                        _L2unit_vector.cmp_info.CmpIdx );
        if ( retval != PAPI_OK )
            return ( retval );
        
        retval = Bgpm_SetOverflow( this_state->EventGroup,
                                   evt_idx,
                                   threshold_for_bgpm );
        CHECK_BGPM_ERROR( retval, "Bgpm_SetOverflow" );
        
        retval = Bgpm_SetEventUser1( this_state->EventGroup,
                                     evt_idx,
                                     1024 );
        CHECK_BGPM_ERROR( retval, "Bgpm_SetEventUser1" );

        /* user signal handler for overflow case */
        retval = Bgpm_SetOverflowHandler( this_state->EventGroup, user_signal_handler_L2UNIT );
        CHECK_BGPM_ERROR( retval, "Bgpm_SetOverflowHandler" );
    }
    
    return ( PAPI_OK );
}

Here is the call graph for this function:

Definition at line 171 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_shutdown_thread\n" );
#endif
    
    ( void ) ctx;
    return ( PAPI_OK );
}
int L2UNIT_start ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 91 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_start\n" );
#endif
    ( void ) ctx;
    int retval;
    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
    
    retval = Bgpm_Apply( this_state->EventGroup ); 
    CHECK_BGPM_ERROR( retval, "Bgpm_Apply" );

    // set flag to 1: BGPM eventGroup HAS BEEN applied
    this_state->bgpm_eventset_applied = 1;

    /* Bgpm_Apply() does an implicit reset; 
     hence no need to use Bgpm_ResetStart */
    retval = Bgpm_Start( this_state->EventGroup );
    CHECK_BGPM_ERROR( retval, "Bgpm_Start" );
    
    return ( PAPI_OK );
}
int L2UNIT_stop ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 119 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_stop\n" );
#endif
    ( void ) ctx;
    int retval;
    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
    
    retval = Bgpm_Stop( this_state->EventGroup );
    CHECK_BGPM_ERROR( retval, "Bgpm_Stop" );
    
    return ( PAPI_OK );
}
int L2UNIT_update_control_state ( hwd_control_state_t ptr,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)

Definition at line 405 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "L2UNIT_update_control_state: count = %d\n", count );
#endif
    
    ( void ) ctx;
    int retval, index, i;
    L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
    
    // Delete and re-create BGPM eventset
    _common_deleteRecreate( &this_state->EventGroup );
    
    // otherwise, add the events to the eventset
    for ( i = 0; i < count; i++ ) {
        index = ( native[i].ni_event ) + OFFSET;
        
        native[i].ni_position = i;
        
#ifdef DEBUG_BGQ
        printf("L2UNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index );
#endif
        
        this_state->EventGroup_local[i] = index;

        
        /* Add events to the BGPM eventGroup */
        retval = Bgpm_AddEvent( this_state->EventGroup, index );
        CHECK_BGPM_ERROR( retval, "Bgpm_AddEvent" );
    }
    
    // store how many events we added to an EventSet
    this_state->count = count;

    return ( PAPI_OK );
}

Here is the call graph for this function:

void user_signal_handler_L2UNIT ( int  hEvtSet,
uint64_t  address,
uint64_t  ovfVector,
const ucontext_t pContext 
)

Definition at line 191 of file linux-L2unit.c.

{
#ifdef DEBUG_BGQ
    printf( "user_signal_handler_L2UNIT\n" );
#endif
    
    int retval, i;
    int isHardware = 1;
    int cidx = _L2unit_vector.cmp_info.CmpIdx;
    long_long overflow_bit = 0;
    caddr_t address1;
    _papi_hwi_context_t ctx;
    ctx.ucontext = ( hwd_ucontext_t * ) pContext;
    ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
    EventSetInfo_t *ESI;
    ESI = thread->running_eventset[cidx];
    // Get the indices of all events which have overflowed.
    unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS];
    unsigned len = BGPM_MAX_OVERFLOW_EVENTS;
    
    retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len );
    if ( retval < 0 ) {
#ifdef DEBUG_BGPM
        printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n",
                 retval );
#endif
        return;
    }
    
    if ( thread == NULL ) {
        PAPIERROR( "thread == NULL in user_signal_handler!" );
        return;
    }
    
    if ( ESI == NULL ) {
        PAPIERROR( "ESI == NULL in user_signal_handler!");
        return;
    }
    
    if ( ESI->overflow.flags == 0 ) {
        PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!");
        return;
    }
    
    for ( i = 0; i < len; i++ ) {
        uint64_t hProf;
        Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf );
        if ( hProf ) {
            overflow_bit ^= 1 << ovfIdxs[i];
            break;
        }
        
    }
    
    if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) {
#ifdef DEBUG_BGQ
        printf("OVERFLOW_SOFTWARE\n");
#endif
        address1 = GET_OVERFLOW_ADDRESS( ctx );
        _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx );
        return;
    }
    else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
#ifdef DEBUG_BGQ
        printf("OVERFLOW_HARDWARE\n");
#endif
        address1 = GET_OVERFLOW_ADDRESS( ctx );
        _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx );
    }
    else {
#ifdef DEBUG_BGQ
        printf("OVERFLOW_NONE\n");
#endif
        PAPIERROR( "ESI->overflow.flags is set to something other than PAPI_OVERFLOW_HARDWARE or PAPI_OVERFLOW_FORCE_SW (%x)", thread->running_eventset[cidx]->overflow.flags);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 23 of file linux-L2unit.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines