PAPI 7.1.0.0
Loading...
Searching...
No Matches
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)
 
unsigned long _papi_gettid (void)
 
unsigned long _papi_getpid (void)
 

Variables

volatile ThreadInfo_t_papi_hwi_thread_head
 
THREAD_LOCAL_STORAGE_KEYWORD ThreadInfo_t_papi_hwi_my_thread
 
unsigned long(* _papi_hwi_thread_id_fn )(void)
 

Function Documentation

◆ _papi_getpid()

unsigned long _papi_getpid ( void  )

Definition at line 634 of file threads.c.

635{
636 return (unsigned long) getpid();
637}
Here is the caller graph for this function:

◆ _papi_gettid()

unsigned long _papi_gettid ( void  )

Definition at line 613 of file threads.c.

614 {
615 return (unsigned long)(gettid());
616 }
Here is the caller graph for this function:

◆ _papi_hwi_gather_all_thrspec_data()

int _papi_hwi_gather_all_thrspec_data ( int  tag,
PAPI_all_thr_spec_t where 
)

Definition at line 568 of file threads.c.

569{
570 int didsomething = 0;
571 ThreadInfo_t *foo = NULL;
572
574
575 for ( foo = ( ThreadInfo_t * ) _papi_hwi_thread_head; foo != NULL;
576 foo = foo->next ) {
577 /* If we want thread ID's */
578 if ( where->id )
579 memcpy( &where->id[didsomething], &foo->tid,
580 sizeof ( where->id[didsomething] ) );
581
582 /* If we want data pointers */
583 if ( where->data )
584 where->data[didsomething] = foo->thread_storage[tag];
585
586 didsomething++;
587
588 if ( ( where->id ) || ( where->data ) ) {
589 if ( didsomething >= where->num )
590 break;
591 }
592
593 if ( foo->next == _papi_hwi_thread_head )
594 break;
595 }
596
597 where->num = didsomething;
599
600 return ( PAPI_OK );
601
602}
#define PAPI_OK
Definition: f90papi.h:73
#define THREADS_LOCK
Definition: papi_internal.h:87
PAPI_thread_id_t * id
Definition: papi.h:569
void ** data
Definition: papi.h:570
unsigned long int tid
Definition: threads.h:25
void * thread_storage[PAPI_MAX_TLS]
Definition: threads.h:29
struct _ThreadInfo * next
Definition: threads.h:27
volatile ThreadInfo_t * _papi_hwi_thread_head
Definition: threads.c:32
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:69
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:83
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_hwi_init_global_threads()

int _papi_hwi_init_global_threads ( void  )

Definition at line 541 of file threads.c.

542{
543 int retval;
545
547
548#if defined(HAVE_THREAD_LOCAL_STORAGE)
549 _papi_hwi_my_thread = NULL;
550#endif
553#if defined(ANY_THREAD_GETS_SIGNAL)
555#endif
556
558 if ( retval == PAPI_OK ) {
560 }
561
563
564 return ( retval );
565}
double tmp
#define GLOBAL_LOCK
Definition: papi_internal.h:91
THREAD_LOCAL_STORAGE_KEYWORD ThreadInfo_t * _papi_hwi_my_thread
Definition: threads.c:37
unsigned long(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
int _papi_hwi_initialize_thread(ThreadInfo_t **dest, int tid)
Definition: threads.c:278
static int lookup_and_set_thread_symbols(void)
Definition: threads.c:55
int(* _papi_hwi_thread_kill_fn)(int, int)
int retval
Definition: zero_fork.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_hwi_initialize_thread()

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 /* init event memory variables, used by papi_internal.c */
290 thread->tls_papi_event_code = -1;
291 thread->tls_papi_event_code_changed = -1;
292
293 /* Call the component to fill in anything special. */
294
295 for ( i = 0; i < papi_num_components; i++ ) {
296 if (_papi_hwd[i]->cmp_info.disabled &&
297 _papi_hwd[i]->cmp_info.disabled != PAPI_EDELAY_INIT)
298 continue;
299 retval = _papi_hwd[i]->init_thread( thread->context[i] );
300 if ( retval ) {
302 *dest = NULL;
303 return retval;
304 }
305 }
306
307 insert_thread( thread, tid );
308
309 *dest = thread;
310 return PAPI_OK;
311}
int i
struct papi_vectors * _papi_hwd[]
#define PAPI_EDELAY_INIT
Definition: f90papi.h:271
#define PAPI_ENOMEM
Definition: f90papi.h:16
void * thread(void *arg)
Definition: kufrin.c:38
int papi_num_components
static void insert_thread(ThreadInfo_t *entry, int tid)
Definition: threads.c:186
static ThreadInfo_t * allocate_thread(int tid)
Definition: threads.c:96
static void free_thread(ThreadInfo_t **thread)
Definition: threads.c:164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_hwi_set_thread_id_fn()

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

Definition at line 358 of file threads.c.

359{
360#if !defined(ANY_THREAD_GETS_SIGNAL)
361 /* Check for multiple threads still in the list, if so, we can't change it */
362
364 return ( PAPI_EINVAL );
365
366 /* We can't change the thread id function from one to another,
367 only NULL to non-NULL and vice versa. */
368
369 if ( ( id_fn != NULL ) && ( _papi_hwi_thread_id_fn != NULL ) )
370 return ( PAPI_EINVAL );
371
373
374 THRDBG( "Set new thread id function to %p\n", id_fn );
375
376 if ( id_fn )
377 _papi_hwi_thread_head->tid = ( *_papi_hwi_thread_id_fn ) ( );
378 else
379 _papi_hwi_thread_head->tid = ( unsigned long ) getpid( );
380
381 THRDBG( "New master tid is %ld\n", _papi_hwi_thread_head->tid );
382#else
383 THRDBG( "Skipping set of thread id function\n" );
384#endif
385
386 return PAPI_OK;
387}
#define PAPI_EINVAL
Definition: f90papi.h:115
#define THRDBG(format, args...)
Definition: papi_debug.h:67
long long int long long
Definition: sde_internal.h:85
Here is the caller graph for this function:

◆ _papi_hwi_shutdown_global_threads()

int _papi_hwi_shutdown_global_threads ( void  )

Definition at line 470 of file threads.c.

471{
472 int err,num_threads,i;
473 ThreadInfo_t *tmp,*next;
474 unsigned long our_tid;
475
477
478 if ( tmp == NULL ) {
479 THRDBG( "Did not find my thread for shutdown!\n" );
480 err = PAPI_EBUG;
481 }
482 else {
483 our_tid=tmp->tid;
484 (void)our_tid;
485
486 THRDBG("Shutting down %ld\n",our_tid);
487
488 err = _papi_hwi_shutdown_thread( tmp, 1 );
489
490 /* count threads */
492 num_threads=0;
493 while(tmp!=NULL) {
494 num_threads++;
495 if (tmp->next==_papi_hwi_thread_head) break;
496 tmp=tmp->next;
497 }
498
499 /* Shut down all threads allocated by this thread */
500 /* Urgh it's a circular list where we removed in the loop */
501 /* so the only sane way to do it is get a count in advance */
503
504 for(i=0;i<num_threads;i++) {
505
506 next=tmp->next;
507
508 THRDBG("looking at #%d %ld our_tid: %ld alloc_tid: %ld\n",
509 i,tmp->tid,our_tid,tmp->allocator_tid);
510
511 THRDBG("Also removing thread %ld\n",tmp->tid);
512 err = _papi_hwi_shutdown_thread( tmp, 1 );
513
514 tmp=next;
515
516 }
517 }
518
519
520#ifdef DEBUG
521 if ( ISLEVEL( DEBUG_THREADS ) ) {
522 if ( _papi_hwi_thread_head ) {
523 THRDBG( "Thread head %p still exists!\n", _papi_hwi_thread_head );
524 }
525 }
526#endif
527
528#if defined(HAVE_THREAD_LOCAL_STORAGE)
529 _papi_hwi_my_thread = NULL;
530#endif
533#if defined(ANY_THREAD_GETS_SIGNAL)
535#endif
536
537 return err;
538}
#define PAPI_EBUG
Definition: f90papi.h:176
static int num_threads
#define ISLEVEL(a)
Definition: papi_debug.h:55
#define DEBUG_THREADS
Definition: papi_debug.h:30
int _papi_hwi_shutdown_thread(ThreadInfo_t *thread, int force_shutdown)
Definition: threads.c:424
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:97
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_hwi_shutdown_thread()

int _papi_hwi_shutdown_thread ( ThreadInfo_t thread,
int  force_shutdown 
)

Definition at line 424 of file threads.c.

425{
426 int retval = PAPI_OK;
427 unsigned long tid;
428 int i, failure = 0;
429
430 /* Clear event memory variables */
431 thread->tls_papi_event_code = -1;
432 thread->tls_papi_event_code_changed = -1;
433
434 /* Get thread id */
436 tid = ( *_papi_hwi_thread_id_fn ) ( );
437 else
438 tid = ( unsigned long ) getpid( );
439
440 THRDBG("Want to shutdown thread %ld, alloc %ld, our_tid: %ld\n",
441 thread->tid,
442 thread->allocator_tid,
443 tid);
444
445 if ((thread->tid==tid) || ( thread->allocator_tid == tid ) || force_shutdown) {
446
448
450 THRDBG( "Shutting down thread %ld at %p\n", thread->tid, thread );
451 for( i = 0; i < papi_num_components; i++ ) {
452 if (_papi_hwd[i]->cmp_info.disabled &&
453 _papi_hwd[i]->cmp_info.disabled != PAPI_EDELAY_INIT)
454 continue;
455 retval = _papi_hwd[i]->shutdown_thread( thread->context[i]);
456 if ( retval != PAPI_OK ) failure = retval;
457 }
459 return ( failure );
460 }
461
462 THRDBG( "Skipping shutdown thread %ld at %p, thread %ld not allocator!\n",
463 thread->tid, thread, tid );
464 return PAPI_EBUG;
465}
static int remove_thread(ThreadInfo_t *entry)
Definition: threads.c:226
static int _papi_hwi_thread_free_eventsets(long tid)
Definition: threads.c:390
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_hwi_thread_free_eventsets()

static int _papi_hwi_thread_free_eventsets ( long  tid)
static

Definition at line 390 of file threads.c.

390 {
391
392 EventSetInfo_t *ESI;
393 ThreadInfo_t *master;
395 int i;
396
397 master = _papi_hwi_lookup_thread( tid );
398
400
401 for( i = 0; i < map->totalSlots; i++ ) {
402 ESI = map->dataSlotArray[i];
403 if ( ( ESI ) && (ESI->master!=NULL) ) {
404
405 if ( ESI->master == master ) {
406 THRDBG("Attempting to remove %d from tid %ld\n",ESI->EventSetIndex,tid);
407
408 /* Code copied from _papi_hwi_remove_EventSet(ESI); */
410 map->dataSlotArray[i] = NULL;
411 map->availSlots++;
412 map->fullSlots--;
413 }
414 }
415 }
416
418
419 return PAPI_OK;
420}
void _papi_hwi_free_EventSet(EventSetInfo_t *ESI)
#define INTERNAL_LOCK
Definition: papi_internal.h:85
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
EventSetInfo_t ** dataSlotArray
struct _ThreadInfo * master
DynamicArray_t global_eventset_map
Here is the call graph for this function:
Here is the caller graph for this function:

◆ allocate_thread()

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 * ) *
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 * ) *
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
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}
long unsigned int size_t
#define papi_free(a)
Definition: papi_memory.h:35
#define papi_malloc(a)
Definition: papi_memory.h:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_thread()

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_thread()

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",
198 } else { /* 2+ elements */
199
200 THRDBG( "_papi_hwi_thread_head was thread %ld at %p\n",
204 }
205
206 _papi_hwi_thread_head = entry;
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,
219 }
220#else
221 ( void ) tid;
222#endif
223}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lookup_and_set_thread_symbols()

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}
static papi_handle_t handle
Definition: Gamum.c:21
int errno
#define PAPI_EMISC
Definition: f90papi.h:122
#define PAPI_ESYS
Definition: f90papi.h:136
void PAPIERROR(char *format,...)
int
Definition: sde_internal.h:89
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_thread()

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
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 ) {
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,
272#endif
273
274 return PAPI_OK;
275}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _papi_hwi_my_thread

Definition at line 37 of file threads.c.

◆ _papi_hwi_thread_head

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.

◆ _papi_hwi_thread_id_fn

unsigned long(* _papi_hwi_thread_id_fn) (void) ( void  )

Function that returns an unsigned long int thread identifier

Definition at line 42 of file threads.c.