|
PAPI
5.0.1.0
|
00001 00006 #ifndef PAPI_THREADS_H 00007 #define PAPI_THREADS_H 00008 00009 #include <stdlib.h> 00010 #include <stdio.h> 00011 #include <unistd.h> 00012 00013 #ifdef HAVE_THREAD_LOCAL_STORAGE 00014 #define THREAD_LOCAL_STORAGE_KEYWORD HAVE_THREAD_LOCAL_STORAGE 00015 #else 00016 #define THREAD_LOCAL_STORAGE_KEYWORD 00017 #endif 00018 00019 #if defined(ANY_THREAD_GETS_SIGNAL) && !defined(_AIX) 00020 #error "lookup_and_set_thread_symbols and _papi_hwi_broadcast_signal have only been tested on AIX" 00021 #endif 00022 00023 typedef struct _ThreadInfo 00024 { 00025 unsigned long int tid; 00026 unsigned long int allocator_tid; 00027 struct _ThreadInfo *next; 00028 hwd_context_t **context; 00029 void *thread_storage[PAPI_MAX_TLS]; 00030 EventSetInfo_t **running_eventset; 00031 EventSetInfo_t *from_esi; /* ESI used for last update this control state */ 00032 int wants_signal; 00033 } ThreadInfo_t; 00034 00038 extern volatile ThreadInfo_t *_papi_hwi_thread_head; 00039 00040 /* If we have TLS, this variable ALWAYS points to our thread descriptor. It's like magic! */ 00041 00042 #if defined(HAVE_THREAD_LOCAL_STORAGE) 00043 extern THREAD_LOCAL_STORAGE_KEYWORD ThreadInfo_t *_papi_hwi_my_thread; 00044 #endif 00045 00049 extern unsigned long int ( *_papi_hwi_thread_id_fn ) ( void ); 00050 00054 extern int ( *_papi_hwi_thread_kill_fn ) ( int, int ); 00055 00056 extern int _papi_hwi_initialize_thread( ThreadInfo_t ** dest, int tid ); 00057 extern int _papi_hwi_init_global_threads( void ); 00058 extern int _papi_hwi_shutdown_thread( ThreadInfo_t * thread ); 00059 extern int _papi_hwi_shutdown_global_threads( void ); 00060 extern int _papi_hwi_broadcast_signal( unsigned int mytid ); 00061 extern int _papi_hwi_set_thread_id_fn( unsigned long int ( *id_fn ) ( void ) ); 00062 00063 inline_static int 00064 _papi_hwi_lock( int lck ) 00065 { 00066 if ( _papi_hwi_thread_id_fn ) { 00067 _papi_hwd_lock( lck ); 00068 THRDBG( "Lock %d\n", lck ); 00069 } else { 00070 ( void ) lck; /* unused if !defined(DEBUG) */ 00071 THRDBG( "Skipped lock %d\n", lck ); 00072 } 00073 00074 return ( PAPI_OK ); 00075 } 00076 00077 inline_static int 00078 _papi_hwi_unlock( int lck ) 00079 { 00080 if ( _papi_hwi_thread_id_fn ) { 00081 _papi_hwd_unlock( lck ); 00082 THRDBG( "Unlock %d\n", lck ); 00083 } else { 00084 ( void ) lck; /* unused if !defined(DEBUG) */ 00085 THRDBG( "Skipped unlock %d\n", lck ); 00086 } 00087 00088 return ( PAPI_OK ); 00089 } 00090 00091 inline_static ThreadInfo_t * 00092 _papi_hwi_lookup_thread( int custom_tid ) 00093 { 00094 00095 unsigned long int tid; 00096 ThreadInfo_t *tmp; 00097 00098 00099 if (custom_tid==0) { 00100 #ifdef HAVE_THREAD_LOCAL_STORAGE 00101 THRDBG( "TLS returning %p\n", _papi_hwi_my_thread ); 00102 return ( _papi_hwi_my_thread ); 00103 #else 00104 if ( _papi_hwi_thread_id_fn == NULL ) { 00105 THRDBG( "Threads not initialized, returning master thread at %p\n", 00106 _papi_hwi_thread_head ); 00107 return ( ( ThreadInfo_t * ) _papi_hwi_thread_head ); 00108 } 00109 00110 tid = ( *_papi_hwi_thread_id_fn ) ( ); 00111 #endif 00112 } 00113 else { 00114 tid=custom_tid; 00115 } 00116 THRDBG( "Threads initialized, looking for thread 0x%lx\n", tid ); 00117 00118 _papi_hwi_lock( THREADS_LOCK ); 00119 00120 tmp = ( ThreadInfo_t * ) _papi_hwi_thread_head; 00121 while ( tmp != NULL ) { 00122 THRDBG( "Examining thread tid 0x%lx at %p\n", tmp->tid, tmp ); 00123 if ( tmp->tid == tid ) 00124 break; 00125 tmp = tmp->next; 00126 if ( tmp == _papi_hwi_thread_head ) { 00127 tmp = NULL; 00128 break; 00129 } 00130 } 00131 00132 if ( tmp ) { 00133 _papi_hwi_thread_head = tmp; 00134 THRDBG( "Found thread %ld at %p\n", tid, tmp ); 00135 } else { 00136 THRDBG( "Did not find tid %ld\n", tid ); 00137 } 00138 00139 _papi_hwi_unlock( THREADS_LOCK ); 00140 return ( tmp ); 00141 00142 } 00143 00144 inline_static int 00145 _papi_hwi_lookup_or_create_thread( ThreadInfo_t ** here, int tid ) 00146 { 00147 ThreadInfo_t *tmp = _papi_hwi_lookup_thread( tid ); 00148 int retval = PAPI_OK; 00149 00150 if ( tmp == NULL ) 00151 retval = _papi_hwi_initialize_thread( &tmp, tid ); 00152 00153 if ( retval == PAPI_OK ) 00154 *here = tmp; 00155 00156 return ( retval ); 00157 } 00158 00159 /* Prototypes */ 00160 void _papi_hwi_shutdown_the_thread_list( void ); 00161 void _papi_hwi_cleanup_thread_list( void ); 00162 int _papi_hwi_insert_in_thread_list( ThreadInfo_t * ptr ); 00163 ThreadInfo_t *_papi_hwi_lookup_in_thread_list( ); 00164 void _papi_hwi_shutdown_the_thread_list( void ); 00165 int _papi_hwi_get_thr_context( void ** ); 00166 int _papi_hwi_gather_all_thrspec_data( int tag, PAPI_all_thr_spec_t * where ); 00167 00168 #endif