24 #define MPX_NONDECR_HYBRID 134 #define MPX_MINCYC 25000 145 #include <sys/time.h> 153 static const struct itimerval
itimestop = { {0, 0}, {0, 0} };
160 static int threads_responding = 0;
167 static void *global_process_record;
176 int domain,
int granularity );
183 MPXDBG(
"signal held\n" );
189 MPXDBG(
"signal released\n" );
200 interval = MPX_DEFAULT_INTERVAL;
205 itime.it_interval.tv_sec = 0;
206 itime.it_interval.tv_usec = 0;
207 itime.it_value.tv_sec = 0;
208 itime.it_value.tv_usec = interval;
211 itime.it_interval.tv_sec = 0;
212 itime.it_interval.tv_usec = interval;
213 itime.it_value.tv_sec = 0;
214 itime.it_value.tv_usec = interval;
228 MPXDBG(
"PID %d\n", getpid( ) );
229 memset( &sigact, 0,
sizeof ( sigact ) );
230 sigact.sa_flags = SA_RESTART;
249 MPXDBG(
"restore signal\n" );
259 MPXDBG(
"setitimer off\n" );
262 (
struct itimerval * ) &
itimestop, NULL ) == -1 )
281 unsigned long pid = (
unsigned long ) getpid( );
284 if ( t->
tid == tid || ( ( tid == 0 ) && ( t->
tid ==
pid ) ) )
296 if ( newset == NULL )
309 int retval, alloced_newset = 0;
314 MPXDBG(
"Adding %p %#x\n",newset,EventCode);
334 MPXDBG(
"New thread at %p\n", t );
337 MPXDBG(
"New process at %p\n", t );
338 t->
tid = (
unsigned long ) getpid( );
358 if ( t->
tid == tid ) {
369 MPXDBG(
"New thread %lx\n", tid );
378 if ( newset == NULL ) {
380 if ( newset == NULL ) {
400 domain, granularity );
402 if ( alloced_newset ) {
412 *mpx_events = newset;
427 #ifdef MPX_DEBUG_TIMER 428 static long long lastcall;
438 #define SCALE_EVENT _PNE_PM_RUN_CYC 440 #define SCALE_EVENT PAPI_TOT_CYC 453 #ifdef MPX_DEBUG_OVERHEAD 458 #ifdef MPX_DEBUG_TIMER 464 MPXDBG(
"Handler in thread\n" );
501 if ( threads_responding == 0 ) {
503 #ifdef MPX_DEBUG_TIMER 504 thiscall = _papi_hwd_get_real_usec( );
505 MPXDBG(
"last signal was %lld usec ago\n", thiscall - lastcall );
508 MPXDBG(
"%#x caught it, tlist is %p\n",
self,
tlist );
509 for ( t =
tlist; t != NULL; t = t->
next ) {
510 if ( pthread_equal( t->thr,
self ) == 0 ) {
511 ++threads_responding;
514 #ifdef MPX_DEBUG_SIGNALS 515 MPXDBG(
"%#x signaling %#x\n",
self, t->thr );
520 #ifdef MPX_DEBUG_SIGNALS 521 MPXDBG(
"%#x was tapped, tr = %d\n",
self, threads_responding );
523 --threads_responding;
526 lastthread = ( threads_responding == 0 );
533 if ( head != NULL ) {
546 if ( me != NULL && me->
cur_event != NULL ) {
549 long long cycles = 0, total_cycles = 0;
552 MPXDBG(
"retval=%d, cur_event=%p, I'm tid=%lx\n",
556 MPXDBG(
"counts[0] = %lld counts[1] = %lld\n", counts[0],
559 cur_event->
count += counts[0];
561 ? counts[0] : counts[1];
569 cur_event->
cycles += cycles;
572 ( double ) counts[0] / (
double ) cycles;
575 (
long long ) ( (
double ) total_cycles *
577 MPXDBG(
"New estimate = %lld (%lld cycles * %lf rate)\n",
588 cur_event->
count -= counts[0];
593 MPXDBG(
"%lx value = %lld cycles = %lld\n\n",
598 (
"tid(%lx): value = %lld (%lld) cycles = %lld (%lld) rate = %lf\n\n",
611 ( cur_event->
next == NULL ) ? head : cur_event->
next;
613 mev = ( mev->
next == NULL ) ? head : mev->
next ) {
625 #ifdef MPX_DEBUG_OVERHEAD 630 #ifdef ANY_THREAD_GETS_SIGNAL 633 for ( t =
tlist; t != NULL; t = t->
next ) {
635 ( t->
head == NULL ) )
637 MPXDBG(
"forwarding signal to thread %lx\n", t->
tid );
640 MPXDBG(
"forwarding signal to thread %lx returned %d\n",
662 #ifdef MPX_DEBUG_TIMER 663 MPXDBG(
"timer restarted by %lx\n", me->
tid );
668 #ifdef MPX_DEBUG_OVERHEAD 669 usec = _papi_hwd_get_real_usec( ) - usec;
670 MPXDBG(
"handler %#x did %swork in %lld usec\n",
671 self, ( didwork ?
"" :
"no " ), usec );
677 int domain,
int granularity )
697 long long cycles_this_slice, current_thread_mpx_c = 0;
700 t = mpx_events->
mythr;
705 current_thread_mpx_c += t->
total_c;
713 cycles_this_slice = 0;
718 cycles_this_slice = 0;
738 #ifdef MPX_NONDECR_HYBRID 742 ( cycles_this_slice + t->
total_c -
747 ( (
values[0] / (
double ) cycles_this_slice ) *
802 MPXDBG(
"%s:%d:: start_c=%lld thread->total_c=%lld\n", __FILE__,
806 (
"%s:%d:: start_values[%d]=%lld estimate=%lld rate=%g last active=%lld\n",
808 mpx_events->
mev[
i]->count_estimate,
809 mpx_events->
mev[
i]->rate_estimate,
810 mpx_events->
mev[
i]->prev_total_c );
827 long long last_value[2];
828 long long cycles_this_slice = 0;
837 thread_data = mpx_events->
mythr;
845 ? last_value[0] : last_value[1];
859 #ifdef MPX_NONDECR_HYBRID 867 if (called_by_stop) {
876 ( cycles_this_slice +
880 (
"%s:%d:: Inactive %d, stop values=%lld (est. %lld, rate %g, cycles %lld)\n",
883 cycles_this_slice + thread_data->
total_c -
891 (
"%s:%d:: -Active- %d, stop values=%lld (est. %lld, rate %g, cycles %lld)\n",
901 mpx_events->
stop_c = thread_data->
total_c + cycles_this_slice;
910 long long elapsed_slices = 0;
924 elapsed_slices ? ( elapsed_values / elapsed_slices ) : 0;
926 MPXDBG(
"%s:%d:: event %d, values=%lld ( %lld - %lld), cycles %lld\n",
927 __FILE__, __LINE__,
i,
976 int i, cur_mpx_event;
978 long long dummy_value[2];
984 if ( mpx_events == NULL )
1017 --mpx_events->
mev[
i]->active;
1018 if ( mpx_events->
mev[
i] == cur_event )
1026 if ( cur_mpx_event > -1 ) {
1029 if ( mev->
active == 0 ) {
1040 for (
tmp = ( cur_event->
next == NULL ) ? head : cur_event->
next;
1042 tmp = (
tmp->next == NULL ) ? head :
tmp->next ) {
1043 if (
tmp->active ) {
1075 if ( mpx_events == NULL )
1078 if ( *mpx_events == NULL )
1104 MPXDBG(
"%d\n", getpid( ) );
1133 if ( strstr(
_papi_hwd[ESI->
CmpIdx]->cmp_info.name,
"perfctr.c" ) == NULL )
1137 unsigned int chk_domain =
1140 if ( ( ESI->
domain.
domain & chk_domain ) != chk_domain ) {
1142 (
"This platform requires PAPI_DOM_USER+PAPI_DOM_KERNEL+PAPI_DOM_SUPERVISOR\n" 1143 "to be set in the domain when using multiplexing. Instead, found %#x\n",
1154 #if defined(PTHREADS) || defined(_POWER6) 1177 int num_events,
int domain,
int granularity )
1179 int i,
retval = 0, num_events_success = 0;
1197 for( mev = *head; mev != NULL; mev = mev->
next ) {
1205 if ( mev == NULL ) {
1207 if ( mev == NULL ) {
1223 MPXDBG(
"Event %d could not be counted.\n",
1230 MPXDBG(
"Event %d could not be counted.\n",
1242 MPXDBG(
"Scale event could not be counted " 1243 "at the same time.\n" );
1251 options.domain.domain = domain;
1254 MPXDBG(
"PAPI_set_opt(PAPI_DOMAIN, ...) = %d\n",
1261 options.granularity.granularity = granularity;
1267 MPXDBG(
"PAPI_set_opt(PAPI_GRANUL, ...) = %d\n",
1289 mpx_events->
mev[mpx_events->
num_events + num_events_success] = mev;
1290 mpx_events->
mev[mpx_events->
num_events + num_events_success]->uses++;
1291 num_events_success++;
1296 if ( *head != NULL ) {
1297 ( *head )->mythr = mpx_events->
mythr;
1300 mpx_events->
num_events += num_events_success;
1320 for (
i = 0;
i < num_events_success;
i++ ) {
1325 if ( num_events_success )
1346 mev = mpx_events->
mev[
i];
1348 mpx_events->
mev[
i] = NULL;
1371 mev = mpx_events->
mev[
i];
1375 mpx_events->
mev[
i] = NULL;
1387 mpx_events->
mev[
i] = mpx_events->
mev[
i + 1];
1392 mpx_events->
mev[
i] = NULL;
1406 Threadlist *thr = ( *head == NULL ) ? NULL : ( *head )->mythr;
1410 for ( mev = *head; mev != NULL; mev = nextmev ) {
1411 nextmev = mev->
next;
1413 if ( lastmev == NULL ) {
1416 lastmev->
next = nextmev;
1428 if ( *head != NULL ) {
1429 ( *head )->
mythr = thr;
int PAPI_stop(int EventSet, long long *values)
unsigned long int(* _papi_hwi_thread_id_fn)(void)
int PAPI_add_event(int EventSet, int EventCode)
inline_static void mpx_hold(void)
static void mpx_shutdown_itimer(void)
static Threadlist * tlist
int MPX_stop(MPX_EventSet *mpx_events, long long *values)
long long stop_values[PAPI_MAX_SW_MPX_EVENTS]
EventSetDomainInfo_t domain
static void mpx_handler(int signal)
int PAPI_event_name_to_code(const char *in, int *out)
A pointer to the following is passed to PAPI_set/get_opt()
#define PAPI_MAX_SW_MPX_EVENTS
EventSetInfo_t * _papi_hwi_lookup_EventSet(int eventset)
long long start_hc[PAPI_MAX_SW_MPX_EVENTS]
int PAPI_set_opt(int option, PAPI_option_t *ptr)
Return codes and api definitions.
int MPX_read(MPX_EventSet *mpx_events, long long *values, int called_by_stop)
int MPX_add_events(MPX_EventSet **mpx_events, int *event_list, int num_events, int domain, int granularity)
struct _masterevent * mev[PAPI_MAX_SW_MPX_EVENTS]
static unsigned int randomseed
inline_static int _papi_hwi_lock(int lck)
static void mpx_remove_unused(MasterEvent **head)
static void mpx_delete_one_event(MPX_EventSet *mpx_events, int Event)
#define PAPI_DOM_SUPERVISOR
PAPI_os_info_t _papi_os_info
int MPX_start(MPX_EventSet *mpx_events)
static void mpx_restore_signal(void)
char model_string[PAPI_MAX_STR_LEN]
inline_static int _papi_hwi_unlock(int lck)
static int mpx_insert_events(MPX_EventSet *, int *event_list, int num_events, int domain, int granularity)
int MPX_cleanup(MPX_EventSet **mpx_events)
void PAPIERROR(char *format,...)
static int Event[MAX_EVENTS]
int sigaction(int __sig, const struct sigaction *__restrict __act, struct sigaction *__restrict __oact) __attribute__((__nothrow__
static int mpx_startup_itimer(void)
int mpx_add_event(MPX_EventSet **mpx_events, int EventCode, int domain, int granularity)
static struct sigaction oaction
static const struct itimerval itimestop
struct _masterevent * next
int PAPI_cleanup_eventset(int EventSet)
int mpx_init(int interval_ns)
int PAPI_create_eventset(int *EventSet)
papi_mdi_t _papi_hwi_system_info
struct _threadlist * mythr
int sigprocmask(int __how, const sigset_t *__restrict __set, sigset_t *__restrict __oset) __attribute__((__nothrow__
int MPX_reset(MPX_EventSet *mpx_events)
__sighandler_t signal(int __sig, __sighandler_t __handler) __attribute__((__nothrow__
#define MPXDBG(format, args...)
int pthread_kill(pthread_t __threadid, int __signo) __attribute__((__nothrow__
static MPX_EventSet * mpx_malloc(Threadlist *t)
static void mpx_init_timers(int interval)
long long PAPI_get_real_usec(void)
struct _threadlist * next
int mpx_remove_event(MPX_EventSet **mpx_events, int EventCode)
static MasterEvent * get_my_threads_master_event_list(void)
struct papi_vectors * _papi_hwd[]
int PAPI_destroy_eventset(int *EventSet)
int PAPI_read(int EventSet, long long *values)
inline_static void mpx_release(void)
int PAPI_start(int EventSet)
static struct itimerval itime
unsigned int pthread_key_t
static long long values[NUM_EVENTS]
struct _threadlist * mythr
static void mpx_delete_events(MPX_EventSet *)
long long start_values[PAPI_MAX_SW_MPX_EVENTS]
int mpx_check(int EventSet)