|
Packit Service |
a1973e |
/** @file threads.h
|
|
Packit Service |
a1973e |
* CVS: $Id$
|
|
Packit Service |
a1973e |
* @author ??
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifndef PAPI_THREADS_H
|
|
Packit Service |
a1973e |
#define PAPI_THREADS_H
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include <stdlib.h>
|
|
Packit Service |
a1973e |
#include <stdio.h>
|
|
Packit Service |
a1973e |
#include <unistd.h>
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef HAVE_THREAD_LOCAL_STORAGE
|
|
Packit Service |
a1973e |
#define THREAD_LOCAL_STORAGE_KEYWORD HAVE_THREAD_LOCAL_STORAGE
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
#define THREAD_LOCAL_STORAGE_KEYWORD
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if defined(ANY_THREAD_GETS_SIGNAL) && !defined(_AIX)
|
|
Packit Service |
a1973e |
#error "lookup_and_set_thread_symbols and _papi_hwi_broadcast_signal have only been tested on AIX"
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
typedef struct _ThreadInfo
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
unsigned long int tid;
|
|
Packit Service |
a1973e |
unsigned long int allocator_tid;
|
|
Packit Service |
a1973e |
struct _ThreadInfo *next;
|
|
Packit Service |
a1973e |
hwd_context_t **context;
|
|
Packit Service |
a1973e |
void *thread_storage[PAPI_MAX_TLS];
|
|
Packit Service |
a1973e |
EventSetInfo_t **running_eventset;
|
|
Packit Service |
a1973e |
EventSetInfo_t *from_esi; /* ESI used for last update this control state */
|
|
Packit Service |
a1973e |
int wants_signal;
|
|
Packit Service |
0798ad |
|
|
Packit Service |
0798ad |
// The current event code can be stored here prior to
|
|
Packit Service |
0798ad |
// component calls and cleared after the component returns.
|
|
Packit Service |
0798ad |
unsigned int tls_papi_event_code;
|
|
Packit Service |
0798ad |
int tls_papi_event_code_changed;
|
|
Packit Service |
a1973e |
} ThreadInfo_t;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** The list of threads, gets initialized to master process with TID of getpid()
|
|
Packit Service |
a1973e |
* @internal */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
extern volatile ThreadInfo_t *_papi_hwi_thread_head;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* If we have TLS, this variable ALWAYS points to our thread descriptor. It's like magic! */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#if defined(HAVE_THREAD_LOCAL_STORAGE)
|
|
Packit Service |
a1973e |
extern THREAD_LOCAL_STORAGE_KEYWORD ThreadInfo_t *_papi_hwi_my_thread;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Function that returns an unsigned long int thread identifier
|
|
Packit Service |
a1973e |
* @internal */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
extern unsigned long int ( *_papi_hwi_thread_id_fn ) ( void );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Function that sends a signal to other threads
|
|
Packit Service |
a1973e |
* @internal */
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
extern int ( *_papi_hwi_thread_kill_fn ) ( int, int );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
extern int _papi_hwi_initialize_thread( ThreadInfo_t ** dest, int tid );
|
|
Packit Service |
a1973e |
extern int _papi_hwi_init_global_threads( void );
|
|
Packit Service |
a1973e |
extern int _papi_hwi_shutdown_thread( ThreadInfo_t * thread, int force );
|
|
Packit Service |
a1973e |
extern int _papi_hwi_shutdown_global_threads( void );
|
|
Packit Service |
a1973e |
extern int _papi_hwi_broadcast_signal( unsigned int mytid );
|
|
Packit Service |
a1973e |
extern int _papi_hwi_set_thread_id_fn( unsigned long int ( *id_fn ) ( void ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
inline_static int
|
|
Packit Service |
a1973e |
_papi_hwi_lock( int lck )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
if ( _papi_hwi_thread_id_fn ) {
|
|
Packit Service |
a1973e |
_papi_hwd_lock( lck );
|
|
Packit Service |
a1973e |
THRDBG( "Lock %d\n", lck );
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
( void ) lck; /* unused if !defined(DEBUG) */
|
|
Packit Service |
a1973e |
THRDBG( "Skipped lock %d\n", lck );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return ( PAPI_OK );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
inline_static int
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( int lck )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
if ( _papi_hwi_thread_id_fn ) {
|
|
Packit Service |
a1973e |
_papi_hwd_unlock( lck );
|
|
Packit Service |
a1973e |
THRDBG( "Unlock %d\n", lck );
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
( void ) lck; /* unused if !defined(DEBUG) */
|
|
Packit Service |
a1973e |
THRDBG( "Skipped unlock %d\n", lck );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return ( PAPI_OK );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
inline_static ThreadInfo_t *
|
|
Packit Service |
a1973e |
_papi_hwi_lookup_thread( int custom_tid )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
unsigned long int tid;
|
|
Packit Service |
a1973e |
ThreadInfo_t *tmp;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (custom_tid==0) {
|
|
Packit Service |
a1973e |
#ifdef HAVE_THREAD_LOCAL_STORAGE
|
|
Packit Service |
a1973e |
THRDBG( "TLS returning %p\n", _papi_hwi_my_thread );
|
|
Packit Service |
a1973e |
return ( _papi_hwi_my_thread );
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
if ( _papi_hwi_thread_id_fn == NULL ) {
|
|
Packit Service |
a1973e |
THRDBG( "Threads not initialized, returning master thread at %p\n",
|
|
Packit Service |
a1973e |
_papi_hwi_thread_head );
|
|
Packit Service |
a1973e |
return ( ( ThreadInfo_t * ) _papi_hwi_thread_head );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tid = ( *_papi_hwi_thread_id_fn ) ( );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
else {
|
|
Packit Service |
a1973e |
tid=custom_tid;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
THRDBG( "Threads initialized, looking for thread %#lx\n", tid );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_lock( THREADS_LOCK );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tmp = ( ThreadInfo_t * ) _papi_hwi_thread_head;
|
|
Packit Service |
a1973e |
while ( tmp != NULL ) {
|
|
Packit Service |
a1973e |
THRDBG( "Examining thread tid %#lx at %p\n", tmp->tid, tmp );
|
|
Packit Service |
a1973e |
if ( tmp->tid == tid )
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
tmp = tmp->next;
|
|
Packit Service |
a1973e |
if ( tmp == _papi_hwi_thread_head ) {
|
|
Packit Service |
a1973e |
tmp = NULL;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( tmp ) {
|
|
Packit Service |
a1973e |
_papi_hwi_thread_head = tmp;
|
|
Packit Service |
a1973e |
THRDBG( "Found thread %ld at %p\n", tid, tmp );
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
THRDBG( "Did not find tid %ld\n", tid );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( THREADS_LOCK );
|
|
Packit Service |
a1973e |
return ( tmp );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
inline_static int
|
|
Packit Service |
a1973e |
_papi_hwi_lookup_or_create_thread( ThreadInfo_t ** here, int tid )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
ThreadInfo_t *tmp = _papi_hwi_lookup_thread( tid );
|
|
Packit Service |
a1973e |
int retval = PAPI_OK;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( tmp == NULL )
|
|
Packit Service |
a1973e |
retval = _papi_hwi_initialize_thread( &tmp, tid );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( retval == PAPI_OK )
|
|
Packit Service |
a1973e |
*here = tmp;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return ( retval );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Prototypes */
|
|
Packit Service |
a1973e |
void _papi_hwi_shutdown_the_thread_list( void );
|
|
Packit Service |
a1973e |
void _papi_hwi_cleanup_thread_list( void );
|
|
Packit Service |
a1973e |
int _papi_hwi_insert_in_thread_list( ThreadInfo_t * ptr );
|
|
Packit Service |
a1973e |
ThreadInfo_t *_papi_hwi_lookup_in_thread_list( );
|
|
Packit Service |
a1973e |
void _papi_hwi_shutdown_the_thread_list( void );
|
|
Packit Service |
a1973e |
int _papi_hwi_get_thr_context( void ** );
|
|
Packit Service |
a1973e |
int _papi_hwi_gather_all_thrspec_data( int tag, PAPI_all_thr_spec_t * where );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#endif
|