Ejemplo n.º 1
0
/** @class PAPI_stop_counters
 *	@brief Stop counting hardware events and reset values to zero.
 *
 *	@par C Interface:
 *	\#include <papi.h> @n
 *	int PAPI_stop_counters( long long *values, int array_len );
 *
 * @param *values
 *		an array where to put the counter values
 * @param array_len
 *		the number of items in the *values array
 *
 * @post
 *	After this function is called, the values are reset to zero.
 *
 *	@retval PAPI_EINVAL
 *		One or more of the arguments is invalid.
 *	@retval PAPI_ENOTRUN
 *		The EventSet is not started yet.
 *	@retval PAPI_ENOEVST
 *		The EventSet has not been added yet.
 *
 * The PAPI_stop_counters() function stops the counters and copies the counts
 * into the *values array.
 * The counters must have been started by a previous call to PAPI_start_counters().
 *
 *	\code
int Events[2] = { PAPI_TOT_CYC, PAPI_TOT_INS };
long long values[2];
if ( PAPI_start_counters( Events, 2 ) != PAPI_OK )
	handle_error(1);
your_slow_code();
if ( PAPI_stop_counters( values, 2 ) != PAPI_OK )
	handle_error(1);
 *	\endcode
 *
 * @see PAPI_read_counters() PAPI_start_counters() PAPI_set_opt()
 */
int
PAPI_stop_counters( long long *values, int array_len )
{
    int retval;
    HighLevelInfo *state = NULL;

    if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK )
        return ( retval );

    if ( state->running == 0 )
        return ( PAPI_ENOTRUN );

    if ( state->running == HL_START ) {
        if ( array_len < state->num_evts  || values == NULL) {
            return ( PAPI_EINVAL );
        } else {
            retval = PAPI_stop( state->EventSet, values );
        }
    }

    if ( state->running > HL_START ) {
        long long tmp_values[3];
        retval = PAPI_stop( state->EventSet, tmp_values );
    }

    if ( retval == PAPI_OK ) {
        _internal_cleanup_hl_info( state );
        PAPI_cleanup_eventset( state->EventSet );
    }
    APIDBG( "PAPI_stop_counters returns %d\n", retval );
    return retval;
}
Ejemplo n.º 2
0
/* Must be called with CPUS_LOCK held! */
int
_papi_hwi_initialize_cpu( CpuInfo_t **dest, unsigned int cpu_num )
{
   APIDBG("Entry: dest: %p, *dest: %p, cpu_num: %d\n", dest, *dest, cpu_num);

   int retval;
   CpuInfo_t *cpu;
   int i;

   if ( ( cpu = allocate_cpu(cpu_num) ) == NULL ) {
      *dest = NULL;
      return PAPI_ENOMEM;
   }

   /* Call the component to fill in anything special. */
   for ( i = 0; i < papi_num_components; i++ ) {
      if (_papi_hwd[i]->cmp_info.disabled) continue;
      retval = _papi_hwd[i]->init_thread( cpu->context[i] );
      if ( retval ) {
	 free_cpu( &cpu );
	 *dest = NULL;
	 return retval;
      }
   }

   insert_cpu( cpu );

   *dest = cpu;
   return PAPI_OK;
}
Ejemplo n.º 3
0
int PAPI_stop_counters(long long * values, int array_len)
{
   int retval;
   HighLevelInfo *state = NULL;

   if ((retval = _internal_check_state(&state)) != PAPI_OK)
      return (retval);

   if (state->running == 0)
      return (PAPI_ENOTRUN);

   if (state->running == HL_FLOPS || state->running == HL_FLIPS || state->running == HL_IPC) {
      long long tmp_values[2];
      retval = PAPI_stop(state->EventSet, tmp_values);
   } 
   else if(state->running != HL_START_COUNTERS || array_len < state->num_evts)
      return (PAPI_EINVAL);
   else
      retval = PAPI_stop(state->EventSet, values);

   if (retval==PAPI_OK) {
      _internal_cleanup_hl_info(state);
      PAPI_cleanup_eventset(state->EventSet);
   }
   APIDBG("PAPI_stop_counters returns %d\n", retval);
   return retval;
}
Ejemplo n.º 4
0
int
_papi_hwi_lookup_or_create_cpu( CpuInfo_t **here, unsigned int cpu_num )
{
   APIDBG("Entry: here: %p\n", here);
	
   CpuInfo_t *tmp = NULL;
   int retval = PAPI_OK;

   _papi_hwi_lock( CPUS_LOCK );

   tmp = _papi_hwi_lookup_cpu(cpu_num);
   if ( tmp == NULL ) {
      retval = _papi_hwi_initialize_cpu( &tmp, cpu_num );
   }

   /* Increment use count */
   tmp->num_users++;

   if ( retval == PAPI_OK ) {
      *here = tmp;
   }

   _papi_hwi_unlock( CPUS_LOCK );
	
   return retval;
}
Ejemplo n.º 5
0
static CpuInfo_t *
_papi_hwi_lookup_cpu( unsigned int cpu_num )
{
   APIDBG("Entry:\n");

   CpuInfo_t *tmp;

   tmp = ( CpuInfo_t * ) _papi_hwi_cpu_head;
   while ( tmp != NULL ) {
      THRDBG( "Examining cpu %#x at %p\n", tmp->cpu_num, tmp );
      if ( tmp->cpu_num == cpu_num ) {
	 break;
      }
      tmp = tmp->next;
      if ( tmp == _papi_hwi_cpu_head ) {
	 tmp = NULL;
	 break;
      }
   }

   if ( tmp ) {
      _papi_hwi_cpu_head = tmp;
      THRDBG( "Found cpu %#x at %p\n", cpu_num, tmp );
   } else {
      THRDBG( "Did not find cpu %#x\n", cpu_num );
   }

   return tmp;
}
Ejemplo n.º 6
0
/* Must be called with CPUS_LOCK held! */
static void
insert_cpu( CpuInfo_t * entry )
{
   APIDBG("Entry: entry: %p\n", entry);

   if ( _papi_hwi_cpu_head == NULL ) {	
      /* 0 elements */
      THRDBG( "_papi_hwi_cpu_head is NULL\n" );
      entry->next = entry;
   } else if ( _papi_hwi_cpu_head->next == _papi_hwi_cpu_head ) {
      /* 1 element */
      THRDBG( "_papi_hwi_cpu_head was cpu %d at %p\n",
              _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
      _papi_hwi_cpu_head->next = entry;
      entry->next = ( CpuInfo_t * ) _papi_hwi_cpu_head;
   } else {
      /* 2+ elements */
      THRDBG( "_papi_hwi_cpu_head was cpu %d at %p\n",
	      _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
      entry->next = _papi_hwi_cpu_head->next;
      _papi_hwi_cpu_head->next = entry;
   }

   _papi_hwi_cpu_head = entry;

   THRDBG( "_papi_hwi_cpu_head now cpu %d at %p\n",
	   _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
}
Ejemplo n.º 7
0
int
_papi_hwi_shutdown_cpu( CpuInfo_t *cpu )
{
   APIDBG("Entry: cpu: %p, cpu_num: %d\n", cpu, cpu->cpu_num);

   free_cpu( &cpu );

   return PAPI_OK;
}
Ejemplo n.º 8
0
static CpuInfo_t *
allocate_cpu( unsigned int cpu_num )
{
   APIDBG("Entry: cpu_num: %d\n", cpu_num);

   CpuInfo_t *cpu;
   int i;

   /* Allocate new CpuInfo structure */
   cpu = ( CpuInfo_t * ) papi_calloc( 1, sizeof ( CpuInfo_t ) );
   if ( cpu == NULL ) {
      goto allocate_error;
   }
	
   /* identify the cpu this info structure represents */
   cpu->cpu_num = cpu_num;
   cpu->context = ( hwd_context_t ** ) 
                  papi_calloc( ( size_t ) papi_num_components ,
			       sizeof ( hwd_context_t * ) );
   if ( !cpu->context ) {
      goto error_free_cpu;
   }
 
   /* Allocate an eventset per component per cpu?  Why? */
	
   cpu->running_eventset = ( EventSetInfo_t ** ) 
                           papi_calloc(( size_t ) papi_num_components, 
                                       sizeof ( EventSetInfo_t * ) );
   if ( !cpu->running_eventset ) {
      goto error_free_context;
   }

   for ( i = 0; i < papi_num_components; i++ ) {
       cpu->context[i] =
	 ( void * ) papi_calloc( 1, ( size_t ) _papi_hwd[i]->size.context );
       cpu->running_eventset[i] = NULL;
       if ( cpu->context[i] == NULL ) {
	  goto error_free_contexts;
       }
   }

   cpu->num_users=0;

   THRDBG( "Allocated CpuInfo: %p\n", cpu );

   return cpu;

error_free_contexts:
   for ( i--; i >= 0; i-- ) papi_free( cpu->context[i] );
error_free_context:
   papi_free( cpu->context );
error_free_cpu:
   papi_free( cpu );
allocate_error:
   return NULL;
}
Ejemplo n.º 9
0
static void
free_cpu( CpuInfo_t **cpu )
{
   APIDBG( "Entry: *cpu: %p, cpu_num: %d, cpu_users: %d\n", 
	   *cpu, ( *cpu )->cpu_num, (*cpu)->num_users);
	
   int i,users,retval;

   _papi_hwi_lock( CPUS_LOCK );

   (*cpu)->num_users--;

   users=(*cpu)->num_users;

   /* Remove from linked list if no users */
   if (!users) remove_cpu( *cpu );

   _papi_hwi_unlock( CPUS_LOCK );

   /* Exit early if still users of this CPU */
   if (users!=0) return;

   THRDBG( "Shutting down cpu %d at %p\n", (*cpu)->cpu_num, cpu );

   for ( i = 0; i < papi_num_components; i++ ) {
     if (_papi_hwd[i]->cmp_info.disabled) continue;
     retval = _papi_hwd[i]->shutdown_thread( (*cpu)->context[i] );
      if ( retval != PAPI_OK ) {
	//	 failure = retval;
      }
   }

   for ( i = 0; i < papi_num_components; i++ ) {
      if ( ( *cpu )->context[i] ) {
	 papi_free( ( *cpu )->context[i] );
      }
   }

   if ( ( *cpu )->context ) {
      papi_free( ( *cpu )->context );
   }

   if ( ( *cpu )->running_eventset ) {
      papi_free( ( *cpu )->running_eventset );
   }

   /* why do we clear this? */
   memset( *cpu, 0x00, sizeof ( CpuInfo_t ) );
   papi_free( *cpu );
   *cpu = NULL;
}
Ejemplo n.º 10
0
/* Must be called with CPUS_LOCK held! */
static int
remove_cpu( CpuInfo_t * entry )
{
   APIDBG("Entry: entry: %p\n", entry);
	
   CpuInfo_t *tmp = NULL, *prev = NULL;

   THRDBG( "_papi_hwi_cpu_head was cpu %d at %p\n",
			_papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );

	/* Find the preceding element and the matched element,
	   short circuit if we've seen the head twice */

   for ( tmp = ( CpuInfo_t * ) _papi_hwi_cpu_head;
       ( entry != tmp ) || ( prev == NULL ); tmp = tmp->next ) {
       prev = tmp;
   }

   if ( tmp != entry ) {
      THRDBG( "Cpu %d at %p was not found in the cpu list!\n",
				entry->cpu_num, entry );
      return PAPI_EBUG;
   }

   /* Only 1 element in list */

   if ( prev == tmp ) {
      _papi_hwi_cpu_head = NULL;
      tmp->next = NULL;
      THRDBG( "_papi_hwi_cpu_head now NULL\n" );
   } else {
      prev->next = tmp->next;
      /* If we're removing the head, better advance it! */
      if ( _papi_hwi_cpu_head == tmp ) {
	 _papi_hwi_cpu_head = tmp->next;
	 THRDBG( "_papi_hwi_cpu_head now cpu %d at %p\n",
		 _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
      }
      THRDBG( "Removed cpu %p from list\n", tmp );
   }

   return PAPI_OK;
}