cpus.c File Reference

Include dependency graph for cpus.c:

Go to the source code of this file.

Functions

static CpuInfo_t_papi_hwi_lookup_cpu (unsigned int cpu_num)
int _papi_hwi_lookup_or_create_cpu (CpuInfo_t **here, unsigned int cpu_num)
static CpuInfo_tallocate_cpu (unsigned int cpu_num)
static int remove_cpu (CpuInfo_t *entry)
static void free_cpu (CpuInfo_t **cpu)
static void insert_cpu (CpuInfo_t *entry)
int _papi_hwi_initialize_cpu (CpuInfo_t **dest, unsigned int cpu_num)
int _papi_hwi_shutdown_cpu (CpuInfo_t *cpu)

Variables

static CpuInfo_t_papi_hwi_cpu_head

Function Documentation

int _papi_hwi_initialize_cpu ( CpuInfo_t **  dest,
unsigned int  cpu_num 
)

Definition at line 275 of file cpus.c.

00276 {
00277    APIDBG("Entry: dest: %p, *dest: %p, cpu_num: %d\n", dest, *dest, cpu_num);
00278 
00279    int retval;
00280    CpuInfo_t *cpu;
00281    int i;
00282 
00283    if ( ( cpu = allocate_cpu(cpu_num) ) == NULL ) {
00284       *dest = NULL;
00285       return PAPI_ENOMEM;
00286    }
00287 
00288    /* Call the component to fill in anything special. */
00289    for ( i = 0; i < papi_num_components; i++ ) {
00290       if (_papi_hwd[i]->cmp_info.disabled) continue;
00291       retval = _papi_hwd[i]->init_thread( cpu->context[i] );
00292       if ( retval ) {
00293      free_cpu( &cpu );
00294      *dest = NULL;
00295      return retval;
00296       }
00297    }
00298 
00299    insert_cpu( cpu );
00300 
00301    *dest = cpu;
00302    return PAPI_OK;
00303 }

Here is the call graph for this function:

Here is the caller graph for this function:

static CpuInfo_t* _papi_hwi_lookup_cpu ( unsigned int  cpu_num  )  [static]

Definition at line 29 of file cpus.c.

00030 {
00031    APIDBG("Entry:\n");
00032 
00033    CpuInfo_t *tmp;
00034 
00035    tmp = ( CpuInfo_t * ) _papi_hwi_cpu_head;
00036    while ( tmp != NULL ) {
00037       THRDBG( "Examining cpu %#x at %p\n", tmp->cpu_num, tmp );
00038       if ( tmp->cpu_num == cpu_num ) {
00039      break;
00040       }
00041       tmp = tmp->next;
00042       if ( tmp == _papi_hwi_cpu_head ) {
00043      tmp = NULL;
00044      break;
00045       }
00046    }
00047 
00048    if ( tmp ) {
00049       _papi_hwi_cpu_head = tmp;
00050       THRDBG( "Found cpu %#x at %p\n", cpu_num, tmp );
00051    } else {
00052       THRDBG( "Did not find cpu %#x\n", cpu_num );
00053    }
00054 
00055    return tmp;
00056 }

Here is the caller graph for this function:

int _papi_hwi_lookup_or_create_cpu ( CpuInfo_t **  here,
unsigned int  cpu_num 
)

Definition at line 59 of file cpus.c.

00060 {
00061    APIDBG("Entry: here: %p\n", here);
00062     
00063    CpuInfo_t *tmp = NULL;
00064    int retval = PAPI_OK;
00065 
00066    _papi_hwi_lock( CPUS_LOCK );
00067 
00068    tmp = _papi_hwi_lookup_cpu(cpu_num);
00069    if ( tmp == NULL ) {
00070       retval = _papi_hwi_initialize_cpu( &tmp, cpu_num );
00071    }
00072 
00073    /* Increment use count */
00074    tmp->num_users++;
00075 
00076    if ( retval == PAPI_OK ) {
00077       *here = tmp;
00078    }
00079 
00080    _papi_hwi_unlock( CPUS_LOCK );
00081     
00082    return retval;
00083 }

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_shutdown_cpu ( CpuInfo_t cpu  ) 

Definition at line 306 of file cpus.c.

00307 {
00308    APIDBG("Entry: cpu: %p, cpu_num: %d\n", cpu, cpu->cpu_num);
00309 
00310    free_cpu( &cpu );
00311 
00312    return PAPI_OK;
00313 }

Here is the call graph for this function:

Here is the caller graph for this function:

static CpuInfo_t* allocate_cpu ( unsigned int  cpu_num  )  [static]

Definition at line 87 of file cpus.c.

00088 {
00089    APIDBG("Entry: cpu_num: %d\n", cpu_num);
00090 
00091    CpuInfo_t *cpu;
00092    int i;
00093 
00094    /* Allocate new CpuInfo structure */
00095    cpu = ( CpuInfo_t * ) papi_calloc( 1, sizeof ( CpuInfo_t ) );
00096    if ( cpu == NULL ) {
00097       goto allocate_error;
00098    }
00099     
00100    /* identify the cpu this info structure represents */
00101    cpu->cpu_num = cpu_num;
00102    cpu->context = ( hwd_context_t ** ) 
00103                   papi_calloc( ( size_t ) papi_num_components ,
00104                    sizeof ( hwd_context_t * ) );
00105    if ( !cpu->context ) {
00106       goto error_free_cpu;
00107    }
00108  
00109    /* Allocate an eventset per component per cpu?  Why? */
00110     
00111    cpu->running_eventset = ( EventSetInfo_t ** ) 
00112                            papi_calloc(( size_t ) papi_num_components, 
00113                                        sizeof ( EventSetInfo_t * ) );
00114    if ( !cpu->running_eventset ) {
00115       goto error_free_context;
00116    }
00117 
00118    for ( i = 0; i < papi_num_components; i++ ) {
00119        cpu->context[i] =
00120      ( void * ) papi_calloc( 1, ( size_t ) _papi_hwd[i]->size.context );
00121        cpu->running_eventset[i] = NULL;
00122        if ( cpu->context[i] == NULL ) {
00123       goto error_free_contexts;
00124        }
00125    }
00126 
00127    cpu->num_users=0;
00128 
00129    THRDBG( "Allocated CpuInfo: %p\n", cpu );
00130 
00131    return cpu;
00132 
00133 error_free_contexts:
00134    for ( i--; i >= 0; i-- ) papi_free( cpu->context[i] );
00135 error_free_context:
00136    papi_free( cpu->context );
00137 error_free_cpu:
00138    papi_free( cpu );
00139 allocate_error:
00140    return NULL;
00141 }

Here is the caller graph for this function:

static void free_cpu ( CpuInfo_t **  cpu  )  [static]

Definition at line 190 of file cpus.c.

00191 {
00192    APIDBG( "Entry: *cpu: %p, cpu_num: %d, cpu_users: %d\n", 
00193        *cpu, ( *cpu )->cpu_num, (*cpu)->num_users);
00194     
00195    int i,users,retval;
00196 
00197    _papi_hwi_lock( CPUS_LOCK );
00198 
00199    (*cpu)->num_users--;
00200 
00201    users=(*cpu)->num_users;
00202 
00203    /* Remove from linked list if no users */
00204    if (!users) remove_cpu( *cpu );
00205 
00206    _papi_hwi_unlock( CPUS_LOCK );
00207 
00208    /* Exit early if still users of this CPU */
00209    if (users!=0) return;
00210 
00211    THRDBG( "Shutting down cpu %d at %p\n", (*cpu)->cpu_num, cpu );
00212 
00213    for ( i = 0; i < papi_num_components; i++ ) {
00214      if (_papi_hwd[i]->cmp_info.disabled) continue;
00215      retval = _papi_hwd[i]->shutdown_thread( (*cpu)->context[i] );
00216       if ( retval != PAPI_OK ) {
00217     //   failure = retval;
00218       }
00219    }
00220 
00221    for ( i = 0; i < papi_num_components; i++ ) {
00222       if ( ( *cpu )->context[i] ) {
00223      papi_free( ( *cpu )->context[i] );
00224       }
00225    }
00226 
00227    if ( ( *cpu )->context ) {
00228       papi_free( ( *cpu )->context );
00229    }
00230 
00231    if ( ( *cpu )->running_eventset ) {
00232       papi_free( ( *cpu )->running_eventset );
00233    }
00234 
00235    /* why do we clear this? */
00236    memset( *cpu, 0x00, sizeof ( CpuInfo_t ) );
00237    papi_free( *cpu );
00238    *cpu = NULL;
00239 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void insert_cpu ( CpuInfo_t entry  )  [static]

Definition at line 243 of file cpus.c.

00244 {
00245    APIDBG("Entry: entry: %p\n", entry);
00246 
00247    if ( _papi_hwi_cpu_head == NULL ) {  
00248       /* 0 elements */
00249       THRDBG( "_papi_hwi_cpu_head is NULL\n" );
00250       entry->next = entry;
00251    } else if ( _papi_hwi_cpu_head->next == _papi_hwi_cpu_head ) {
00252       /* 1 element */
00253       THRDBG( "_papi_hwi_cpu_head was cpu %d at %p\n",
00254               _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
00255       _papi_hwi_cpu_head->next = entry;
00256       entry->next = ( CpuInfo_t * ) _papi_hwi_cpu_head;
00257    } else {
00258       /* 2+ elements */
00259       THRDBG( "_papi_hwi_cpu_head was cpu %d at %p\n",
00260           _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
00261       entry->next = _papi_hwi_cpu_head->next;
00262       _papi_hwi_cpu_head->next = entry;
00263    }
00264 
00265    _papi_hwi_cpu_head = entry;
00266 
00267    THRDBG( "_papi_hwi_cpu_head now cpu %d at %p\n",
00268        _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
00269 }

Here is the caller graph for this function:

static int remove_cpu ( CpuInfo_t entry  )  [static]

Definition at line 145 of file cpus.c.

00146 {
00147    APIDBG("Entry: entry: %p\n", entry);
00148     
00149    CpuInfo_t *tmp = NULL, *prev = NULL;
00150 
00151    THRDBG( "_papi_hwi_cpu_head was cpu %d at %p\n",
00152             _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
00153 
00154     /* Find the preceding element and the matched element,
00155        short circuit if we've seen the head twice */
00156 
00157    for ( tmp = ( CpuInfo_t * ) _papi_hwi_cpu_head;
00158        ( entry != tmp ) || ( prev == NULL ); tmp = tmp->next ) {
00159        prev = tmp;
00160    }
00161 
00162    if ( tmp != entry ) {
00163       THRDBG( "Cpu %d at %p was not found in the cpu list!\n",
00164                 entry->cpu_num, entry );
00165       return PAPI_EBUG;
00166    }
00167 
00168    /* Only 1 element in list */
00169 
00170    if ( prev == tmp ) {
00171       _papi_hwi_cpu_head = NULL;
00172       tmp->next = NULL;
00173       THRDBG( "_papi_hwi_cpu_head now NULL\n" );
00174    } else {
00175       prev->next = tmp->next;
00176       /* If we're removing the head, better advance it! */
00177       if ( _papi_hwi_cpu_head == tmp ) {
00178      _papi_hwi_cpu_head = tmp->next;
00179      THRDBG( "_papi_hwi_cpu_head now cpu %d at %p\n",
00180          _papi_hwi_cpu_head->cpu_num, _papi_hwi_cpu_head );
00181       }
00182       THRDBG( "Removed cpu %p from list\n", tmp );
00183    }
00184 
00185    return PAPI_OK;
00186 }

Here is the caller graph for this function:


Variable Documentation

Definition at line 25 of file cpus.c.


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1