diff --git a/src/tracer/Makefile.am b/src/tracer/Makefile.am index cbdb36c7..d5a92471 100644 --- a/src/tracer/Makefile.am +++ b/src/tracer/Makefile.am @@ -153,6 +153,7 @@ WRAPPERS_CORE = \ core_SRCS = \ calltrace.c calltrace.h \ signals.c signals.h \ + pthread_redirect.c pthread_redirect.h \ xml-parse.c xml-parse.h \ UF_gcc_instrument.c UF_gcc_instrument.h \ UF_xl_instrument.c UF_xl_instrument.h \ diff --git a/src/tracer/calltrace.c b/src/tracer/calltrace.c index a894f92d..39e96c38 100644 --- a/src/tracer/calltrace.c +++ b/src/tracer/calltrace.c @@ -28,6 +28,9 @@ #include "trace_macros.h" #include "wrapper.h" #include "common_hwc.h" +#include "pthread_redirect.h" + +extern pthread_rwlock_t pThread_mtx_change_number_threads; //#define DEBUG //#define MPICALLER_DEBUG @@ -87,14 +90,19 @@ void Extrae_trace_callers (iotimer_t time, int offset, int type) { if (Trace_Caller[type][current_deep-offset]) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); TRACE_EVENT(time, CALLER_EVENT_TYPE(type, current_deep-offset+1), (UINT64)ip); + mtx_rw_unlock(&pThread_mtx_change_number_threads); } } #if defined(SAMPLING_SUPPORT) else if (type == CALLER_SAMPLING) { - if (Trace_Caller[type][current_deep-offset]) + if (Trace_Caller[type][current_deep-offset]) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); SAMPLE_EVENT_NOHWC(time, SAMPLING_EV+current_deep-offset+1, (UINT64) ip); + mtx_rw_unlock(&pThread_mtx_change_number_threads); + } } #endif } diff --git a/src/tracer/clocks/clock.c b/src/tracer/clocks/clock.c index 8324ce85..ce9b22db 100644 --- a/src/tracer/clocks/clock.c +++ b/src/tracer/clocks/clock.c @@ -72,6 +72,9 @@ # error "Unhandled clock type" #endif +#include "pthread_redirect.h" +static pthread_rwlock_t pThread_mtx_extrae_last_read_clock = PTHREAD_RWLOCK_INITIALIZER; + static UINT64 *_extrae_last_read_clock = NULL; static unsigned ClockType = REAL_CLOCK; iotimer_t (*get_clock)(); @@ -89,7 +92,11 @@ unsigned Clock_getType (void) /* We obtain the last read time */ UINT64 Clock_getLastReadTime (unsigned thread) { - return _extrae_last_read_clock[thread]; + UINT64 ret; + mtx_rw_rdlock(&pThread_mtx_extrae_last_read_clock); + ret = _extrae_last_read_clock[thread]; + mtx_rw_unlock(&pThread_mtx_extrae_last_read_clock); + return ret; } /* We obtain the current time, but we don't store it in the last read time */ @@ -103,24 +110,31 @@ UINT64 Clock_getCurrentTime_nstore (void) UINT64 Clock_getCurrentTime (unsigned thread) { UINT64 tmp = Clock_getCurrentTime_nstore (); + mtx_rw_rdlock(&pThread_mtx_extrae_last_read_clock); _extrae_last_read_clock[thread] = tmp; + mtx_rw_unlock(&pThread_mtx_extrae_last_read_clock); return tmp; } void Clock_AllocateThreads (unsigned numthreads) { + mtx_rw_wrlock(&pThread_mtx_extrae_last_read_clock); _extrae_last_read_clock = (UINT64*) realloc (_extrae_last_read_clock, sizeof(UINT64)*numthreads); if (_extrae_last_read_clock == NULL) { fprintf (stderr, PACKAGE_NAME": Cannot allocate timing memory for %u threads\n", numthreads); + mtx_rw_unlock(&pThread_mtx_extrae_last_read_clock); exit (-1); } + mtx_rw_unlock(&pThread_mtx_extrae_last_read_clock); } void Clock_CleanUp (void) { + mtx_rw_wrlock(&pThread_mtx_extrae_last_read_clock); xfree (_extrae_last_read_clock); + mtx_rw_unlock(&pThread_mtx_extrae_last_read_clock); } void Clock_Initialize (unsigned numthreads) diff --git a/src/tracer/hwc/common_hwc.c b/src/tracer/hwc/common_hwc.c index 557ca65f..9e736a3c 100644 --- a/src/tracer/hwc/common_hwc.c +++ b/src/tracer/hwc/common_hwc.c @@ -50,6 +50,11 @@ #if defined(ENABLE_PEBS_SAMPLING) # include "sampling-intel-pebs.h" #endif +#include +#include "pthread_redirect.h" + +pthread_mutex_t pThread_mtx_HWC_current_changetype = PTHREAD_MUTEX_INITIALIZER; +extern pthread_rwlock_t pThread_mtx_change_number_threads; /*------------------------------------------------ Global Variables ---------*/ int HWCEnabled = FALSE; /* Have the HWC been started? */ @@ -103,7 +108,11 @@ int HWC_IsEnabled() */ int HWC_Get_Current_Set (int threadid) { - return HWC_current_set[threadid]; + int ret; + mtx_rw_rdlock(&pThread_mtx_change_number_threads); + ret = HWC_current_set[threadid]; + mtx_rw_unlock(&pThread_mtx_change_number_threads); + return ret; } /* @@ -194,9 +203,11 @@ void HWC_Stop_Current_Set (UINT64 time, int thread_id) { /* make sure we don't loose the current counter values */ Extrae_counters_at_Time_Wrapper(time); - + + mtx_rw_rdlock(&pThread_mtx_change_number_threads); /* Actually stop the counters */ HWCBE_STOP_SET (time, HWC_current_set[thread_id], thread_id); + mtx_rw_unlock(&pThread_mtx_change_number_threads); } } @@ -209,8 +220,10 @@ void HWC_Start_Current_Set (UINT64 countglops, UINT64 time, int thread_id) /* If there are less than 2 sets, don't do anything! */ if (HWC_num_sets > 0) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); /* Actually start the counters */ HWCBE_START_SET (countglops, time, HWC_current_set[thread_id], thread_id); + mtx_rw_unlock(&pThread_mtx_change_number_threads); } } @@ -226,11 +239,13 @@ void HWC_Start_Next_Set (UINT64 countglops, UINT64 time, int thread_id) { HWC_Stop_Current_Set (time, thread_id); + mtx_rw_rdlock(&pThread_mtx_change_number_threads); /* Move to the next set */ if (HWC_current_changeto == CHANGE_SEQUENTIAL) HWC_current_set[thread_id] = (HWC_current_set[thread_id] + 1) % HWC_num_sets; else if (HWC_current_changeto == CHANGE_RANDOM) HWC_current_set[thread_id] = random()%HWC_num_sets; + mtx_rw_unlock(&pThread_mtx_change_number_threads); HWC_Start_Current_Set (countglops, time, thread_id); } @@ -247,11 +262,13 @@ void HWC_Start_Previous_Set (UINT64 countglops, UINT64 time, int thread_id) { HWC_Stop_Current_Set (time, thread_id); + mtx_rw_rdlock(&pThread_mtx_change_number_threads); /* Move to the previous set */ if (HWC_current_changeto == CHANGE_SEQUENTIAL) HWC_current_set[thread_id] = ((HWC_current_set[thread_id] - 1) < 0) ? (HWC_num_sets - 1) : (HWC_current_set[thread_id] - 1) ; else if (HWC_current_changeto == CHANGE_RANDOM) HWC_current_set[thread_id] = random()%HWC_num_sets; + mtx_rw_unlock(&pThread_mtx_change_number_threads); HWC_Start_Current_Set (countglops, time, thread_id); } @@ -291,12 +308,13 @@ static inline int CheckForHWCSetChange_TIME (UINT64 countglops, UINT64 time, int int ret = 0; // fprintf (stderr, "HWC_current_timebegin[%d]=%llu HWC_current_changeat=%llu time = %llu\n", THREADID, HWC_current_timebegin[threadid], HWC_current_changeat, time); - + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if (HWC_current_timebegin[threadid] + HWC_current_changeat < time) { HWC_Start_Next_Set (countglops, time, threadid); ret = 1; } + mtx_rw_unlock(&pThread_mtx_change_number_threads); return ret; } @@ -309,12 +327,16 @@ static inline int CheckForHWCSetChange_TIME (UINT64 countglops, UINT64 time, int */ int HWC_Check_Pending_Set_Change (UINT64 countglops, UINT64 time, int thread_id) { - if (HWC_current_changetype == CHANGE_GLOPS) + mtx_lock(&pThread_mtx_HWC_current_changetype); + if (HWC_current_changetype == CHANGE_GLOPS) { + mtx_unlock(&pThread_mtx_HWC_current_changetype); return CheckForHWCSetChange_GLOPS(countglops, time, thread_id); - else if (HWC_current_changetype == CHANGE_TIME) + } else if (HWC_current_changetype == CHANGE_TIME) { + mtx_unlock(&pThread_mtx_HWC_current_changetype); return CheckForHWCSetChange_TIME(countglops, time, thread_id); - else - return 0; + } + mtx_unlock(&pThread_mtx_HWC_current_changetype); + return 0; } /** @@ -324,7 +346,6 @@ int HWC_Check_Pending_Set_Change (UINT64 countglops, UINT64 time, int thread_id) void HWC_Initialize (int options) { int num_threads = Backend_getMaximumOfThreads(); - HWC_current_set = (int *)malloc(sizeof(int) * num_threads); ASSERT(HWC_current_set != NULL, "Cannot allocate memory for HWC_current_set"); memset (HWC_current_set, 0, sizeof(int) * num_threads); @@ -393,8 +414,9 @@ void HWC_Start_Counters (int num_threads, UINT64 time, int forked) HWC_Accum_Reset(i); } - if (HWC_num_sets <= 0) + if (HWC_num_sets <= 0) { return; + } HWCEnabled = TRUE; } @@ -403,6 +425,7 @@ void HWC_Start_Counters (int num_threads, UINT64 time, int forked) HWCEnabled = HWCBE_START_COUNTERS_THREAD (time, 0, forked); /* Inherit hwc set change values from thread 0 */ + mtx_rw_rdlock(&pThread_mtx_change_number_threads); for (i = 1; i < num_threads; i++) { /* @@ -414,6 +437,7 @@ void HWC_Start_Counters (int num_threads, UINT64 time, int forked) HWC_current_timebegin[i] = HWC_current_timebegin[0]; HWC_current_glopsbegin[i] = HWC_current_glopsbegin[0]; } + mtx_rw_unlock(&pThread_mtx_change_number_threads); } /** @@ -424,7 +448,6 @@ void HWC_Start_Counters (int num_threads, UINT64 time, int forked) void HWC_Restart_Counters (int old_num_threads, int new_num_threads) { int i; - #if defined(PAPI_COUNTERS) for (i = 0; i < HWC_num_sets; i++) HWCBE_PAPI_Allocate_eventsets_per_thread (i, old_num_threads, new_num_threads); @@ -588,12 +611,14 @@ int HWC_Read (unsigned int tid, UINT64 time, long long *store_buffer) if (HWCEnabled) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if (!HWC_Thread_Initialized[tid]) HWCBE_START_COUNTERS_THREAD(time, tid, FALSE); TOUCH_LASTFIELD( store_buffer ); read_ok = HWCBE_READ (tid, store_buffer); reset_ok = (Reset_After_Read ? HWCBE_RESET (tid) : TRUE); + mtx_rw_unlock(&pThread_mtx_change_number_threads); } return (HWCEnabled && read_ok && reset_ok); } @@ -629,6 +654,7 @@ int HWC_Accum (unsigned int tid, UINT64 time) if (HWCEnabled) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if (!HWC_Thread_Initialized[tid]) HWCBE_START_COUNTERS_THREAD(time, tid, FALSE); TOUCH_LASTFIELD( Accumulated_HWC[tid] ); @@ -642,6 +668,7 @@ int HWC_Accum (unsigned int tid, UINT64 time) #endif Accumulated_HWC_Valid[tid] = TRUE; + mtx_rw_unlock(&pThread_mtx_change_number_threads); } return (HWCEnabled && accum_ok); } @@ -665,7 +692,11 @@ int HWC_Accum_Reset (unsigned int tid) /** Returns whether Accumulated_HWC contains valid values or not */ int HWC_Accum_Valid_Values (unsigned int tid) { - return ( HWCEnabled ? Accumulated_HWC_Valid[tid] : 0 ); + int ret; + mtx_rw_rdlock(&pThread_mtx_change_number_threads); + ret = ( HWCEnabled ? Accumulated_HWC_Valid[tid] : 0 ); + mtx_rw_unlock(&pThread_mtx_change_number_threads); + return ret; } /** @@ -677,7 +708,9 @@ int HWC_Accum_Copy_Here (unsigned int tid, long long *store_buffer) { if (HWCEnabled) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); memcpy(store_buffer, Accumulated_HWC[tid], MAX_HWC * sizeof(long long)); + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 1; } else return 0; @@ -693,10 +726,12 @@ int HWC_Accum_Add_Here (unsigned int tid, long long *store_buffer) int i; if (HWCEnabled) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); for (i=0; i +#include "pthread_redirect.h" #if defined(IS_BGL_MACHINE) # define COUNTERS_INFO @@ -69,6 +71,8 @@ static HWC_Definition_t *hwc_used = NULL; static unsigned num_hwc_used = 0; +extern pthread_rwlock_t pThread_mtx_change_number_threads; + static void HWCBE_PAPI_AddDefinition (unsigned event_code, char *code, char *description) { int found = FALSE; @@ -381,8 +385,8 @@ int HWCBE_PAPI_Add_Set (int pretended_set, int rank, int ncounters, char **count Add_Overflows_To_Set (rank, num_set, pretended_set, num_overflows, overflow_counters, overflow_values); #endif - - return HWC_sets[num_set].num_counters; + int ret = HWC_sets[num_set].num_counters; + return ret; } #if defined(PAPI_SAMPLING_SUPPORT) @@ -408,7 +412,9 @@ int HWCBE_PAPI_Start_Set (UINT64 countglops, UINT64 time, int numset, int thread return FALSE; HWC_current_changeat = HWC_sets[numset].change_at; + mtx_lock(&pThread_mtx_HWC_current_changetype); HWC_current_changetype = HWC_sets[numset].change_type; + mtx_unlock(&pThread_mtx_HWC_current_changetype); HWC_current_timebegin[threadid] = time; HWC_current_glopsbegin[threadid] = countglops; @@ -499,7 +505,6 @@ void HWCBE_PAPI_CleanUp (unsigned nthreads) int state; int i; unsigned t; - if (PAPI_state (HWCEVTSET(THREADID), &state) == PAPI_OK) { if (state & PAPI_RUNNING) @@ -531,8 +536,7 @@ void HWCBE_PAPI_CleanUp (unsigned nthreads) } } #endif - xfree (HWC_sets); - + xfree (HWC_sets); PAPI_shutdown(); } } @@ -659,9 +663,9 @@ int HWCBE_PAPI_Init_Thread (UINT64 time, int threadid, int forked) #if defined(ENABLE_PEBS_SAMPLING) Extrae_IntelPEBS_startSampling(); -#endif - - return HWC_Thread_Initialized[threadid]; +#endif + int ret = HWC_Thread_Initialized[threadid]; + return ret; } #if defined(IS_BG_MACHINE) @@ -669,6 +673,7 @@ int __in_PAPI_read_BG = FALSE; #endif int HWCBE_PAPI_Read (unsigned int tid, long long *store_buffer) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); int EventSet = HWCEVTSET(tid); #if !defined(IS_BG_MACHINE) @@ -676,8 +681,10 @@ int HWCBE_PAPI_Read (unsigned int tid, long long *store_buffer) { fprintf (stderr, PACKAGE_NAME": PAPI_read failed for thread %d evtset %d (%s:%d)\n", tid, EventSet, __FILE__, __LINE__); + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 0; } + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 1; #else if (!__in_PAPI_read_BG) @@ -687,35 +694,45 @@ int HWCBE_PAPI_Read (unsigned int tid, long long *store_buffer) { fprintf (stderr, PACKAGE_NAME": PAPI_read failed for thread %d evtset %d (%s:%d)\n", tid, EventSet, __FILE__, __LINE__); + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 0; } __in_PAPI_read_BG = FALSE; + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 1; } - else + else { + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 0; + } #endif } int HWCBE_PAPI_Reset (unsigned int tid) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if (PAPI_reset(HWCEVTSET(tid)) != PAPI_OK) { fprintf (stderr, PACKAGE_NAME": PAPI_reset failed for thread %d evtset %d (%s:%d)\n", \ tid, HWCEVTSET(tid), __FILE__, __LINE__); + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 0; } + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 1; } int HWCBE_PAPI_Accum (unsigned int tid, long long *store_buffer) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if (PAPI_accum(HWCEVTSET(tid), store_buffer) != PAPI_OK) { fprintf (stderr, PACKAGE_NAME": PAPI_accum failed for thread %d evtset %d (%s:%d)\n", \ tid, HWCEVTSET(tid), __FILE__, __LINE__); - return 0; + mtx_rw_unlock(&pThread_mtx_change_number_threads); + return 0; } + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 1; } diff --git a/src/tracer/hwc/pmapi_hwc.c b/src/tracer/hwc/pmapi_hwc.c index c286c7df..fba2f12d 100644 --- a/src/tracer/hwc/pmapi_hwc.c +++ b/src/tracer/hwc/pmapi_hwc.c @@ -261,7 +261,9 @@ int HWCBE_PMAPI_Start_Set (UINT64 countglops, UINT64 time, int numset, int threa return FALSE; HWC_current_changeat = HWC_sets[numset].change_at; + mtx_lock(&pThread_mtx_HWC_current_changetype); HWC_current_changetype = HWC_sets[numset].change_type; + mtx_unlock(&pThread_mtx_HWC_current_changetype); HWC_current_timebegin[threadid] = time; HWC_current_glopsbegin[threadid] = countglops; diff --git a/src/tracer/mode.c b/src/tracer/mode.c index cac9083a..5508a570 100644 --- a/src/tracer/mode.c +++ b/src/tracer/mode.c @@ -45,6 +45,8 @@ int Starting_Trace_Mode = TRACE_MODE_DETAIL; unsigned long long BurstsMode_Threshold = 10000000; /* 10ms */ int BurstsMode_MPI_Stats = ENABLED; +extern pthread_rwlock_t pThread_mtx_change_number_threads; + static int is_ValidMode (int mode) { switch(mode) @@ -121,7 +123,11 @@ int Trace_Mode_reInitialize (int old_num_threads, int new_num_threads) int Trace_Mode_FirstMode (unsigned thread) { - return First_Trace_Mode[thread]; + int ret; + mtx_rw_rdlock(&pThread_mtx_change_number_threads); + ret = First_Trace_Mode[thread]; + mtx_rw_unlock(&pThread_mtx_change_number_threads); + return ret; } int Trace_Mode_Initialize (int num_threads) @@ -153,6 +159,7 @@ int Trace_Mode_Initialize (int num_threads) void Trace_Mode_Change (int tid, iotimer_t time) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if (Pending_Trace_Mode_Change[tid] || First_Trace_Mode[tid]) { if (Future_Trace_Mode[tid] != Current_Trace_Mode[tid] || First_Trace_Mode[tid]) @@ -173,6 +180,7 @@ void Trace_Mode_Change (int tid, iotimer_t time) Pending_Trace_Mode_Change[tid] = FALSE; First_Trace_Mode[tid] = FALSE; } + mtx_rw_unlock(&pThread_mtx_change_number_threads); } void @@ -180,17 +188,19 @@ Trace_mode_switch(void) { unsigned i; - /* + /* * XXX Should this be Backend_getMaximumOfThreads()? If we decrease the * number of threads, switch tracing mode and then increase again the the * number of threads, only the "old" threads will use burst mode, while the * "new" ones will continue in detail. */ + mtx_rw_rdlock(&pThread_mtx_change_number_threads); for (i=0; i + +int (*pthread_create_real)(pthread_t*,const pthread_attr_t*,void *(*) (void *),void*) = NULL; +int (*pthread_join_real)(pthread_t,void**) = NULL; +int (*pthread_detach_real)(pthread_t) = NULL; +void (*pthread_exit_real)(void*) = NULL; +int (*pthread_barrier_wait_real)(pthread_barrier_t *barrier) = NULL; + +int (*pthread_mutex_lock_real)(pthread_mutex_t*) = NULL; +int (*pthread_mutex_trylock_real)(pthread_mutex_t*) = NULL; +int (*pthread_mutex_timedlock_real)(pthread_mutex_t*,const struct timespec *) = NULL; +int (*pthread_mutex_unlock_real)(pthread_mutex_t*) = NULL; + +int (*pthread_cond_broadcast_real)(pthread_cond_t*) = NULL; +int (*pthread_cond_timedwait_real)(pthread_cond_t*,pthread_mutex_t*,const struct timespec *) = NULL; +int (*pthread_cond_signal_real)(pthread_cond_t*) = NULL; +int (*pthread_cond_wait_real)(pthread_cond_t*,pthread_mutex_t*) = NULL; + +int (*pthread_rwlock_rdlock_real)(pthread_rwlock_t *) = NULL; +int (*pthread_rwlock_tryrdlock_real)(pthread_rwlock_t *) = NULL; +int (*pthread_rwlock_timedrdlock_real)(pthread_rwlock_t *, const struct timespec *) = NULL; +int (*pthread_rwlock_wrlock_real)(pthread_rwlock_t *) = NULL; +int (*pthread_rwlock_trywrlock_real)(pthread_rwlock_t *) = NULL; +int (*pthread_rwlock_timedwrlock_real)(pthread_rwlock_t *, const struct timespec *) = NULL; +int (*pthread_rwlock_unlock_real)(pthread_rwlock_t *) = NULL; + +void GetpthreadHookPoints (int rank) +{ +#if defined(PIC) + /* Obtain @ for pthread_create */ + pthread_create_real = + (int(*)(pthread_t*,const pthread_attr_t*,void *(*) (void *),void*)) + dlsym (RTLD_NEXT, "pthread_create"); + if (pthread_create_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_create in DSOs!!\n"); + + /* Obtain @ for pthread_join */ + pthread_join_real = + (int(*)(pthread_t,void**)) dlsym (RTLD_NEXT, "pthread_join"); + if (pthread_join_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_join in DSOs!!\n"); + + /* Obtain @ for pthread_barrier_wait */ + pthread_barrier_wait_real = + (int(*)(pthread_barrier_t *)) dlsym (RTLD_NEXT, "pthread_barrier_wait"); + if (pthread_barrier_wait_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_barrier_wait in DSOs!!\n"); + + /* Obtain @ for pthread_detach */ + pthread_detach_real = (int(*)(pthread_t)) dlsym (RTLD_NEXT, "pthread_detach"); + if (pthread_detach_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_detach in DSOs!!\n"); + + /* Obtain @ for pthread_exit */ + pthread_exit_real = (void(*)(void*)) dlsym (RTLD_NEXT, "pthread_exit"); + if (pthread_exit_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_exit in DSOs!!\n"); + + /* Obtain @ for pthread_mutex_lock */ + pthread_mutex_lock_real = (int(*)(pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_mutex_lock"); + if (pthread_mutex_lock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_lock in DSOs!!\n"); + + /* Obtain @ for pthread_mutex_unlock */ + pthread_mutex_unlock_real = (int(*)(pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_mutex_unlock"); + if (pthread_mutex_unlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_unlock in DSOs!!\n"); + + /* Obtain @ for pthread_mutex_trylock */ + pthread_mutex_trylock_real = (int(*)(pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_mutex_trylock"); + if (pthread_mutex_trylock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_trylock in DSOs!!\n"); + + /* Obtain @ for pthread_mutex_timedlock */ + pthread_mutex_timedlock_real = (int(*)(pthread_mutex_t*,const struct timespec*)) dlsym (RTLD_NEXT, "pthread_mutex_timedlock"); + if (pthread_mutex_timedlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_mutex_timedlock in DSOs!!\n"); + + /* Obtain @ for pthread_cond_signal */ + pthread_cond_signal_real = (int(*)(pthread_cond_t*)) dlsym (RTLD_NEXT, "pthread_cond_signal"); + if (pthread_cond_signal_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_cond_signal in DSOs!!\n"); + + /* Obtain @ for pthread_cond_broadcast */ + pthread_cond_broadcast_real = (int(*)(pthread_cond_t*)) dlsym (RTLD_NEXT, "pthread_cond_broadcast"); + if (pthread_cond_broadcast_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_cond_broadcast in DSOs!!\n"); + + /* Obtain @ for pthread_cond_wait */ + pthread_cond_wait_real = (int(*)(pthread_cond_t*,pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_cond_wait"); + if (pthread_cond_wait_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_cond_wait in DSOs!!\n"); + + /* Obtain @ for pthread_cond_timedwait */ + pthread_cond_timedwait_real = (int(*)(pthread_cond_t*,pthread_mutex_t*,const struct timespec*)) dlsym (RTLD_NEXT, "pthread_cond_timedwait"); + if (pthread_cond_timedwait_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_cond_timedwait in DSOs!!\n"); + + /* Obtain @ for pthread_rwlock_rdlock */ + pthread_rwlock_rdlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_rdlock"); + if (pthread_rwlock_rdlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_rwlock_rdlock in DSOs!!\n"); + + /* Obtain @ for pthread_rwlock_tryrdlock */ + pthread_rwlock_tryrdlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_tryrdlock"); + if (pthread_rwlock_tryrdlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_rwlock_tryrdlock in DSOs!!\n"); + + /* Obtain @ for pthread_rwlock_timedrdlock */ + pthread_rwlock_timedrdlock_real = (int(*)(pthread_rwlock_t *, const struct timespec *)) dlsym (RTLD_NEXT, "pthread_rwlock_timedrdlock"); + if (pthread_rwlock_timedrdlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_rwlock_timedrdlock in DSOs!!\n"); + + /* Obtain @ for pthread_rwlock_rwlock */ + pthread_rwlock_wrlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_wrlock"); + if (pthread_rwlock_wrlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_rwlock_wrlock in DSOs!!\n"); + + /* Obtain @ for pthread_rwlock_tryrwlock */ + pthread_rwlock_trywrlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_trywrlock"); + if (pthread_rwlock_trywrlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_rwlock_trywrlock in DSOs!!\n"); + + /* Obtain @ for pthread_rwlock_timedrwlock */ + pthread_rwlock_timedwrlock_real = (int(*)(pthread_rwlock_t *, const struct timespec *)) dlsym (RTLD_NEXT, "pthread_rwlock_timedwrlock"); + if (pthread_rwlock_timedwrlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_rwlock_timedwrlock in DSOs!!\n"); + + /* Obtain @ for pthread_rwlock_unlock */ + pthread_rwlock_unlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_unlock"); + if (pthread_rwlock_unlock_real == NULL && rank == 0) + fprintf (stderr, "Unable to find pthread_rwlock_unlock in DSOs!!\n"); +#else + fprintf (stderr, "Warning! pthread instrumentation requires linking with shared library!\n"); +#endif /* PIC */ +} + +// #define DEBUG_PRINT_LOCKING + +#ifdef DEBUG_PRINT_LOCKING +#define LOCK_LVL_PADDING_FACTOR 1 +#define LOCK_LVL_NUM_LOCKS 200 +#define LOCK_LVL_MAX_LEN_HOSTNAME 100 + +static pthread_mutex_t mtx_output_stderr = PTHREAD_MUTEX_INITIALIZER; + +typedef struct lock_idx { + char name[LOCK_LVL_MAX_LEN_HOSTNAME]; + // more features? +} lock_idx; + +__thread int current_lock_level[LOCK_LVL_NUM_LOCKS*LOCK_LVL_PADDING_FACTOR]; // use padding to avoid false sharing +__thread lock_idx lock_assignments[LOCK_LVL_NUM_LOCKS*LOCK_LVL_PADDING_FACTOR]; // use padding to avoid false sharing +__thread int cur_idx = -1; +__thread int current_lock_level_init = 0; + +static void init_lock_level(){ + int i; + for(i = 0; i < LOCK_LVL_NUM_LOCKS; i++) { + current_lock_level[i*LOCK_LVL_PADDING_FACTOR] = 0; + } + current_lock_level_init = 1; +} + +static int get_lock_idx(const char *name) { + if (!current_lock_level_init) + init_lock_level(); + + int i; + for(i = 0; i <= cur_idx; i++) { + if(strcmp(name, lock_assignments[i*LOCK_LVL_PADDING_FACTOR].name) == 0) { + return i; + } + } + + int tmp_idx = ++cur_idx; + strncpy(lock_assignments[tmp_idx*LOCK_LVL_PADDING_FACTOR].name, name, strlen(name)); + return tmp_idx; +} + +static void mtx_print_message(const char *lock_type, const char *lock_name, int lock_name_idx, const char *caller_name, int before) { + char cur_host_name[LOCK_LVL_MAX_LEN_HOSTNAME]; + cur_host_name[LOCK_LVL_MAX_LEN_HOSTNAME-1] = '\0'; + gethostname(cur_host_name, LOCK_LVL_MAX_LEN_HOSTNAME-1); + pthread_mutex_lock_real(&mtx_output_stderr); + if(before) { + fprintf(stderr, "DEBUG_LOCK\t%s\tOS_TID:\t%ld\t%s\t%s\tBEFORE\tidx=%d\tLvl=%d\tCaller=%s\n", cur_host_name, syscall(SYS_gettid), lock_type, lock_name, lock_name_idx, current_lock_level[lock_name_idx], caller_name); + } else { + fprintf(stderr, "DEBUG_LOCK\t%s\tOS_TID:\t%ld\t%s\t%s\tAFTER\tidx=%d\tLvl=%d\tCaller=%s\n", cur_host_name, syscall(SYS_gettid), lock_type, lock_name, lock_name_idx, current_lock_level[lock_name_idx], caller_name); + } + fflush(stderr); + pthread_mutex_unlock_real(&mtx_output_stderr); +} +#endif /* DEBUG_PRINT_LOCKING */ + +void mtx_lock_caller(pthread_mutex_t* lock, const char *name, const char *caller_name) { + if(pthread_mutex_lock_real == NULL) + GetpthreadHookPoints(0); + +#ifdef DEBUG_PRINT_LOCKING + const char *lock_type = "mtx_lock"; + int tmp_idx = get_lock_idx(name); + mtx_print_message(lock_type, name, tmp_idx, caller_name, 1); +#endif + pthread_mutex_lock_real(lock); +#ifdef DEBUG_PRINT_LOCKING + current_lock_level[tmp_idx]++; + mtx_print_message(lock_type, name, tmp_idx, caller_name, 0); +#endif +} + +void mtx_unlock_caller(pthread_mutex_t* lock, const char *name, const char *caller_name){ +#ifdef DEBUG_PRINT_LOCKING + const char *lock_type = "mtx_unlock"; + int tmp_idx = get_lock_idx(name); + mtx_print_message(lock_type, name, tmp_idx, caller_name, 1); +#endif + pthread_mutex_unlock_real(lock); +#ifdef DEBUG_PRINT_LOCKING + current_lock_level[tmp_idx]--; + mtx_print_message(lock_type, name, tmp_idx, caller_name, 0); +#endif +} + +void mtx_rw_wrlock_caller(pthread_rwlock_t* lock, const char *name, const char *caller_name) { + if(pthread_rwlock_wrlock_real == NULL) + GetpthreadHookPoints(0); + +#ifdef DEBUG_PRINT_LOCKING + const char *lock_type = "mtx_rw_wrlock"; + int tmp_idx = get_lock_idx(name); + mtx_print_message(lock_type, name, tmp_idx, caller_name, 1); +#endif + pthread_rwlock_wrlock_real(lock); +#ifdef DEBUG_PRINT_LOCKING + current_lock_level[tmp_idx]++; + mtx_print_message(lock_type, name, tmp_idx, caller_name, 0); +#endif +} + +void mtx_rw_rdlock_caller(pthread_rwlock_t* lock, const char *name, const char *caller_name) { + if(pthread_rwlock_rdlock_real == NULL) + GetpthreadHookPoints(0); + +#ifdef DEBUG_PRINT_LOCKING + const char *lock_type = "mtx_rw_rdlock"; + int tmp_idx = get_lock_idx(name); + mtx_print_message(lock_type, name, tmp_idx, caller_name, 1); +#endif + pthread_rwlock_rdlock_real(lock); +#ifdef DEBUG_PRINT_LOCKING + current_lock_level[tmp_idx]++; + mtx_print_message(lock_type, name, tmp_idx, caller_name, 0); +#endif +} + +void mtx_rw_unlock_caller(pthread_rwlock_t* lock, const char *name, const char *caller_name) { +#ifdef DEBUG_PRINT_LOCKING + const char *lock_type = "mtx_rw_unlock"; + int tmp_idx = get_lock_idx(name); + mtx_print_message(lock_type, name, tmp_idx, caller_name, 1); +#endif + pthread_rwlock_unlock_real(lock); +#ifdef DEBUG_PRINT_LOCKING + current_lock_level[tmp_idx]--; + mtx_print_message(lock_type, name, tmp_idx, caller_name, 0); +#endif +} \ No newline at end of file diff --git a/src/tracer/pthread_redirect.h b/src/tracer/pthread_redirect.h new file mode 100644 index 00000000..efe9dafd --- /dev/null +++ b/src/tracer/pthread_redirect.h @@ -0,0 +1,92 @@ +#ifndef __PTHREAD_REDIRECT_H__ +#define __PTHREAD_REDIRECT_H__ + +#include "common.h" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#ifdef HAVE_PTHREAD_H +# include +#endif +#ifdef HAVE_DLFCN_H +# define __USE_GNU +# include +# undef __USE_GNU +#endif +#ifdef HAVE_STDIO_H +# include +#endif +#ifdef HAVE_STDLIB_H +# include +#endif +#ifdef HAVE_TIME_H +# include +#endif + +#include +#include +#include +#include +#include + +extern int (*pthread_create_real)(pthread_t*,const pthread_attr_t*,void *(*) (void *),void*); +extern int (*pthread_join_real)(pthread_t,void**); +extern int (*pthread_detach_real)(pthread_t); +extern void (*pthread_exit_real)(void*); +extern int (*pthread_barrier_wait_real)(pthread_barrier_t *barrier); + +extern int (*pthread_mutex_lock_real)(pthread_mutex_t*); +extern int (*pthread_mutex_trylock_real)(pthread_mutex_t*); +extern int (*pthread_mutex_timedlock_real)(pthread_mutex_t*,const struct timespec *); +extern int (*pthread_mutex_unlock_real)(pthread_mutex_t*); + +extern int (*pthread_cond_broadcast_real)(pthread_cond_t*); +extern int (*pthread_cond_timedwait_real)(pthread_cond_t*,pthread_mutex_t*,const struct timespec *); +extern int (*pthread_cond_signal_real)(pthread_cond_t*); +extern int (*pthread_cond_wait_real)(pthread_cond_t*,pthread_mutex_t*); + +extern int (*pthread_rwlock_rdlock_real)(pthread_rwlock_t *); +extern int (*pthread_rwlock_tryrdlock_real)(pthread_rwlock_t *); +extern int (*pthread_rwlock_timedrdlock_real)(pthread_rwlock_t *, const struct timespec *); +extern int (*pthread_rwlock_wrlock_real)(pthread_rwlock_t *); +extern int (*pthread_rwlock_trywrlock_real)(pthread_rwlock_t *); +extern int (*pthread_rwlock_timedwrlock_real)(pthread_rwlock_t *, const struct timespec *); +extern int (*pthread_rwlock_unlock_real)(pthread_rwlock_t *); + +int GetpThreadIdentifier (void); + +// ============================= Locking helper =================================== +void mtx_lock_caller(pthread_mutex_t* lock, const char *name, const char *caller_name); + +void mtx_unlock_caller(pthread_mutex_t* lock, const char *name, const char *caller_name); + +void mtx_rw_wrlock_caller(pthread_rwlock_t* lock, const char *name, const char *caller_name); + +void mtx_rw_rdlock_caller(pthread_rwlock_t* lock, const char *name, const char *caller_name); + +void mtx_rw_unlock_caller(pthread_rwlock_t* lock, const char *name, const char *caller_name); + +#ifndef mtx_lock +#define mtx_lock(mtx) mtx_lock_caller(mtx, #mtx, __func__) +#endif + +#ifndef mtx_unlock +#define mtx_unlock(mtx) mtx_unlock_caller(mtx, #mtx, __func__) +#endif + +#ifndef mtx_rw_wrlock +#define mtx_rw_wrlock(mtx) mtx_rw_wrlock_caller(mtx, #mtx, __func__) +#endif + +#ifndef mtx_rw_rdlock +#define mtx_rw_rdlock(mtx) mtx_rw_rdlock_caller(mtx, #mtx, __func__) +#endif + +#ifndef mtx_rw_unlock +#define mtx_rw_unlock(mtx) mtx_rw_unlock_caller(mtx, #mtx, __func__) +#endif + +#endif \ No newline at end of file diff --git a/src/tracer/signals.c b/src/tracer/signals.c index 094d873e..8aa72658 100644 --- a/src/tracer/signals.c +++ b/src/tracer/signals.c @@ -42,6 +42,7 @@ # include # endif #endif +#include "pthread_redirect.h" /* #define DBG_SIGNALS */ @@ -50,21 +51,31 @@ * Flushes the buffers to disk and disables tracing * ----------------------------------------------------------------------- */ -int sigInhibited = FALSE; +volatile int sigInhibited = FALSE; + +static pthread_mutex_t pThread_mtx_sigInhibited = PTHREAD_MUTEX_INITIALIZER; void Signals_Inhibit() { + mtx_lock(&pThread_mtx_sigInhibited); sigInhibited = TRUE; + mtx_unlock(&pThread_mtx_sigInhibited); } void Signals_Desinhibit() { + mtx_lock(&pThread_mtx_sigInhibited); sigInhibited = FALSE; + mtx_unlock(&pThread_mtx_sigInhibited); } int Signals_Inhibited() { - return sigInhibited; + int ret; + mtx_lock(&pThread_mtx_sigInhibited); + ret = sigInhibited; + mtx_unlock(&pThread_mtx_sigInhibited); + return ret; } int Deferred_Signal_FlushAndTerminate = FALSE; @@ -220,20 +231,20 @@ void Signals_CondInit (Condition_t *cond) void Signals_CondWait (Condition_t *cond) { - pthread_mutex_lock(&(cond->ConditionMutex)); + mtx_lock(&(cond->ConditionMutex)); while (cond->WaitingForCondition) { pthread_cond_wait(&(cond->WaitCondition), &(cond->ConditionMutex)); } - pthread_mutex_unlock(&(cond->ConditionMutex)); + mtx_unlock(&(cond->ConditionMutex)); } void Signals_CondWakeUp (Condition_t *cond) { - pthread_mutex_lock(&(cond->ConditionMutex)); + mtx_lock(&(cond->ConditionMutex)); cond->WaitingForCondition = FALSE; pthread_cond_signal(&(cond->WaitCondition)); - pthread_mutex_unlock(&(cond->ConditionMutex)); + mtx_unlock(&(cond->ConditionMutex)); } #endif /* HAVE_ONLINE */ diff --git a/src/tracer/wrappers/API/buffers.c b/src/tracer/wrappers/API/buffers.c index f59b8b36..fd210d2b 100644 --- a/src/tracer/wrappers/API/buffers.c +++ b/src/tracer/wrappers/API/buffers.c @@ -55,6 +55,9 @@ #include "buffers.h" #include "utils.h" +#include "pthread_redirect.h" + +extern pthread_rwlock_t pThread_mtx_change_number_threads; #define EVENT_INDEX(buffer, event) (event - Buffer_GetFirst(buffer)) #define ALL_BITS_SET 0xFFFFFFFF @@ -75,12 +78,12 @@ static void DataBlocks_Free (DataBlocks_t *blocks); Buffer_t * new_Buffer (int n_events, char *file, int enable_cache) { Buffer_t *buffer = NULL; -#if defined(HAVE_ONLINE) +// #if defined(HAVE_ONLINE) #if 0 pthread_mutexattr_t attr; #endif int rc; -#endif +// #endif xmalloc(buffer, sizeof(Buffer_t)); buffer->FillCount = 0; @@ -116,7 +119,7 @@ Buffer_t * new_Buffer (int n_events, char *file, int enable_cache) } } -#if defined(HAVE_ONLINE) +// #if defined(HAVE_ONLINE) #if 0 pthread_mutexattr_init( &attr ); pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE_NP ); @@ -139,7 +142,7 @@ Buffer_t * new_Buffer (int n_events, char *file, int enable_cache) exit(1); } #endif -#endif +// #endif xmalloc(buffer->Masks, n_events * sizeof(Mask_t)); Mask_Wipe(buffer); @@ -163,9 +166,9 @@ void Buffer_Free (Buffer_t *buffer) if (buffer != NULL) { xfree (buffer->FirstEvt); -#if defined(HAVE_ONLINE) +// #if defined(HAVE_ONLINE) pthread_mutex_destroy(&(buffer->Lock)); -#endif +// #endif xfree (buffer->Masks); xfree (buffer->CachedEvents); @@ -355,20 +358,20 @@ event_t * Buffer_GetNext (Buffer_t *buffer, event_t *current) void Buffer_Lock (Buffer_t *buffer) { -#if defined(HAVE_ONLINE) - pthread_mutex_lock(&(buffer->Lock)); -#else - UNREFERENCED_PARAMETER(buffer); -#endif +// #if defined(HAVE_ONLINE) + mtx_lock(&(buffer->Lock)); +// #else +// UNREFERENCED_PARAMETER(buffer); +// #endif } void Buffer_Unlock (Buffer_t *buffer) { -#if defined(HAVE_ONLINE) - pthread_mutex_unlock(&(buffer->Lock)); -#else - UNREFERENCED_PARAMETER(buffer); -#endif +// #if defined(HAVE_ONLINE) + mtx_unlock(&(buffer->Lock)); +// #else +// UNREFERENCED_PARAMETER(buffer); +// #endif } /* @@ -462,6 +465,7 @@ void Buffer_InsertSingle(Buffer_t *buffer, event_t *new_event) { #if defined(LOCK_AT_INSERT) Buffer_Lock (buffer); + mtx_rw_rdlock(&pThread_mtx_change_number_threads); #endif if (Buffer_IsFull (buffer)) @@ -480,6 +484,7 @@ void Buffer_InsertSingle(Buffer_t *buffer, event_t *new_event) buffer->FillCount ++; #if defined(LOCK_AT_INSERT) + mtx_rw_unlock(&pThread_mtx_change_number_threads); Buffer_Unlock (buffer); #endif } diff --git a/src/tracer/wrappers/API/buffers.h b/src/tracer/wrappers/API/buffers.h index d31d067e..47d1d31a 100644 --- a/src/tracer/wrappers/API/buffers.h +++ b/src/tracer/wrappers/API/buffers.h @@ -56,9 +56,9 @@ struct Buffer int fd; -#if defined(HAVE_ONLINE) +// #if defined(HAVE_ONLINE) pthread_mutex_t Lock; -#endif +// #endif Mask_t *Masks; int (*FlushCallback)(struct Buffer *); diff --git a/src/tracer/wrappers/API/trace_buffers.h b/src/tracer/wrappers/API/trace_buffers.h index c943072b..a71a215e 100644 --- a/src/tracer/wrappers/API/trace_buffers.h +++ b/src/tracer/wrappers/API/trace_buffers.h @@ -26,6 +26,7 @@ #include "buffers.h" #include "signals.h" +#include "pthread_redirect.h" /* Don't like these externs -> Declare fetch functions in wrapper.c and include prototypes in wrapper.h ? */ extern Buffer_t **TracingBuffer; diff --git a/src/tracer/wrappers/API/wrapper.c b/src/tracer/wrappers/API/wrapper.c index 2c23b014..19419444 100644 --- a/src/tracer/wrappers/API/wrapper.c +++ b/src/tracer/wrappers/API/wrapper.c @@ -23,6 +23,14 @@ #include "common.h" +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include + #ifdef HAVE_STDIO_H # include #endif @@ -153,11 +161,14 @@ #include "syscall_probe.h" #include "syscall_wrapper.h" #include "taskid.h" +#include "pthread_redirect.h" int Extrae_Flush_Wrapper (Buffer_t *buffer); static int requestedDynamicMemoryInstrumentation = FALSE; +pthread_rwlock_t pThread_mtx_change_number_threads = PTHREAD_RWLOCK_INITIALIZER; +static pthread_rwlock_t pThread_mtx_Extrae_inInstrumentation = PTHREAD_RWLOCK_INITIALIZER; #if defined(STANDALONE) module_t *Modules = NULL; @@ -316,11 +327,13 @@ char tmp_dir[TMP_DIR_LEN]; int PENDING_TRACE_CPU_EVENT(int thread_id, iotimer_t current_time) { + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if ((LastCPUEmissionTime[thread_id] == 0) || (((current_time - LastCPUEmissionTime[thread_id]) > MinimumCPUEventTime) && MinimumCPUEventTime > 0)) { LastCPUEmissionTime[thread_id] = current_time; + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 1; } - + mtx_rw_unlock(&pThread_mtx_change_number_threads); return 0; } @@ -487,11 +500,17 @@ void Extrae_AnnotateCPU (UINT64 timestamp) #if defined(HAVE_SCHED_GETCPU) int cpu = sched_getcpu(); + mtx_rw_rdlock(&pThread_mtx_change_number_threads); + int unlocked = 0; if (cpu != LastCPUEvent[THREADID] || AlwaysEmitCPUEvent) { LastCPUEvent[THREADID] = cpu; + mtx_rw_unlock(&pThread_mtx_change_number_threads); + unlocked = 1; TRACE_EVENT (timestamp, GETCPU_EV, cpu); } + if(!unlocked) + mtx_rw_unlock(&pThread_mtx_change_number_threads); #else UNREFERENCED_PARAMETER(timestamp); #endif @@ -1434,7 +1453,6 @@ static int Allocate_buffers_and_files (int world_size, int num_threads, int fork for (i = 0; i < num_threads; i++) Allocate_buffer_and_file (i, forked); - return TRUE; } @@ -1453,10 +1471,8 @@ static int Reallocate_buffers_and_files (int new_num_threads) #if defined(SAMPLING_SUPPORT) xrealloc(SamplingBuffer, SamplingBuffer, new_num_threads * sizeof(Buffer_t *)); #endif - for (i = get_maximum_NumOfThreads(); i < new_num_threads; i++) Allocate_buffer_and_file (i, FALSE); - return TRUE; } @@ -1548,7 +1564,7 @@ void Backend_Flush_pThread (pthread_t t) // Protect race condition with the master thread flushing the buffers at // the end of this pthread and the process - pthread_mutex_lock(&pthreadFreeBuffer_mtx); + mtx_lock(&pthreadFreeBuffer_mtx); // TracingBuffer may have been already free'd by the master thread if the process finished if (TracingBuffer != NULL) @@ -1574,7 +1590,7 @@ void Backend_Flush_pThread (pthread_t t) } #endif - pthread_mutex_unlock(&pthreadFreeBuffer_mtx); + mtx_unlock(&pthreadFreeBuffer_mtx); break; } @@ -1601,13 +1617,13 @@ void Backend_NotifyNewPthread (void) { int numthreads; - pthread_mutex_lock (&pThreadIdentifier_mtx); + mtx_lock(&pThreadIdentifier_mtx); numthreads = Backend_getNumberOfThreads(); Backend_SetpThreadIdentifier (numthreads); Backend_ChangeNumberOfThreads (numthreads+1); - pthread_mutex_unlock (&pThreadIdentifier_mtx); + mtx_unlock (&pThreadIdentifier_mtx); } #endif @@ -1961,11 +1977,17 @@ int Backend_ChangeNumberOfThreads (unsigned numberofthreads) { unsigned new_num_threads = numberofthreads; + mtx_rw_wrlock(&pThread_mtx_change_number_threads); + if (EXTRAE_INITIALIZED()) { /* Just modify things if there are more threads */ if (new_num_threads > get_maximum_NumOfThreads()) { + // char cur_host_name[100]; + // cur_host_name[99] = '\0'; + // gethostname(cur_host_name, 99); + // fprintf(stderr, "%s OS_TID:%ld Start Backend_ChangeNumberOfThreads: %d\n", cur_host_name, syscall(SYS_gettid), new_num_threads); unsigned u; #if defined(ENABLE_PEBS_SAMPLING) @@ -2013,7 +2035,7 @@ int Backend_ChangeNumberOfThreads (unsigned numberofthreads) #if defined(ENABLE_PEBS_SAMPLING) Extrae_IntelPEBS_resumeSampling(); #endif - + // fprintf(stderr, "%s OS_TID:%ld End Backend_ChangeNumberOfThreads: %d\n", cur_host_name, syscall(SYS_gettid), new_num_threads); } else current_NumOfThreads = new_num_threads; @@ -2026,6 +2048,8 @@ int Backend_ChangeNumberOfThreads (unsigned numberofthreads) current_NumOfThreads = new_num_threads; } + mtx_rw_unlock(&pThread_mtx_change_number_threads); + return TRUE; } @@ -2442,7 +2466,7 @@ void Backend_Finalize (void) for (thread = 0; thread < get_maximum_NumOfThreads(); thread++) { // Protects race condition with Backend_Flush_pThread - pthread_mutex_lock(&pthreadFreeBuffer_mtx); + mtx_lock(&pthreadFreeBuffer_mtx); // If buffer was working in circular mode, change it to flush mode to dump the final data into the trace if ((circular_buffering) && (!online_mode)) @@ -2459,7 +2483,7 @@ void Backend_Finalize (void) Extrae_Flush_Wrapper_setCounters (TRUE); - pthread_mutex_unlock(&pthreadFreeBuffer_mtx); + mtx_unlock(&pthreadFreeBuffer_mtx); } /* Final write files to disk, include renaming of the filenames, @@ -2468,7 +2492,7 @@ void Backend_Finalize (void) for (thread = 0; thread < get_maximum_NumOfThreads(); thread++) { // Protects race condition with Backend_Flush_pThread - pthread_mutex_lock(&pthreadFreeBuffer_mtx); + mtx_lock(&pthreadFreeBuffer_mtx); if (TRACING_BUFFER(thread) != NULL) { @@ -2477,7 +2501,7 @@ void Backend_Finalize (void) Backend_Finalize_close_mpits (getpid(), thread, FALSE); } - pthread_mutex_unlock(&pthreadFreeBuffer_mtx); + mtx_unlock(&pthreadFreeBuffer_mtx); } /* Free allocated memory */ @@ -2491,7 +2515,7 @@ void Backend_Finalize (void) pThreads[thread] = (pthread_t)0; #endif // Protects race condition with Backend_Flush_pThread - pthread_mutex_lock(&pthreadFreeBuffer_mtx); + mtx_lock(&pthreadFreeBuffer_mtx); if (TRACING_BUFFER(thread) != NULL) { Buffer_Free (TRACING_BUFFER(thread)); @@ -2504,7 +2528,7 @@ void Backend_Finalize (void) SAMPLING_BUFFER(thread) = NULL; } #endif - pthread_mutex_unlock(&pthreadFreeBuffer_mtx); + mtx_unlock(&pthreadFreeBuffer_mtx); } xfree(LastCPUEmissionTime); xfree(LastCPUEvent); @@ -2573,14 +2597,14 @@ void Backend_Finalize (void) int pid; Extrae_getAppendingEventsToGivenPID (&pid); // Protects race condition with Backend_Flush_pThread - pthread_mutex_lock(&pthreadFreeBuffer_mtx); + mtx_lock(&pthreadFreeBuffer_mtx); if (TRACING_BUFFER(THREADID) != NULL) { Buffer_Flush(TRACING_BUFFER(THREADID)); for (thread = 0; thread < get_maximum_NumOfThreads(); thread++) Backend_Finalize_close_mpits (pid, thread, TRUE); } - pthread_mutex_unlock(&pthreadFreeBuffer_mtx); + mtx_unlock(&pthreadFreeBuffer_mtx); remove_temporal_files (); } } @@ -2591,26 +2615,33 @@ static int *Extrae_inSampling = NULL; int Backend_inInstrumentation (unsigned thread) { + mtx_rw_rdlock(&pThread_mtx_Extrae_inInstrumentation); + int ret = FALSE; if ((Extrae_inInstrumentation != NULL) && (Extrae_inSampling != NULL)) - return (Extrae_inInstrumentation[thread] || Extrae_inSampling[thread]); - else - return FALSE; + ret = (Extrae_inInstrumentation[thread] || Extrae_inSampling[thread]); + mtx_rw_unlock(&pThread_mtx_Extrae_inInstrumentation); + return ret; } -void Backend_setInSampling (unsigned thread, int insampling) -{ - if (Extrae_inSampling != NULL) - Extrae_inSampling[thread] = insampling; -} +void Backend_setInSampling (unsigned thread, int insampling) +{ + mtx_rw_rdlock(&pThread_mtx_Extrae_inInstrumentation); + if (Extrae_inSampling != NULL) + Extrae_inSampling[thread] = insampling; + mtx_rw_unlock(&pThread_mtx_Extrae_inInstrumentation); +} void Backend_setInInstrumentation (unsigned thread, int ininstrumentation) { + mtx_rw_wrlock(&pThread_mtx_Extrae_inInstrumentation); if (Extrae_inInstrumentation != NULL) Extrae_inInstrumentation[thread] = ininstrumentation; + mtx_rw_unlock(&pThread_mtx_Extrae_inInstrumentation); } void Backend_ChangeNumberOfThreads_InInstrumentation (unsigned nthreads) { + mtx_rw_wrlock(&pThread_mtx_Extrae_inInstrumentation); Extrae_inInstrumentation = (int*) realloc (Extrae_inInstrumentation, sizeof(int)*nthreads); if (Extrae_inInstrumentation == NULL) { @@ -2625,6 +2656,7 @@ void Backend_ChangeNumberOfThreads_InInstrumentation (unsigned nthreads) ": Failed to allocate memory for inSampling structure\n"); exit (-1); } + mtx_rw_unlock(&pThread_mtx_Extrae_inInstrumentation); } void Backend_Enter_Instrumentation () @@ -2638,6 +2670,7 @@ void Backend_Enter_Instrumentation () Backend_setInInstrumentation (thread, TRUE); /* Check if we have to fill the sampling buffer */ + mtx_rw_rdlock(&pThread_mtx_change_number_threads); #if defined(SAMPLING_SUPPORT) if (Extrae_get_DumpBuffersAtInstrumentation()) if (Buffer_IsFull (SAMPLING_BUFFER(THREADID))) @@ -2677,14 +2710,14 @@ void Backend_Enter_Instrumentation () /* Check whether we will fill the buffer soon (or now) */ if (Buffer_RemainingEvents(TracingBuffer[thread]) <= NEVENTS) Buffer_ExecuteFlushCallback (TracingBuffer[thread]); - + mtx_rw_unlock(&pThread_mtx_change_number_threads); /* Record the time when this is happening we need this for subsequent calls to TIME, as this is being cached in clock routines */ current_time = TIME; if (Trace_Mode_FirstMode(thread)) - Trace_Mode_Change (thread, current_time); + Trace_Mode_Change (thread, current_time); #if defined(PAPI_COUNTERS) || defined(PMAPI_COUNTERS) /* Must change counters? check only at detail tracing, at bursty @@ -2710,8 +2743,10 @@ void Backend_Leave_Instrumentation (void) } /* Change trace mode? (issue from API) */ + mtx_rw_rdlock(&pThread_mtx_change_number_threads); if (PENDING_TRACE_MODE_CHANGE(thread) && MPI_Deepness[thread] == 0) Trace_Mode_Change(thread, LAST_READ_TIME); + mtx_rw_unlock(&pThread_mtx_change_number_threads); Backend_setInInstrumentation (thread, FALSE); } diff --git a/src/tracer/wrappers/MALLOC/malloc_wrapper.c b/src/tracer/wrappers/MALLOC/malloc_wrapper.c index aef13f5a..849f5075 100644 --- a/src/tracer/wrappers/MALLOC/malloc_wrapper.c +++ b/src/tracer/wrappers/MALLOC/malloc_wrapper.c @@ -98,7 +98,7 @@ static void Extrae_malloctrace_add (void *p, size_t s) unsigned u; assert (real_realloc != NULL); - pthread_mutex_lock (&mutex_allocations); + mtx_lock(&mutex_allocations); if (nmallocentries == nmallocentries_allocated) { @@ -124,7 +124,7 @@ static void Extrae_malloctrace_add (void *p, size_t s) break; } - pthread_mutex_unlock (&mutex_allocations); + mtx_unlock(&mutex_allocations); } } @@ -136,7 +136,7 @@ static int Extrae_malloctrace_remove (const void *p) { unsigned u; - pthread_mutex_lock (&mutex_allocations); + mtx_lock(&mutex_allocations); for (u = 0; u < nmallocentries_allocated; u++) if (mallocentries[u] == p) @@ -148,7 +148,7 @@ static int Extrae_malloctrace_remove (const void *p) break; } - pthread_mutex_unlock (&mutex_allocations); + mtx_unlock(&mutex_allocations); } return found; } @@ -157,7 +157,7 @@ static size_t Extrae_malloctrace_replace (const void *p1, void *p2, size_t s) { size_t prev_sz = 0; - pthread_mutex_lock (&mutex_allocations); + mtx_lock(&mutex_allocations); int replaced = FALSE; if (p1) @@ -206,7 +206,7 @@ static size_t Extrae_malloctrace_replace (const void *p1, void *p2, size_t s) } } - pthread_mutex_unlock (&mutex_allocations); + mtx_unlock(&mutex_allocations); return prev_sz; } diff --git a/src/tracer/wrappers/MPI/hash_table.c b/src/tracer/wrappers/MPI/hash_table.c index e7acd050..95fda38b 100644 --- a/src/tracer/wrappers/MPI/hash_table.c +++ b/src/tracer/wrappers/MPI/hash_table.c @@ -27,7 +27,7 @@ #include #include #include "hash_table.h" - +#include "pthread_redirect.h" /*** Prototypes ***/ static inline int xtr_hash_search (xtr_hash_t *hash, uintptr_t key, xtr_hash_cell_t **previous_out, xtr_hash_cell_t **cell_out) __attribute__((always_inline)); @@ -165,7 +165,7 @@ int xtr_hash_add (xtr_hash_t *hash, uintptr_t key, void *data) if (hash->flags & XTR_HASH_LOCK) { - pthread_rwlock_wrlock(&hash->lock); + mtx_rw_wrlock(&hash->lock); } #if defined(DEBUG) @@ -199,7 +199,7 @@ int xtr_hash_add (xtr_hash_t *hash, uintptr_t key, void *data) if (hash->flags & XTR_HASH_LOCK) { - pthread_rwlock_unlock(&hash->lock); + mtx_rw_unlock(&hash->lock); } return 1; @@ -263,7 +263,7 @@ int xtr_hash_query (xtr_hash_t *hash, uintptr_t key, void *data) if (hash->flags & XTR_HASH_LOCK) { - pthread_rwlock_rdlock(&hash->lock); + mtx_rw_rdlock(&hash->lock); } #if defined(DEBUG) @@ -283,7 +283,7 @@ int xtr_hash_query (xtr_hash_t *hash, uintptr_t key, void *data) if (hash->flags & XTR_HASH_LOCK) { - pthread_rwlock_unlock(&hash->lock); + mtx_rw_unlock(&hash->lock); } return 0; @@ -308,7 +308,7 @@ int xtr_hash_fetch (xtr_hash_t * hash, uintptr_t key, void *data) if (hash->flags & XTR_HASH_LOCK) { - pthread_rwlock_wrlock(&hash->lock); + mtx_rw_wrlock(&hash->lock); } #if defined(DEBUG) @@ -341,7 +341,7 @@ int xtr_hash_fetch (xtr_hash_t * hash, uintptr_t key, void *data) if (hash->flags & XTR_HASH_LOCK) { - pthread_rwlock_unlock(&hash->lock); + mtx_rw_unlock(&hash->lock); } return found; diff --git a/src/tracer/wrappers/MPI/mpi_wrapper.c b/src/tracer/wrappers/MPI/mpi_wrapper.c index 36d5f867..bab17c66 100644 --- a/src/tracer/wrappers/MPI/mpi_wrapper.c +++ b/src/tracer/wrappers/MPI/mpi_wrapper.c @@ -85,6 +85,8 @@ # define MPI_F_STATUSES_IGNORE ((MPI_Fint *) 0) #endif +extern pthread_rwlock_t pThread_mtx_change_number_threads; + /* He d'incloure la capc,alera del misc_wrapper per poder comenc,ar a tracejar quan es cridi al MPI_init i acabar al MPI_Finalize. @@ -264,7 +266,8 @@ void translateLocalToGlobalRank (MPI_Comm comm, MPI_Group group, int partner_loc PMPI_Group_size(remote_group, &remote_group_size); local_ranks = (int *)malloc(sizeof(int) * remote_group_size); world_ranks = (int *)malloc(sizeof(int) * remote_group_size); - for (int i = 0; i < remote_group_size; i++) local_ranks[i] = i; + int i; + for (i = 0; i < remote_group_size; i++) local_ranks[i] = i; PMPI_Group_translate_ranks (remote_group, remote_group_size, local_ranks, CommWorldRanks, world_ranks); @@ -342,8 +345,10 @@ static void Traceja_Persistent_Request (MPI_Request* reqid, iotimer_t temps) * tag : message tag or MPI_ANY_TAG commid: Communicator id * aux: request id */ + mtx_rw_rdlock(&pThread_mtx_change_number_threads); TRACE_MPIEVENT_NOHWC (temps, MPI_PERSIST_REQ_EV, p_request->tipus, src_world, size, p_request->tag, p_request->comm, p_request->req); + mtx_rw_unlock(&pThread_mtx_change_number_threads); } @@ -3115,8 +3120,9 @@ void ProcessRequest(iotimer_t ts, MPI_Request request, MPI_Status *status) if (cancel_flag) { // Communication was cancelled + mtx_rw_rdlock(&pThread_mtx_change_number_threads); TRACE_MPIEVENT_NOHWC (ts, MPI_REQUEST_CANCELLED_EV, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, request); - + mtx_rw_unlock(&pThread_mtx_change_number_threads); CancelRequest(request); } else @@ -3135,8 +3141,9 @@ void ProcessRequest(iotimer_t ts, MPI_Request request, MPI_Status *status) getCommDataFromStatus(status, MPI_BYTE, request_data.commid, request_data.group, &size, &tag, &src_world); updateStats_P2P(global_mpi_stats, src_world, size, 0); - + mtx_rw_rdlock(&pThread_mtx_change_number_threads); TRACE_MPIEVENT_NOHWC (ts, MPI_IRECVED_EV, EMPTY, src_world, size, tag, request_data.commid, request); + mtx_rw_unlock(&pThread_mtx_change_number_threads); } else { @@ -3145,7 +3152,9 @@ void ProcessRequest(iotimer_t ts, MPI_Request request, MPI_Status *status) /* This case would also trigger if a receive request was not found in the hash (e.g. hash full) This should not happen unless there's errors in xtr_hash_add or we've missed instrumenting any recv calls. */ + mtx_rw_rdlock(&pThread_mtx_change_number_threads); TRACE_MPIEVENT_NOHWC (ts, MPI_IRECVED_EV, EMPTY, EMPTY, EMPTY, status->MPI_TAG, EMPTY, request); + mtx_rw_unlock(&pThread_mtx_change_number_threads); } } } diff --git a/src/tracer/wrappers/OMP/ompt-helper.c b/src/tracer/wrappers/OMP/ompt-helper.c index c5b4a0bd..56654b59 100644 --- a/src/tracer/wrappers/OMP/ompt-helper.c +++ b/src/tracer/wrappers/OMP/ompt-helper.c @@ -34,7 +34,7 @@ #endif #include "ompt-helper.h" - +#include "pthread_redirect.h" /* Relation between parallel id and parallel function */ typedef struct ompt_parallel_id_pf_st @@ -165,8 +165,8 @@ void Extrae_OMPT_register_ompt_task_id_tf (ompt_task_id_t ompt_tid, const void *tf, int implicit) { unsigned u; - - pthread_rwlock_wrlock (&mutex_tid_tf); + + mtx_rw_wrlock(&mutex_tid_tf); if (n_ompt_tids_tf == n_allocated_ompt_tids_tf) { #if defined(DEBUG) @@ -205,7 +205,7 @@ void Extrae_OMPT_register_ompt_task_id_tf (ompt_task_id_t ompt_tid, #endif break; } - pthread_rwlock_unlock (&mutex_tid_tf); + mtx_rw_unlock(&mutex_tid_tf); } /* Extrae_OMPT_unregister_ompt_task_id_tf @@ -217,7 +217,7 @@ void Extrae_OMPT_unregister_ompt_task_id_tf (ompt_task_id_t ompt_tid) { unsigned u; - pthread_rwlock_wrlock (&mutex_tid_tf); + mtx_rw_wrlock(&mutex_tid_tf); for (u = 0; u < n_allocated_ompt_tids_tf; u++) if (ompt_tids_tf[u].tid == ompt_tid) { @@ -230,7 +230,7 @@ void Extrae_OMPT_unregister_ompt_task_id_tf (ompt_task_id_t ompt_tid) #endif break; } - pthread_rwlock_unlock (&mutex_tid_tf); + mtx_rw_unlock(&mutex_tid_tf); } } @@ -242,7 +242,7 @@ const void * Extrae_OMPT_get_tf_task_id (ompt_task_id_t ompt_tid, unsigned u; const void *ptr = NULL; - pthread_rwlock_rdlock (&mutex_tid_tf); + mtx_rw_rdlock(&mutex_tid_tf); for (u = 0; u < n_allocated_ompt_tids_tf; u++) if (ompt_tids_tf[u].tid == ompt_tid) { @@ -253,7 +253,7 @@ const void * Extrae_OMPT_get_tf_task_id (ompt_task_id_t ompt_tid, *taskctr = ompt_tids_tf[u].task_ctr; break; } - pthread_rwlock_unlock (&mutex_tid_tf); + mtx_rw_unlock(&mutex_tid_tf); return ptr; } @@ -264,7 +264,7 @@ void Extrae_OMPT_tf_task_id_set_running (ompt_task_id_t ompt_tid, int b) { unsigned u; - pthread_rwlock_rdlock (&mutex_tid_tf); + mtx_rw_rdlock(&mutex_tid_tf); for (u = 0; u < n_allocated_ompt_tids_tf; u++) if (ompt_tids_tf[u].tid == ompt_tid) @@ -273,7 +273,7 @@ void Extrae_OMPT_tf_task_id_set_running (ompt_task_id_t ompt_tid, int b) break; } - pthread_rwlock_unlock (&mutex_tid_tf); + mtx_rw_unlock(&mutex_tid_tf); } @@ -285,7 +285,7 @@ int Extrae_OMPT_tf_task_id_is_running (ompt_task_id_t ompt_tid) unsigned u; int res = FALSE; - pthread_rwlock_rdlock (&mutex_tid_tf); + mtx_rw_rdlock(&mutex_tid_tf); for (u = 0; u < n_allocated_ompt_tids_tf; u++) if (ompt_tids_tf[u].tid == ompt_tid) @@ -294,7 +294,7 @@ int Extrae_OMPT_tf_task_id_is_running (ompt_task_id_t ompt_tid) break; } - pthread_rwlock_unlock (&mutex_tid_tf); + mtx_rw_unlock(&mutex_tid_tf); return res; } diff --git a/src/tracer/wrappers/pthread/Makefile.am b/src/tracer/wrappers/pthread/Makefile.am index 16f9cd29..fab8e848 100644 --- a/src/tracer/wrappers/pthread/Makefile.am +++ b/src/tracer/wrappers/pthread/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/PATHS # Wrappers for pthread instrumentation WRAPPERS_PTHREAD = \ pthread_wrapper.c pthread_wrapper.h \ - pthread_probe.c pthread_probe.h + pthread_probe.c pthread_probe.h noinst_LTLIBRARIES = libwrap_pthread.la diff --git a/src/tracer/wrappers/pthread/pthread_wrapper.c b/src/tracer/wrappers/pthread/pthread_wrapper.c index e8d755e7..5a8436dc 100644 --- a/src/tracer/wrappers/pthread/pthread_wrapper.c +++ b/src/tracer/wrappers/pthread/pthread_wrapper.c @@ -42,156 +42,13 @@ #endif #include "wrapper.h" +#include "pthread_redirect.h" #include "trace_macros.h" #include "pthread_probe.h" //#define DEBUG //#define DEBUG_MUTEX -#if defined(PIC) - -static int (*pthread_create_real)(pthread_t*,const pthread_attr_t*,void *(*) (void *),void*) = NULL; -static int (*pthread_join_real)(pthread_t,void**) = NULL; -static int (*pthread_detach_real)(pthread_t) = NULL; -static void (*pthread_exit_real)(void*) = NULL; -static int (*pthread_barrier_wait_real)(pthread_barrier_t *barrier) = NULL; - -static int (*pthread_mutex_lock_real)(pthread_mutex_t*) = NULL; -static int (*pthread_mutex_trylock_real)(pthread_mutex_t*) = NULL; -static int (*pthread_mutex_timedlock_real)(pthread_mutex_t*,const struct timespec *) = NULL; -static int (*pthread_mutex_unlock_real)(pthread_mutex_t*) = NULL; - -static int (*pthread_cond_broadcast_real)(pthread_cond_t*) = NULL; -static int (*pthread_cond_timedwait_real)(pthread_cond_t*,pthread_mutex_t*,const struct timespec *) = NULL; -static int (*pthread_cond_signal_real)(pthread_cond_t*) = NULL; -static int (*pthread_cond_wait_real)(pthread_cond_t*,pthread_mutex_t*) = NULL; - -static int (*pthread_rwlock_rdlock_real)(pthread_rwlock_t *) = NULL; -static int (*pthread_rwlock_tryrdlock_real)(pthread_rwlock_t *) = NULL; -static int (*pthread_rwlock_timedrdlock_real)(pthread_rwlock_t *, const struct timespec *) = NULL; -static int (*pthread_rwlock_wrlock_real)(pthread_rwlock_t *) = NULL; -static int (*pthread_rwlock_trywrlock_real)(pthread_rwlock_t *) = NULL; -static int (*pthread_rwlock_timedwrlock_real)(pthread_rwlock_t *, const struct timespec *) = NULL; -static int (*pthread_rwlock_unlock_real)(pthread_rwlock_t *) = NULL; - -static pthread_mutex_t extrae_pthread_create_mutex; - -#endif /* PIC */ - -static void GetpthreadHookPoints (int rank) -{ -#if defined(PIC) - /* Create mutex to protect pthread_create calls */ - pthread_mutex_init (&extrae_pthread_create_mutex, NULL); - - /* Obtain @ for pthread_create */ - pthread_create_real = - (int(*)(pthread_t*,const pthread_attr_t*,void *(*) (void *),void*)) - dlsym (RTLD_NEXT, "pthread_create"); - if (pthread_create_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_create in DSOs!!\n"); - - /* Obtain @ for pthread_join */ - pthread_join_real = - (int(*)(pthread_t,void**)) dlsym (RTLD_NEXT, "pthread_join"); - if (pthread_join_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_join in DSOs!!\n"); - - /* Obtain @ for pthread_barrier_wait */ - pthread_barrier_wait_real = - (int(*)(pthread_barrier_t *)) dlsym (RTLD_NEXT, "pthread_barrier_wait"); - if (pthread_barrier_wait_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_barrier_wait in DSOs!!\n"); - - /* Obtain @ for pthread_detach */ - pthread_detach_real = (int(*)(pthread_t)) dlsym (RTLD_NEXT, "pthread_detach"); - if (pthread_detach_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_detach in DSOs!!\n"); - - /* Obtain @ for pthread_exit */ - pthread_exit_real = (void(*)(void*)) dlsym (RTLD_NEXT, "pthread_exit"); - if (pthread_exit_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_exit in DSOs!!\n"); - - /* Obtain @ for pthread_mutex_lock */ - pthread_mutex_lock_real = (int(*)(pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_mutex_lock"); - if (pthread_mutex_lock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_lock in DSOs!!\n"); - - /* Obtain @ for pthread_mutex_unlock */ - pthread_mutex_unlock_real = (int(*)(pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_mutex_unlock"); - if (pthread_mutex_unlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_unlock in DSOs!!\n"); - - /* Obtain @ for pthread_mutex_trylock */ - pthread_mutex_trylock_real = (int(*)(pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_mutex_trylock"); - if (pthread_mutex_trylock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_trylock in DSOs!!\n"); - - /* Obtain @ for pthread_mutex_timedlock */ - pthread_mutex_timedlock_real = (int(*)(pthread_mutex_t*,const struct timespec*)) dlsym (RTLD_NEXT, "pthread_mutex_timedlock"); - if (pthread_mutex_timedlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_mutex_timedlock in DSOs!!\n"); - - /* Obtain @ for pthread_cond_signal */ - pthread_cond_signal_real = (int(*)(pthread_cond_t*)) dlsym (RTLD_NEXT, "pthread_cond_signal"); - if (pthread_cond_signal_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_cond_signal in DSOs!!\n"); - - /* Obtain @ for pthread_cond_broadcast */ - pthread_cond_broadcast_real = (int(*)(pthread_cond_t*)) dlsym (RTLD_NEXT, "pthread_cond_broadcast"); - if (pthread_cond_broadcast_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_cond_broadcast in DSOs!!\n"); - - /* Obtain @ for pthread_cond_wait */ - pthread_cond_wait_real = (int(*)(pthread_cond_t*,pthread_mutex_t*)) dlsym (RTLD_NEXT, "pthread_cond_wait"); - if (pthread_cond_wait_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_cond_wait in DSOs!!\n"); - - /* Obtain @ for pthread_cond_timedwait */ - pthread_cond_timedwait_real = (int(*)(pthread_cond_t*,pthread_mutex_t*,const struct timespec*)) dlsym (RTLD_NEXT, "pthread_cond_timedwait"); - if (pthread_cond_timedwait_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_cond_timedwait in DSOs!!\n"); - - /* Obtain @ for pthread_rwlock_rdlock */ - pthread_rwlock_rdlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_rdlock"); - if (pthread_rwlock_rdlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_rwlock_rdlock in DSOs!!\n"); - - /* Obtain @ for pthread_rwlock_tryrdlock */ - pthread_rwlock_tryrdlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_tryrdlock"); - if (pthread_rwlock_tryrdlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_rwlock_tryrdlock in DSOs!!\n"); - - /* Obtain @ for pthread_rwlock_timedrdlock */ - pthread_rwlock_timedrdlock_real = (int(*)(pthread_rwlock_t *, const struct timespec *)) dlsym (RTLD_NEXT, "pthread_rwlock_timedrdlock"); - if (pthread_rwlock_timedrdlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_rwlock_timedrdlock in DSOs!!\n"); - - /* Obtain @ for pthread_rwlock_rwlock */ - pthread_rwlock_wrlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_wrlock"); - if (pthread_rwlock_wrlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_rwlock_wrlock in DSOs!!\n"); - - /* Obtain @ for pthread_rwlock_tryrwlock */ - pthread_rwlock_trywrlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_trywrlock"); - if (pthread_rwlock_trywrlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_rwlock_trywrlock in DSOs!!\n"); - - /* Obtain @ for pthread_rwlock_timedrwlock */ - pthread_rwlock_timedwrlock_real = (int(*)(pthread_rwlock_t *, const struct timespec *)) dlsym (RTLD_NEXT, "pthread_rwlock_timedwrlock"); - if (pthread_rwlock_timedwrlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_rwlock_timedwrlock in DSOs!!\n"); - - /* Obtain @ for pthread_rwlock_unlock */ - pthread_rwlock_unlock_real = (int(*)(pthread_rwlock_t*)) dlsym (RTLD_NEXT, "pthread_rwlock_unlock"); - if (pthread_rwlock_unlock_real == NULL && rank == 0) - fprintf (stderr, PACKAGE_NAME": Unable to find pthread_rwlock_unlock in DSOs!!\n"); -#else - fprintf (stderr, PACKAGE_NAME": Warning! pthread instrumentation requires linking with shared library!\n"); -#endif /* PIC */ -} - /* INJECTED CODE -- INJECTED CODE -- INJECTED CODE -- INJECTED CODE @@ -199,6 +56,8 @@ static void GetpthreadHookPoints (int rank) */ +static pthread_mutex_t extrae_pthread_create_mutex = PTHREAD_MUTEX_INITIALIZER; + #if defined(PIC) struct pthread_create_info @@ -221,6 +80,9 @@ static void * pthread_create_hook (void *p1) /* Wake up the calling thread */ pthread_barrier_wait_real(&(i->barrier)); + if (pthread_create_real == NULL) + GetpthreadHookPoints(0); + Backend_Enter_Instrumentation (); Probe_pthread_Function_Entry (routine); Backend_Leave_Instrumentation (); @@ -317,7 +179,7 @@ int pthread_create (pthread_t* p1, const pthread_attr_t* p2, res = pthread_create_real (p1, p2, p3, p4); /* Stop protecting the region, more pthread creations can enter */ - pthread_mutex_unlock_real (&extrae_pthread_create_mutex); + pthread_mutex_unlock_real(&extrae_pthread_create_mutex); } else if (pthread_create_real != NULL) { @@ -736,7 +598,7 @@ int pthread_cond_timedwait (pthread_cond_t *c, pthread_mutex_t *m, const struct return res; } -int pthread_rwlock_rdlock (pthread_rwlock_t *l) +int pthread_rwlock_rdlock(pthread_rwlock_t *l) { int res = 0;