PAPI 7.1.0.0
Loading...
Searching...
No Matches
sde_lib_internal.h File Reference
Include dependency graph for sde_lib_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  cset_hash_decorated_object_t
 
struct  cset_hash_bucket_t
 
struct  cset_hash_table_t
 
struct  papisde_list_entry_t
 
struct  recorder_data_t
 
struct  cntr_class_basic_t
 
struct  cntr_class_callback_t
 
struct  cntr_class_recorder_t
 
struct  cntr_class_cset_t
 
struct  cntr_class_group_t
 
union  cntr_class_specific_t
 
struct  sde_counter_t
 
struct  sde_sorting_params_t
 
struct  papisde_library_desc_t
 
struct  papisde_control_t
 

Macros

#define EXP_CONTAINER_ENTRIES   52
 
#define EXP_CONTAINER_MIN_SIZE   2048
 
#define PAPISDE_HT_SIZE   512
 
#define is_readonly(_X_)   (PAPI_SDE_RO == ((_X_)&0x0F))
 
#define is_readwrite(_X_)   (PAPI_SDE_RW == ((_X_)&0x0F))
 
#define is_delta(_X_)   (PAPI_SDE_DELTA == ((_X_)&0xF0))
 
#define is_instant(_X_)   (PAPI_SDE_INSTANT == ((_X_)&0xF0))
 
#define _SDE_HASH_BUCKET_COUNT_   373
 
#define _SDE_HASH_BUCKET_WIDTH_   14
 
#define SDE_HASH_IS_FUZZY   0
 
#define IS_CNTR_REGISTERED(_CNT)   ( CNTR_CLASS_REGISTERED == (_CNT)->cntr_class )
 
#define IS_CNTR_CREATED(_CNT)   ( CNTR_CLASS_CREATED == (_CNT)->cntr_class )
 
#define IS_CNTR_BASIC(_CNT)   ( CNTR_CLASS_BASIC & (_CNT)->cntr_class )
 
#define IS_CNTR_CALLBACK(_CNT)   ( CNTR_CLASS_CB == (_CNT)->cntr_class )
 
#define IS_CNTR_RECORDER(_CNT)   ( CNTR_CLASS_RECORDER == (_CNT)->cntr_class )
 
#define IS_CNTR_CSET(_CNT)   ( CNTR_CLASS_CSET == (_CNT)->cntr_class )
 
#define IS_CNTR_PLACEHOLDER(_CNT)   ( CNTR_CLASS_PLACEHOLDER == (_CNT)->cntr_class )
 
#define IS_CNTR_GROUP(_CNT)   ( CNTR_CLASS_GROUP == (_CNT)->cntr_class )
 
#define mix(h)
 

Enumerations

enum  CNTR_CLASS {
  CNTR_CLASS_REGISTERED = 0x1 , CNTR_CLASS_CREATED = 0x2 , CNTR_CLASS_BASIC = 0x3 , CNTR_CLASS_CB = 0x4 ,
  CNTR_CLASS_RECORDER = 0x8 , CNTR_CLASS_CSET = 0x10 , CNTR_CLASS_PLACEHOLDER = 0x1000 , CNTR_CLASS_GROUP = 0x2000
}
 

Functions

int sdei_setup_counter_internals (papi_handle_t handle, const char *event_name, int cntr_mode, int cntr_type, enum CNTR_CLASS cntr_class, cntr_class_specific_t cntr_union)
 
int sdei_delete_counter (papisde_library_desc_t *lib_handle, const char *name)
 
int sdei_inc_ref_count (sde_counter_t *counter)
 
int sdei_read_counter_group (sde_counter_t *counter, long long int *rslt_ptr)
 
void sdei_counting_set_to_list (void *cset_handle, cset_list_object_t **list_head)
 
int sdei_read_and_update_data_value (sde_counter_t *counter, long long int previous_value, long long int *rslt_ptr)
 
int sdei_hardware_write (sde_counter_t *counter, long long int new_value)
 
int sdei_set_timer_for_overflow (void)
 
papisde_control_t * sdei_get_global_struct (void)
 
sde_counter_t * ht_lookup_by_id (papisde_list_entry_t *hash_table, uint32_t uniq_id)
 
sde_counter_t * ht_lookup_by_name (papisde_list_entry_t *hash_table, const char *name)
 
sde_counter_t * ht_delete (papisde_list_entry_t *hash_table, int ht_key, uint32_t uniq_id)
 
void ht_insert (papisde_list_entry_t *hash_table, int ht_key, sde_counter_t *sde_counter)
 
int ht_to_array (papisde_list_entry_t *hash_table, sde_counter_t **rslt_array)
 
uint32_t ht_hash_name (const char *str)
 
uint32_t ht_hash_id (uint32_t uniq_id)
 
papi_handle_t do_sde_init (const char *name_of_library, papisde_control_t *gctl)
 
sde_counter_t * allocate_and_insert (papisde_control_t *gctl, papisde_library_desc_t *lib_handle, const char *name, uint32_t uniq_id, int cntr_mode, int cntr_type, enum CNTR_CLASS cntr_class, cntr_class_specific_t cntr_union)
 
void exp_container_to_contiguous (recorder_data_t *exp_container, void *cont_buffer)
 
int exp_container_insert_element (recorder_data_t *exp_container, size_t typesize, const void *value)
 
void exp_container_init (sde_counter_t *handle, size_t typesize)
 
void papi_sde_counting_set_to_list (void *cset_handle, cset_list_object_t **list_head)
 
int cset_insert_elem (cset_hash_table_t *hash_ptr, size_t element_size, size_t hashable_size, const void *element, uint32_t type_id)
 
int cset_remove_elem (cset_hash_table_t *hash_ptr, size_t hashable_size, const void *element, uint32_t type_id)
 
cset_list_object_t * cset_to_list (cset_hash_table_t *hash_ptr)
 
int cset_delete (cset_hash_table_t *hash_ptr)
 
int sde_ti_reset_counter (uint32_t)
 
int sde_ti_read_counter (uint32_t, long long int *)
 
int sde_ti_write_counter (uint32_t, long long)
 
int sde_ti_name_to_code (const char *, uint32_t *)
 
int sde_ti_is_simple_counter (uint32_t)
 
int sde_ti_is_counter_set_to_overflow (uint32_t)
 
int sde_ti_set_counter_overflow (uint32_t, int)
 
char * sde_ti_get_event_name (int)
 
char * sde_ti_get_event_description (int)
 
int sde_ti_get_num_reg_events (void)
 
int sde_ti_shutdown (void)
 
static uint64_t fasthash64 (const void *buf, size_t len, uint64_t seed)
 

Variables

papisde_control_t * _papisde_global_control
 

Detailed Description

Macro Definition Documentation

◆ _SDE_HASH_BUCKET_COUNT_

#define _SDE_HASH_BUCKET_COUNT_   373

Definition at line 49 of file sde_lib_internal.h.

◆ _SDE_HASH_BUCKET_WIDTH_

#define _SDE_HASH_BUCKET_WIDTH_   14

Definition at line 50 of file sde_lib_internal.h.

◆ EXP_CONTAINER_ENTRIES

#define EXP_CONTAINER_ENTRIES   52

Definition at line 24 of file sde_lib_internal.h.

◆ EXP_CONTAINER_MIN_SIZE

#define EXP_CONTAINER_MIN_SIZE   2048

Definition at line 25 of file sde_lib_internal.h.

◆ IS_CNTR_BASIC

#define IS_CNTR_BASIC (   _CNT)    ( CNTR_CLASS_BASIC & (_CNT)->cntr_class )

Definition at line 164 of file sde_lib_internal.h.

◆ IS_CNTR_CALLBACK

#define IS_CNTR_CALLBACK (   _CNT)    ( CNTR_CLASS_CB == (_CNT)->cntr_class )

Definition at line 165 of file sde_lib_internal.h.

◆ IS_CNTR_CREATED

#define IS_CNTR_CREATED (   _CNT)    ( CNTR_CLASS_CREATED == (_CNT)->cntr_class )

Definition at line 163 of file sde_lib_internal.h.

◆ IS_CNTR_CSET

#define IS_CNTR_CSET (   _CNT)    ( CNTR_CLASS_CSET == (_CNT)->cntr_class )

Definition at line 167 of file sde_lib_internal.h.

◆ IS_CNTR_GROUP

#define IS_CNTR_GROUP (   _CNT)    ( CNTR_CLASS_GROUP == (_CNT)->cntr_class )

Definition at line 169 of file sde_lib_internal.h.

◆ IS_CNTR_PLACEHOLDER

#define IS_CNTR_PLACEHOLDER (   _CNT)    ( CNTR_CLASS_PLACEHOLDER == (_CNT)->cntr_class )

Definition at line 168 of file sde_lib_internal.h.

◆ IS_CNTR_RECORDER

#define IS_CNTR_RECORDER (   _CNT)    ( CNTR_CLASS_RECORDER == (_CNT)->cntr_class )

Definition at line 166 of file sde_lib_internal.h.

◆ IS_CNTR_REGISTERED

#define IS_CNTR_REGISTERED (   _CNT)    ( CNTR_CLASS_REGISTERED == (_CNT)->cntr_class )

Definition at line 162 of file sde_lib_internal.h.

◆ is_delta

#define is_delta (   _X_)    (PAPI_SDE_DELTA == ((_X_)&0xF0))

Definition at line 31 of file sde_lib_internal.h.

◆ is_instant

#define is_instant (   _X_)    (PAPI_SDE_INSTANT == ((_X_)&0xF0))

Definition at line 32 of file sde_lib_internal.h.

◆ is_readonly

#define is_readonly (   _X_)    (PAPI_SDE_RO == ((_X_)&0x0F))

Definition at line 29 of file sde_lib_internal.h.

◆ is_readwrite

#define is_readwrite (   _X_)    (PAPI_SDE_RW == ((_X_)&0x0F))

Definition at line 30 of file sde_lib_internal.h.

◆ mix

#define mix (   h)
Value:
({ \
(h) ^= (h) >> 23; \
(h) *= 0x2127599bf4325c37ULL; \
(h) ^= (h) >> 47; })

Definition at line 239 of file sde_lib_internal.h.

◆ PAPISDE_HT_SIZE

#define PAPISDE_HT_SIZE   512

Definition at line 27 of file sde_lib_internal.h.

◆ SDE_HASH_IS_FUZZY

#define SDE_HASH_IS_FUZZY   0

Definition at line 58 of file sde_lib_internal.h.

Enumeration Type Documentation

◆ CNTR_CLASS

enum CNTR_CLASS
Enumerator
CNTR_CLASS_REGISTERED 
CNTR_CLASS_CREATED 
CNTR_CLASS_BASIC 
CNTR_CLASS_CB 
CNTR_CLASS_RECORDER 
CNTR_CLASS_CSET 
CNTR_CLASS_PLACEHOLDER 
CNTR_CLASS_GROUP 

Definition at line 151 of file sde_lib_internal.h.

151 {
153 CNTR_CLASS_CREATED = 0x2,
154 CNTR_CLASS_BASIC = 0x3, // both previous types combined.
155 CNTR_CLASS_CB = 0x4,
157 CNTR_CLASS_CSET = 0x10,
158 CNTR_CLASS_PLACEHOLDER = 0x1000,
159 CNTR_CLASS_GROUP = 0x2000
160};
@ CNTR_CLASS_GROUP
@ CNTR_CLASS_CREATED
@ CNTR_CLASS_CSET
@ CNTR_CLASS_CB
@ CNTR_CLASS_PLACEHOLDER
@ CNTR_CLASS_REGISTERED
@ CNTR_CLASS_BASIC
@ CNTR_CLASS_RECORDER

Function Documentation

◆ allocate_and_insert()

sde_counter_t * allocate_and_insert ( papisde_control_t *  gctl,
papisde_library_desc_t *  lib_handle,
const char *  name,
uint32_t  uniq_id,
int  cntr_mode,
int  cntr_type,
enum CNTR_CLASS  cntr_class,
cntr_class_specific_t  cntr_union 
)

Definition at line 112 of file sde_lib_misc.c.

112 {
113
114 // make sure to calloc() the structure, so all the fields which we do not explicitly set remain zero.
115 sde_counter_t *item = (sde_counter_t *)calloc(1, sizeof(sde_counter_t));
116 if( NULL == item )
117 return NULL;
118
119 item->u = cntr_union;
120 item->cntr_class = cntr_class;
121 item->cntr_type = cntr_type;
122 item->cntr_mode = cntr_mode;
123 item->glb_uniq_id = uniq_id;
124 item->name = strdup( name );
125 item->description = strdup( name );
126 item->which_lib = lib_handle;
127
128 (void)ht_insert(lib_handle->lib_counters, ht_hash_name(name), item);
129 (void)ht_insert(gctl->all_reg_counters, ht_hash_id(uniq_id), item);
130
131 return item;
132}
const char * name
Definition: rocs.c:225
uint32_t ht_hash_name(const char *str)
void ht_insert(papisde_list_entry_t *hash_table, int ht_key, sde_counter_t *sde_counter)
uint32_t ht_hash_id(uint32_t uniq_id)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cset_delete()

int cset_delete ( cset_hash_table_t hash_ptr)

Definition at line 526 of file sde_lib_datastructures.c.

526 {
527 cset_hash_bucket_t *bucket_ptr;
528 int bucket_idx;
529 uint32_t i, occupied;
530
531 if( NULL == hash_ptr ){
532 return SDE_EINVAL;
533 }
534 bucket_ptr = hash_ptr->buckets;
535
536 for( bucket_idx = 0; bucket_idx < _SDE_HASH_BUCKET_COUNT_; bucket_idx++){
537 cset_hash_decorated_object_t *obj_ptr = bucket_ptr[bucket_idx].objects;
538 occupied = bucket_ptr[bucket_idx].occupied;
539 // Free all the elements that occupy entries in this bucket.
540 for(i=0; i<occupied; i++){
541 free(obj_ptr[i].ptr);
542 }
543 bucket_ptr[bucket_idx].occupied = 0;
544 }
545
546 cset_list_object_t *list_runner, *ptr_to_free=NULL;
547 // Since there are elements in the overflow list, we need to search for ours.
548 for( list_runner = hash_ptr->overflow_list; list_runner != NULL; list_runner = list_runner->next){
549 // Free the list element from the previous iteration.
550 free(ptr_to_free);
551 free(list_runner->ptr);
552 // Keep a reference to this element so we can free it _after_ this iteration, because we need the list_runner->next for now.
553 ptr_to_free = list_runner;
554 // If the current element is at the head of the overflow list, then we should mark the head as NULL.
555 if( list_runner == hash_ptr->overflow_list )
556 hash_ptr->overflow_list = NULL;
557
558 }
559 free(ptr_to_free);
560
561 return SDE_OK;
562}
int i
#define SDE_EINVAL
Definition: sde_lib.h:40
#define SDE_OK
Definition: sde_lib.h:39
#define _SDE_HASH_BUCKET_COUNT_
cset_hash_decorated_object_t objects[_SDE_HASH_BUCKET_WIDTH_]
cset_list_object_t * overflow_list
cset_hash_bucket_t buckets[_SDE_HASH_BUCKET_COUNT_]
Here is the caller graph for this function:

◆ cset_insert_elem()

int cset_insert_elem ( cset_hash_table_t hash_ptr,
size_t  element_size,
size_t  hashable_size,
const void *  element,
uint32_t  type_id 
)

Definition at line 285 of file sde_lib_datastructures.c.

285 {
286 cset_hash_bucket_t *bucket_ptr;
287 int element_found = 0;
288 uint32_t i, occupied;
289 int ret_val;
290
291 if( NULL == hash_ptr ){
292 ret_val = SDE_EINVAL;
293 goto fn_exit;
294 }
295 bucket_ptr = hash_ptr->buckets;
296
297 uint64_t seed = (uint64_t)79365; // decided to be a good seed by a committee.
298 uint64_t key = fasthash64(element, hashable_size, seed);
299 int bucket_idx = (int)(key % _SDE_HASH_BUCKET_COUNT_);
300 uint64_t *key_ptr = bucket_ptr[bucket_idx].keys;
301 cset_hash_decorated_object_t *obj_ptr = bucket_ptr[bucket_idx].objects;
302 occupied = bucket_ptr[bucket_idx].occupied;
303 if( occupied > _SDE_HASH_BUCKET_WIDTH_ ){
304 SDE_ERROR("cset_insert_elem(): Counting set is clobbered, bucket %d has exceeded capacity.",bucket_idx);
305 ret_val = SDE_ECMP;
306 goto fn_exit;
307 }
308
309 // First look in the bucket where the hash function told us to look.
310 for(i=0; i<occupied; i++){
311 // If the key and type_id match a stored element and the hashable_size is less or equal to
312 // the size of the stored element, then we are onto something.
313 if( (key == key_ptr[i]) && (type_id == obj_ptr[i].type_id) && (hashable_size <= obj_ptr[i].type_size) ){
314 // If the actual element matches too (or if we don't care about perfect matches),
315 // then we update the count for this entry and we are done.
316 if( SDE_HASH_IS_FUZZY || !memcmp(element, obj_ptr[i].ptr, hashable_size) ){
317 obj_ptr[i].count += 1;
318 element_found = 1;
319 break;
320 }
321 }
322 }
323
324 // If we didn't find the element in the appropriate bucket, then we need to add it (or look in the overflow list).
325 if( !element_found ){
326 // If the overflow list is empty, then we are certainly dealing with a new element.
327 if( NULL == hash_ptr->overflow_list ){
328 // Check if we still have room in the bucket, and if so, add the new element to the bucket.
330 key_ptr[i] = key;
331 obj_ptr[i].count = 1;
332 obj_ptr[i].type_id = type_id;
333 obj_ptr[i].type_size = element_size;
334 obj_ptr[i].ptr = malloc(element_size);
335 (void)memcpy(obj_ptr[i].ptr, element, element_size);
336 // Let the bucket know that it now has one more element.
337 bucket_ptr[bucket_idx].occupied += 1;
338 }else{
339 // If the overflow list is empty and the bucket does not have room,
340 // then we add the new element at the head of the overflow list.
341 cset_list_object_t *new_list_element = (cset_list_object_t *)malloc(sizeof(cset_list_object_t));
342 new_list_element->next = NULL;
343 new_list_element->count = 1;
344 new_list_element->type_id = type_id;
345 new_list_element->type_size = element_size;
346 new_list_element->ptr = malloc(element_size);
347 (void)memcpy(new_list_element->ptr, element, element_size);
348 // Make the head point to the new element.
349 hash_ptr->overflow_list = new_list_element;
350 }
351 }else{
352 // Since there are elements in the overflow list, we need to search there for the one we are looking for.
353 cset_list_object_t *list_runner;
354 for( list_runner = hash_ptr->overflow_list; list_runner != NULL; list_runner = list_runner->next){
355 // if we find the element in the overflow list, increment the counter and exit the loop.
356 // When we traverse the overflow list we can _not_ use the SDE_HASH_IS_FUZZY flag, because we
357 // don't have matching hashes to indicate that the two elements are close; we are traversing the whole list.
358 if( (hashable_size <= list_runner->type_size) && (type_id == list_runner->type_id) && !memcmp(element, list_runner->ptr, hashable_size) ){
359 list_runner->count += 1;
360 break;
361 }
362 }
363 // If we traversed the entire list and didn't find our element, insert it before the current head of the list.
364 if( NULL == list_runner ){
365 cset_list_object_t *new_list_element = (cset_list_object_t *)malloc(sizeof(cset_list_object_t));
366 // Make the new element's "next" pointer be the current head of the list.
367 new_list_element->next = hash_ptr->overflow_list;
368 new_list_element->count = 1;
369 new_list_element->type_id = type_id;
370 new_list_element->type_size = element_size;
371 new_list_element->ptr = malloc(element_size);
372 (void)memcpy(new_list_element->ptr, element, element_size);
373 // Update the head of the list to point to the new element.
374 hash_ptr->overflow_list = new_list_element;
375 }
376 }
377 }
378
379 ret_val = SDE_OK;
380fn_exit:
381 return ret_val;
382}
static pthread_key_t key
int
Definition: sde_internal.h:89
#define SDE_ECMP
Definition: sde_lib.h:42
static void SDE_ERROR(const char *format,...)
Definition: sde_lib.h:60
static uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
#define SDE_HASH_IS_FUZZY
#define _SDE_HASH_BUCKET_WIDTH_
uint64_t keys[_SDE_HASH_BUCKET_WIDTH_]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cset_remove_elem()

int cset_remove_elem ( cset_hash_table_t hash_ptr,
size_t  hashable_size,
const void *  element,
uint32_t  type_id 
)

Definition at line 385 of file sde_lib_datastructures.c.

385 {
386 cset_hash_bucket_t *bucket_ptr;
387 int element_found = 0;
388 uint32_t i, occupied;
389 int ret_val;
390
391 if( NULL == hash_ptr ){
392 ret_val = SDE_EINVAL;
393 goto fn_exit;
394 }
395 bucket_ptr = hash_ptr->buckets;
396
397 uint64_t seed = (uint64_t)79365; // decided to be a good seed by a committee.
398 uint64_t key = fasthash64(element, hashable_size, seed);
399 int bucket_idx = (int)(key % _SDE_HASH_BUCKET_COUNT_);
400 uint64_t *key_ptr = bucket_ptr[bucket_idx].keys;
401 cset_hash_decorated_object_t *obj_ptr = bucket_ptr[bucket_idx].objects;
402 occupied = bucket_ptr[bucket_idx].occupied;
403 if( occupied > _SDE_HASH_BUCKET_WIDTH_ ){
404 SDE_ERROR("cset_remove_elem(): Counting set is clobbered, bucket %d has exceeded capacity.",bucket_idx);
405 ret_val = SDE_EINVAL;
406 goto fn_exit;
407 }
408
409 // First look in the bucket where the hash function told us to look.
410 for(i=0; i<occupied; i++){
411 // If the key and type_id match a stored element and the hashable_size is less or equal to
412 // the size of the stored element, then we are onto something.
413 if( (key == key_ptr[i]) && (type_id == obj_ptr[i].type_id) && (hashable_size <= obj_ptr[i].type_size) ){
414 // If the actual element matches too (or if we don't care about perfect matches),
415 // then we update the count for this entry.
416 if( SDE_HASH_IS_FUZZY || !memcmp(element, obj_ptr[i].ptr, hashable_size) ){
417 obj_ptr[i].count -= 1;
418 // If the element reached a count of zero after we removed it, then shift all the other keys and entries in the bucket.
419 if( 0 == obj_ptr[i].count ){
420 uint32_t j;
421 // free the memory taken by the user object.
422 free(obj_ptr[i].ptr);
423 // now shift the remaining entries in this bucket.
424 for(j=i; j<occupied-1; j++){
425 key_ptr[j] = key_ptr[j+1];
426 obj_ptr[j] = obj_ptr[j+1];
427 }
428 bucket_ptr[bucket_idx].occupied -= 1;
429 }
430 // since we found the element, we don't need to look further.
431 element_found = 1;
432 break;
433 }
434 }
435 }
436
437 // If we didn't find the element in the appropriate bucket, then we need to look for it in the overflow list.
438 if( !element_found ){
439 // If the overflow list is empty, then something went wrong.
440 if( NULL == hash_ptr->overflow_list ){
441 SDE_ERROR("cset_remove_elem(): Attempted to remove element that is NOT in the counting set.");
442 }else{
443 // Since there are elements in the overflow list, we need to search there for the one we are looking for.
444 cset_list_object_t *list_runner, *prev;
445 prev = hash_ptr->overflow_list;
446 for( list_runner = hash_ptr->overflow_list; list_runner != NULL; list_runner = list_runner->next){
447 // if we find the element in the overflow list
448 if( (hashable_size <= list_runner->type_size) && (type_id == list_runner->type_id) && !memcmp(element, list_runner->ptr, hashable_size) ){
449 list_runner->count -= 1;
450 // If the element reached a count of zero, then remove it from the list, and connect the list around it.
451 if( 0 == list_runner->count ){
452 // free the memory taken by the user object.
453 free(list_runner->ptr);
454 if( list_runner == hash_ptr->overflow_list ){
455 hash_ptr->overflow_list = NULL;
456 }else{
457 prev->next = list_runner->next;
458 }
459 // free the memory taken by the link node. We can do this here safely
460 // because we will break out of the loop, so we will not need the "next" pointer.
461 free(list_runner);
462 }
463 // since we found the element, we don't need to look at the rest of the list.
464 break;
465 }
466 prev = list_runner;
467 }
468 }
469 }
470
471 ret_val = SDE_OK;
472fn_exit:
473 return ret_val;
474}
static long count
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cset_to_list()

cset_list_object_t * cset_to_list ( cset_hash_table_t hash_ptr)

Definition at line 476 of file sde_lib_datastructures.c.

476 {
477 cset_hash_bucket_t *bucket_ptr;
478 int bucket_idx;
479 uint32_t i, occupied;
480 cset_list_object_t *head_ptr = NULL;
481
482 if( NULL == hash_ptr ){
483 return NULL;
484 }
485 bucket_ptr = hash_ptr->buckets;
486
487 for( bucket_idx = 0; bucket_idx < _SDE_HASH_BUCKET_COUNT_; bucket_idx++){
488 cset_hash_decorated_object_t *obj_ptr = bucket_ptr[bucket_idx].objects;
489 occupied = bucket_ptr[bucket_idx].occupied;
490
491 for(i=0; i<occupied; i++){
492 int type_size = obj_ptr[i].type_size;
493 cset_list_object_t *new_list_element = (cset_list_object_t *)malloc(sizeof(cset_list_object_t));
494 // make the current list head be the element after the new one we are creating.
495 new_list_element->next = head_ptr;
496 new_list_element->count = obj_ptr[i].count;
497 new_list_element->type_id = obj_ptr[i].type_id;
498 new_list_element->type_size = type_size;
499 new_list_element->ptr = malloc(type_size);
500 (void)memcpy(new_list_element->ptr, obj_ptr[i].ptr, type_size);
501 // Update the head of the list to point to the new element.
502 head_ptr = new_list_element;
503 }
504 }
505
506 cset_list_object_t *list_runner;
507 // Since there are elements in the overflow list, we need to search for ours.
508 for( list_runner = hash_ptr->overflow_list; list_runner != NULL; list_runner = list_runner->next){
509 int type_size = list_runner->type_size;
510 cset_list_object_t *new_list_element = (cset_list_object_t *)malloc(sizeof(cset_list_object_t));
511 // make the current list head be the element after the new one we are creating.
512 new_list_element->next = head_ptr;
513 new_list_element->count = list_runner->count;
514 new_list_element->type_id = list_runner->type_id;
515 new_list_element->type_size = type_size;
516 new_list_element->ptr = malloc(type_size);
517 (void)memcpy(new_list_element->ptr, list_runner->ptr, type_size);
518 // Update the head of the list to point to the new element.
519 head_ptr = new_list_element;
520 }
521
522 return head_ptr;
523}
Here is the caller graph for this function:

◆ do_sde_init()

papi_handle_t do_sde_init ( const char *  name_of_library,
papisde_control_t *  gctl 
)

Definition at line 91 of file sde_lib_misc.c.

91 {
92
93 papisde_library_desc_t *tmp_lib;
94
95 SDEDBG("Registering library: '%s'\n",name_of_library);
96
97 // If the library is already initialized, return the handle to it
98 tmp_lib = find_library_by_name(name_of_library, gctl);
99 if( NULL != tmp_lib ){
100 return tmp_lib;
101 }
102
103 // If the library is not already initialized, then initialize it.
104 tmp_lib = ( papisde_library_desc_t* ) calloc( 1, sizeof( papisde_library_desc_t ) );
105 tmp_lib->libraryName = strdup(name_of_library);
106
107 insert_library_handle(tmp_lib, gctl);
108
109 return tmp_lib;
110}
#define SDEDBG(format, args...)
Definition: sde_lib.h:58
static papisde_library_desc_t * find_library_by_name(const char *library_name, papisde_control_t *gctl)
Definition: sde_lib_misc.c:53
static void insert_library_handle(papisde_library_desc_t *lib_handle, papisde_control_t *gctl)
Definition: sde_lib_misc.c:79
Here is the call graph for this function:
Here is the caller graph for this function:

◆ exp_container_init()

void exp_container_init ( sde_counter_t *  handle,
size_t  typesize 
)

◆ exp_container_insert_element()

int exp_container_insert_element ( recorder_data_t *  exp_container,
size_t  typesize,
const void *  value 
)

Definition at line 229 of file sde_lib_datastructures.c.

229 {
230 long long used_entries, total_entries, prev_entries, offset;
231 int i, chunk;
232 long long tmp_size;
233
234 if( NULL == exp_container || NULL == exp_container->ptr_array[0]){
235 SDE_ERROR("exp_container_insert_element(): Exponential container is clobbered. Unable to insert element.");
236 return SDE_EINVAL;
237 }
238
239 used_entries = exp_container->used_entries;
240 total_entries = exp_container->total_entries;
241 assert(used_entries <= total_entries);
242
243 // Find how many chunks we have already allocated
244 tmp_size = 0;
245 for(i=0; i<EXP_CONTAINER_ENTRIES; i++){
246 long long factor = (long long)1<<i; // 2^i;
247 prev_entries = tmp_size;
248 tmp_size += factor * EXP_CONTAINER_MIN_SIZE;
249 // At least the first chunk "exp_container->ptr_array[0]"
250 // must have been already allocated when creating the recorder, so we can
251 // compare the total size after we add the "i-th" size.
252 if (total_entries == tmp_size)
253 break;
254 }
255 chunk = i;
256
257 // Find how many entries down the last chunk we are.
258 offset = used_entries - prev_entries;
259
260 if( used_entries == total_entries ){
261 long long new_segment_size;
262
263 // If we had used all the available entries (and thus we are allocating more), we start from the beginning of the new chunk.
264 offset = 0;
265
266 chunk += 1; // we need to allocate the next chunk from the last one we found.
267 new_segment_size = ((long long)1<<chunk) * EXP_CONTAINER_MIN_SIZE;
268 exp_container->ptr_array[chunk] = malloc(new_segment_size*typesize);
269 exp_container->total_entries += new_segment_size;
270 }
271
272 void *dest = (char *)(exp_container->ptr_array[chunk]) + offset*typesize;
273
274 (void)memcpy( dest, value, typesize );
275 exp_container->used_entries++;
276
277 return SDE_OK;
278}
long long int long long
Definition: sde_internal.h:85
#define EXP_CONTAINER_MIN_SIZE
#define EXP_CONTAINER_ENTRIES
Here is the call graph for this function:
Here is the caller graph for this function:

◆ exp_container_to_contiguous()

void exp_container_to_contiguous ( recorder_data_t *  exp_container,
void *  cont_buffer 
)

Definition at line 204 of file sde_lib_datastructures.c.

204 {
205 long long current_size, typesize, used_entries, tmp_size = 0;
206 void *src, *dst;
207 int i;
208
209 typesize = exp_container->typesize;
210 used_entries = exp_container->used_entries;
211
212 for(i=0; i<EXP_CONTAINER_ENTRIES; i++){
213 current_size = ((long long)1<<i) * EXP_CONTAINER_MIN_SIZE;
214 src = exp_container->ptr_array[i];
215 dst = (char *)cont_buffer + tmp_size*typesize;
216 if ( (tmp_size+current_size) <= used_entries){
217 memcpy(dst, src, current_size*typesize);
218 if ( (tmp_size+current_size) == used_entries){
219 return;
220 }
221 }else{
222 memcpy(dst, src, (used_entries-tmp_size)*typesize);
223 return;
224 }
225 tmp_size += current_size;
226 }
227}
Here is the caller graph for this function:

◆ fasthash64()

static uint64_t fasthash64 ( const void *  buf,
size_t  len,
uint64_t  seed 
)
inlinestatic

Definition at line 245 of file sde_lib_internal.h.

246{
247 const uint64_t m = 0x880355f21e6d1965ULL;
248 const uint64_t *pos = (const uint64_t *)buf;
249 const uint64_t *end = pos + (len / 8);
250 const uint32_t *pos2;
251 uint64_t h = seed ^ (len * m);
252 uint64_t v;
253
254 while (pos != end) {
255 v = *pos++;
256 h ^= mix(v);
257 h *= m;
258 }
259
260 pos2 = (const uint32_t*)pos;
261 v = 0;
262
263 switch (len & 7) {
264 case 7: v ^= (uint64_t)pos2[6] << 48;
265 /* fall through */
266 case 6: v ^= (uint64_t)pos2[5] << 40;
267 /* fall through */
268 case 5: v ^= (uint64_t)pos2[4] << 32;
269 /* fall through */
270 case 4: v ^= (uint64_t)pos2[3] << 24;
271 /* fall through */
272 case 3: v ^= (uint64_t)pos2[2] << 16;
273 /* fall through */
274 case 2: v ^= (uint64_t)pos2[1] << 8;
275 /* fall through */
276 case 1: v ^= (uint64_t)pos2[0];
277 h ^= mix(v);
278 h *= m;
279 }
280
281 return mix(h);
282}
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
Definition: do_loops.c:12
#define mix(h)
Here is the caller graph for this function:

◆ ht_delete()

sde_counter_t * ht_delete ( papisde_list_entry_t *  hash_table,
int  ht_key,
uint32_t  uniq_id 
)

Definition at line 114 of file sde_lib_datastructures.c.

115{
116 papisde_list_entry_t *list_head, *curr, *prev;
117 sde_counter_t *item;
118
119 list_head = &hash_table[ht_key];
120 if( NULL == list_head->item ){
121 SDE_ERROR("ht_delete(): the entry does not exist.");
122 return NULL;
123 }
124
125 // If the head contains the element to be deleted, free the space of the counter and pull the list up.
126 if( list_head->item->glb_uniq_id == uniq_id ){
127 item = list_head->item;
128 if( NULL != list_head->next){
129 *list_head = *(list_head->next);
130 }else{
131 memset(list_head, 0, sizeof(papisde_list_entry_t));
132 }
133 return item;
134 }
135
136 prev = list_head;
137 // Traverse the linked list to find the element.
138 for(curr=list_head->next; NULL != curr; curr=curr->next){
139 if(NULL == curr->item){ // This is only permitted for the head of the list.
140 SDE_ERROR("ht_delete(): the hash table is clobbered.");
141 return NULL;
142 }
143 if(curr->item->glb_uniq_id == uniq_id){
144 prev->next = curr->next;
145 item = curr->item;
146 free(curr); // free the hash table entry
147 return item;
148 }
149 prev = curr;
150 }
151
152 SDE_ERROR("ht_delete(): the item is not in the list.");
153 return NULL;
154}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ht_hash_id()

uint32_t ht_hash_id ( uint32_t  uniq_id)

Definition at line 18 of file sde_lib_datastructures.c.

18 {
19 return uniq_id%PAPISDE_HT_SIZE;
20}
#define PAPISDE_HT_SIZE
Here is the caller graph for this function:

◆ ht_hash_name()

uint32_t ht_hash_name ( const char *  str)

Definition at line 23 of file sde_lib_datastructures.c.

24{
25 uint32_t hash = 5381;
26 int c;
27
28 while ((c = *str++))
29 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
30
31 return hash % PAPISDE_HT_SIZE;
32}
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
Here is the caller graph for this function:

◆ ht_insert()

void ht_insert ( papisde_list_entry_t *  hash_table,
int  ht_key,
sde_counter_t *  sde_counter 
)

Definition at line 34 of file sde_lib_datastructures.c.

35{
36 papisde_list_entry_t *list_head, *new_entry;
37
38 list_head = &hash_table[ht_key];
39 // If we have no counter is associated with this key we will put the new
40 // counter on the head of the list which has already been allocated.
41 if( NULL == list_head->item ){
42 list_head->item = sde_counter;
43 list_head->next = NULL; // Just for aesthetic reasons.
44 return;
45 }
46
47 // If we made it here it means that the head was occupied, so we
48 // will allocate a new element and put it just after the head.
49 new_entry = (papisde_list_entry_t *)calloc(1, sizeof(papisde_list_entry_t));
50 new_entry->item = sde_counter;
51 new_entry->next = list_head->next;
52 list_head->next = new_entry;
53
54 return;
55}
Here is the caller graph for this function:

◆ ht_lookup_by_id()

sde_counter_t * ht_lookup_by_id ( papisde_list_entry_t *  hash_table,
uint32_t  uniq_id 
)

Definition at line 178 of file sde_lib_datastructures.c.

179{
180 papisde_list_entry_t *list_head, *curr;
181
182 list_head = &hash_table[ht_hash_id(uniq_id)];
183 if( NULL == list_head->item ){
184 return NULL;
185 }
186
187 for(curr=list_head; NULL != curr; curr=curr->next){
188 if(NULL == curr->item){ // This can only legally happen for the head of the list.
189 SDE_ERROR("ht_lookup_by_id() the hash table is clobbered.");
190 return NULL;
191 }
192 if(curr->item->glb_uniq_id == uniq_id){
193 return curr->item;
194 }
195 }
196
197 return NULL;
198}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ht_lookup_by_name()

sde_counter_t * ht_lookup_by_name ( papisde_list_entry_t *  hash_table,
const char *  name 
)

Definition at line 156 of file sde_lib_datastructures.c.

157{
158 papisde_list_entry_t *list_head, *curr;
159
160 list_head = &hash_table[ht_hash_name(name)];
161 if( NULL == list_head->item ){
162 return NULL;
163 }
164
165 for(curr=list_head; NULL != curr; curr=curr->next){
166 if(NULL == curr->item){ // This can only legally happen for the head of the list.
167 SDE_ERROR("ht_lookup_by_name() the hash table is clobbered.");
168 return NULL;
169 }
170 if( !strcmp(curr->item->name, name) ){
171 return curr->item;
172 }
173 }
174
175 return NULL;
176}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ht_to_array()

int ht_to_array ( papisde_list_entry_t *  hash_table,
sde_counter_t **  rslt_array 
)

Definition at line 65 of file sde_lib_datastructures.c.

66{
67 int i, item_cnt = 0, index=0;
68 papisde_list_entry_t *list_head, *curr;
69
70 // First pass counts how many items have been inserted in the hash table.
71
72 // Traverse all the elements of the hash-table.
73 for(i=0; i<PAPISDE_HT_SIZE; i++){
74 // For each element traverse the linked-list starting there (if any).
75 list_head = &(hash_table[i]);
76
77 if(NULL != list_head->item){
78 item_cnt++;
79 }
80 for(curr = list_head->next; NULL != curr; curr=curr->next){
81 if(NULL == curr->item){ // This can only legally happen for the head of the list.
82 SDE_ERROR("ht_to_array(): the hash table is clobbered.");
83 }else{
84 item_cnt++;
85 }
86 }
87 }
88
89 // Allocate a contiguous array to store the items.
90 sde_counter_t *array = (sde_counter_t *)malloc( item_cnt * sizeof(sde_counter_t));
91
92 // Traverse the hash-table again and copy all the items to the array we just allocated.
93 for(i=0; i<PAPISDE_HT_SIZE; i++){
94 list_head = &(hash_table[i]);
95
96 if(NULL != list_head->item){
97 memcpy( &array[index], list_head->item, sizeof(sde_counter_t) );
98 index++;
99 }
100 for(curr = list_head->next; NULL != curr; curr=curr->next){
101 if(NULL == curr->item){ // This can only legally happen for the head of the list.
102 SDE_ERROR("ht_to_array(): the hash table is clobbered.");
103 }else{
104 memcpy( &array[index], curr->item, sizeof(sde_counter_t) );
105 index++;
106 }
107 }
108 }
109 *rslt_array = array;
110
111 return item_cnt;
112}
static double array[ARRAYSIZE]
Definition: papi_l1_dca.c:23
Here is the call graph for this function:
Here is the caller graph for this function:

◆ papi_sde_counting_set_to_list()

void papi_sde_counting_set_to_list ( void *  cset_handle,
cset_list_object_t **  list_head 
)

◆ sde_ti_get_event_description()

char * sde_ti_get_event_description ( int  event_id)

Definition at line 416 of file sde_lib_ti.c.

416 {
417
418 papisde_control_t *gctl = _papisde_global_control;
419 if( NULL == gctl )
420 return NULL;
421
422 sde_counter_t *counter = ht_lookup_by_id(gctl->all_reg_counters, event_id);
423 if( NULL == counter )
424 return NULL;
425
426 return counter->description;
427}
papisde_control_t * _papisde_global_control
Definition: sde_lib.c:37
sde_counter_t * ht_lookup_by_id(papisde_list_entry_t *hash_table, uint32_t uniq_id)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sde_ti_get_event_name()

char * sde_ti_get_event_name ( int  event_id)

Definition at line 399 of file sde_lib_ti.c.

399 {
400
401 papisde_control_t *gctl = _papisde_global_control;
402 if( NULL == gctl )
403 return NULL;
404
405 sde_counter_t *counter = ht_lookup_by_id(gctl->all_reg_counters, event_id);
406 if( NULL == counter )
407 return NULL;
408
409 return counter->name;
410}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sde_ti_get_num_reg_events()

int sde_ti_get_num_reg_events ( void  )

Definition at line 433 of file sde_lib_ti.c.

433 {
434
435 papisde_control_t *gctl = _papisde_global_control;
436 if( NULL == gctl )
437 return 0;
438
439 return gctl->num_reg_events;
440}
Here is the caller graph for this function:

◆ sde_ti_is_counter_set_to_overflow()

int sde_ti_is_counter_set_to_overflow ( uint32_t  counter_id)

Definition at line 343 of file sde_lib_ti.c.

343 {
344
345 papisde_control_t *gctl = _papisde_global_control;
346 if( NULL == gctl )
347 return 0;
348
349 sde_counter_t *counter = ht_lookup_by_id(gctl->all_reg_counters, counter_id);
350 if( (NULL == counter) || !counter->overflow || IS_CNTR_CREATED(counter) )
351 return 0;
352
353 return 1;
354}
#define IS_CNTR_CREATED(_CNT)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sde_ti_is_simple_counter()

int sde_ti_is_simple_counter ( uint32_t  counter_id)

Definition at line 325 of file sde_lib_ti.c.

325 {
326
327 papisde_control_t *gctl = _papisde_global_control;
328 if( NULL == gctl )
329 return 0;
330
331 sde_counter_t *counter = ht_lookup_by_id(gctl->all_reg_counters, counter_id);
332
333 if( (NULL == counter) || !IS_CNTR_REGISTERED(counter) )
334 return 0;
335
336 return 1;
337}
#define IS_CNTR_REGISTERED(_CNT)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sde_ti_name_to_code()

int sde_ti_name_to_code ( const char *  event_name,
uint32_t *  event_code 
)

Definition at line 204 of file sde_lib_ti.c.

204 {
205 int ret_val;
206 papisde_library_desc_t *lib_handle;
207 char *pos, *tmp_lib_name;
208 sde_counter_t *tmp_item = NULL;
209 papisde_control_t *gctl;
210
211 SDEDBG( "%s\n", event_name );
212
213 sde_lock();
215
216 // Let's see if the event has the library name as a prefix (as it should). Note that this is
217 // the event name as it comes from the framework, so it should contain the library name, although
218 // when the library registers an event counter it will not use the library name as part of the event name.
219 tmp_lib_name = strdup(event_name);
220 pos = strstr(tmp_lib_name, "::");
221 if( NULL != pos ){ // Good, it does.
222 *pos = '\0';
223
224 if( NULL == gctl ){
225 // If no library has initialized SDEs, and the application is already inquiring
226 // about an event, let's initialize SDEs pretending to be the library which corresponds to this event.
227 gctl = sdei_get_global_struct();
228 lib_handle = do_sde_init(tmp_lib_name, gctl);
229 if(NULL == lib_handle){
230 SDE_ERROR("sde_ti_name_to_code(): Initialized SDE but unable to register new library: %s\n", tmp_lib_name);
231 ret_val = SDE_ECMP;
232 goto fn_exit;
233 }
234 }else{
235 int is_library_present = 0;
236 // If the library side of the component has been initialized, then look for the library.
237 lib_handle = gctl->lib_list_head;
238 while(NULL != lib_handle){ // Look for the library.
239 if( !strcmp(lib_handle->libraryName, tmp_lib_name) ){
240 // We found the library.
241 is_library_present = 1;
242 // Now, look for the event in the library.
243 tmp_item = ht_lookup_by_name(lib_handle->lib_counters, event_name);
244 break;
245 }
246 lib_handle = lib_handle->next;
247 }
248
249 if( !is_library_present ){
250 // If the library side of the component was initialized, but the specific library hasn't called
251 // papi_sde_init() then we call it here to allocate the data structures.
252 lib_handle = do_sde_init(tmp_lib_name, gctl);
253 if(NULL == lib_handle){
254 SDE_ERROR("sde_ti_name_to_code(): Unable to register new library: %s\n", tmp_lib_name);
255 ret_val = SDE_ECMP;
256 goto fn_exit;
257 }
258 }
259 }
260 free(tmp_lib_name); // We don't need the library name any more.
261
262 if( NULL != tmp_item ){
263 SDEDBG("Found matching counter with global uniq id: %d in library: %s\n", tmp_item->glb_uniq_id, lib_handle->libraryName );
264 *event_code = tmp_item->glb_uniq_id;
265 ret_val = SDE_OK;
266 goto fn_exit;
267 } else {
268 cntr_class_specific_t cntr_union = {0};
269 SDEDBG("Did not find event %s in library %s. Registering a placeholder.\n", event_name, lib_handle->libraryName );
270
271 // Use the current number of registered events as the index of the new one, and increment it.
272 uint32_t counter_uniq_id = gctl->num_reg_events++;
273 gctl->num_live_events++;
274
275 // At this point in the code "lib_handle" contains a pointer to the data structure for this library whether
276 // the actual library has been initialized or not.
277 tmp_item = allocate_and_insert(gctl, lib_handle, event_name, counter_uniq_id, PAPI_SDE_RO, PAPI_SDE_long_long, CNTR_CLASS_PLACEHOLDER, cntr_union );
278 if(NULL == tmp_item) {
279 SDEDBG("Event %s does not exist in library %s and placeholder could not be inserted.\n", event_name, lib_handle->libraryName);
280 ret_val = SDE_ECMP;
281 goto fn_exit;
282 }
283 *event_code = tmp_item->glb_uniq_id;
284 ret_val = SDE_OK;
285 goto fn_exit;
286 }
287 }else{
288 free(tmp_lib_name);
289 }
290
291 // If no library has initialized the component and we don't know a library name, then we have to return.
292 if( NULL == gctl ){
293 ret_val = SDE_ENOEVNT;
294 goto fn_exit;
295 }
296
297 // If the event name does not have the library name as a prefix, then we need to look in all the libraries for the event. However, in this case
298 // we can _not_ register a placeholder because we don't know which library the event belongs to.
299 lib_handle = gctl->lib_list_head;
300 while(NULL != lib_handle){
301
302 tmp_item = ht_lookup_by_name(lib_handle->lib_counters, event_name);
303 if( NULL != tmp_item ){
304 *event_code = tmp_item->glb_uniq_id;
305 SDEDBG("Found matching counter with global uniq id: %d in library: %s\n", tmp_item->glb_uniq_id, lib_handle->libraryName );
306 ret_val = SDE_OK;
307 goto fn_exit;
308 } else {
309 SDEDBG("Failed to find event %s in library %s. Looking in other libraries.\n", event_name, lib_handle->libraryName );
310 }
311
312 lib_handle = lib_handle->next;
313 }
314
315 ret_val = SDE_ENOEVNT;
316fn_exit:
317 sde_unlock();
318 return ret_val;
319}
char event_name[2][PAPI_MAX_STR_LEN]
Definition: data_range.c:29
#define SDE_ENOEVNT
Definition: sde_lib.h:43
#define PAPI_SDE_long_long
Definition: sde_lib.h:28
#define PAPI_SDE_RO
Definition: sde_lib.h:23
sde_counter_t * ht_lookup_by_name(papisde_list_entry_t *hash_table, const char *name)
papi_handle_t do_sde_init(const char *name_of_library, papisde_control_t *gctl)
Definition: sde_lib_misc.c:91
sde_counter_t * allocate_and_insert(papisde_control_t *gctl, papisde_library_desc_t *lib_handle, const char *name, uint32_t uniq_id, int cntr_mode, int cntr_type, enum CNTR_CLASS cntr_class, cntr_class_specific_t cntr_union)
Definition: sde_lib_misc.c:112
papisde_control_t * sdei_get_global_struct(void)
Definition: sde_lib_misc.c:34
#define sde_lock()
Definition: sde_lib_lock.h:24
#define sde_unlock(lck)
Definition: sde_lib_lock.h:29
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sde_ti_read_counter()

int sde_ti_read_counter ( uint32_t  ,
long long int  
)
Here is the caller graph for this function:

◆ sde_ti_reset_counter()

int sde_ti_reset_counter ( uint32_t  counter_id)

Definition at line 169 of file sde_lib_ti.c.

169 {
170 int ret_val = SDE_OK;
171 papisde_control_t *gctl;
172
174 if( NULL == gctl ){
175 SDE_ERROR("sde_ti_reset_counter(): Attempt to modify unintialized SDE structures.\n");
176 return SDE_EINVAL;
177 }
178
179 if( counter_id >= gctl->num_reg_events ){
180 SDE_ERROR("sde_ti_reset_counter(): SDE with id %d does not correspond to a registered event.\n",counter_id);
181 return SDE_EINVAL;
182 }
183
184 sde_counter_t *counter = ht_lookup_by_id(gctl->all_reg_counters, counter_id);
185 if( (NULL == counter) || (!IS_CNTR_BASIC(counter) && !IS_CNTR_CALLBACK(counter)) ){
186 SDEDBG("sde_ti_reset_counter(): SDE with id %d is clobbered, or a type which does not support resetting.\n",counter_id);
187 // We allow tools to call this function even if the counter type does not support
188 // reseting, so we do not return an error if this is the case.
189 return SDE_OK;
190 }
191
192 ret_val = sdei_read_and_update_data_value( counter, 0, &(counter->previous_data) );
193 if( SDE_OK != ret_val ){
194 SDE_ERROR("sde_ti_reset_counter(): Error occured when resetting counter: %s.\n",counter->name);
195 }
196
197 return ret_val;
198}
#define IS_CNTR_BASIC(_CNT)
int sdei_read_and_update_data_value(sde_counter_t *counter, long long int previous_value, long long int *rslt_ptr)
Definition: sde_lib_misc.c:490
#define IS_CNTR_CALLBACK(_CNT)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sde_ti_set_counter_overflow()

int sde_ti_set_counter_overflow ( uint32_t  counter_id,
int  threshold 
)

Definition at line 360 of file sde_lib_ti.c.

360 {
361
362 papisde_control_t *gctl = _papisde_global_control;
363 if( NULL == gctl )
364 return SDE_OK;
365
366 sde_counter_t *counter = ht_lookup_by_id(gctl->all_reg_counters, counter_id);
367 // If the counter is created then we will check for overflow every time its value gets updated, we don't need to poll.
368 // That is in cases c[1-3]
369 if( IS_CNTR_CREATED(counter) )
370 return SDE_OK;
371
372 // We do not want to overflow on recorders or counting-sets, because we don't even know what this means.
373 if( ( IS_CNTR_RECORDER(counter) || IS_CNTR_CSET(counter) ) && (threshold > 0) ){
374 return SDE_EINVAL;
375 }
376
377 // If we still don't know what type the counter is, then we are _not_ in r[1-3] so we can't create a timer here.
378 if( IS_CNTR_PLACEHOLDER(counter) && (threshold > 0) ){
379 SDEDBG("Event is a placeholder (it has not been registered by a library yet), so we cannot start overflow, but we can remember it.\n");
380 counter->overflow = 1;
381 return SDE_OK;
382 }
383
384 if( 0 == threshold ){
385 counter->overflow = 0;
386 }
387
388 // Return a number higher than SDE_OK (which is zero) to indicate to the caller that the timer needs to be set,
389 // because SDE_OK only means that there was no error, but the timer should not be set either because we are dealing
390 // with a placeholder, or created counter.
391 return 0xFF;
392}
static int threshold
#define IS_CNTR_CSET(_CNT)
#define IS_CNTR_RECORDER(_CNT)
#define IS_CNTR_PLACEHOLDER(_CNT)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sde_ti_shutdown()

int sde_ti_shutdown ( void  )

Definition at line 446 of file sde_lib_ti.c.

446 {
447 return SDE_OK;
448}
Here is the caller graph for this function:

◆ sde_ti_write_counter()

int sde_ti_write_counter ( uint32_t  counter_id,
long long  value 
)

Definition at line 136 of file sde_lib_ti.c.

136 {
137 papisde_control_t *gctl;
138 int ret_val = SDE_OK;
139
141 if( NULL == gctl ){
142 SDE_ERROR("sde_ti_write_counter(): Attempt to write in unintialized SDE structures.\n");
143 return SDE_EINVAL;
144 }
145
146 if( counter_id >= gctl->num_reg_events ){
147 SDE_ERROR("sde_ti_write_counter(): SDE with id %d does not correspond to a registered event.\n",counter_id);
148 return SDE_EINVAL;
149 }
150
151 sde_counter_t *counter = ht_lookup_by_id(gctl->all_reg_counters, counter_id);
152 if( (NULL == counter) || !IS_CNTR_BASIC(counter) ){
153 SDE_ERROR("sde_ti_write_counter(): SDE with id %d is clobbered, or a type which does not support writing.\n",counter_id);
154 return SDE_EINVAL;
155 }
156
157 ret_val = sdei_hardware_write( counter, value );
158 if( SDE_OK != ret_val ){
159 SDE_ERROR("sde_ti_write_counter(): Error occured when writing counter: '%s'.\n",counter->name);
160 }
161
162 return ret_val;
163}
int sdei_hardware_write(sde_counter_t *counter, long long int new_value)
Definition: sde_lib_misc.c:556
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sdei_counting_set_to_list()

void sdei_counting_set_to_list ( void *  cset_handle,
cset_list_object_t **  list_head 
)

Definition at line 135 of file sde_lib_misc.c.

136{
137 sde_counter_t *tmp_cset;
138
139 if( NULL == list_head )
140 return;
141
142 tmp_cset = (sde_counter_t *)cset_handle;
143 if( (NULL == tmp_cset) || !IS_CNTR_CSET(tmp_cset) || (NULL == tmp_cset->u.cntr_cset.data) ){
144 SDE_ERROR("sdei_counting_set_to_list(): 'cset_handle' is clobbered.");
145 return;
146 }
147
148 *list_head = cset_to_list(tmp_cset->u.cntr_cset.data);
149
150 return;
151}
cset_list_object_t * cset_to_list(cset_hash_table_t *hash_ptr)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sdei_delete_counter()

int sdei_delete_counter ( papisde_library_desc_t *  lib_handle,
const char *  name 
)

Definition at line 260 of file sde_lib_misc.c.

260 {
261 sde_counter_t *tmp_item;
262 papisde_control_t *gctl;
263 uint32_t item_uniq_id;
264 int ret_val = SDE_OK;
265
266 gctl = sdei_get_global_struct();
267
268 // Look for the counter entry in the hash-table of the library
269 tmp_item = ht_lookup_by_name(lib_handle->lib_counters, name);
270 if( NULL == tmp_item ){
271 ret_val = SDE_EINVAL;
272 goto fn_exit;
273 }
274
275 if( CNTR_CLASS_GROUP == tmp_item->cntr_class ){
276 papisde_list_entry_t *curr, *prev;
277 // If we are dealing with a goup, then we need to recurse down all its children and
278 // delete them (this might mean free them, or just decrement their ref_count).
279 curr = tmp_item->u.cntr_group.group_head;
280 prev = curr;
281 while(NULL != curr){
282 int counter_is_dead = 0;
283 sde_counter_t *tmp_cntr = curr->item;
284 if( NULL == tmp_cntr ){
285 ret_val = SDE_EMISC;
286 goto fn_exit;
287 }
288
289 // If this counter is going to be freed, we need to remove it from this group.
290 if( 0 == tmp_cntr->ref_count )
291 counter_is_dead = 1;
292
293 // recursively delete all the elements of the group.
294 int ret_val = sdei_delete_counter(lib_handle, tmp_cntr->name);
295 if( SDE_OK != ret_val )
296 goto fn_exit;
297
298 if( counter_is_dead ){
299 if( curr == tmp_item->u.cntr_group.group_head ){
300 // if we were removing with the head, change the head, we can't free() it.
301 tmp_item->u.cntr_group.group_head = curr->next;
302 prev = curr->next;
303 curr = curr->next;
304 }else{
305 // if we are removing an element, first bridge the previous to the next.
306 prev->next = curr->next;
307 free(curr);
308 curr = prev->next;
309 }
310 }else{
311 // if we are not removing anything, just move the pointers.
312 prev = curr;
313 curr = curr->next;
314 }
315 }
316 }
317
318 item_uniq_id = tmp_item->glb_uniq_id;
319
320 // If the reference count is not zero, then we don't remove it from the hash tables
321 if( 0 == tmp_item->ref_count ){
322 // Delete the entry from the library hash-table (which hashes by name)
323 tmp_item = ht_delete(lib_handle->lib_counters, ht_hash_name(name), item_uniq_id);
324 if( NULL == tmp_item ){
325 ret_val = SDE_EMISC;
326 goto fn_exit;
327 }
328
329 // Delete the entry from the global hash-table (which hashes by id) and free the memory
330 // occupied by the counter (not the hash-table entry 'papisde_list_entry_t', the 'sde_counter_t')
331 tmp_item = ht_delete(gctl->all_reg_counters, ht_hash_id(item_uniq_id), item_uniq_id);
332 if( NULL == tmp_item ){
333 ret_val = SDE_EMISC;
334 goto fn_exit;
335 }
336
337 // We free the counter only once, although it is in two hash-tables,
338 // because it is the same structure that is pointed to by both hash-tables.
339 free_counter_resources(tmp_item);
340
341 // Decrement the number of live events.
342 (gctl->num_live_events)--;
343 }else{
344 (tmp_item->ref_count)--;
345 }
346
347fn_exit:
348 return ret_val;
349}
#define SDE_EMISC
Definition: sde_lib.h:44
sde_counter_t * ht_delete(papisde_list_entry_t *hash_table, int ht_key, uint32_t uniq_id)
static int free_counter_resources(sde_counter_t *counter)
Definition: sde_lib_misc.c:351
int sdei_delete_counter(papisde_library_desc_t *lib_handle, const char *name)
Definition: sde_lib_misc.c:260
papisde_control_t * sdei_get_global_struct(void)
Definition: sde_lib_misc.c:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sdei_get_global_struct()

papisde_control_t * sdei_get_global_struct ( void  )

sdei_get_global_struct() checks if the global structure has been allocated and allocates it if has not.

Returns
a pointer to the global structure.

Definition at line 34 of file sde_lib_misc.c.

34 {
35 // Allocate the global control structure, unless it has already been allocated by another library
36 // or the application code calling PAPI_name_to_code() for an SDE.
38 SDEDBG("sdei_get_global_struct(): global SDE control struct is being allocated.\n");
39 _papisde_global_control = (papisde_control_t *)calloc( 1, sizeof( papisde_control_t ) );
40 }
42}
Here is the caller graph for this function:

◆ sdei_hardware_write()

int sdei_hardware_write ( sde_counter_t *  counter,
long long int  new_value 
)

Definition at line 556 of file sde_lib_misc.c.

556 {
557 double tmp_double;
558 void *tmp_ptr;
559
560 switch(counter->cntr_type){
562 *((long long int *)(counter->u.cntr_basic.data)) = new_value;
563 break;
564 case PAPI_SDE_int:
565 *((int *)(counter->u.cntr_basic.data)) = (int)new_value;
566 break;
567 case PAPI_SDE_double:
568 tmp_ptr = &new_value;
569 tmp_double = *((double *)tmp_ptr);
570 *((double *)(counter->u.cntr_basic.data)) = tmp_double;
571 break;
572 case PAPI_SDE_float:
573 // The pointer has to be 64bit. We can cast the variable to safely convert between bit-widths later on.
574 tmp_ptr = &new_value;
575 tmp_double = *((double *)tmp_ptr);
576 *((float *)(counter->u.cntr_basic.data)) = (float)tmp_double;
577 break;
578 default:
579 SDEDBG("Unsupported counter type: %d\n",counter->cntr_type);
580 return -1;
581 }
582
583 return SDE_OK;
584}
#define PAPI_SDE_double
Definition: sde_lib.h:30
#define PAPI_SDE_float
Definition: sde_lib.h:31
#define PAPI_SDE_int
Definition: sde_lib.h:29
Here is the caller graph for this function:

◆ sdei_inc_ref_count()

int sdei_inc_ref_count ( sde_counter_t *  counter)

Definition at line 236 of file sde_lib_misc.c.

236 {
237 papisde_list_entry_t *curr;
238 if( NULL == counter )
239 return SDE_OK;
240
241 // If the counter is a group, recursivelly increment the ref_count of all its children.
242 if(CNTR_CLASS_GROUP == counter->cntr_class){
243 curr = counter->u.cntr_group.group_head;
244 do{
245 sde_counter_t *tmp_cntr = curr->item;
246 // recursively increment the ref_count of all the elements in the group.
247 int ret_val = sdei_inc_ref_count(tmp_cntr);
248 if( SDE_OK != ret_val )
249 return ret_val;
250 curr = curr->next;
251 }while(NULL != curr);
252 }
253
254 // Increment the ref_count of the counter itself, INCLUDING the case where the counter is a group.
255 (counter->ref_count)++;
256
257 return SDE_OK;
258}
int sdei_inc_ref_count(sde_counter_t *counter)
Definition: sde_lib_misc.c:236
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sdei_read_and_update_data_value()

int sdei_read_and_update_data_value ( sde_counter_t *  counter,
long long int  previous_value,
long long int rslt_ptr 
)

Definition at line 490 of file sde_lib_misc.c.

490 {
491 int ret_val;
492 long long int tmp_int;
493 void *tmp_data;
494
495 char *event_name = counter->name;
496
497 if( IS_CNTR_BASIC(counter) ){
498 SDEDBG("Reading %s by accessing data pointer.\n", event_name);
499 tmp_data = counter->u.cntr_basic.data;
500 }else if( IS_CNTR_CALLBACK(counter) ){
501 SDEDBG("Reading %s by calling registered function pointer.\n", event_name);
502 tmp_int = counter->u.cntr_cb.callback(counter->u.cntr_cb.param);
503 tmp_data = &tmp_int;
504 }else{
505 SDEDBG("sdei_read_and_update_data_value(): Event %s has neither a variable nor a function pointer associated with it.\n", event_name);
506 return -1;
507 }
508
509 if( is_instant(counter->cntr_mode) ){
510 /* Instant counter means that we don't subtract the previous value (which we read at PAPI_Start()) */
511 previous_value = 0;
512 } else if( is_delta(counter->cntr_mode) ){
513 /* Do nothing here, this is the default mode */
514 } else{
515 SDEDBG("Unsupported mode (%d) for event: %s\n",counter->cntr_mode, event_name);
516 return -1;
517 }
518
519 ret_val = cast_and_store(tmp_data, previous_value, rslt_ptr, counter->cntr_type);
520 return ret_val;
521}
#define is_delta(_X_)
#define is_instant(_X_)
static int cast_and_store(void *data, long long int previous_value, void *rslt_ptr, int cntr_type)
Definition: sde_lib_misc.c:524
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sdei_read_counter_group()

int sdei_read_counter_group ( sde_counter_t *  counter,
long long int rslt_ptr 
)

This function assumes that all counters in a group (including recursive subgroups) have the same type.

Definition at line 390 of file sde_lib_misc.c.

390 {
391 papisde_list_entry_t *curr;
392 long long int final_value = 0;
393
394 if( NULL == counter ){
395 SDE_ERROR("sdei_read_counter_group(): Counter parameter is NULL.\n");
396 return SDE_EINVAL;
397 }
398
399 if( !IS_CNTR_GROUP(counter) ){
400 SDE_ERROR("sdei_read_counter_group(): Counter '%s' is not a counter group.\n",counter->name);
401 return SDE_EINVAL;
402 }
403 curr = counter->u.cntr_group.group_head;
404
405 do{
406 long long int tmp_value = 0;
407 int ret_val;
408
409 sde_counter_t *tmp_cntr = curr->item;
410 if( NULL == tmp_cntr ){
411 SDE_ERROR("sdei_read_counter_group(): List of counters in counter group '%s' is clobbered.\n",counter->name);
412 return SDE_EINVAL;
413 }
414
415 int read_succesfully = 1;
416 // We can _not_ have a recorder inside a group.
417 if( IS_CNTR_RECORDER(tmp_cntr) || IS_CNTR_CSET(tmp_cntr) || IS_CNTR_PLACEHOLDER(tmp_cntr) ){
418 SDE_ERROR("sdei_read_counter_group(): Counter group contains counter: %s with class: %d.\n",tmp_cntr->name, tmp_cntr->cntr_class);
419 }else{
420 // We allow counter groups to contain other counter groups recursively.
421 if( IS_CNTR_GROUP(tmp_cntr) ){
422 ret_val = sdei_read_counter_group( tmp_cntr, &tmp_value );
423 if( ret_val != SDE_OK ){
424 // If something went wrong with one counter group, ignore it silently.
425 read_succesfully = 0;
426 }
427 }else{ // If we are here it means that we are trying to read a real counter.
428 ret_val = sdei_read_and_update_data_value( tmp_cntr, tmp_cntr->previous_data, &tmp_value );
429 if( SDE_OK != ret_val ){
430 SDE_ERROR("sdei_read_counter_group(): Error occured when reading counter: %s.\n",tmp_cntr->name);
431 read_succesfully = 0;
432 }
433 }
434
435 if( read_succesfully )
436 aggregate_value_in_group(&tmp_value, &final_value, tmp_cntr->cntr_type, counter->u.cntr_group.group_flags);
437 }
438
439 curr = curr->next;
440 }while(NULL != curr);
441
442 *rslt_ptr = final_value;
443 return SDE_OK;
444}
#define IS_CNTR_GROUP(_CNT)
int sdei_read_and_update_data_value(sde_counter_t *counter, long long int previous_value, long long int *rslt_ptr)
Definition: sde_lib_misc.c:490
int sdei_read_counter_group(sde_counter_t *counter, long long int *rslt_ptr)
Definition: sde_lib_misc.c:390
static int aggregate_value_in_group(long long int *data, long long int *rslt, int cntr_type, int group_flags)
Definition: sde_lib_misc.c:467
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sdei_set_timer_for_overflow()

int sdei_set_timer_for_overflow ( void  )
inline

Definition at line 60 of file sde_lib.c.

60 {
63 return -1;
64}
int(* papi_sde_set_timer_for_overflow_ptr)(void)
Definition: sde.c:22
Here is the caller graph for this function:

◆ sdei_setup_counter_internals()

int sdei_setup_counter_internals ( papi_handle_t  handle,
const char *  event_name,
int  cntr_mode,
int  cntr_type,
enum CNTR_CLASS  cntr_class,
cntr_class_specific_t  cntr_union 
)

Definition at line 156 of file sde_lib_misc.c.

157{
158 papisde_library_desc_t *lib_handle;
159 sde_counter_t *tmp_item;
160 uint32_t counter_uniq_id;
161 char *full_event_name;
162 int ret_val = SDE_OK;
163 int needs_overflow = 0;
164
165 lib_handle = (papisde_library_desc_t *) handle;
166 if( (NULL == lib_handle) || (NULL == lib_handle->libraryName) ){
167 SDE_ERROR("sdei_setup_counter_internals(): 'handle' is clobbered. Unable to register counter.");
168 return SDE_EINVAL;
169 }
170
171 size_t str_len = strlen(lib_handle->libraryName)+strlen(event_name)+2+1; // +2 for "::" and +1 for '\0'
172 full_event_name = (char *)malloc(str_len*sizeof(char));
173 snprintf(full_event_name, str_len, "%s::%s", lib_handle->libraryName, event_name);
174
175 SDEDBG("%s: Counter: '%s' will be added in library: %s.\n", __FILE__, full_event_name, lib_handle->libraryName);
176
177 if( !is_instant(cntr_mode) && !is_delta(cntr_mode) ){
178 SDE_ERROR("Unknown mode %d. SDE counter mode must be either Instant or Delta.",cntr_mode);
179 free(full_event_name);
180 return SDE_ECMP;
181 }
182
183 // Look if the event is already registered.
184 tmp_item = ht_lookup_by_name(lib_handle->lib_counters, full_event_name);
185
186 if( NULL != tmp_item ){
187 if( !IS_CNTR_PLACEHOLDER(tmp_item) ){
188 // If it is registered and it is _not_ a placeholder then ignore it silently.
189 SDEDBG("%s: Counter: '%s' was already in library: %s.\n", __FILE__, full_event_name, lib_handle->libraryName);
190 free(full_event_name);
191 return SDE_OK;
192 }
193 // If we are here, then it IS a placeholder, so check if we need to start overflowing.
194 if( tmp_item->overflow && ( (CNTR_CLASS_REGISTERED == cntr_class) || (CNTR_CLASS_CB == cntr_class) ) ){
195 needs_overflow = 1;
196 }
197
198 // Since the counter is a placeholder update the mode, the type, and the union that contains the 'data'.
199 SDEDBG("%s: Updating placeholder for counter: '%s' in library: %s.\n", __FILE__, full_event_name, lib_handle->libraryName);
200
201 tmp_item->u = cntr_union;
202 tmp_item->cntr_class = cntr_class;
203 tmp_item->cntr_mode = cntr_mode;
204 tmp_item->cntr_type = cntr_type;
205 free(full_event_name);
206
207 return SDE_OK;
208 }
209
210 // If neither the event, nor a placeholder exists, then use the current
211 // number of registered events as the index of the new one, and increment it.
212 papisde_control_t *gctl = sdei_get_global_struct();
213 counter_uniq_id = gctl->num_reg_events++;
214 gctl->num_live_events++;
215
216 SDEDBG("%s: Counter %s has unique ID = %d\n", __FILE__, full_event_name, counter_uniq_id);
217
218 tmp_item = allocate_and_insert( gctl, lib_handle, full_event_name, counter_uniq_id, cntr_mode, cntr_type, cntr_class, cntr_union );
219
220 if(NULL == tmp_item) {
221 SDEDBG("%s: Counter not inserted in SDE %s\n", __FILE__, lib_handle->libraryName);
222 free(full_event_name);
223 return SDE_ECMP;
224 }
225
226 free(full_event_name);
227
228 // Check if we need to worry about overflow (cases r[4-6])
229 if( needs_overflow ){
230 ret_val = sdei_set_timer_for_overflow();
231 }
232
233 return ret_val;
234}
static papi_handle_t handle
Definition: Gamum.c:21
int sdei_set_timer_for_overflow(void)
Definition: sde_lib.c:60
sde_counter_t * allocate_and_insert(papisde_control_t *gctl, papisde_library_desc_t *lib_handle, const char *name, uint32_t uniq_id, int cntr_mode, int cntr_type, enum CNTR_CLASS cntr_class, cntr_class_specific_t cntr_union)
Definition: sde_lib_misc.c:112
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _papisde_global_control

papisde_control_t* _papisde_global_control
extern

This global variable is defined in sde_lib.c and points to the head of the control state list

This global variable points to the head of the control state list

Definition at line 37 of file sde_lib.c.