Enabled support for nesting mutexes and condition variables in higher-level synchronization primitives. Changed mutex tracing output slightly.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8377
This commit is contained in:
Bart Van Assche 2008-07-07 16:53:07 +00:00
parent 92a407514b
commit 10c73ac342
4 changed files with 73 additions and 23 deletions

View File

@ -257,13 +257,21 @@ static Bool drd_handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret)
break;
case VG_USERREQ__PRE_COND_INIT:
tl_assert(thread_get_synchr_nesting_count(drd_tid) == 0);
drd_pre_cond_init(arg[1]);
if (thread_enter_synchr(drd_tid) == 0)
drd_pre_cond_init(arg[1]);
break;
case VG_USERREQ__POST_COND_INIT:
thread_leave_synchr(drd_tid);
break;
case VG_USERREQ__PRE_COND_DESTROY:
thread_enter_synchr(drd_tid);
break;
case VG_USERREQ__POST_COND_DESTROY:
tl_assert(thread_get_synchr_nesting_count(drd_tid) == 0);
drd_post_cond_destroy(arg[1]);
if (thread_leave_synchr(drd_tid) == 0)
drd_post_cond_destroy(arg[1]);
break;
case VG_USERREQ__PRE_COND_WAIT:
@ -277,13 +285,21 @@ static Bool drd_handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret)
break;
case VG_USERREQ__PRE_COND_SIGNAL:
tl_assert(thread_get_synchr_nesting_count(drd_tid) == 0);
drd_pre_cond_signal(arg[1]);
if (thread_enter_synchr(drd_tid) == 0)
drd_pre_cond_signal(arg[1]);
break;
case VG_USERREQ__POST_COND_SIGNAL:
thread_leave_synchr(drd_tid);
break;
case VG_USERREQ__PRE_COND_BROADCAST:
tl_assert(thread_get_synchr_nesting_count(drd_tid) == 0);
drd_pre_cond_broadcast(arg[1]);
if (thread_enter_synchr(drd_tid) == 0)
drd_pre_cond_broadcast(arg[1]);
break;
case VG_USERREQ__POST_COND_BROADCAST:
thread_leave_synchr(drd_tid);
break;
case VG_USERREQ__PRE_SEM_INIT:

View File

@ -94,17 +94,27 @@ enum {
/* to notify the drd tool of a pthread_cond_init call. */
VG_USERREQ__PRE_COND_INIT,
/* args: Addr */
/* to notify the drd tool of a pthread_cond_init call. */
VG_USERREQ__POST_COND_INIT,
/* args: Addr */
/* to notify the drd tool of a pthread_cond_destroy call. */
VG_USERREQ__PRE_COND_DESTROY,
/* args: Addr */
/* to notify the drd tool of a pthread_cond_destroy call. */
VG_USERREQ__POST_COND_DESTROY,
/* args: Addr cond */
/* args: Addr */
VG_USERREQ__PRE_COND_WAIT,
/* args: Addr cond, Addr mutex, MutexT mt */
VG_USERREQ__POST_COND_WAIT,
/* args: Addr cond, Addr mutex, Bool took_lock*/
VG_USERREQ__PRE_COND_SIGNAL,
/* args: Addr cond */
VG_USERREQ__POST_COND_SIGNAL,
/* args: Addr cond */
VG_USERREQ__PRE_COND_BROADCAST,
/* args: Addr cond */
VG_USERREQ__POST_COND_BROADCAST,
/* args: Addr cond */
/* To notify the drd tool of a sem_init call. */
VG_USERREQ__PRE_SEM_INIT,
@ -179,11 +189,12 @@ enum {
typedef enum
{
mutex_type_invalid_mutex = 0,
mutex_type_recursive_mutex = 1,
mutex_type_errorcheck_mutex = 2,
mutex_type_default_mutex = 3,
mutex_type_spinlock = 4
mutex_type_unknown = -1,
mutex_type_invalid_mutex = 0,
mutex_type_recursive_mutex = 1,
mutex_type_errorcheck_mutex = 2,
mutex_type_default_mutex = 3,
mutex_type_spinlock = 4
} MutexT;
typedef enum

View File

@ -67,9 +67,10 @@ static
void mutex_initialize(struct mutex_info* const p,
const Addr mutex, const MutexT mutex_type)
{
tl_assert(mutex != 0);
tl_assert(mutex);
tl_assert(mutex_type != mutex_type_unknown);
tl_assert(p->a1 == mutex);
p->cleanup = (void(*)(DrdClientobj*))&mutex_cleanup;
p->mutex_type = mutex_type;
p->recursion_count = 0;
@ -87,11 +88,13 @@ static void mutex_cleanup(struct mutex_info* p)
if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] mutex_destroy %s 0x%lx",
"[%d/%d] mutex_destroy %s 0x%lx rc %d owner %d",
VG_(get_running_tid)(),
thread_get_running_tid(),
mutex_get_typename(p),
p->a1);
p->a1,
p ? p->recursion_count : -1,
p ? p->owner : DRD_INVALID_THREADID);
}
if (mutex_is_locked(p))
@ -138,6 +141,8 @@ mutex_get_or_allocate(const Addr mutex, const MutexT mutex_type)
return 0;
}
tl_assert(mutex_type != mutex_type_unknown);
p = &clientobj_add(mutex, ClientMutex)->mutex;
mutex_initialize(p, mutex, mutex_type);
return p;
@ -155,6 +160,8 @@ mutex_init(const Addr mutex, const MutexT mutex_type)
{
struct mutex_info* p;
tl_assert(mutex_type != mutex_type_unknown);
if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
@ -209,18 +216,22 @@ void mutex_post_destroy(const Addr mutex)
* an attempt is made to lock recursively a synchronization object that must
* not be locked recursively.
*/
void mutex_pre_lock(const Addr mutex, const MutexT mutex_type,
void mutex_pre_lock(const Addr mutex, MutexT mutex_type,
const Bool trylock)
{
struct mutex_info* p;
p = mutex_get_or_allocate(mutex, mutex_type);
if (mutex_type == mutex_type_unknown)
mutex_type = p->mutex_type;
if (s_trace_mutex)
{
VG_(message)(Vg_UserMsg,
"[%d/%d] pre_mutex_lock %s 0x%lx rc %d owner %d",
"[%d/%d] %s %s 0x%lx rc %d owner %d",
VG_(get_running_tid)(),
thread_get_running_tid(),
trylock ? "pre_mutex_lock " : "mutex_trylock ",
p ? mutex_get_typename(p) : "(?)",
mutex,
p ? p->recursion_count : -1,
@ -325,11 +336,15 @@ void mutex_post_lock(const Addr mutex, const Bool took_lock,
* @note This function must be called before pthread_mutex_unlock() is called,
* or a race condition is triggered !
*/
void mutex_unlock(const Addr mutex, const MutexT mutex_type)
void mutex_unlock(const Addr mutex, MutexT mutex_type)
{
const DrdThreadId drd_tid = thread_get_running_tid();
const ThreadId vg_tid = VG_(get_running_tid)();
struct mutex_info* const p = mutex_get(mutex);
struct mutex_info* p;
p = mutex_get(mutex);
if (mutex_type == mutex_type_unknown)
mutex_type = p->mutex_type;
if (s_trace_mutex)
{

View File

@ -1,6 +1,6 @@
/*--------------------------------------------------------------------*/
/*--- Client-space code for drd. drd_intercepts.c ---*/
/*--- Client-space code for drd. drd_pthread_intercepts.c ---*/
/*--------------------------------------------------------------------*/
/*
@ -460,6 +460,8 @@ PTH_FUNC(int, pthreadZucondZuinitZa, // pthread_cond_init*
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_INIT,
cond, 0, 0, 0, 0);
CALL_FN_W_WW(ret, fn, cond, attr);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_INIT,
cond, 0, 0, 0, 0);
return ret;
}
@ -471,6 +473,8 @@ PTH_FUNC(int, pthreadZucondZudestroyZa, // pthread_cond_destroy*
int res;
OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_DESTROY,
cond, 0, 0, 0, 0);
CALL_FN_W_W(ret, fn, cond);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_DESTROY,
cond, 0, 0, 0, 0);
@ -523,6 +527,8 @@ PTH_FUNC(int, pthreadZucondZusignalZa, // pthread_cond_signal*
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_SIGNAL,
cond, 0, 0, 0, 0);
CALL_FN_W_W(ret, fn, cond);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_SIGNAL,
cond, 0, 0, 0, 0);
return ret;
}
@ -537,6 +543,8 @@ PTH_FUNC(int, pthreadZucondZubroadcastZa, // pthread_cond_broadcast*
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_COND_BROADCAST,
cond, 0, 0, 0, 0);
CALL_FN_W_W(ret, fn, cond);
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_COND_BROADCAST,
cond, 0, 0, 0, 0);
return ret;
}