Example #1
0
static void reorder_elem_down(unsigned int index)
{
    /* If the size of the heap is even, there is a node with only one leaf, so
       we should stop reordering the heap before encountering such a node, and
       treat it specificaly if necessary. This trick does not behave correctly
       if the heap size is 0, but then we do not need to reorder anything. */
    unsigned int half_size = (heap_size - 1) / 2;

    while (index < half_size)
    {
        unsigned int childs = index * 2 + 1;
        unsigned int lower_child = childs +
            (events_heap[childs].trigger >= events_heap[childs + 1].trigger);

        if (events_heap[index].trigger <= events_heap[lower_child].trigger)
            return;
        swap_events(index, lower_child);
        index = lower_child;
    }

    // Special case for a possible mono-leaf node.
    if (index == half_size && !(heap_size % 2))
    {
        unsigned int child = index * 2 + 1;

        if (events_heap[index].trigger > events_heap[child].trigger)
            swap_events(index, child);
    }
}
Example #2
0
File: event.c Project: surki/hipl
// remove the event at the top of the heap
void removeNextEvent(EventHeap *h)
{
    unsigned int idx, idx1, idx_left, idx_right;

    free(h->heap[0]);
    if (h->size > 1)
        h->heap[0] = h->heap[h->size - 1];
    if (h->size)
        h->size--;

    // rebuild heap
    idx = 0;
    while (1) {
        idx_left = 2*idx + 1;
        idx_right = idx_left + 1;
        if (idx_left >= h->size) {
            return;
        }
        if (idx_left == h->size - 1)
            // only left child
            idx1 = idx_left;
        else {
            if (h->heap[idx_left]->time < h->heap[idx_right]->time)
                idx1 = idx_left;
            else
                idx1 = idx_right;
        }
        if (h->heap[idx]->time > h->heap[idx1]->time) {
            swap_events(h, idx, idx1);
            idx = idx1;
        } else {
            return;
        }
    }
}
Example #3
0
static void reorder_elem_up(unsigned int index)
{
    while (index)
    {
        unsigned int parent = (index - 1) / 2;
        if (events_heap[index].trigger >= events_heap[parent].trigger)
            return;
        swap_events(index, parent);
        index = parent;
    }
}
Example #4
0
File: event.c Project: surki/hipl
// insert new event in the heap
void insertEvent(EventHeap *h, Event *ev)
{
    int idx, idx1;

    if (h->size > h->max_size - 1) {
        printf("Event not inserted; too many events.\n");
        return;
    }

    h->heap[h->size] = ev;
    (h->size)++;

    // rebuild heap
    idx = h->size - 1;
    idx1 = (idx-1)/2;
    while ((idx >= 1) && (h->heap[idx]->time < h->heap[idx1]->time)) {
        swap_events(h, idx, idx1);
        idx = idx1;
        idx1 = (idx-1)/2;
    }
}
Example #5
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 );
}
Example #6
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 );
}