drd: Ignore ordering introduced by a mutex used in the thread creation wrapper
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14015 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/drd/drd.h b/drd/drd.h
index f82c2b2..1e96857 100644
--- a/drd/drd.h
+++ b/drd/drd.h
@@ -488,6 +488,10 @@
VG_USERREQ__DRD_ANNOTATE_SEM_POST_PRE,
/* args: Addr. */
+ /* Tell DRD to ignore the inter-thread ordering introduced by a mutex. */
+ VG_USERREQ__DRD_IGNORE_MUTEX_ORDERING,
+ /* args: Addr. */
+
/* Tell DRD that a user-defined reader-writer synchronization object
* has been created. */
VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE
diff --git a/drd/drd_clientobj.h b/drd/drd_clientobj.h
index d615d79..b3190ab 100644
--- a/drd/drd_clientobj.h
+++ b/drd/drd_clientobj.h
@@ -68,6 +68,7 @@
ExeContext* first_observed_at;
MutexT mutex_type; // pthread_mutex_t or pthread_spinlock_t.
int recursion_count; // 0 if free, >= 1 if locked.
+ Bool ignore_ordering;
DrdThreadId owner; // owner if locked, last owner if free.
struct segment* last_locked_segment;
ULong acquiry_time_ms;
diff --git a/drd/drd_clientreq.c b/drd/drd_clientreq.c
index 92ac92a..a3d485f 100644
--- a/drd/drd_clientreq.c
+++ b/drd/drd_clientreq.c
@@ -378,6 +378,10 @@
DRD_(thread_leave_synchr)(drd_tid);
break;
+ case VG_USERREQ__DRD_IGNORE_MUTEX_ORDERING:
+ DRD_(mutex_ignore_ordering)(arg[1]);
+ break;
+
case VG_USERREQ__PRE_SPIN_INIT_OR_UNLOCK:
if (DRD_(thread_enter_synchr)(drd_tid) == 0)
DRD_(spinlock_init_or_unlock)(arg[1]);
diff --git a/drd/drd_mutex.c b/drd/drd_mutex.c
index 12ee4de..76cabcf 100644
--- a/drd/drd_mutex.c
+++ b/drd/drd_mutex.c
@@ -76,12 +76,30 @@
= (void(*)(DrdClientobj*, DrdThreadId))mutex_delete_thread;
p->mutex_type = mutex_type;
p->recursion_count = 0;
+ p->ignore_ordering = False;
p->owner = DRD_INVALID_THREADID;
p->last_locked_segment = 0;
p->acquiry_time_ms = 0;
p->acquired_at = 0;
}
+void DRD_(mutex_ignore_ordering)(const Addr mutex)
+{
+ struct mutex_info* p = DRD_(mutex_get)(mutex);
+
+ if (s_trace_mutex)
+ DRD_(trace_msg)("[%d] mutex_ignore_ordering %s 0x%lx",
+ DRD_(thread_get_running_tid)(),
+ p ? DRD_(mutex_type_name)(p->mutex_type) : "(?)",
+ mutex);
+
+ if (p) {
+ p->ignore_ordering = True;
+ } else {
+ DRD_(not_a_mutex)(mutex);
+ }
+}
+
/** Deallocate the memory that was allocated by mutex_initialize(). */
static void mutex_cleanup(struct mutex_info* p)
{
@@ -302,17 +320,18 @@
return;
if (p->recursion_count == 0) {
- if (p->owner != drd_tid && p->owner != DRD_INVALID_THREADID)
- {
- tl_assert(p->last_locked_segment);
+ if (!p->ignore_ordering) {
+ if (p->owner != drd_tid && p->owner != DRD_INVALID_THREADID) {
+ tl_assert(p->last_locked_segment);
- DRD_(thread_new_segment_and_combine_vc)(drd_tid,
- p->last_locked_segment);
+ DRD_(thread_new_segment_and_combine_vc)(drd_tid,
+ p->last_locked_segment);
+ } else {
+ DRD_(thread_new_segment)(drd_tid);
+ }
+
+ s_mutex_segment_creation_count++;
}
- else
- DRD_(thread_new_segment)(drd_tid);
-
- s_mutex_segment_creation_count++;
p->owner = drd_tid;
p->acquiry_time_ms = VG_(read_millisecond_timer)();
@@ -426,7 +445,8 @@
/* this mutex is locked again. */
DRD_(thread_get_latest_segment)(&p->last_locked_segment, drd_tid);
- DRD_(thread_new_segment)(drd_tid);
+ if (!p->ignore_ordering)
+ DRD_(thread_new_segment)(drd_tid);
p->acquired_at = 0;
s_mutex_segment_creation_count++;
}
diff --git a/drd/drd_mutex.h b/drd/drd_mutex.h
index fb8a8bc..953045a 100644
--- a/drd/drd_mutex.h
+++ b/drd/drd_mutex.h
@@ -37,6 +37,7 @@
void DRD_(mutex_set_trace)(const Bool trace_mutex);
void DRD_(mutex_set_lock_threshold)(const UInt lock_threshold_ms);
struct mutex_info* DRD_(mutex_init)(const Addr mutex, const MutexT mutex_type);
+void DRD_(mutex_ignore_ordering)(const Addr mutex);
void DRD_(mutex_post_destroy)(const Addr mutex);
void DRD_(not_a_mutex)(const Addr mutex);
struct mutex_info* DRD_(mutex_get)(const Addr mutex);
diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c
index e66297e..a3119de 100644
--- a/drd/drd_pthread_intercepts.c
+++ b/drd/drd_pthread_intercepts.c
@@ -179,10 +179,17 @@
DRD_(set_main_thread_state)();
}
+static __always_inline void DRD_(ignore_mutex_ordering)(pthread_mutex_t *mutex)
+{
+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_IGNORE_MUTEX_ORDERING,
+ mutex, 0, 0, 0, 0);
+}
+
static void DRD_(sema_init)(DrdSema* sema)
{
- DRD_IGNORE_VAR(sema->counter);
+ DRD_IGNORE_VAR(*sema);
pthread_mutex_init(&sema->mutex, NULL);
+ DRD_(ignore_mutex_ordering)(&sema->mutex);
sema->counter = 0;
sema->waiters = 0;
}