Beispiel #1
0
/*
 * Set Overflow
 *
 * This is commented out in BG/L/P - need to explore and complete...
 * However, with true 64-bit counters in BG/Q and all counters for PAPI
 * always starting from a true zero (we don't allow write...), the possibility
 * for overflow is remote at best...
 */
int
IOUNIT_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
{
#ifdef DEBUG_BGQ
	printf("BEGIN IOUNIT_set_overflow\n");
#endif
	IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ESI->ctl_state;
	int retval;
	int evt_idx;
	uint64_t threshold_for_bgpm;
		
	/* convert threadhold value assigned by PAPI user to value that is
	 * programmed into the counter. This value is required by Bgpm_SetOverflow() */ 
	threshold_for_bgpm = BGPM_PERIOD2THRES( threshold );

	evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
	SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#ifdef DEBUG_BGQ
	printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#endif
	/* If this counter isn't set to overflow, it's an error */
	if ( threshold == 0 ) {
		/* Remove the signal handler */
		retval = _papi_hwi_stop_signal( _IOunit_vector.cmp_info.hardware_intr_sig );
		if ( retval != PAPI_OK )
			return ( retval );
	}
	else {
#ifdef DEBUG_BGQ
		printf( "IOUNIT_set_overflow: Enable the signal handler\n" );
#endif
		/* Enable the signal handler */
		retval = _papi_hwi_start_signal( _IOunit_vector.cmp_info.hardware_intr_sig, 
										NEED_CONTEXT, 
										_IOunit_vector.cmp_info.CmpIdx );
		if ( retval != PAPI_OK )
			return ( retval );
		
		retval = Bgpm_SetOverflow( this_state->EventGroup,
								   evt_idx,
								   threshold_for_bgpm );
		CHECK_BGPM_ERROR( retval, "Bgpm_SetOverflow" );
		
        retval = Bgpm_SetEventUser1( this_state->EventGroup,
									 evt_idx,
									 1024 );
		CHECK_BGPM_ERROR( retval, "Bgpm_SetEventUser1" );
		
		/* user signal handler for overflow case */
		retval = Bgpm_SetOverflowHandler( this_state->EventGroup, user_signal_handler_IOUNIT );
		CHECK_BGPM_ERROR( retval, "Bgpm_SetOverflowHandler" );
	}
	
	return ( PAPI_OK );
}
Beispiel #2
0
/*
 * Set Overflow
 *
 * This is commented out in BG/L/P - need to explore and complete...
 * However, with true 64-bit counters in BG/Q and all counters for PAPI
 * always starting from a true zero (we don't allow write...), the possibility
 * for overflow is remote at best...
 */
int
IOUNIT_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
{
#ifdef DEBUG_BGQ
	printf("BEGIN IOUNIT_set_overflow\n");
#endif
	IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ESI->ctl_state;
	int retval;
	int evt_idx;
		
	evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
	SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#ifdef DEBUG_BGQ
	printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#endif
	/* If this counter isn't set to overflow, it's an error */
	if ( threshold == 0 ) {
		/* Remove the signal handler */
		retval = _papi_hwi_stop_signal( _IOunit_vector.cmp_info.hardware_intr_sig );
		if ( retval != PAPI_OK )
			return ( retval );
	}
	else {
		this_state->overflow = 1;
        this_state->overflow_count++;
		this_state->overflow_list[this_state->overflow_count-1].threshold = threshold;
		this_state->overflow_list[this_state->overflow_count-1].EventIndex = evt_idx;
		
#ifdef DEBUG_BGQ
		printf( "IOUNIT_set_overflow: Enable the signal handler\n" );
#endif
		/* Enable the signal handler */
		retval = _papi_hwi_start_signal( _IOunit_vector.cmp_info.hardware_intr_sig, 
										NEED_CONTEXT, 
										_IOunit_vector.cmp_info.CmpIdx );
		if ( retval != PAPI_OK )
			return ( retval );

        retval = _common_set_overflow_BGPM( this_state->EventGroup,
                                  this_state->overflow_list[this_state->overflow_count-1].EventIndex,
                                  this_state->overflow_list[this_state->overflow_count-1].threshold,
                                  user_signal_handler_IOUNIT );
		if ( retval < 0 ) return retval;
	}
	
	return ( PAPI_OK );
}
Beispiel #3
0
int
_papi_hwd_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
{
	hwd_control_state_t *this_state = &ESI->machdep;
	struct hwd_pmc_control *contr = &this_state->control;
	int i, ncntrs, nricntrs = 0, nracntrs = 0, retval = 0;

	OVFDBG( "EventIndex=%d, threshold = %d\n", EventIndex, threshold );

	/* The correct event to overflow is EventIndex */
	ncntrs = _papi_hwi_system_info.sub_info.num_cntrs;
	i = ESI->EventInfoArray[EventIndex].pos[0];
	if ( i >= ncntrs ) {
		OVFDBG( "Selector id (%d) larger than ncntrs (%d)\n", i, ncntrs );
		return PAPI_EINVAL;
	}
	if ( threshold != 0 ) {	 /* Set an overflow threshold */
		if ( ESI->EventInfoArray[EventIndex].derived ) {
			OVFDBG( "Can't overflow on a derived event.\n" );
			return PAPI_EINVAL;
		}

		if ( ( retval =
			   _papi_hwi_start_signal( _papi_hwi_system_info.sub_info.
									   hardware_intr_sig,
									   NEED_CONTEXT ) ) != PAPI_OK )
			return ( retval );

		contr->cpu_control.ireset[i] = PMC_OVFL - threshold;
		nricntrs = ++contr->cpu_control.nrictrs;
		nracntrs = --contr->cpu_control.nractrs;
		contr->si_signo = _papi_hwi_system_info.sub_info.hardware_intr_sig;
		contr->cpu_control.ppc64.mmcr0 |= PERF_INT_ENABLE;

		/* move this event to the bottom part of the list if needed */
		if ( i < nracntrs )
			swap_events( ESI, contr, i, nracntrs );

		OVFDBG( "Modified event set\n" );
	} else {
		if ( contr->cpu_control.ppc64.mmcr0 & PERF_INT_ENABLE ) {
			contr->cpu_control.ireset[i] = 0;
			nricntrs = --contr->cpu_control.nrictrs;
			nracntrs = ++contr->cpu_control.nractrs;
			if ( !nricntrs )
				contr->cpu_control.ppc64.mmcr0 &= ( ~PERF_INT_ENABLE );
		}
		/* move this event to the top part of the list if needed */
		if ( i >= nracntrs )
			swap_events( ESI, contr, i, nracntrs - 1 );
		if ( !nricntrs )
			contr->si_signo = 0;

		OVFDBG( "Modified event set\n" );

		retval =
			_papi_hwi_stop_signal( _papi_hwi_system_info.sub_info.
								   hardware_intr_sig );
	}
#ifdef DEBUG
	print_control( &contr->cpu_control );
#endif
	OVFDBG( "%s:%d: Hardware overflow is still experimental.\n", __FILE__,
			__LINE__ );
	OVFDBG( "End of call. Exit code: %d\n", retval );

	return ( retval );
}
Beispiel #4
0
static int
_x86_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
{
	struct hwd_pmc_control *contr = &ESI->ctl_state->control;
	int i, ncntrs, nricntrs = 0, nracntrs = 0, retval = 0;
	OVFDBG( "EventIndex=%d\n", EventIndex );

#ifdef DEBUG
	if ( is_pentium4() )
		print_control( &ESI->ctl_state->control.cpu_control );
#endif

	/* The correct event to overflow is EventIndex */
	ncntrs = MY_VECTOR.cmp_info.num_cntrs;
	i = ESI->EventInfoArray[EventIndex].pos[0];

	if ( i >= ncntrs ) {
		PAPIERROR( "Selector id %d is larger than ncntrs %d", i, ncntrs );
		return PAPI_EINVAL;
	}

	if ( threshold != 0 ) {	 /* Set an overflow threshold */
		retval = _papi_hwi_start_signal( MY_VECTOR.cmp_info.hardware_intr_sig,
										 NEED_CONTEXT,
										 MY_VECTOR.cmp_info.CmpIdx );
		if ( retval != PAPI_OK )
			return ( retval );

		/* overflow interrupt occurs on the NEXT event after overflow occurs
		   thus we subtract 1 from the threshold. */
		contr->cpu_control.ireset[i] = ( -threshold + 1 );

		if ( is_pentium4() )
			contr->cpu_control.evntsel[i] |= CCCR_OVF_PMI_T0;
		else
			contr->cpu_control.evntsel[i] |= PERF_INT_ENABLE;

		contr->cpu_control.nrictrs++;
		contr->cpu_control.nractrs--;
		nricntrs = ( int ) contr->cpu_control.nrictrs;
		nracntrs = ( int ) contr->cpu_control.nractrs;
		contr->si_signo = MY_VECTOR.cmp_info.hardware_intr_sig;

		/* move this event to the bottom part of the list if needed */
		if ( i < nracntrs )
			swap_events( ESI, contr, i, nracntrs );
		OVFDBG( "Modified event set\n" );
	} else {
	  if ( is_pentium4() && contr->cpu_control.evntsel[i] & CCCR_OVF_PMI_T0 ) {
			contr->cpu_control.ireset[i] = 0;
			contr->cpu_control.evntsel[i] &= ( ~CCCR_OVF_PMI_T0 );
			contr->cpu_control.nrictrs--;
			contr->cpu_control.nractrs++;
	  } else if ( !is_pentium4() &&
					contr->cpu_control.evntsel[i] & PERF_INT_ENABLE ) {
			contr->cpu_control.ireset[i] = 0;
			contr->cpu_control.evntsel[i] &= ( ~PERF_INT_ENABLE );
			contr->cpu_control.nrictrs--;
			contr->cpu_control.nractrs++;
		}

		nricntrs = ( int ) contr->cpu_control.nrictrs;
		nracntrs = ( int ) contr->cpu_control.nractrs;

		/* move this event to the top part of the list if needed */
		if ( i >= nracntrs )
			swap_events( ESI, contr, i, nracntrs - 1 );

		if ( !nricntrs )
			contr->si_signo = 0;

		OVFDBG( "Modified event set\n" );

		retval = _papi_hwi_stop_signal( MY_VECTOR.cmp_info.hardware_intr_sig );
	}

#ifdef DEBUG
	if ( is_pentium4() )
		print_control( &ESI->ctl_state->control.cpu_control );
#endif
	OVFDBG( "End of call. Exit code: %d\n", retval );
	return ( retval );
}
Beispiel #5
0
/*
 * Set Overflow
 *
 * This is commented out in BG/L/P - need to explore and complete...
 * However, with true 64-bit counters in BG/Q and all counters for PAPI
 * always starting from a true zero (we don't allow write...), the possibility
 * for overflow is remote at best...
 */
int
L2UNIT_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
{
#ifdef DEBUG_BGQ
	printf("BEGIN L2UNIT_set_overflow\n");
#endif
	L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ESI->ctl_state;
	int retval;
	int evt_idx;
	
	/*
	 * In case an BGPM eventGroup HAS BEEN applied or attached before
	 * overflow is set, delete the eventGroup and create an new empty one,
	 * and rebuild as it was prior to deletion
	 */
#ifdef DEBUG_BGQ
	printf( "L2UNIT_set_overflow: bgpm_eventset_applied = %d, threshold = %d\n",
		   this_state->bgpm_eventset_applied, threshold );
#endif	
	if ( 1 == this_state->bgpm_eventset_applied && 0 != threshold ) {
		_common_deleteRecreate( &this_state->EventGroup );
		_common_rebuildEventgroup( this_state->count,
								  this_state->EventGroup_local,
								  &this_state->EventGroup );
		
		/* set BGPM eventGroup flag back to NOT applied yet (0) 
		 * because the eventGroup has been recreated from scratch */
		this_state->bgpm_eventset_applied = 0;
	}
		
	evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
	SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#ifdef DEBUG_BGQ
	printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#endif
	/* If this counter isn't set to overflow, it's an error */
	if ( threshold == 0 ) {
		/* Remove the signal handler */
		retval = _papi_hwi_stop_signal( _L2unit_vector.cmp_info.hardware_intr_sig );
		if ( retval != PAPI_OK )
			return ( retval );
	}
	else {
		this_state->overflow = 1;
        this_state->overflow_count++;
		this_state->overflow_list[this_state->overflow_count-1].threshold = threshold;
		this_state->overflow_list[this_state->overflow_count-1].EventIndex = evt_idx;
		
#ifdef DEBUG_BGQ
		printf( "L2UNIT_set_overflow: Enable the signal handler\n" );
#endif
		/* Enable the signal handler */
		retval = _papi_hwi_start_signal( _L2unit_vector.cmp_info.hardware_intr_sig, 
										NEED_CONTEXT, 
										_L2unit_vector.cmp_info.CmpIdx );
		if ( retval != PAPI_OK )
			return ( retval );

        _common_set_overflow_BGPM( this_state->EventGroup,
                                  this_state->overflow_list[this_state->overflow_count-1].EventIndex,
                                  this_state->overflow_list[this_state->overflow_count-1].threshold,
                                  user_signal_handler_L2UNIT );
	}
	
	return ( PAPI_OK );
}