void MPX_shutdown( void ) { MPXDBG( "%d\n", getpid( ) ); mpx_shutdown_itimer( ); mpx_restore_signal( ); if ( tlist ) { Threadlist *next,*t=tlist; while(t!=NULL) { next=t->next; papi_free( t ); t = next; } tlist = NULL; } }
int mpx_init( int interval_ns ) { #if defined(PTHREADS) || defined(_POWER6) int retval; #endif #ifdef _POWER6 retval = PAPI_event_name_to_code( "PM_RUN_CYC", &_PNE_PM_RUN_CYC ); if ( retval != PAPI_OK ) return ( retval ); #endif tlist = NULL; mpx_hold( ); mpx_shutdown_itimer( ); mpx_init_timers( interval_ns / 1000 ); return ( PAPI_OK ); }
int MPX_stop( MPX_EventSet * mpx_events, long long *values ) { int i, cur_mpx_event; int retval = PAPI_OK; long long dummy_value[2]; long long dummy_mpx_values[PAPI_MAX_SW_MPX_EVENTS]; /* long long cycles_this_slice, total_cycles; */ MasterEvent *cur_event = NULL, *head; Threadlist *thr = NULL; if ( mpx_events == NULL ) return PAPI_EINVAL; if ( mpx_events->status != MPX_RUNNING ) return PAPI_ENOTRUN; /* Read the counter values, this updates mpx_events->stop_values[] */ MPXDBG( "Start\n" ); if ( values == NULL ) retval = MPX_read( mpx_events, dummy_mpx_values, 1 ); else retval = MPX_read( mpx_events, values, 1 ); /* Block timer interrupts while modifying active events */ mpx_hold( ); /* Get the master event list for this thread. */ head = get_my_threads_master_event_list( ); if (!head) { retval=PAPI_EBUG; goto exit_mpx_stop; } /* Get this threads data structure */ thr = head->mythr; cur_event = thr->cur_event; /* This would be a good spot to "hold" the counter and then restart * it at the end, but PAPI_start resets counters so it is not possible */ /* Run through all the events decrement their activity counters. */ cur_mpx_event = -1; for ( i = 0; i < mpx_events->num_events; i++ ) { --mpx_events->mev[i]->active; if ( mpx_events->mev[i] == cur_event ) cur_mpx_event = i; } /* One event in this set is currently running, if this was the * last active event set using this event, we need to start the next * event if there still is one left in the queue */ if ( cur_mpx_event > -1 ) { MasterEvent *tmp, *mev = mpx_events->mev[cur_mpx_event]; if ( mev->active == 0 ) { /* Event is now inactive; stop it * There is no need to update master event set * counters as this is the last active user */ retval = PAPI_stop( mev->papi_event, dummy_value ); mev->rate_estimate = 0.0; /* Fall-back value if none is found */ thr->cur_event = NULL; /* Now find a new cur_event */ for ( tmp = ( cur_event->next == NULL ) ? head : cur_event->next; tmp != cur_event; tmp = ( tmp->next == NULL ) ? head : tmp->next ) { if ( tmp->active ) { /* Found the next one to start */ thr->cur_event = tmp; break; } } if ( thr->cur_event != NULL ) { retval = PAPI_start( thr->cur_event->papi_event ); assert( retval == PAPI_OK ); } else { mpx_shutdown_itimer( ); } } } mpx_events->status = MPX_STOPPED; exit_mpx_stop: MPXDBG( "End\n" ); /* Restore the timer (for other event sets that may be running) */ mpx_release( ); return retval; }
static void mpx_hold( void ) { mpx_shutdown_itimer( ); }