24#define DLSYM_CHECK(name) \
26 if ( NULL != (err=dlerror()) ) { \
27 int strErr=snprintf(_sde_vector.cmp_info.disabled_reason, \
29 "Function '%s' not found in any dynamic lib", \
31 if (strErr > PAPI_MAX_STR_LEN) \
32 SUBDBG("Unexpected snprintf error.\n"); \
34 SUBDBG("sde_load_sde_ti(): Unable to load symbol %s: %s\n", #name, err);\
35 return ( PAPI_ECMP ); \
52 if( (NULL != sde_ti_reset_counter_ptr) &&
53 (NULL != sde_ti_reset_counter_ptr) &&
54 (NULL != sde_ti_read_counter_ptr) &&
55 (NULL != sde_ti_write_counter_ptr) &&
56 (NULL != sde_ti_name_to_code_ptr) &&
57 (NULL != sde_ti_is_simple_counter_ptr) &&
58 (NULL != sde_ti_is_counter_set_to_overflow_ptr) &&
59 (NULL != sde_ti_set_counter_overflow_ptr) &&
60 (NULL != sde_ti_get_event_name_ptr) &&
61 (NULL != sde_ti_get_event_description_ptr) &&
62 (NULL != sde_ti_get_num_reg_events_ptr) &&
63 (NULL != sde_ti_shutdown_ptr)
70 void *
handle = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
71 if( NULL != (err = dlerror()) ){
72 SUBDBG(
"sde_load_sde_ti(): %s\n",err);
76 sde_ti_reset_counter_ptr = (
int (*)( uint32_t ))dlsym(
handle,
"sde_ti_reset_counter" );
79 sde_ti_read_counter_ptr = (
int (*)( uint32_t,
long long int * ))dlsym(
handle,
"sde_ti_read_counter" );
82 sde_ti_write_counter_ptr = (
int (*)( uint32_t,
long long ))dlsym(
handle,
"sde_ti_write_counter" );
85 sde_ti_name_to_code_ptr = (
int (*)(
const char *, uint32_t * ))dlsym(
handle,
"sde_ti_name_to_code" );
88 sde_ti_is_simple_counter_ptr = (
int (*)( uint32_t ))dlsym(
handle,
"sde_ti_is_simple_counter" );
91 sde_ti_is_counter_set_to_overflow_ptr = (
int (*)( uint32_t ))dlsym(
handle,
"sde_ti_is_counter_set_to_overflow" );
94 sde_ti_set_counter_overflow_ptr = (
int (*)( uint32_t,
int ))dlsym(
handle,
"sde_ti_set_counter_overflow" );
97 sde_ti_get_event_name_ptr = (
char * (*)(
int ))dlsym(
handle,
"sde_ti_get_event_name" );
100 sde_ti_get_event_description_ptr = (
char * (*)(
int ))dlsym(
handle,
"sde_ti_get_event_description" );
103 sde_ti_get_num_reg_events_ptr = (
int (*)( void ))dlsym(
handle,
"sde_ti_get_num_reg_events" );
106 sde_ti_shutdown_ptr = (
int (*)( void ))dlsym(
handle,
"sde_ti_shutdown" );
120 SUBDBG(
"_sde_init_component...\n");
130 PAPI_MAX_STR_LEN,
"libsde API not found. No SDEs exist in this executable.");
132 SUBDBG(
"disabled_reason truncated");
146 SUBDBG(
"_sde_init_thread %p...\n", ctx );
160 SUBDBG(
"sde_init_control_state... %p\n", ctl );
180 SUBDBG(
"_sde_update_control_state %p %p...\n", ctl, ctx );
187 PAPIERROR(
"_sde_update_control_state(): Event at index %d has a negative native event code = %d.\n",
i,index);
190 SUBDBG(
"_sde_update_control_state: i=%d index=%u\n",
i, index );
212 struct itimerspec its;
216 SUBDBG(
"%p %p...\n", ctx, ctl );
222 its.it_value.tv_sec = 0;
225 its.it_value.tv_nsec = 100*1000;
226 its.it_interval.tv_sec = its.it_value.tv_sec;
227 its.it_interval.tv_nsec = its.it_value.tv_nsec;
238 if( sde_ti_is_counter_set_to_overflow_ptr(sde_ctl->
which_counter[
i]) ){
249 SUBDBG(
"starting SDE internal timer for emulating HARDWARE overflowing\n");
250 if (timer_settime(sde_ctl->
timerid, 0, &its, NULL) == -1){
252 timer_delete(sde_ctl->
timerid);
272 struct itimerspec zero_time;
274 SUBDBG(
"sde_stop %p %p...\n", ctx, ctl );
284 SUBDBG(
"stopping SDE internal timer\n");
285 memset(&zero_time, 0,
sizeof(
struct itimerspec));
286 if (timer_settime(sde_ctl->
timerid, 0, &zero_time, NULL) == -1){
288 timer_delete(sde_ctl->
timerid);
307 SUBDBG(
"_sde_read... %p %d\n", ctx, flags );
313 ret_val = sde_ti_read_counter_ptr( counter_uniq_id, &(sde_ctl->
counter[
i]) );
315 PAPIERROR(
"_sde_read(): Error when reading event at index %d.\n",
i);
336 SUBDBG(
"_sde_write... %p\n", ctx );
343 ret_val = sde_ti_write_counter_ptr( counter_uniq_id,
values[
i] );
345 PAPIERROR(
"_sde_write(): Error when writing event at index %d.\n",
i);
365 SUBDBG(
"_sde_reset ctx=%p ctrl=%p...\n", ctx, ctl );
371 ret_val = sde_ti_reset_counter_ptr( counter_uniq_id );
373 PAPIERROR(
"_sde_reset(): Error when reseting event at index %d.\n",
i);
388 SUBDBG(
"sde_shutdown_component...\n" );
389 return sde_ti_shutdown_ptr();
399 SUBDBG(
"sde_shutdown_thread... %p\n", ctx );
442 SUBDBG(
"sde_set_domain...\n" );
445 SUBDBG(
" PAPI_DOM_USER\n" );
449 SUBDBG(
" PAPI_DOM_KERNEL\n" );
453 SUBDBG(
" PAPI_DOM_OTHER\n" );
457 SUBDBG(
" PAPI_DOM_ALL\n" );
481 unsigned int curr_code, next_code, num_reg_events;
484 SUBDBG(
"_sde_ntv_enum_events begin\n\tEventCode=%u modifier=%d\n", *EventCode, modifier);
486 switch ( modifier ) {
491 if( sde_ti_get_num_reg_events_ptr() <= 0 ){
506 num_reg_events = (
unsigned int)sde_ti_get_num_reg_events_ptr();
507 if( curr_code >= num_reg_events-1 ){
517 next_code = curr_code;
520 char *ev_name = sde_ti_get_event_name_ptr((uint32_t)next_code);
521 if( NULL != ev_name ){
522 *EventCode = next_code;
523 SUBDBG(
"Event name = %s (code = %d)\n", ev_name, next_code);
527 }
while(next_code < num_reg_events);
555 SUBDBG(
"_sde_ntv_code_to_name %u\n", code);
559 char *ev_name = sde_ti_get_event_name_ptr((uint32_t)code);
560 if( NULL == ev_name ){
564 SUBDBG(
"Event name = %s (code = %d)\n", ev_name, code);
565 (void)strncpy(
name, ev_name, len );
584 SUBDBG(
"_sde_ntv_code_to_descr %u\n", code);
588 char *ev_descr = sde_ti_get_event_description_ptr((uint32_t)code);
589 if( NULL == ev_descr ){
593 SUBDBG(
"Event (code = %d) description: %s\n", code, ev_descr);
595 (void)strncpy(
descr, ev_descr, len );
614 ret_val = sde_ti_name_to_code_ptr(
event_name, (uint32_t *)event_code);
639 int ret_val = sde_ti_set_counter_overflow_ptr(counter_uniq_id,
threshold);
648 timer_delete(sde_ctl->
timerid);
663 int signo, sig_offset;
664 struct sigevent sigev;
670 signo = SIGRTMIN+sig_offset;
671 if(signo > SIGRTMAX){
672 PAPIERROR(
"do_set_timer_for_overflow(): Unable to create new timer due to large number of existing timers. Overflowing will not be activated for the current event.\n");
677 sa.sa_flags = SA_SIGINFO;
679 sigemptyset(&sa.sa_mask);
681 PAPIERROR(
"do_set_timer_for_overflow(): sigaction() failed.");
687 sigev.sigev_signo = signo;
688 sigev.sigev_value.sival_ptr = &(sde_ctl->
timerid);
689 if (timer_create(CLOCK_REALTIME, &sigev, &(sde_ctl->
timerid)) == -1){
690 PAPIERROR(
"do_set_timer_for_overflow(): timer_create() failed.");
699 struct itimerspec its;
703 its.it_value.tv_sec = 0;
704 its.it_value.tv_nsec = 100*1000;
705 its.it_interval.tv_sec = its.it_value.tv_sec;
706 its.it_interval.tv_nsec = its.it_value.tv_nsec;
708 SUBDBG(
"starting SDE internal timer for emulating HARDWARE overflowing\n");
709 if (timer_settime(sde_ctl->
timerid, 0, &its, NULL) == -1){
711 timer_delete(sde_ctl->
timerid);
726 int i,
cidx,
retval, isHardware, slow_down, speed_up;
727 int found_registered_counters, period_has_changed = 0;
729 struct itimerspec its;
730 long long overflow_vector = 0;
735 SUBDBG(
"SDE timer expired. Dispatching (papi internal) overflow handler\n");
751 found_registered_counters = 0;
754 for (
i = 0;
i < event_counter;
i++ ) {
756 long long deadline,
threshold, latest, previous, diff;
758 uint32_t counter_uniq_id = sde_ctl->
which_counter[papi_index];
759 if( !sde_ti_is_simple_counter_ptr( counter_uniq_id ) )
762 found_registered_counters = 1;
764 latest = ESI->
sw_stop[papi_index];
773 diff = latest-previous;
787 if ( latest >= deadline ) {
792 SUBDBG (
"Event at index %d (and pos %d) has value %lld which exceeds deadline %lld (threshold %lld, accuracy %.2lf)\n",
793 papi_index, pos, latest, deadline,
threshold, 100.0*(
double)(latest-deadline)/(
double)
threshold);
795 overflow_vector ^= (
long long ) 1 << pos;
801 if( !found_registered_counters && sde_ctl->
has_timer ){
802 struct itimerspec zero_time;
803 memset(&zero_time, 0,
sizeof(
struct itimerspec));
804 if (timer_settime(sde_ctl->
timerid, 0, &zero_time, NULL) == -1){
806 timer_delete(sde_ctl->
timerid);
810 goto no_change_in_period;
819 if( !speed_up && !slow_down )
820 goto no_change_in_period;
823 goto no_change_in_period;
826 if( timer_gettime(sde_ctl->
timerid, &its) == -1){
827 PAPIERROR(
"timer_gettime() failed. Timer will not be modified.\n");
828 goto no_change_in_period;
831 period_has_changed = 0;
833 if( speed_up && (its.it_interval.tv_nsec > 131607) ){
834 double new_val = (double)its.it_interval.tv_nsec;
836 its.it_value.tv_nsec = (
int)new_val;
837 its.it_interval.tv_nsec = its.it_value.tv_nsec;
838 period_has_changed = 1;
839 SUBDBG (
"Timer will be sped up to %ld ns\n", its.it_value.tv_nsec);
843 if( slow_down && (its.it_interval.tv_nsec < 75983800) ){
844 double new_val = (double)its.it_interval.tv_nsec;
846 its.it_value.tv_nsec = (
int)new_val;
847 its.it_interval.tv_nsec = its.it_value.tv_nsec;
848 period_has_changed = 1;
849 SUBDBG (
"Timer will be slowed down to %ld ns\n", its.it_value.tv_nsec);
852 if( !period_has_changed )
853 goto no_change_in_period;
855 if (timer_settime(sde_ctl->
timerid, 0, &its, NULL) == -1){
856 PAPIERROR(
"timer_settime() failed when modifying PAPI internal timer. This might have broken overflow support for this eventset.\n");
857 goto no_change_in_period;
863 if( 0 == overflow_vector ){
868 PAPIERROR(
"_sde_dispatch_timer(): 'Can not access overflow flags'");
872 hw_context.
si = info;
877 int genOverflowBit = 0;
892 long long overflow_vector;
911 if( uniq_id == cntr_uniq_id ){
917 PAPIERROR(
"The PAPI framework considers this event removed from the eventset, but the component does not\n");
920 overflow_vector = (
long long ) 1 << pos;
926 hw_context.
si = NULL;
937 int cidx,
i, index_in_ESI;
956 for (
i = 0;
i < event_counter;
i++ ) {
961 if( uniq_id == cntr_uniq_id ){
967 if( index_in_ESI >= 0 ){
974 if( latest > deadline ){
1029 .short_name =
"sde",
1030 .description =
"Software Defined Events (SDE) component",
1032 .support_version =
"n/a",
1033 .kernel_version =
"n/a",
static papi_handle_t handle
#define GET_OVERFLOW_ADDRESS(ctx)
char event_name[2][PAPI_MAX_STR_LEN]
#define PAPI_OVERFLOW_HARDWARE
char events[MAX_EVENTS][BUFSIZ]
static long long values[NUM_EVENTS]
unsigned long AO_t __attribute__((__aligned__(4)))
#define PAPI_NATIVE_AND_MASK
#define SUBDBG(format, args...)
int sigaction(int __sig, const struct sigaction *__restrict __act, struct sigaction *__restrict __oact) __attribute__((__nothrow__
void PAPIERROR(char *format,...)
int _papi_hwi_read(hwd_context_t *context, EventSetInfo_t *ESI, long long *values)
static int sde_arm_timer(sde_control_state_t *sde_ctl)
static int _sde_write(hwd_context_t *ctx, hwd_control_state_t *ctl, long long *values)
static int do_set_timer_for_overflow(sde_control_state_t *sde_ctl)
static int _sde_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _sde_init_control_state(hwd_control_state_t *ctl)
static int _sde_set_overflow(EventSetInfo_t *ESI, int EventIndex, int threshold)
static int _sde_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _sde_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _sde_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
papi_vector_t _sde_vector
static int sde_load_sde_ti(void)
static int _sde_shutdown_component(void)
static int _sde_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _sde_ntv_code_to_descr(unsigned int EventCode, char *descr, int len)
void _sde_dispatch_timer(int n, hwd_siginfo_t *info, void *uc)
static int _sde_init_component(int cidx)
static int _sde_ntv_code_to_name(unsigned int EventCode, char *name, int len)
static int _sde_init_thread(hwd_context_t *ctx)
static int _sde_set_domain(hwd_control_state_t *cntrl, int domain)
void(* papi_sde_check_overflow_status_ptr)(uint32_t cntr_id, long long int value)
static void invoke_user_handler(uint32_t cntr_uniq_id)
static int _sde_ntv_name_to_code(const char *event_name, unsigned int *event_code)
int(* papi_sde_set_timer_for_overflow_ptr)(void)
static int _sde_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _sde_shutdown_thread(hwd_context_t *ctx)
static int _sde_ntv_enum_events(unsigned int *EventCode, int modifier)
#define DLSYM_CHECK(name)
#define SDE_MAX_SIMULTANEOUS_COUNTERS
void papi_sde_check_overflow_status(unsigned int cntr_uniq_id, long long int latest)
#define REGISTERED_EVENT_MASK
int papi_sde_set_timer_for_overflow(void)
int sde_ti_read_counter(uint32_t, long long int *)
int sde_ti_is_simple_counter(uint32_t)
int sde_ti_name_to_code(const char *, uint32_t *)
int sde_ti_is_counter_set_to_overflow(uint32_t)
int sde_ti_reset_counter(uint32_t)
int sde_ti_set_counter_overflow(uint32_t, int)
int sde_ti_get_num_reg_events(void)
char * sde_ti_get_event_name(int)
char * sde_ti_get_event_description(int)
int sde_ti_write_counter(uint32_t, long long)
int sde_ti_shutdown(void)
int pos[PAPI_EVENTS_IN_DERIVED_EVENT]
EventInfo_t * EventInfoArray
hwd_control_state_t * ctl_state
EventSetOverflowInfo_t overflow
PAPI_overflow_handler_t handler
char name[PAPI_MAX_STR_LEN]
char disabled_reason[PAPI_HUGE_STR_LEN]
hwd_ucontext_t * ucontext
PAPI_component_info_t cmp_info
long long counter[SDE_MAX_SIMULTANEOUS_COUNTERS]
uint32_t which_counter[SDE_MAX_SIMULTANEOUS_COUNTERS]
long long previous_value[SDE_MAX_SIMULTANEOUS_COUNTERS]
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
inline_static int _papi_hwi_lock(int lck)
inline_static int _papi_hwi_unlock(int lck)