PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
threads.c File Reference
Include dependency graph for threads.c:

Go to the source code of this file.

Functions

static int lookup_and_set_thread_symbols (void)
 
static ThreadInfo_tallocate_thread (int tid)
 
static void free_thread (ThreadInfo_t **thread)
 
static void insert_thread (ThreadInfo_t *entry, int tid)
 
static int remove_thread (ThreadInfo_t *entry)
 
int _papi_hwi_initialize_thread (ThreadInfo_t **dest, int tid)
 
int _papi_hwi_set_thread_id_fn (unsigned long(*id_fn)(void))
 
static int _papi_hwi_thread_free_eventsets (long tid)
 
int _papi_hwi_shutdown_thread (ThreadInfo_t *thread, int force_shutdown)
 
int _papi_hwi_shutdown_global_threads (void)
 
int _papi_hwi_init_global_threads (void)
 
int _papi_hwi_gather_all_thrspec_data (int tag, PAPI_all_thr_spec_t *where)
 

Variables

volatile ThreadInfo_t_papi_hwi_thread_head
 
unsigned long(* _papi_hwi_thread_id_fn )(void)
 

Function Documentation

int _papi_hwi_gather_all_thrspec_data ( int  tag,
PAPI_all_thr_spec_t where 
)

Definition at line 554 of file threads.c.

555 {
556  int didsomething = 0;
557  ThreadInfo_t *foo = NULL;
558 
560 
561  for ( foo = ( ThreadInfo_t * ) _papi_hwi_thread_head; foo != NULL;
562  foo = foo->next ) {
563  /* If we want thread ID's */
564  if ( where->id )
565  memcpy( &where->id[didsomething], &foo->tid,
566  sizeof ( where->id[didsomething] ) );
567 
568  /* If we want data pointers */
569  if ( where->data )
570  where->data[didsomething] = foo->thread_storage[tag];
571 
572  didsomething++;
573 
574  if ( ( where->id ) || ( where->data ) ) {
575  if ( didsomething >= where->num )
576  break;
577  }
578 
579  if ( foo->next == _papi_hwi_thread_head )
580  break;
581  }
582 
583  where->num = didsomething;
585 
586  return ( PAPI_OK );
587 
588 }
void ** data
Definition: papi.h:561
struct _ThreadInfo * next
Definition: threads.h:27
return PAPI_OK
Definition: linux-nvml.c:458
volatile ThreadInfo_t * _papi_hwi_thread_head
Definition: threads.c:32
void * thread_storage[PAPI_MAX_TLS]
Definition: threads.h:29
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
unsigned long int tid
Definition: threads.h:25
pthread_attr_t foo
Definition: iozone.c:18592
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
#define THREADS_LOCK
Definition: papi_internal.h:87
PAPI_thread_id_t * id
Definition: papi.h:560
again struct sockaddr sizeof(struct sockaddr_in))

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_init_global_threads ( void  )

Definition at line 527 of file threads.c.

528 {
529  int retval;
530  ThreadInfo_t *tmp;
531 
533 
534 #if defined(HAVE_THREAD_LOCAL_STORAGE)
535  _papi_hwi_my_thread = NULL;
536 #endif
537  _papi_hwi_thread_head = NULL;
538  _papi_hwi_thread_id_fn = NULL;
539 #if defined(ANY_THREAD_GETS_SIGNAL)
541 #endif
542 
543  retval = _papi_hwi_initialize_thread( &tmp , 0);
544  if ( retval == PAPI_OK ) {
545  retval = lookup_and_set_thread_symbols( );
546  }
547 
549 
550  return ( retval );
551 }
static int lookup_and_set_thread_symbols(void)
Definition: threads.c:55
return PAPI_OK
Definition: linux-nvml.c:458
volatile ThreadInfo_t * _papi_hwi_thread_head
Definition: threads.c:32
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
int(* _papi_hwi_thread_kill_fn)(int, int)
#define GLOBAL_LOCK
Definition: papi_internal.h:91
ssize_t retval
Definition: libasync.c:338
long long tmp
Definition: iozone.c:12031
int _papi_hwi_initialize_thread(ThreadInfo_t **dest, int tid)
Definition: threads.c:278

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_initialize_thread ( ThreadInfo_t **  dest,
int  tid 
)

Definition at line 278 of file threads.c.

279 {
280  int retval;
282  int i;
283 
284  if ( ( thread = allocate_thread( tid ) ) == NULL ) {
285  *dest = NULL;
286  return PAPI_ENOMEM;
287  }
288 
289  /* Call the component to fill in anything special. */
290 
291  for ( i = 0; i < papi_num_components; i++ ) {
292  if (_papi_hwd[i]->cmp_info.disabled) continue;
293  retval = _papi_hwd[i]->init_thread( thread->context[i] );
294  if ( retval ) {
295  free_thread( &thread );
296  *dest = NULL;
297  return retval;
298  }
299  }
300 
301  insert_thread( thread, tid );
302 
303  *dest = thread;
304  return PAPI_OK;
305 }
static void free_thread(ThreadInfo_t **thread)
Definition: threads.c:164
return PAPI_OK
Definition: linux-nvml.c:458
papi_vector_t * _papi_hwd[]
static ThreadInfo_t * allocate_thread(int tid)
Definition: threads.c:96
int i
Definition: fileop.c:140
hwd_context_t ** context
Definition: threads.h:28
void * thread(void *arg)
Definition: kufrin.c:31
void *long long tid
Definition: iozone.c:18586
static void insert_thread(ThreadInfo_t *entry, int tid)
Definition: threads.c:186
#define PAPI_ENOMEM
Definition: papi.h:252
int papi_num_components
int(* init_thread)(hwd_context_t *)
Definition: papi_vector.h:36
ssize_t retval
Definition: libasync.c:338

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_set_thread_id_fn ( unsigned long(*)(void id_fn)

Definition at line 352 of file threads.c.

353 {
354 #if !defined(ANY_THREAD_GETS_SIGNAL)
355  /* Check for multiple threads still in the list, if so, we can't change it */
356 
358  return ( PAPI_EINVAL );
359 
360  /* We can't change the thread id function from one to another,
361  only NULL to non-NULL and vice versa. */
362 
363  if ( ( id_fn != NULL ) && ( _papi_hwi_thread_id_fn != NULL ) )
364  return ( PAPI_EINVAL );
365 
366  _papi_hwi_thread_id_fn = id_fn;
367 
368  THRDBG( "Set new thread id function to %p\n", id_fn );
369 
370  if ( id_fn )
371  _papi_hwi_thread_head->tid = ( *_papi_hwi_thread_id_fn ) ( );
372  else
373  _papi_hwi_thread_head->tid = ( unsigned long ) getpid( );
374 
375  THRDBG( "New master tid is %ld\n", _papi_hwi_thread_head->tid );
376 #else
377  THRDBG( "Skipping set of thread id function\n" );
378 #endif
379 
380  return PAPI_OK;
381 }
struct _ThreadInfo * next
Definition: threads.h:27
return PAPI_OK
Definition: linux-nvml.c:458
#define THRDBG(format, args...)
Definition: papi_debug.h:66
return PAPI_EINVAL
Definition: linux-nvml.c:408
volatile ThreadInfo_t * _papi_hwi_thread_head
Definition: threads.c:32
unsigned long int tid
Definition: threads.h:25
long long
Definition: iozone.c:19827
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42

Here is the caller graph for this function:

int _papi_hwi_shutdown_global_threads ( void  )

Definition at line 457 of file threads.c.

458 {
459  int err,num_threads,i;
461  unsigned long our_tid;
462 
463  tmp = _papi_hwi_lookup_thread( 0 );
464 
465  if ( tmp == NULL ) {
466  THRDBG( "Did not find my thread for shutdown!\n" );
467  err = PAPI_EBUG;
468  }
469  else {
470  our_tid=tmp->tid;
471 
472  THRDBG("Shutting down %ld\n",our_tid);
473 
474  err = _papi_hwi_shutdown_thread( tmp, 1 );
475 
476  /* count threads */
478  num_threads=0;
479  while(tmp!=NULL) {
480  num_threads++;
481  if (tmp->next==_papi_hwi_thread_head) break;
482  tmp=tmp->next;
483  }
484 
485  /* Shut down all threads allocated by this thread */
486  /* Urgh it's a circular list where we removed in the loop */
487  /* so the only sane way to do it is get a count in advance */
489 
490  for(i=0;i<num_threads;i++) {
491 
492  next=tmp->next;
493 
494  THRDBG("looking at #%d %ld our_tid: %ld alloc_tid: %ld\n",
495  i,tmp->tid,our_tid,tmp->allocator_tid);
496 
497  THRDBG("Also removing thread %ld\n",tmp->tid);
498  err = _papi_hwi_shutdown_thread( tmp, 1 );
499 
500  tmp=next;
501 
502  }
503  }
504 
505 
506 #ifdef DEBUG
507  if ( ISLEVEL( DEBUG_THREADS ) ) {
508  if ( _papi_hwi_thread_head ) {
509  THRDBG( "Thread head %p still exists!\n", _papi_hwi_thread_head );
510  }
511  }
512 #endif
513 
514 #if defined(HAVE_THREAD_LOCAL_STORAGE)
515  _papi_hwi_my_thread = NULL;
516 #endif
517  _papi_hwi_thread_head = NULL;
518  _papi_hwi_thread_id_fn = NULL;
519 #if defined(ANY_THREAD_GETS_SIGNAL)
521 #endif
522 
523  return err;
524 }
struct _ThreadInfo * next
Definition: threads.h:27
#define PAPI_EBUG
Definition: papi.h:257
#define THRDBG(format, args...)
Definition: papi_debug.h:66
volatile ThreadInfo_t * _papi_hwi_thread_head
Definition: threads.c:32
err
Definition: linux-cuda.c:323
int i
Definition: fileop.c:140
unsigned long int tid
Definition: threads.h:25
int num_threads
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
nsize_list next
Definition: iozone.c:20053
unsigned long int allocator_tid
Definition: threads.h:26
int(* _papi_hwi_thread_kill_fn)(int, int)
#define ISLEVEL(a)
Definition: papi_debug.h:54
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:92
#define DEBUG_THREADS
Definition: papi_debug.h:30
int _papi_hwi_shutdown_thread(ThreadInfo_t *thread, int force_shutdown)
Definition: threads.c:418
long long tmp
Definition: iozone.c:12031

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_shutdown_thread ( ThreadInfo_t thread,
int  force_shutdown 
)

Definition at line 418 of file threads.c.

419 {
420  int retval = PAPI_OK;
421  unsigned long tid;
422  int i, failure = 0;
423 
425  tid = ( *_papi_hwi_thread_id_fn ) ( );
426  else
427  tid = ( unsigned long ) getpid( );
428 
429  THRDBG("Want to shutdown thread %ld, alloc %ld, our_tid: %ld\n",
430  thread->tid,
431  thread->allocator_tid,
432  tid);
433 
434  if ((thread->tid==tid) || ( thread->allocator_tid == tid ) || force_shutdown) {
435 
437 
438  remove_thread( thread );
439  THRDBG( "Shutting down thread %ld at %p\n", thread->tid, thread );
440  for( i = 0; i < papi_num_components; i++ ) {
441  if (_papi_hwd[i]->cmp_info.disabled) continue;
442  retval = _papi_hwd[i]->shutdown_thread( thread->context[i]);
443  if ( retval != PAPI_OK ) failure = retval;
444  }
445  free_thread( &thread );
446  return ( failure );
447  }
448 
449  THRDBG( "Skipping shutdown thread %ld at %p, thread %ld not allocator!\n",
450  thread->tid, thread, tid );
451  return PAPI_EBUG;
452 }
static void free_thread(ThreadInfo_t **thread)
Definition: threads.c:164
#define PAPI_EBUG
Definition: papi.h:257
return PAPI_OK
Definition: linux-nvml.c:458
#define THRDBG(format, args...)
Definition: papi_debug.h:66
papi_vector_t * _papi_hwd[]
int(* shutdown_thread)(hwd_context_t *)
Definition: papi_vector.h:53
int i
Definition: fileop.c:140
unsigned long int tid
Definition: threads.h:25
hwd_context_t ** context
Definition: threads.h:28
void *long long tid
Definition: iozone.c:18586
long long
Definition: iozone.c:19827
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
unsigned long int allocator_tid
Definition: threads.h:26
static int _papi_hwi_thread_free_eventsets(long tid)
Definition: threads.c:384
int papi_num_components
ssize_t retval
Definition: libasync.c:338
static int remove_thread(ThreadInfo_t *entry)
Definition: threads.c:226

Here is the call graph for this function:

Here is the caller graph for this function:

static int _papi_hwi_thread_free_eventsets ( long  tid)
static

Definition at line 384 of file threads.c.

384  {
385 
386  EventSetInfo_t *ESI;
387  ThreadInfo_t *master;
389  int i;
390 
391  master = _papi_hwi_lookup_thread( tid );
392 
394 
395  for( i = 0; i < map->totalSlots; i++ ) {
396  ESI = map->dataSlotArray[i];
397  if ( ( ESI ) && (ESI->master!=NULL) ) {
398 
399  if ( ESI->master == master ) {
400  THRDBG("Attempting to remove %d from tid %ld\n",ESI->EventSetIndex,tid);
401 
402  /* Code copied from _papi_hwi_remove_EventSet(ESI); */
404  map->dataSlotArray[i] = NULL;
405  map->availSlots++;
406  map->fullSlots--;
407  }
408  }
409  }
410 
412 
413  return PAPI_OK;
414 }
return PAPI_OK
Definition: linux-nvml.c:458
#define THRDBG(format, args...)
Definition: papi_debug.h:66
int i
Definition: fileop.c:140
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
DynamicArray_t global_eventset_map
struct _ThreadInfo * master
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
void *long long tid
Definition: iozone.c:18586
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:57
EventSetInfo_t ** dataSlotArray
#define INTERNAL_LOCK
Definition: papi_internal.h:85
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:92
void _papi_hwi_free_EventSet(EventSetInfo_t *ESI)

Here is the call graph for this function:

Here is the caller graph for this function:

static ThreadInfo_t* allocate_thread ( int  tid)
static

Definition at line 96 of file threads.c.

97 {
99  int i;
100 
101  /* The Thread EventSet is special. It is not in the EventSet list, but is pointed
102  to by each EventSet of that particular thread. */
103 
104  thread = ( ThreadInfo_t * ) papi_malloc( sizeof ( ThreadInfo_t ) );
105  if ( thread == NULL )
106  return ( NULL );
107  memset( thread, 0x00, sizeof ( ThreadInfo_t ) );
108 
109  thread->context =
110  ( hwd_context_t ** ) papi_malloc( sizeof ( hwd_context_t * ) *
111  ( size_t ) papi_num_components );
112  if ( !thread->context ) {
113  papi_free( thread );
114  return ( NULL );
115  }
116 
117  thread->running_eventset =
118  ( EventSetInfo_t ** ) papi_malloc( sizeof ( EventSetInfo_t * ) *
119  ( size_t ) papi_num_components );
120  if ( !thread->running_eventset ) {
121  papi_free( thread->context );
122  papi_free( thread );
123  return ( NULL );
124  }
125 
126  for ( i = 0; i < papi_num_components; i++ ) {
127  thread->context[i] =
128  ( void * ) papi_malloc( ( size_t ) _papi_hwd[i]->size.context );
129  thread->running_eventset[i] = NULL;
130  if ( thread->context[i] == NULL ) {
131  for ( i--; i >= 0; i-- )
132  papi_free( thread->context[i] );
133  papi_free( thread->context );
134  papi_free( thread );
135  return ( NULL );
136  }
137  memset( thread->context[i], 0x00,
138  ( size_t ) _papi_hwd[i]->size.context );
139  }
140 
141  if ( _papi_hwi_thread_id_fn ) {
142  thread->tid = ( *_papi_hwi_thread_id_fn ) ( );
143  }
144  else {
145  thread->tid = ( unsigned long ) getpid( );
146  }
147 
148  thread->allocator_tid=thread->tid;
149 
150  if (tid == 0 ) {
151  }
152  else {
153  thread->tid=tid;
154  }
155 
156  THRDBG( "Allocated thread %ld at %p, allocator: %ld\n", thread->tid,
157  thread,
158  thread->allocator_tid );
159 
160  return thread;
161 }
memset(eventId, 0, size)
#define papi_free(a)
Definition: papi_memory.h:35
#define papi_malloc(a)
Definition: papi_memory.h:34
#define THRDBG(format, args...)
Definition: papi_debug.h:66
papi_vector_t * _papi_hwd[]
int i
Definition: fileop.c:140
unsigned long int tid
Definition: threads.h:25
hwd_context_t ** context
Definition: threads.h:28
void * thread(void *arg)
Definition: kufrin.c:31
void *long long tid
Definition: iozone.c:18586
long long
Definition: iozone.c:19827
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
cmp_struct_sizes_t size
Definition: papi_vector.h:23
unsigned long int allocator_tid
Definition: threads.h:26
int papi_num_components
EventSetInfo_t ** running_eventset
Definition: threads.h:30

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_thread ( ThreadInfo_t **  thread)
static

Definition at line 164 of file threads.c.

165 {
166  int i;
167  THRDBG( "Freeing thread %ld at %p\n", ( *thread )->tid, *thread );
168 
169  for ( i = 0; i < papi_num_components; i++ ) {
170  if ( ( *thread )->context[i] )
171  papi_free( ( *thread )->context[i] );
172  }
173 
174  if ( ( *thread )->context )
175  papi_free( ( *thread )->context );
176 
177  if ( ( *thread )->running_eventset )
178  papi_free( ( *thread )->running_eventset );
179 
180  memset( *thread, 0x00, sizeof ( ThreadInfo_t ) );
181  papi_free( *thread );
182  *thread = NULL;
183 }
memset(eventId, 0, size)
#define papi_free(a)
Definition: papi_memory.h:35
#define THRDBG(format, args...)
Definition: papi_debug.h:66
int i
Definition: fileop.c:140
int papi_num_components

Here is the call graph for this function:

Here is the caller graph for this function:

static void insert_thread ( ThreadInfo_t entry,
int  tid 
)
static

Definition at line 186 of file threads.c.

187 {
189 
190  if ( _papi_hwi_thread_head == NULL ) { /* 0 elements */
191  THRDBG( "_papi_hwi_thread_head is NULL\n" );
192  entry->next = entry;
193  } else if ( _papi_hwi_thread_head->next == _papi_hwi_thread_head ) { /* 1 elements */
194  THRDBG( "_papi_hwi_thread_head was thread %ld at %p\n",
197  entry->next = ( ThreadInfo_t * ) _papi_hwi_thread_head;
198  } else { /* 2+ elements */
199 
200  THRDBG( "_papi_hwi_thread_head was thread %ld at %p\n",
202  entry->next = _papi_hwi_thread_head->next;
204  }
205 
207 
208  THRDBG( "_papi_hwi_thread_head now thread %ld at %p\n",
210 
212 
213 #if defined(HAVE_THREAD_LOCAL_STORAGE)
214  /* Don't set the current local thread if we are a fake attach thread */
215  if (tid==0) {
216  _papi_hwi_my_thread = entry;
217  THRDBG( "TLS for thread %ld is now %p\n", entry->tid,
218  _papi_hwi_my_thread );
219  }
220 #else
221  ( void ) tid;
222 #endif
223 }
struct _ThreadInfo * next
Definition: threads.h:27
struct cache_ent * entry
Definition: libasync.c:1170
#define THRDBG(format, args...)
Definition: papi_debug.h:66
void
Definition: iozone.c:18627
volatile ThreadInfo_t * _papi_hwi_thread_head
Definition: threads.c:32
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
unsigned long int tid
Definition: threads.h:25
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
void *long long tid
Definition: iozone.c:18586
#define THREADS_LOCK
Definition: papi_internal.h:87

Here is the call graph for this function:

Here is the caller graph for this function:

static int lookup_and_set_thread_symbols ( void  )
static

Definition at line 55 of file threads.c.

56 {
57 #if defined(ANY_THREAD_GETS_SIGNAL)
58  int retval;
59  char *error_ptc = NULL, *error_ptk = NULL;
60  void *symbol_ptc = NULL, *symbol_ptk = NULL, *handle = NULL;
61 
62  handle = dlopen( NULL, RTLD_LAZY );
63  if ( handle == NULL ) {
64  PAPIERROR( "Error from dlopen(NULL, RTLD_LAZY): %d %s", errno,
65  dlerror( ) );
66  return ( PAPI_ESYS );
67  }
68 
69  symbol_ptc = dlsym( handle, "pthread_self" );
70  if ( symbol_ptc == NULL ) {
71  error_ptc = dlerror( );
72  THRDBG( "dlsym(%p,pthread_self) returned NULL: %s\n",
73  ( error_ptc ? error_ptc : "No error, NULL symbol!" ) );
74  }
75 
76  symbol_ptk = dlsym( handle, "pthread_kill" );
77  if ( symbol_ptk == NULL ) {
78  error_ptk = dlerror( );
79  THRDBG( "dlsym(%p,pthread_kill) returned NULL: %s\n",
80  ( error_ptk ? error_ptk : "No error, NULL symbol!" ) );
81  }
82 
83  dlclose( handle );
84 
87  return ( PAPI_EMISC );
88 
89  _papi_hwi_thread_kill_fn = ( int ( * )( int, int ) ) symbol_ptk;
90  _papi_hwi_thread_id_fn = ( unsigned long ( * )( void ) ) symbol_ptc;
91 #endif
92  return ( PAPI_OK );
93 }
int errno
return PAPI_OK
Definition: linux-nvml.c:458
#define THRDBG(format, args...)
Definition: papi_debug.h:66
void
Definition: iozone.c:18627
#define PAPI_EMISC
Definition: papi.h:265
#define PAPI_ESYS
Definition: papi.h:253
long long
Definition: iozone.c:19827
void PAPIERROR(char *format,...)
nvmlDevice_t handle
Definition: linux-nvml.c:399
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
int(* _papi_hwi_thread_kill_fn)(int, int)
int
Definition: iozone.c:18528
ssize_t retval
Definition: libasync.c:338

Here is the call graph for this function:

Here is the caller graph for this function:

static int remove_thread ( ThreadInfo_t entry)
static

Definition at line 226 of file threads.c.

227 {
228  ThreadInfo_t *tmp = NULL, *prev = NULL;
229 
231 
232  THRDBG( "_papi_hwi_thread_head was thread %ld at %p\n",
234 
235  /* Find the preceding element and the matched element,
236  short circuit if we've seen the head twice */
237 
238  for ( tmp = ( ThreadInfo_t * ) _papi_hwi_thread_head;
239  ( entry != tmp ) || ( prev == NULL ); tmp = tmp->next ) {
240  prev = tmp;
241  }
242 
243  if ( tmp != entry ) {
244  THRDBG( "Thread %ld at %p was not found in the thread list!\n",
245  entry->tid, entry );
246  return ( PAPI_EBUG );
247  }
248 
249  /* Only 1 element in list */
250 
251  if ( prev == tmp ) {
252  _papi_hwi_thread_head = NULL;
253  tmp->next = NULL;
254  THRDBG( "_papi_hwi_thread_head now NULL\n" );
255  } else {
256  prev->next = tmp->next;
257  /* If we're removing the head, better advance it! */
258  if ( _papi_hwi_thread_head == tmp ) {
260  THRDBG( "_papi_hwi_thread_head now thread %ld at %p\n",
262  }
263  THRDBG( "Removed thread %p from list\n", tmp );
264  }
265 
267 
268 #if defined(HAVE_THREAD_LOCAL_STORAGE)
269  _papi_hwi_my_thread = NULL;
270  THRDBG( "TLS for thread %ld is now %p\n", entry->tid,
271  _papi_hwi_my_thread );
272 #endif
273 
274  return PAPI_OK;
275 }
struct _ThreadInfo * next
Definition: threads.h:27
#define PAPI_EBUG
Definition: papi.h:257
return PAPI_OK
Definition: linux-nvml.c:458
#define THRDBG(format, args...)
Definition: papi_debug.h:66
volatile ThreadInfo_t * _papi_hwi_thread_head
Definition: threads.c:32
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
unsigned long int tid
Definition: threads.h:25
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
#define THREADS_LOCK
Definition: papi_internal.h:87
long long tmp
Definition: iozone.c:12031

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

volatile ThreadInfo_t* _papi_hwi_thread_head

The list of threads, gets initialized to master process with TID of getpid()

Definition at line 32 of file threads.c.

unsigned long( * _papi_hwi_thread_id_fn)(void)

Function that returns an unsigned long int thread identifier

Definition at line 42 of file threads.c.