src/components/sde/sde.c
// The following function works only for counters created using papi_sde_create_counter().
The following function works only for counters created using papi_sde_create_counter().
The following function works only for counters created using papi_sde_create_counter () .
int 
__attribute__((visibility("default")))
papi_sde_inc_counter( papi_handle_t cntr_handle, long long int increment)
{
    long long int *ptr;
    sde_counter_t *tmp_cntr;
#if defined(SDE_HAVE_OVERFLOW)
    EventSetInfo_t *ESI;
    int cidx, i, index_in_ESI = -1;
    ThreadInfo_t *thread;
    sde_control_state_t *sde_ctl;
#endif 
    papi_sde_lock();
    tmp_cntr = (sde_counter_t *)cntr_handle;
    if( NULL == tmp_cntr ){
        papi_sde_unlock();
        PAPIERROR("papi_sde_inc_counter(): 'cntr_handle' is clobbered. Unable to modify value of counter.\n");
        return PAPI_EINVAL;
    }
    ptr = (long long int *)(tmp_cntr->data);
    if( NULL == ptr ){
        papi_sde_unlock();
        PAPIERROR("papi_sde_inc_counter(): Counter structure is clobbered. Unable to modify value of counter.\n");
        return PAPI_EINVAL;
    }
    if( !tmp_cntr->is_created ){
        papi_sde_unlock();
        PAPIERROR("papi_sde_inc_counter(): Counter is not created by PAPI, cannot be modified using this function.\n");
        return PAPI_EINVAL;
    }
    if( PAPI_SDE_long_long != tmp_cntr->cntr_type ){
        papi_sde_unlock();
        PAPIERROR("papi_sde_inc_counter(): Counter is not of type \"long long int\" and cannot be modified using this function.\n");
        return PAPI_EINVAL;
    }
    *ptr += increment;
#if defined(SDE_HAVE_OVERFLOW)
    cidx = _sde_vector.cmp_info.CmpIdx;
    thread = _papi_hwi_lookup_thread( 0 );
    if( NULL == thread )
        goto counter_did_not_overflow;
    ESI = thread->running_eventset[cidx];
    if( (NULL == ESI) || !(ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE) ) 
        goto counter_did_not_overflow;
    sde_ctl = ( sde_control_state_t * ) ESI->ctl_state;
    int event_counter = ESI->overflow.event_counter;
    index_in_ESI = -1;
    for (i = 0; i < event_counter; i++ ) {
        int papi_index = ESI->overflow.EventIndex[i];
        unsigned int counter_uniq_id = sde_ctl->which_counter[papi_index];
        if( counter_uniq_id == tmp_cntr->glb_uniq_id ){
            index_in_ESI = i;
            break;
        }
    }
    if( index_in_ESI >= 0 ){
        long long deadline, threshold, latest;
        deadline = ESI->overflow.deadline[index_in_ESI];
        threshold = ESI->overflow.threshold[index_in_ESI];
        latest = *ptr;
        SUBDBG("counter: '%s::%s' has value: %lld and the overflow deadline is at: %lld.\n", tmp_cntr->which_lib->libraryName, tmp_cntr->name, latest, deadline);
        if( latest > deadline ){
            ESI->overflow.deadline[index_in_ESI] = threshold*(latest/threshold) + threshold;
            invoke_user_handler(cntr_handle);
        }
    }
counter_did_not_overflow:
#endif 
    papi_sde_unlock();
    return PAPI_OK;
}
int __attribute__ ( ( visibility ( " " ) ) ) papi_sde_inc_counter ( papi_handle_t cntr_handle , long long int increment ) { long long int * ptr ; sde_counter_t * tmp_cntr ; #if defined ( SDE_HAVE_OVERFLOW ) EventSetInfo_t * ESI ; int cidx , i , index_in_ESI = -1 ; ThreadInfo_t * thread ; sde_control_state_t * sde_ctl ; #endif papi_sde_lock ( ) ; tmp_cntr = ( sde_counter_t * ) cntr_handle ; if ( NULL == tmp_cntr ) { papi_sde_unlock ( ) ; PAPIERROR ( " \n " ) ; return PAPI_EINVAL ; } ptr = ( long long int * ) ( tmp_cntr -> data ) ; if ( NULL == ptr ) { papi_sde_unlock ( ) ; PAPIERROR ( " \n " ) ; return PAPI_EINVAL ; } if ( ! tmp_cntr -> is_created ) { papi_sde_unlock ( ) ; PAPIERROR ( " \n " ) ; return PAPI_EINVAL ; } if ( PAPI_SDE_long_long != tmp_cntr -> cntr_type ) { papi_sde_unlock ( ) ; PAPIERROR ( " \" \" \n " ) ; return PAPI_EINVAL ; } * ptr += increment ; #if defined ( SDE_HAVE_OVERFLOW ) cidx = _sde_vector . cmp_info . CmpIdx ; thread = _papi_hwi_lookup_thread ( 0 ) ; if ( NULL == thread ) goto counter_did_not_overflow ; ESI = thread -> running_eventset [ cidx ] ; if ( ( NULL == ESI ) || ! ( ESI -> overflow . flags & PAPI_OVERFLOW_HARDWARE ) ) goto counter_did_not_overflow ; sde_ctl = ( sde_control_state_t * ) ESI -> ctl_state ; int event_counter = ESI -> overflow . event_counter ; index_in_ESI = -1 ; for ( i = 0 ; i < event_counter ; i ++ ) { int papi_index = ESI -> overflow . EventIndex [ i ] ; unsigned int counter_uniq_id = sde_ctl -> which_counter [ papi_index ] ; if ( counter_uniq_id == tmp_cntr -> glb_uniq_id ) { index_in_ESI = i ; break ; } } if ( index_in_ESI >= 0 ) { long long deadline , threshold , latest ; deadline = ESI -> overflow . deadline [ index_in_ESI ] ; threshold = ESI -> overflow . threshold [ index_in_ESI ] ; latest = * ptr ; SUBDBG ( " \n " , tmp_cntr -> which_lib -> libraryName , tmp_cntr -> name , latest , deadline ) ; if ( latest > deadline ) { ESI -> overflow . deadline [ index_in_ESI ] = threshold * ( latest / threshold ) + threshold ; invoke_user_handler ( cntr_handle ) ; } } counter_did_not_overflow : #endif papi_sde_unlock ( ) ; return PAPI_OK ; }
The following function works only for counters created using papi_sde_create_counter().
The following function works only for counters created using papi_sde_create_counter () .
//defined(SDE_HAVE_OVERFLOW) //    SUBDBG("Preparing to increment counter: '%s::%s' by %lld.\n", tmp_cntr->which_lib->libraryName, tmp_cntr->name, increment); // Check if there is a running event set and it has some events set to overflow // Check all the events that are set to overflow // If the created counter that we are incrementing corresponds to // an event that was set to overflow, read the deadline and threshold. // If the current value has exceeded the deadline then // invoke the user handler and update the deadline. // We adjust the deadline in a way that it remains a multiple of threshold // so we don't create an additive error. However, this code path should // result in a precise overflow trigger, so this might not be necessary. // defined(SDE_HAVE_OVERFLOW)