src/components/sde/sde.c
// In contrast with papi_sde_register_counter(), the following function creates
// a counter whose memory is allocated and managed by PAPI, not the library.
// This counter can only by modified via the functions papi_sde_inc_counter()
// and papi_sde_reset_counter(). This has two benefits over a counter which
// lives inside a library and is modified directly by that library:
// A) Our counter and the modifying API is guaranteed to be thread safe.
// B) Since we learn about each change in the value of the counter, we can
//    implement accurate overflowing and/or a push mode.
//
// However, this approach has higher overhead than executing "my_cntr += value" inside a library.
In contrast with papi_sde_register_counter(), the following function creates
a counter whose memory is allocated and managed by PAPI, not the library.
This counter can only by modified via the functions papi_sde_inc_counter()
and papi_sde_reset_counter(). This has two benefits over a counter which
lives inside a library and is modified directly by that library:
A) Our counter and the modifying API is guaranteed to be thread safe.
B) Since we learn about each change in the value of the counter, we can
implement accurate overflowing and/or a push mode.

However, this approach has higher overhead than executing "my_cntr += value" inside a library.
In contrast with papi_sde_register_counter () the following function creates a counter whose memory is allocated and managed by PAPI not the library . This counter can only by modified via the functions papi_sde_inc_counter () and papi_sde_reset_counter () . This has two benefits over a counter which lives inside a library and is modified directly by that library : A ) Our counter and the modifying API is guaranteed to be thread safe . B ) Since we learn about each change in the value of the counter we can implement accurate overflowing and / or a push mode . However this approach has higher overhead than executing " my_cntr + = value " inside a library .
int 
__attribute__((visibility("default")))
papi_sde_create_counter( papi_handle_t handle, const char *event_name, int cntr_mode, void **cntr_handle )
{
    int ret_val;
    long long int *counter_data;
    char *full_event_name;
    papisde_library_desc_t *lib_handle;
    sde_counter_t *cntr, *placeholder;
    lib_handle = (papisde_library_desc_t *) handle;
    if( (NULL == lib_handle) || (NULL == lib_handle->libraryName) ){
        PAPIERROR("papi_sde_create_counter(): 'handle' is clobbered. Unable to create counter.\n");
        return PAPI_EINVAL;
    }
    SUBDBG("Preparing to create counter: '%s' with mode: '%d' in SDE library: %s.\n", event_name, cntr_mode, lib_handle->libraryName);
    counter_data = calloc(1, sizeof(long long int));
    ret_val = sde_setup_counter_internals( lib_handle, event_name, cntr_mode, PAPI_SDE_long_long, counter_data, NULL, NULL, &placeholder );
    if( PAPI_OK != ret_val ){
        return ret_val;
    }
    size_t str_len = strlen(lib_handle->libraryName)+strlen(event_name)+2+1; 
    full_event_name = malloc(str_len*sizeof(char));
    snprintf(full_event_name, str_len, "%s::%s", lib_handle->libraryName, event_name);
    cntr = ht_lookup_by_name(lib_handle->lib_counters, full_event_name);
    if(NULL == cntr) {
        SUBDBG("Logging counter '%s' not properly inserted in SDE library '%s'\n", full_event_name, lib_handle->libraryName);
        free(full_event_name);
        return PAPI_ECMP;
    }
    cntr->is_created = 1;
    if( NULL != cntr_handle ){
        *(sde_counter_t **)cntr_handle = cntr;
    }
    free(full_event_name);
    return PAPI_OK;
}
int __attribute__ ( ( visibility ( " " ) ) ) papi_sde_create_counter ( papi_handle_t handle , const char * event_name , int cntr_mode , void * * cntr_handle ) { int ret_val ; long long int * counter_data ; char * full_event_name ; papisde_library_desc_t * lib_handle ; sde_counter_t * cntr , * placeholder ; lib_handle = ( papisde_library_desc_t * ) handle ; if ( ( NULL == lib_handle ) || ( NULL == lib_handle -> libraryName ) ) { PAPIERROR ( " \n " ) ; return PAPI_EINVAL ; } SUBDBG ( " \n " , event_name , cntr_mode , lib_handle -> libraryName ) ; counter_data = calloc ( 1 , sizeof ( long long int ) ) ; ret_val = sde_setup_counter_internals ( lib_handle , event_name , cntr_mode , PAPI_SDE_long_long , counter_data , NULL , NULL , & placeholder ) ; if ( PAPI_OK != ret_val ) { return ret_val ; } size_t str_len = strlen ( lib_handle -> libraryName ) + strlen ( event_name ) + 2 + 1 ; full_event_name = malloc ( str_len * sizeof ( char ) ) ; snprintf ( full_event_name , str_len , " " , lib_handle -> libraryName , event_name ) ; cntr = ht_lookup_by_name ( lib_handle -> lib_counters , full_event_name ) ; if ( NULL == cntr ) { SUBDBG ( " \n " , full_event_name , lib_handle -> libraryName ) ; free ( full_event_name ) ; return PAPI_ECMP ; } cntr -> is_created = 1 ; if ( NULL != cntr_handle ) { * ( sde_counter_t * * ) cntr_handle = cntr ; } free ( full_event_name ) ; return PAPI_OK ; }
In contrast with papi_sde_register_counter(), the following function creates
a counter whose memory is allocated and managed by PAPI, not the library.
In contrast with papi_sde_register_counter () the following function creates a counter whose memory is allocated and managed by PAPI not the library .
// +2 for "::" and +1 for '\0' // Signify that this counter is a created counter (as opposed to a registered one). // The reason we need to know is so we can free() the 'data' entry which we allocated here, and for // correctness checking in papi_sde_inc_coutner() and papi_sde_reset_counter().