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

Go to the source code of this file.

Data Structures

struct  sde_register_t
 
struct  sde_reg_alloc_t
 
struct  sde_control_state_t
 
struct  sde_context_t
 

Macros

#define SDE_MAX_SIMULTANEOUS_COUNTERS   40
 
#define REGISTERED_EVENT_MASK   0x2;
 

Functions

static int _sde_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _sde_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *events)
 
static int _sde_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
 
static int _sde_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _sde_start (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_init_control_state (hwd_control_state_t *ctl)
 
static int _sde_init_thread (hwd_context_t *ctx)
 
static int _sde_init_component (int cidx)
 
static int _sde_shutdown_component (void)
 
static int _sde_shutdown_thread (hwd_context_t *ctx)
 
static int _sde_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
 
static int _sde_set_domain (hwd_control_state_t *cntrl, int domain)
 
static int _sde_ntv_enum_events (unsigned int *EventCode, int modifier)
 
static int _sde_ntv_code_to_name (unsigned int EventCode, char *name, int len)
 
static int _sde_ntv_code_to_descr (unsigned int EventCode, char *descr, int len)
 
static int _sde_ntv_name_to_code (const char *name, unsigned int *event_code)
 
static void _sde_dispatch_timer (int n, hwd_siginfo_t *info, void *uc)
 
static void invoke_user_handler (unsigned int cntr_uniq_id)
 
static int do_set_timer_for_overflow (sde_control_state_t *sde_ctl)
 
static int sde_arm_timer (sde_control_state_t *sde_ctl)
 
int papi_sde_lock (void)
 
int papi_sde_unlock (void)
 
void papi_sde_check_overflow_status (unsigned int cntr_uniq_id, long long int latest)
 
int papi_sde_set_timer_for_overflow (void)
 
 __attribute__ ((__common__)) int(*sde_ti_reset_counter_ptr)(uint32_t)
 

Variables

long long int long long
 
 int
 

Macro Definition Documentation

◆ REGISTERED_EVENT_MASK

#define REGISTERED_EVENT_MASK   0x2;

Definition at line 19 of file sde_internal.h.

◆ SDE_MAX_SIMULTANEOUS_COUNTERS

#define SDE_MAX_SIMULTANEOUS_COUNTERS   40

Definition at line 5 of file sde_internal.h.

Function Documentation

◆ __attribute__()

__attribute__ ( (__common__)  )

◆ _sde_ctl()

static int _sde_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)
static

◆ _sde_dispatch_timer()

static void _sde_dispatch_timer ( int  n,
hwd_siginfo_t info,
void *  uc 
)
static

Definition at line 721 of file sde.c.

721 {
722
723 _papi_hwi_context_t hw_context;
724 vptr_t address;
726 int i, cidx, retval, isHardware, slow_down, speed_up;
727 int found_registered_counters, period_has_changed = 0;
728 EventSetInfo_t *ESI;
729 struct itimerspec its;
730 long long overflow_vector = 0;
731 sde_control_state_t *sde_ctl;
732
733 (void) n;
734
735 SUBDBG("SDE timer expired. Dispatching (papi internal) overflow handler\n");
736
739
740 ESI = thread->running_eventset[cidx];
741 // This holds only the number of events in the eventset that are set to overflow.
742 int event_counter = ESI->overflow.event_counter;
743 sde_ctl = ( sde_control_state_t * ) ESI->ctl_state;
744
745 retval = _papi_hwi_read( thread->context[cidx], ESI, ESI->sw_stop );
746 if ( retval < PAPI_OK )
747 return;
748
749 slow_down = 0;
750 speed_up = 0;
751 found_registered_counters = 0;
752 // Reset the deadline of counters which have exceeded the current deadline
753 // and check if we need to slow down the frequency of the timer.
754 for ( i = 0; i < event_counter; i++ ) {
755 int papi_index = ESI->overflow.EventIndex[i];
756 long long deadline, threshold, latest, previous, diff;
757
758 uint32_t counter_uniq_id = sde_ctl->which_counter[papi_index];
759 if( !sde_ti_is_simple_counter_ptr( counter_uniq_id ) )
760 continue;
761
762 found_registered_counters = 1;
763
764 latest = ESI->sw_stop[papi_index];
765 deadline = ESI->overflow.deadline[i];
767
768 // Find the increment from the previous measurement.
769 previous = sde_ctl->previous_value[papi_index];
770
771 // NOTE: The following code assumes that the counters are "long long". No other
772 // NOTE: type will work correctly.
773 diff = latest-previous;
774
775 // If it's too small we need to slow down the timer, it it's
776 // too large we need to speed up the timer.
777 if( 30*diff < threshold ){
778 slow_down = 1; // I.e., grow the sampling period
779 }else if( 10*diff > threshold ){
780 speed_up = 1; // I.e., shrink the sampling period
781 }
782
783 // Update the "previous" measurement to be the latest one.
784 sde_ctl->previous_value[papi_index] = latest;
785
786 // If this counter has exceeded the deadline, add it in the vector.
787 if ( latest >= deadline ) {
788 // pos[0] holds the first among the native events that compose the given event. If it is a derived event,
789 // then it might be made up of multiple native events, but this is a CPU component concept. The SDE component
790 // does not have derived events (the groups are first class citizens, they don't have multiple pos[] entries).
791 int pos = ESI->EventInfoArray[papi_index].pos[0];
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);
794
795 overflow_vector ^= ( long long ) 1 << pos;
796 // We adjust the deadline in a way that it remains a multiple of threshold so we don't create an additive error.
797 ESI->overflow.deadline[i] = threshold*(latest/threshold) + threshold;
798 }
799 }
800
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){
805 PAPIERROR("timer_settime");
806 timer_delete(sde_ctl->timerid);
807 sde_ctl->has_timer = 0;
808 return;
809 }
810 goto no_change_in_period;
811 }
812
813 // Since we potentially check multiple counters in the loop above, both conditions could be true (for different counter).
814 // In this case, we give speed_up priority.
815 if( speed_up )
816 slow_down = 0;
817
818 // If neither was set, there is nothing to do here.
819 if( !speed_up && !slow_down )
820 goto no_change_in_period;
821
822 if( !sde_ctl->has_timer )
823 goto no_change_in_period;
824
825 // Get the current value of the timer.
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;
829 }
830
831 period_has_changed = 0;
832 // We only reduce the period if it is above 131.6us, so it never drops below 100us.
833 if( speed_up && (its.it_interval.tv_nsec > 131607) ){
834 double new_val = (double)its.it_interval.tv_nsec;
835 new_val /= 1.31607; // sqrt(sqrt(3)) = 1.316074
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);
840 }
841
842 // We only increase the period if it is below 75.9ms, so it never grows above 100ms.
843 if( slow_down && (its.it_interval.tv_nsec < 75983800) ){
844 double new_val = (double)its.it_interval.tv_nsec;
845 new_val *= 1.31607; // sqrt(sqrt(3)) = 1.316074
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);
850 }
851
852 if( !period_has_changed )
853 goto no_change_in_period;
854
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;
858 }
859
860no_change_in_period:
861
862 // If none of the events exceeded their deadline, there is nothing else to do.
863 if( 0 == overflow_vector ){
864 return;
865 }
866
867 if ( (NULL== thread) || (NULL == thread->running_eventset[cidx]) || (0 == thread->running_eventset[cidx]->overflow.flags) ){
868 PAPIERROR( "_sde_dispatch_timer(): 'Can not access overflow flags'");
869 return;
870 }
871
872 hw_context.si = info;
873 hw_context.ucontext = ( hwd_ucontext_t * ) uc;
874
875 address = GET_OVERFLOW_ADDRESS( hw_context );
876
877 int genOverflowBit = 0;
878
879 _papi_hwi_dispatch_overflow_signal( ( void * ) &hw_context, address, &isHardware, overflow_vector, genOverflowBit, &thread, cidx );
880
881 return;
882}
int i
#define GET_OVERFLOW_ADDRESS(ctx)
Definition: aix-context.h:12
int _papi_hwi_dispatch_overflow_signal(void *papiContext, vptr_t address, int *isHardware, long long overflow_bit, int genOverflowBit, ThreadInfo_t **t, int cidx)
Definition: extras.c:216
#define PAPI_OK
Definition: f90papi.h:73
static int threshold
void * thread(void *arg)
Definition: kufrin.c:38
void * vptr_t
Definition: papi.h:576
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
void PAPIERROR(char *format,...)
int _papi_hwi_read(hwd_context_t *context, EventSetInfo_t *ESI, long long *values)
static int cidx
papi_vector_t _sde_vector
Definition: sde.c:17
long long int long long
Definition: sde_internal.h:85
int pos[PAPI_EVENTS_IN_DERIVED_EVENT]
long long * sw_stop
EventInfo_t * EventInfoArray
hwd_control_state_t * ctl_state
EventSetOverflowInfo_t overflow
hwd_siginfo_t * si
hwd_ucontext_t * ucontext
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
uint32_t which_counter[SDE_MAX_SIMULTANEOUS_COUNTERS]
Definition: sde_internal.h:40
long long previous_value[SDE_MAX_SIMULTANEOUS_COUNTERS]
Definition: sde_internal.h:42
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:97
int retval
Definition: zero_fork.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _sde_init_component()

static int _sde_init_component ( int  cidx)
static

◆ _sde_init_control_state()

static int _sde_init_control_state ( hwd_control_state_t ctl)
static

◆ _sde_init_thread()

static int _sde_init_thread ( hwd_context_t ctx)
static

◆ _sde_ntv_code_to_descr()

static int _sde_ntv_code_to_descr ( unsigned int  EventCode,
char *  descr,
int  len 
)
static

◆ _sde_ntv_code_to_name()

static int _sde_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)
static

◆ _sde_ntv_enum_events()

static int _sde_ntv_enum_events ( unsigned int EventCode,
int  modifier 
)
static

◆ _sde_ntv_name_to_code()

static int _sde_ntv_name_to_code ( const char *  name,
unsigned int event_code 
)
static

◆ _sde_read()

static int _sde_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)
static

◆ _sde_reset()

static int _sde_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

◆ _sde_set_domain()

static int _sde_set_domain ( hwd_control_state_t cntrl,
int  domain 
)
static

◆ _sde_shutdown_component()

static int _sde_shutdown_component ( void  )
static

◆ _sde_shutdown_thread()

static int _sde_shutdown_thread ( hwd_context_t ctx)
static

◆ _sde_start()

static int _sde_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

◆ _sde_stop()

static int _sde_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

◆ _sde_update_control_state()

static int _sde_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)
static

◆ _sde_write()

static int _sde_write ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long events 
)
static

◆ do_set_timer_for_overflow()

static int do_set_timer_for_overflow ( sde_control_state_t sde_ctl)
static

◆ invoke_user_handler()

static void invoke_user_handler ( unsigned int  cntr_uniq_id)
static

◆ papi_sde_check_overflow_status()

void papi_sde_check_overflow_status ( unsigned int  cntr_uniq_id,
long long int  latest 
)
Here is the caller graph for this function:

◆ papi_sde_lock()

int papi_sde_lock ( void  )

◆ papi_sde_set_timer_for_overflow()

int papi_sde_set_timer_for_overflow ( void  )
Here is the caller graph for this function:

◆ papi_sde_unlock()

int papi_sde_unlock ( void  )

◆ sde_arm_timer()

static int sde_arm_timer ( sde_control_state_t sde_ctl)
inlinestatic

Variable Documentation

◆ int

int

Definition at line 89 of file sde_internal.h.

◆ long

long long int long long

Definition at line 85 of file sde_internal.h.