PAPI  5.0.1.0
threads.h
Go to the documentation of this file.
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
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines