File: threads.h

package info (click to toggle)
papi 5.7.0+dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 9,856 kB
  • sloc: ansic: 93,265; fortran: 3,338; xml: 2,460; makefile: 815; sh: 290
file content (168 lines) | stat: -rw-r--r-- 4,210 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/** @file threads.h
 *  CVS: $Id$
 *  @author ??
 */

#ifndef PAPI_THREADS_H
#define PAPI_THREADS_H

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#ifdef HAVE_THREAD_LOCAL_STORAGE
#define THREAD_LOCAL_STORAGE_KEYWORD HAVE_THREAD_LOCAL_STORAGE
#else
#define THREAD_LOCAL_STORAGE_KEYWORD
#endif

#if defined(ANY_THREAD_GETS_SIGNAL) && !defined(_AIX)
#error "lookup_and_set_thread_symbols and _papi_hwi_broadcast_signal have only been tested on AIX"
#endif

typedef struct _ThreadInfo
{
	unsigned long int tid;
	unsigned long int allocator_tid;
	struct _ThreadInfo *next;
	hwd_context_t **context;
	void *thread_storage[PAPI_MAX_TLS];
	EventSetInfo_t **running_eventset;
	EventSetInfo_t *from_esi;          /* ESI used for last update this control state */
	int wants_signal;
} ThreadInfo_t;

/** The list of threads, gets initialized to master process with TID of getpid() 
 *	@internal */

extern volatile ThreadInfo_t *_papi_hwi_thread_head;

/* If we have TLS, this variable ALWAYS points to our thread descriptor. It's like magic! */

#if defined(HAVE_THREAD_LOCAL_STORAGE)
extern THREAD_LOCAL_STORAGE_KEYWORD ThreadInfo_t *_papi_hwi_my_thread;
#endif

/** Function that returns an unsigned long int thread identifier 
 *	@internal */

extern unsigned long int ( *_papi_hwi_thread_id_fn ) ( void );

/** Function that sends a signal to other threads 
 *	@internal */

extern int ( *_papi_hwi_thread_kill_fn ) ( int, int );

extern int _papi_hwi_initialize_thread( ThreadInfo_t ** dest, int tid );
extern int _papi_hwi_init_global_threads( void );
extern int _papi_hwi_shutdown_thread( ThreadInfo_t * thread, int force );
extern int _papi_hwi_shutdown_global_threads( void );
extern int _papi_hwi_broadcast_signal( unsigned int mytid );
extern int _papi_hwi_set_thread_id_fn( unsigned long int ( *id_fn ) ( void ) );

inline_static int
_papi_hwi_lock( int lck )
{
	if ( _papi_hwi_thread_id_fn ) {
		_papi_hwd_lock( lck );
		THRDBG( "Lock %d\n", lck );
	} else {
		( void ) lck;		 /* unused if !defined(DEBUG) */
		THRDBG( "Skipped lock %d\n", lck );
	}

	return ( PAPI_OK );
}

inline_static int
_papi_hwi_unlock( int lck )
{
	if ( _papi_hwi_thread_id_fn ) {
		_papi_hwd_unlock( lck );
		THRDBG( "Unlock %d\n", lck );
	} else {
		( void ) lck;		 /* unused if !defined(DEBUG) */
		THRDBG( "Skipped unlock %d\n", lck );
	}

	return ( PAPI_OK );
}

inline_static ThreadInfo_t *
_papi_hwi_lookup_thread( int custom_tid )
{

	unsigned long int tid;
	ThreadInfo_t *tmp;


	if (custom_tid==0) {
#ifdef HAVE_THREAD_LOCAL_STORAGE
	   THRDBG( "TLS returning %p\n", _papi_hwi_my_thread );
	   return ( _papi_hwi_my_thread );
#else
	   if ( _papi_hwi_thread_id_fn == NULL ) {
	      THRDBG( "Threads not initialized, returning master thread at %p\n",
				_papi_hwi_thread_head );
	      return ( ( ThreadInfo_t * ) _papi_hwi_thread_head );
	   }

	   tid = ( *_papi_hwi_thread_id_fn ) (  );
#endif
	}
	else {
	  tid=custom_tid;
	}
	THRDBG( "Threads initialized, looking for thread %#lx\n", tid );

	_papi_hwi_lock( THREADS_LOCK );

	tmp = ( ThreadInfo_t * ) _papi_hwi_thread_head;
	while ( tmp != NULL ) {
		THRDBG( "Examining thread tid %#lx at %p\n", tmp->tid, tmp );
		if ( tmp->tid == tid )
			break;
		tmp = tmp->next;
		if ( tmp == _papi_hwi_thread_head ) {
			tmp = NULL;
			break;
		}
	}

	if ( tmp ) {
		_papi_hwi_thread_head = tmp;
		THRDBG( "Found thread %ld at %p\n", tid, tmp );
	} else {
		THRDBG( "Did not find tid %ld\n", tid );
	}

	_papi_hwi_unlock( THREADS_LOCK );
	return ( tmp );

}

inline_static int
_papi_hwi_lookup_or_create_thread( ThreadInfo_t ** here, int tid )
{
	ThreadInfo_t *tmp = _papi_hwi_lookup_thread( tid );
	int retval = PAPI_OK;

	if ( tmp == NULL )
	  retval = _papi_hwi_initialize_thread( &tmp, tid );

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

	return ( retval );
}

/* Prototypes */
void _papi_hwi_shutdown_the_thread_list( void );
void _papi_hwi_cleanup_thread_list( void );
int _papi_hwi_insert_in_thread_list( ThreadInfo_t * ptr );
ThreadInfo_t *_papi_hwi_lookup_in_thread_list(  );
void _papi_hwi_shutdown_the_thread_list( void );
int _papi_hwi_get_thr_context( void ** );
int _papi_hwi_gather_all_thrspec_data( int tag, PAPI_all_thr_spec_t * where );

#endif