From: Bart Van Assche Date: Sat, 29 May 2010 18:43:21 +0000 (+0000) Subject: Handle statically initialized condition variables properly. X-Git-Tag: svn/VALGRIND_3_6_0~285 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ebc0c2cb8848a640cd680983bce10089dc9d688c;p=thirdparty%2Fvalgrind.git Handle statically initialized condition variables properly. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11139 --- diff --git a/drd/drd_clientreq.c b/drd/drd_clientreq.c index 852348e3bb..9a78b79641 100644 --- a/drd/drd_clientreq.c +++ b/drd/drd_clientreq.c @@ -174,6 +174,11 @@ static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret) DRD_(rwlock_pre_unlock)(arg[1], user_rwlock); break; + case VG_USERREQ__SET_PTHREAD_COND_INITIALIZER: + DRD_(pthread_cond_initializer) = (Addr)arg[1]; + DRD_(pthread_cond_initializer_size) = arg[2]; + break; + case VG_USERREQ__DRD_START_NEW_SEGMENT: DRD_(thread_new_segment)(DRD_(PtThreadIdToDrdThreadId)(arg[1])); break; diff --git a/drd/drd_clientreq.h b/drd/drd_clientreq.h index f059c66839..2f63170391 100644 --- a/drd/drd_clientreq.h +++ b/drd/drd_clientreq.h @@ -45,8 +45,14 @@ * source files. */ enum { + /* Declare the address and size of a variable with value + * PTHREAD_COND_INITIALIZER. + */ + VG_USERREQ__SET_PTHREAD_COND_INITIALIZER = VG_USERREQ_TOOL_BASE('D', 'r'), + /* args: address, size. */ + /* To ask the drd tool to start a new segment in the specified thread. */ - VG_USERREQ__DRD_START_NEW_SEGMENT = VG_USERREQ_TOOL_BASE('D', 'r'), + VG_USERREQ__DRD_START_NEW_SEGMENT, /* args: POSIX thread ID. */ /* Tell drd the pthread_t of the running thread. */ diff --git a/drd/drd_cond.c b/drd/drd_cond.c index 456b290f3e..bef880f825 100644 --- a/drd/drd_cond.c +++ b/drd/drd_cond.c @@ -29,6 +29,7 @@ #include "drd_mutex.h" #include "pub_tool_errormgr.h" /* VG_(maybe_record_error)() */ #include "pub_tool_libcassert.h" /* tl_assert() */ +#include "pub_tool_libcbase.h" /* VG_(memcmp)() */ #include "pub_tool_libcprint.h" /* VG_(printf)() */ #include "pub_tool_machine.h" /* VG_(get_IP)() */ #include "pub_tool_threadstate.h" /* VG_(get_running_tid)() */ @@ -45,6 +46,12 @@ static Bool DRD_(s_report_signal_unlocked) = True; static Bool DRD_(s_trace_cond); +/* Global variables. */ + +Addr DRD_(pthread_cond_initializer); +int DRD_(pthread_cond_initializer_size); + + /* Function definitions. */ void DRD_(cond_set_report_signal_unlocked)(const Bool r) @@ -382,12 +389,17 @@ void DRD_(cond_pre_signal)(Addr const cond) cond); } - if (!p) + tl_assert(DRD_(pthread_cond_initializer)); + if (!p && VG_(memcmp)((void*)cond, (void*)DRD_(pthread_cond_initializer), + DRD_(pthread_cond_initializer_size)) != 0) { not_initialized(cond); return; } + if (!p) + p = cond_get_or_allocate(cond); + cond_signal(DRD_(thread_get_running_tid)(), p); } @@ -405,11 +417,16 @@ void DRD_(cond_pre_broadcast)(Addr const cond) } p = DRD_(cond_get)(cond); - if (!p) + tl_assert(DRD_(pthread_cond_initializer)); + if (!p && VG_(memcmp)((void*)cond, (void*)DRD_(pthread_cond_initializer), + DRD_(pthread_cond_initializer_size)) != 0) { not_initialized(cond); return; } + if (!p) + p = cond_get_or_allocate(cond); + cond_signal(DRD_(thread_get_running_tid)(), p); } diff --git a/drd/drd_cond.h b/drd/drd_cond.h index a511912d57..755fe82b3c 100644 --- a/drd/drd_cond.h +++ b/drd/drd_cond.h @@ -36,6 +36,12 @@ struct cond_info; +/* Variable declarations. */ + +extern Addr DRD_(pthread_cond_initializer); +extern int DRD_(pthread_cond_initializer_size); + + /* Function declarations. */ void DRD_(cond_set_report_signal_unlocked)(const Bool r); diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c index bead0e9859..c414231a21 100644 --- a/drd/drd_pthread_intercepts.c +++ b/drd/drd_pthread_intercepts.c @@ -134,6 +134,7 @@ typedef struct static void DRD_(init)(void) __attribute__((constructor)); static void DRD_(check_threading_library)(void); static void DRD_(set_main_thread_state)(void); +static void DRD_(set_pthread_cond_initializer)(void); /* Function definitions. */ @@ -152,6 +153,7 @@ static void DRD_(init)(void) { DRD_(check_threading_library)(); DRD_(set_main_thread_state)(); + DRD_(set_pthread_cond_initializer)(); } /** @@ -339,7 +341,20 @@ static void DRD_(set_main_thread_state)(void) // Make sure that DRD knows about the main thread's POSIX thread ID. VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID, pthread_self(), 0, 0, 0, 0); +} + +/** Tell DRD which value PTHREAD_COND_INITIALIZER has. */ +static void DRD_(set_pthread_cond_initializer)(void) +{ + int res; + static pthread_cond_t pthread_cond_initializer = PTHREAD_COND_INITIALIZER; + + // Make sure that DRD knows about the main thread's POSIX thread ID. + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREAD_COND_INITIALIZER, + &pthread_cond_initializer, + sizeof(pthread_cond_initializer), + 0, 0, 0); }