Blame src/threads.h

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