PAPI  5.6.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 555 of file threads.c.

556 {
557  int didsomething = 0;
558  ThreadInfo_t *foo = NULL;
559 
561 
562  for ( foo = ( ThreadInfo_t * ) _papi_hwi_thread_head; foo != NULL;
563  foo = foo->next ) {
564  /* If we want thread ID's */
565  if ( where->id )
566  memcpy( &where->id[didsomething], &foo->tid,
567  sizeof ( where->id[didsomething] ) );
568 
569  /* If we want data pointers */
570  if ( where->data )
571  where->data[didsomething] = foo->thread_storage[tag];
572 
573  didsomething++;
574 
575  if ( ( where->id ) || ( where->data ) ) {
576  if ( didsomething >= where->num )
577  break;
578  }
579 
580  if ( foo->next == _papi_hwi_thread_head )
581  break;
582  }
583 
584  where->num = didsomething;
586 
587  return ( PAPI_OK );
588 
589 }
void ** data
Definition: papi.h:563
struct _ThreadInfo * next
Definition: threads.h:27
return PAPI_OK
Definition: linux-nvml.c:497
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:88
PAPI_thread_id_t * id
Definition: papi.h:562
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 528 of file threads.c.

529 {
530  int retval;
531  ThreadInfo_t *tmp;
532 
534 
535 #if defined(HAVE_THREAD_LOCAL_STORAGE)
536  _papi_hwi_my_thread = NULL;
537 #endif
538  _papi_hwi_thread_head = NULL;
539  _papi_hwi_thread_id_fn = NULL;
540 #if defined(ANY_THREAD_GETS_SIGNAL)
542 #endif
543 
544  retval = _papi_hwi_initialize_thread( &tmp , 0);
545  if ( retval == PAPI_OK ) {
546  retval = lookup_and_set_thread_symbols( );
547  }
548 
550 
551  return ( retval );
552 }
static int lookup_and_set_thread_symbols(void)
Definition: threads.c:55
return PAPI_OK
Definition: linux-nvml.c:497
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:92
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:497
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:38
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:254
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:497
#define THRDBG(format, args...)
Definition: papi_debug.h:66
return PAPI_EINVAL
Definition: linux-nvml.c:436
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  (void)our_tid;
472 
473  THRDBG("Shutting down %ld\n",our_tid);
474 
475  err = _papi_hwi_shutdown_thread( tmp, 1 );
476 
477  /* count threads */
479  num_threads=0;
480  while(tmp!=NULL) {
481  num_threads++;
482  if (tmp->next==_papi_hwi_thread_head) break;
483  tmp=tmp->next;
484  }
485 
486  /* Shut down all threads allocated by this thread */
487  /* Urgh it's a circular list where we removed in the loop */
488  /* so the only sane way to do it is get a count in advance */
490 
491  for(i=0;i<num_threads;i++) {
492 
493  next=tmp->next;
494 
495  THRDBG("looking at #%d %ld our_tid: %ld alloc_tid: %ld\n",
496  i,tmp->tid,our_tid,tmp->allocator_tid);
497 
498  THRDBG("Also removing thread %ld\n",tmp->tid);
499  err = _papi_hwi_shutdown_thread( tmp, 1 );
500 
501  tmp=next;
502 
503  }
504  }
505 
506 
507 #ifdef DEBUG
508  if ( ISLEVEL( DEBUG_THREADS ) ) {
509  if ( _papi_hwi_thread_head ) {
510  THRDBG( "Thread head %p still exists!\n", _papi_hwi_thread_head );
511  }
512  }
513 #endif
514 
515 #if defined(HAVE_THREAD_LOCAL_STORAGE)
516  _papi_hwi_my_thread = NULL;
517 #endif
518  _papi_hwi_thread_head = NULL;
519  _papi_hwi_thread_id_fn = NULL;
520 #if defined(ANY_THREAD_GETS_SIGNAL)
522 #endif
523 
524  return err;
525 }
struct _ThreadInfo * next
Definition: threads.h:27
#define PAPI_EBUG
Definition: papi.h:259
#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
int i
Definition: fileop.c:140
unsigned long int tid
Definition: threads.h:25
static 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:259
return PAPI_OK
Definition: linux-nvml.c:497
#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:497
#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:56
EventSetInfo_t ** dataSlotArray
#define INTERNAL_LOCK
Definition: papi_internal.h:86
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 }
#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:38
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 }
#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 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:88

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:497
#define THRDBG(format, args...)
Definition: papi_debug.h:66
void
Definition: iozone.c:18627
#define PAPI_EMISC
Definition: papi.h:267
#define PAPI_ESYS
Definition: papi.h:255
long long
Definition: iozone.c:19827
void PAPIERROR(char *format,...)
nvmlDevice_t handle
Definition: linux-nvml.c:427
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:259
return PAPI_OK
Definition: linux-nvml.c:497
#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:88
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.