aboutsummaryrefslogtreecommitdiff
path: root/drd/drd_rwlock.c
diff options
context:
space:
mode:
authorbart <bart@a5019735-40e9-0310-863c-91ae7b9d1cf9>2009-03-26 19:07:15 +0000
committerbart <bart@a5019735-40e9-0310-863c-91ae7b9d1cf9>2009-03-26 19:07:15 +0000
commitbedfd237fbdc80d0c917cfcb85a94b5561c92633 (patch)
treeca3765f5de096ac686cb53fa0bc47585b031c373 /drd/drd_rwlock.c
parentcd7bfdf7393ca23803c4097b540e214b3aca01c4 (diff)
downloadvalgrind-bedfd237fbdc80d0c917cfcb85a94b5561c92633.tar.gz
- Reindented code such that it uses three spaces for indentation instead
of two. The indentation of the DRD source code is now consistent with the other Valgrind source files. - Added emacs mode line with indentation settings. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9496 a5019735-40e9-0310-863c-91ae7b9d1cf9
Diffstat (limited to 'drd/drd_rwlock.c')
-rw-r--r--drd/drd_rwlock.c757
1 files changed, 380 insertions, 377 deletions
diff --git a/drd/drd_rwlock.c b/drd/drd_rwlock.c
index 12d89200a..a2cfdaf1a 100644
--- a/drd/drd_rwlock.c
+++ b/drd/drd_rwlock.c
@@ -1,3 +1,4 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
/*
This file is part of drd, a thread error detector.
@@ -39,11 +40,11 @@
struct rwlock_thread_info
{
- UWord tid; // DrdThreadId.
- UInt reader_nesting_count;
- UInt writer_nesting_count;
- Segment* last_unlock_segment; // Segment of last unlock call by this thread.
- Bool last_lock_was_writer_lock;
+ UWord tid; // DrdThreadId.
+ UInt reader_nesting_count;
+ UInt writer_nesting_count;
+ Segment* last_unlock_segment; // Segment of last unlock call by this thread.
+ Bool last_lock_was_writer_lock;
};
@@ -66,74 +67,74 @@ static ULong DRD_(s_rwlock_segment_creation_count);
void DRD_(rwlock_set_trace)(const Bool trace_rwlock)
{
- tl_assert(trace_rwlock == False || trace_rwlock == True);
- DRD_(s_trace_rwlock) = trace_rwlock;
+ tl_assert(trace_rwlock == False || trace_rwlock == True);
+ DRD_(s_trace_rwlock) = trace_rwlock;
}
void DRD_(rwlock_set_exclusive_threshold)(const UInt exclusive_threshold_ms)
{
- DRD_(s_exclusive_threshold_ms) = exclusive_threshold_ms;
+ DRD_(s_exclusive_threshold_ms) = exclusive_threshold_ms;
}
void DRD_(rwlock_set_shared_threshold)(const UInt shared_threshold_ms)
{
- DRD_(s_shared_threshold_ms) = shared_threshold_ms;
+ DRD_(s_shared_threshold_ms) = shared_threshold_ms;
}
static Bool DRD_(rwlock_is_rdlocked)(struct rwlock_info* p)
{
- struct rwlock_thread_info* q;
-
- VG_(OSetGen_ResetIter)(p->thread_info);
- for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
- {
- return q->reader_nesting_count > 0;
- }
- return False;
+ struct rwlock_thread_info* q;
+
+ VG_(OSetGen_ResetIter)(p->thread_info);
+ for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
+ {
+ return q->reader_nesting_count > 0;
+ }
+ return False;
}
static Bool DRD_(rwlock_is_wrlocked)(struct rwlock_info* p)
{
- struct rwlock_thread_info* q;
-
- VG_(OSetGen_ResetIter)(p->thread_info);
- for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
- {
- return q->writer_nesting_count > 0;
- }
- return False;
+ struct rwlock_thread_info* q;
+
+ VG_(OSetGen_ResetIter)(p->thread_info);
+ for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
+ {
+ return q->writer_nesting_count > 0;
+ }
+ return False;
}
static Bool DRD_(rwlock_is_locked)(struct rwlock_info* p)
{
- return DRD_(rwlock_is_rdlocked)(p) || DRD_(rwlock_is_wrlocked)(p);
+ return DRD_(rwlock_is_rdlocked)(p) || DRD_(rwlock_is_wrlocked)(p);
}
static Bool DRD_(rwlock_is_rdlocked_by)(struct rwlock_info* p,
const DrdThreadId tid)
{
- const UWord uword_tid = tid;
- struct rwlock_thread_info* q;
+ const UWord uword_tid = tid;
+ struct rwlock_thread_info* q;
- q = VG_(OSetGen_Lookup)(p->thread_info, &uword_tid);
- return q && q->reader_nesting_count > 0;
+ q = VG_(OSetGen_Lookup)(p->thread_info, &uword_tid);
+ return q && q->reader_nesting_count > 0;
}
static Bool DRD_(rwlock_is_wrlocked_by)(struct rwlock_info* p,
const DrdThreadId tid)
{
- const UWord uword_tid = tid;
- struct rwlock_thread_info* q;
+ const UWord uword_tid = tid;
+ struct rwlock_thread_info* q;
- q = VG_(OSetGen_Lookup)(p->thread_info, &uword_tid);
- return q && q->writer_nesting_count > 0;
+ q = VG_(OSetGen_Lookup)(p->thread_info, &uword_tid);
+ return q && q->writer_nesting_count > 0;
}
static Bool DRD_(rwlock_is_locked_by)(struct rwlock_info* p,
const DrdThreadId tid)
{
- return (DRD_(rwlock_is_rdlocked_by)(p, tid)
- || DRD_(rwlock_is_wrlocked_by)(p, tid));
+ return (DRD_(rwlock_is_rdlocked_by)(p, tid)
+ || DRD_(rwlock_is_wrlocked_by)(p, tid));
}
/** Either look up or insert a node corresponding to DRD thread id 'tid'. */
@@ -141,21 +142,21 @@ static
struct rwlock_thread_info*
DRD_(lookup_or_insert_node)(OSet* oset, const UWord tid)
{
- struct rwlock_thread_info* q;
-
- q = VG_(OSetGen_Lookup)(oset, &tid);
- if (q == 0)
- {
- q = VG_(OSetGen_AllocNode)(oset, sizeof(*q));
- q->tid = tid;
- q->reader_nesting_count = 0;
- q->writer_nesting_count = 0;
- q->last_unlock_segment = 0;
- q->last_lock_was_writer_lock = False;
- VG_(OSetGen_Insert)(oset, q);
- }
- tl_assert(q);
- return q;
+ struct rwlock_thread_info* q;
+
+ q = VG_(OSetGen_Lookup)(oset, &tid);
+ if (q == 0)
+ {
+ q = VG_(OSetGen_AllocNode)(oset, sizeof(*q));
+ q->tid = tid;
+ q->reader_nesting_count = 0;
+ q->writer_nesting_count = 0;
+ q->last_unlock_segment = 0;
+ q->last_lock_was_writer_lock = False;
+ VG_(OSetGen_Insert)(oset, q);
+ }
+ tl_assert(q);
+ return q;
}
/**
@@ -166,155 +167,156 @@ static void DRD_(rwlock_combine_other_vc)(struct rwlock_info* const p,
const DrdThreadId tid,
const Bool readers_too)
{
- struct rwlock_thread_info* q;
-
- VG_(OSetGen_ResetIter)(p->thread_info);
- for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
- {
- if (q->tid != tid && (readers_too || q->last_lock_was_writer_lock))
- {
- DRD_(thread_combine_vc2)(tid, &q->last_unlock_segment->vc);
- }
- }
+ struct rwlock_thread_info* q;
+
+ VG_(OSetGen_ResetIter)(p->thread_info);
+ for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
+ {
+ if (q->tid != tid && (readers_too || q->last_lock_was_writer_lock))
+ {
+ DRD_(thread_combine_vc2)(tid, &q->last_unlock_segment->vc);
+ }
+ }
}
/** Initialize the rwlock_info data structure *p. */
static
void DRD_(rwlock_initialize)(struct rwlock_info* const p, const Addr rwlock)
{
- tl_assert(rwlock != 0);
- tl_assert(p->a1 == rwlock);
- tl_assert(p->type == ClientRwlock);
-
- p->cleanup = (void(*)(DrdClientobj*))rwlock_cleanup;
- p->delete_thread = (void(*)(DrdClientobj*, DrdThreadId))rwlock_delete_thread;
- p->thread_info = VG_(OSetGen_Create)(
- 0, 0, VG_(malloc), "drd.rwlock.ri.1", VG_(free));
- p->acquiry_time_ms = 0;
- p->acquired_at = 0;
+ tl_assert(rwlock != 0);
+ tl_assert(p->a1 == rwlock);
+ tl_assert(p->type == ClientRwlock);
+
+ p->cleanup = (void(*)(DrdClientobj*))rwlock_cleanup;
+ p->delete_thread
+ = (void(*)(DrdClientobj*, DrdThreadId))rwlock_delete_thread;
+ p->thread_info = VG_(OSetGen_Create)(
+ 0, 0, VG_(malloc), "drd.rwlock.ri.1", VG_(free));
+ p->acquiry_time_ms = 0;
+ p->acquired_at = 0;
}
/** Deallocate the memory that was allocated by rwlock_initialize(). */
static void rwlock_cleanup(struct rwlock_info* p)
{
- struct rwlock_thread_info* q;
-
- tl_assert(p);
-
- if (DRD_(s_trace_rwlock))
- {
- VG_(message)(Vg_UserMsg,
- "[%d/%d] rwlock_destroy 0x%lx",
- VG_(get_running_tid)(),
- DRD_(thread_get_running_tid)(),
- p->a1);
- }
-
- if (DRD_(rwlock_is_locked)(p))
- {
- RwlockErrInfo REI = { p->a1 };
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- RwlockErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Destroying locked rwlock",
- &REI);
- }
-
- VG_(OSetGen_ResetIter)(p->thread_info);
- for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
- {
- DRD_(sg_put)(q->last_unlock_segment);
- }
- VG_(OSetGen_Destroy)(p->thread_info);
+ struct rwlock_thread_info* q;
+
+ tl_assert(p);
+
+ if (DRD_(s_trace_rwlock))
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] rwlock_destroy 0x%lx",
+ VG_(get_running_tid)(),
+ DRD_(thread_get_running_tid)(),
+ p->a1);
+ }
+
+ if (DRD_(rwlock_is_locked)(p))
+ {
+ RwlockErrInfo REI = { p->a1 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ RwlockErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Destroying locked rwlock",
+ &REI);
+ }
+
+ VG_(OSetGen_ResetIter)(p->thread_info);
+ for ( ; (q = VG_(OSetGen_Next)(p->thread_info)) != 0; )
+ {
+ DRD_(sg_put)(q->last_unlock_segment);
+ }
+ VG_(OSetGen_Destroy)(p->thread_info);
}
static
struct rwlock_info*
DRD_(rwlock_get_or_allocate)(const Addr rwlock)
{
- struct rwlock_info* p;
-
- tl_assert(offsetof(DrdClientobj, rwlock) == 0);
- p = &(DRD_(clientobj_get)(rwlock, ClientRwlock)->rwlock);
- if (p)
- {
- return p;
- }
-
- if (DRD_(clientobj_present)(rwlock, rwlock + 1))
- {
- GenericErrInfo GEI;
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- GenericErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Not a reader-writer lock",
- &GEI);
- return 0;
- }
-
- p = &(DRD_(clientobj_add)(rwlock, ClientRwlock)->rwlock);
- DRD_(rwlock_initialize)(p, rwlock);
- return p;
+ struct rwlock_info* p;
+
+ tl_assert(offsetof(DrdClientobj, rwlock) == 0);
+ p = &(DRD_(clientobj_get)(rwlock, ClientRwlock)->rwlock);
+ if (p)
+ {
+ return p;
+ }
+
+ if (DRD_(clientobj_present)(rwlock, rwlock + 1))
+ {
+ GenericErrInfo GEI;
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ GenericErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Not a reader-writer lock",
+ &GEI);
+ return 0;
+ }
+
+ p = &(DRD_(clientobj_add)(rwlock, ClientRwlock)->rwlock);
+ DRD_(rwlock_initialize)(p, rwlock);
+ return p;
}
static struct rwlock_info* DRD_(rwlock_get)(const Addr rwlock)
{
- tl_assert(offsetof(DrdClientobj, rwlock) == 0);
- return &(DRD_(clientobj_get)(rwlock, ClientRwlock)->rwlock);
+ tl_assert(offsetof(DrdClientobj, rwlock) == 0);
+ return &(DRD_(clientobj_get)(rwlock, ClientRwlock)->rwlock);
}
/** Called before pthread_rwlock_init(). */
struct rwlock_info* DRD_(rwlock_pre_init)(const Addr rwlock)
{
- struct rwlock_info* p;
-
- if (DRD_(s_trace_rwlock))
- {
- VG_(message)(Vg_UserMsg,
- "[%d/%d] rwlock_init 0x%lx",
- VG_(get_running_tid)(),
- DRD_(thread_get_running_tid)(),
- rwlock);
- }
-
- p = DRD_(rwlock_get)(rwlock);
-
- if (p)
- {
- const ThreadId vg_tid = VG_(get_running_tid)();
- RwlockErrInfo REI
- = { p->a1 };
- VG_(maybe_record_error)(vg_tid,
- RwlockErr,
- VG_(get_IP)(vg_tid),
- "Reader-writer lock reinitialization",
- &REI);
- return p;
- }
-
- p = DRD_(rwlock_get_or_allocate)(rwlock);
-
- return p;
+ struct rwlock_info* p;
+
+ if (DRD_(s_trace_rwlock))
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] rwlock_init 0x%lx",
+ VG_(get_running_tid)(),
+ DRD_(thread_get_running_tid)(),
+ rwlock);
+ }
+
+ p = DRD_(rwlock_get)(rwlock);
+
+ if (p)
+ {
+ const ThreadId vg_tid = VG_(get_running_tid)();
+ RwlockErrInfo REI
+ = { p->a1 };
+ VG_(maybe_record_error)(vg_tid,
+ RwlockErr,
+ VG_(get_IP)(vg_tid),
+ "Reader-writer lock reinitialization",
+ &REI);
+ return p;
+ }
+
+ p = DRD_(rwlock_get_or_allocate)(rwlock);
+
+ return p;
}
/** Called after pthread_rwlock_destroy(). */
void DRD_(rwlock_post_destroy)(const Addr rwlock)
{
- struct rwlock_info* p;
-
- p = DRD_(rwlock_get)(rwlock);
- if (p == 0)
- {
- GenericErrInfo GEI;
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- GenericErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Not a reader-writer lock",
- &GEI);
- return;
- }
-
- DRD_(clientobj_remove)(rwlock, ClientRwlock);
+ struct rwlock_info* p;
+
+ p = DRD_(rwlock_get)(rwlock);
+ if (p == 0)
+ {
+ GenericErrInfo GEI;
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ GenericErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Not a reader-writer lock",
+ &GEI);
+ return;
+ }
+
+ DRD_(clientobj_remove)(rwlock, ClientRwlock);
}
/**
@@ -325,27 +327,27 @@ void DRD_(rwlock_post_destroy)(const Addr rwlock)
*/
void DRD_(rwlock_pre_rdlock)(const Addr rwlock)
{
- struct rwlock_info* p;
-
- if (DRD_(s_trace_rwlock))
- {
- VG_(message)(Vg_UserMsg,
- "[%d/%d] pre_rwlock_rdlock 0x%lx",
- VG_(get_running_tid)(),
- DRD_(thread_get_running_tid)(),
- rwlock);
- }
-
- p = DRD_(rwlock_get_or_allocate)(rwlock);
- tl_assert(p);
-
- if (DRD_(rwlock_is_wrlocked_by)(p, DRD_(thread_get_running_tid)()))
- {
- VG_(message)(Vg_UserMsg,
- "reader-writer lock 0x%lx is already locked for"
- " writing by calling thread",
- p->a1);
- }
+ struct rwlock_info* p;
+
+ if (DRD_(s_trace_rwlock))
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] pre_rwlock_rdlock 0x%lx",
+ VG_(get_running_tid)(),
+ DRD_(thread_get_running_tid)(),
+ rwlock);
+ }
+
+ p = DRD_(rwlock_get_or_allocate)(rwlock);
+ tl_assert(p);
+
+ if (DRD_(rwlock_is_wrlocked_by)(p, DRD_(thread_get_running_tid)()))
+ {
+ VG_(message)(Vg_UserMsg,
+ "reader-writer lock 0x%lx is already locked for"
+ " writing by calling thread",
+ p->a1);
+ }
}
/**
@@ -355,37 +357,37 @@ void DRD_(rwlock_pre_rdlock)(const Addr rwlock)
*/
void DRD_(rwlock_post_rdlock)(const Addr rwlock, const Bool took_lock)
{
- const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
- struct rwlock_info* p;
- struct rwlock_thread_info* q;
-
- if (DRD_(s_trace_rwlock))
- {
- VG_(message)(Vg_UserMsg,
- "[%d/%d] post_rwlock_rdlock 0x%lx",
- VG_(get_running_tid)(),
- drd_tid,
- rwlock);
- }
-
- p = DRD_(rwlock_get)(rwlock);
-
- if (! p || ! took_lock)
- return;
-
- tl_assert(! DRD_(rwlock_is_wrlocked)(p));
-
- q = DRD_(lookup_or_insert_node)(p->thread_info, drd_tid);
- if (++q->reader_nesting_count == 1)
- {
- DRD_(rwlock_combine_other_vc)(p, drd_tid, False);
- q->last_lock_was_writer_lock = False;
- DRD_(thread_new_segment)(drd_tid);
- DRD_(s_rwlock_segment_creation_count)++;
-
- p->acquiry_time_ms = VG_(read_millisecond_timer)();
- p->acquired_at = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
- }
+ const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
+ struct rwlock_info* p;
+ struct rwlock_thread_info* q;
+
+ if (DRD_(s_trace_rwlock))
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] post_rwlock_rdlock 0x%lx",
+ VG_(get_running_tid)(),
+ drd_tid,
+ rwlock);
+ }
+
+ p = DRD_(rwlock_get)(rwlock);
+
+ if (! p || ! took_lock)
+ return;
+
+ tl_assert(! DRD_(rwlock_is_wrlocked)(p));
+
+ q = DRD_(lookup_or_insert_node)(p->thread_info, drd_tid);
+ if (++q->reader_nesting_count == 1)
+ {
+ DRD_(rwlock_combine_other_vc)(p, drd_tid, False);
+ q->last_lock_was_writer_lock = False;
+ DRD_(thread_new_segment)(drd_tid);
+ DRD_(s_rwlock_segment_creation_count)++;
+
+ p->acquiry_time_ms = VG_(read_millisecond_timer)();
+ p->acquired_at = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
+ }
}
/**
@@ -396,35 +398,35 @@ void DRD_(rwlock_post_rdlock)(const Addr rwlock, const Bool took_lock)
*/
void DRD_(rwlock_pre_wrlock)(const Addr rwlock)
{
- struct rwlock_info* p;
-
- p = DRD_(rwlock_get)(rwlock);
-
- if (DRD_(s_trace_rwlock))
- {
- VG_(message)(Vg_UserMsg,
- "[%d/%d] pre_rwlock_wrlock 0x%lx",
- VG_(get_running_tid)(),
- DRD_(thread_get_running_tid)(),
- rwlock);
- }
-
- if (p == 0)
- {
- p = DRD_(rwlock_get_or_allocate)(rwlock);
- }
-
- tl_assert(p);
-
- if (DRD_(rwlock_is_wrlocked_by)(p, DRD_(thread_get_running_tid)()))
- {
- RwlockErrInfo REI = { p->a1 };
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- RwlockErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Recursive writer locking not allowed",
- &REI);
- }
+ struct rwlock_info* p;
+
+ p = DRD_(rwlock_get)(rwlock);
+
+ if (DRD_(s_trace_rwlock))
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] pre_rwlock_wrlock 0x%lx",
+ VG_(get_running_tid)(),
+ DRD_(thread_get_running_tid)(),
+ rwlock);
+ }
+
+ if (p == 0)
+ {
+ p = DRD_(rwlock_get_or_allocate)(rwlock);
+ }
+
+ tl_assert(p);
+
+ if (DRD_(rwlock_is_wrlocked_by)(p, DRD_(thread_get_running_tid)()))
+ {
+ RwlockErrInfo REI = { p->a1 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ RwlockErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Recursive writer locking not allowed",
+ &REI);
+ }
}
/**
@@ -434,35 +436,35 @@ void DRD_(rwlock_pre_wrlock)(const Addr rwlock)
*/
void DRD_(rwlock_post_wrlock)(const Addr rwlock, const Bool took_lock)
{
- const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
- struct rwlock_info* p;
- struct rwlock_thread_info* q;
-
- p = DRD_(rwlock_get)(rwlock);
-
- if (DRD_(s_trace_rwlock))
- {
- VG_(message)(Vg_UserMsg,
- "[%d/%d] post_rwlock_wrlock 0x%lx",
- VG_(get_running_tid)(),
- drd_tid,
- rwlock);
- }
-
- if (! p || ! took_lock)
- return;
-
- q = DRD_(lookup_or_insert_node)(p->thread_info,
- DRD_(thread_get_running_tid)());
- tl_assert(q->writer_nesting_count == 0);
- q->writer_nesting_count++;
- q->last_lock_was_writer_lock = True;
- tl_assert(q->writer_nesting_count == 1);
- DRD_(rwlock_combine_other_vc)(p, drd_tid, True);
- DRD_(thread_new_segment)(drd_tid);
- DRD_(s_rwlock_segment_creation_count)++;
- p->acquiry_time_ms = VG_(read_millisecond_timer)();
- p->acquired_at = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
+ const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
+ struct rwlock_info* p;
+ struct rwlock_thread_info* q;
+
+ p = DRD_(rwlock_get)(rwlock);
+
+ if (DRD_(s_trace_rwlock))
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] post_rwlock_wrlock 0x%lx",
+ VG_(get_running_tid)(),
+ drd_tid,
+ rwlock);
+ }
+
+ if (! p || ! took_lock)
+ return;
+
+ q = DRD_(lookup_or_insert_node)(p->thread_info,
+ DRD_(thread_get_running_tid)());
+ tl_assert(q->writer_nesting_count == 0);
+ q->writer_nesting_count++;
+ q->last_lock_was_writer_lock = True;
+ tl_assert(q->writer_nesting_count == 1);
+ DRD_(rwlock_combine_other_vc)(p, drd_tid, True);
+ DRD_(thread_new_segment)(drd_tid);
+ DRD_(s_rwlock_segment_creation_count)++;
+ p->acquiry_time_ms = VG_(read_millisecond_timer)();
+ p->acquired_at = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
}
/**
@@ -477,94 +479,95 @@ void DRD_(rwlock_post_wrlock)(const Addr rwlock, const Bool took_lock)
*/
void DRD_(rwlock_pre_unlock)(const Addr rwlock)
{
- const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
- const ThreadId vg_tid = VG_(get_running_tid)();
- struct rwlock_info* p;
- struct rwlock_thread_info* q;
-
- if (DRD_(s_trace_rwlock))
- {
- VG_(message)(Vg_UserMsg,
- "[%d/%d] rwlock_unlock 0x%lx",
- vg_tid,
- drd_tid,
- rwlock);
- }
-
- p = DRD_(rwlock_get)(rwlock);
- if (p == 0)
- {
- GenericErrInfo GEI;
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- GenericErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Not a reader-writer lock",
- &GEI);
- return;
- }
- if (! DRD_(rwlock_is_locked_by)(p, drd_tid))
- {
- RwlockErrInfo REI = { p->a1 };
- VG_(maybe_record_error)(vg_tid,
- RwlockErr,
- VG_(get_IP)(vg_tid),
- "Reader-writer lock not locked by calling thread",
- &REI);
- return;
- }
- q = DRD_(lookup_or_insert_node)(p->thread_info, drd_tid);
- tl_assert(q);
- if (q->reader_nesting_count > 0)
- {
- q->reader_nesting_count--;
- if (q->reader_nesting_count == 0 && DRD_(s_shared_threshold_ms) > 0)
- {
- ULong held = VG_(read_millisecond_timer)() - p->acquiry_time_ms;
- if (held > DRD_(s_shared_threshold_ms))
+ const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
+ const ThreadId vg_tid = VG_(get_running_tid)();
+ struct rwlock_info* p;
+ struct rwlock_thread_info* q;
+
+ if (DRD_(s_trace_rwlock))
+ {
+ VG_(message)(Vg_UserMsg,
+ "[%d/%d] rwlock_unlock 0x%lx",
+ vg_tid,
+ drd_tid,
+ rwlock);
+ }
+
+ p = DRD_(rwlock_get)(rwlock);
+ if (p == 0)
+ {
+ GenericErrInfo GEI;
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ GenericErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Not a reader-writer lock",
+ &GEI);
+ return;
+ }
+ if (! DRD_(rwlock_is_locked_by)(p, drd_tid))
+ {
+ RwlockErrInfo REI = { p->a1 };
+ VG_(maybe_record_error)(vg_tid,
+ RwlockErr,
+ VG_(get_IP)(vg_tid),
+ "Reader-writer lock not locked by calling thread",
+ &REI);
+ return;
+ }
+ q = DRD_(lookup_or_insert_node)(p->thread_info, drd_tid);
+ tl_assert(q);
+ if (q->reader_nesting_count > 0)
+ {
+ q->reader_nesting_count--;
+ if (q->reader_nesting_count == 0 && DRD_(s_shared_threshold_ms) > 0)
{
- HoldtimeErrInfo HEI
- = { rwlock, p->acquired_at, held, DRD_(s_shared_threshold_ms) };
- VG_(maybe_record_error)(vg_tid,
- HoldtimeErr,
- VG_(get_IP)(vg_tid),
- "rwlock",
- &HEI);
+ ULong held = VG_(read_millisecond_timer)() - p->acquiry_time_ms;
+ if (held > DRD_(s_shared_threshold_ms))
+ {
+ HoldtimeErrInfo HEI
+ = { rwlock, p->acquired_at, held, DRD_(s_shared_threshold_ms) };
+ VG_(maybe_record_error)(vg_tid,
+ HoldtimeErr,
+ VG_(get_IP)(vg_tid),
+ "rwlock",
+ &HEI);
+ }
}
- }
- }
- else if (q->writer_nesting_count > 0)
- {
- q->writer_nesting_count--;
- if (q->writer_nesting_count == 0 && DRD_(s_exclusive_threshold_ms) > 0)
- {
- ULong held = VG_(read_millisecond_timer)() - p->acquiry_time_ms;
- if (held > DRD_(s_exclusive_threshold_ms))
+ }
+ else if (q->writer_nesting_count > 0)
+ {
+ q->writer_nesting_count--;
+ if (q->writer_nesting_count == 0 && DRD_(s_exclusive_threshold_ms) > 0)
{
- HoldtimeErrInfo HEI
- = { rwlock, p->acquired_at, held, DRD_(s_exclusive_threshold_ms) };
- VG_(maybe_record_error)(vg_tid,
- HoldtimeErr,
- VG_(get_IP)(vg_tid),
- "rwlock",
- &HEI);
+ ULong held = VG_(read_millisecond_timer)() - p->acquiry_time_ms;
+ if (held > DRD_(s_exclusive_threshold_ms))
+ {
+ HoldtimeErrInfo HEI
+ = { rwlock, p->acquired_at, held,
+ DRD_(s_exclusive_threshold_ms) };
+ VG_(maybe_record_error)(vg_tid,
+ HoldtimeErr,
+ VG_(get_IP)(vg_tid),
+ "rwlock",
+ &HEI);
+ }
}
- }
- }
- else
- {
- tl_assert(False);
- }
-
- if (q->reader_nesting_count == 0 && q->writer_nesting_count == 0)
- {
- /* This pthread_rwlock_unlock() call really unlocks the rwlock. Save the */
- /* current vector clock of the thread such that it is available when */
- /* this rwlock is locked again. */
-
- DRD_(thread_get_latest_segment)(&q->last_unlock_segment, drd_tid);
- DRD_(thread_new_segment)(drd_tid);
- DRD_(s_rwlock_segment_creation_count)++;
- }
+ }
+ else
+ {
+ tl_assert(False);
+ }
+
+ if (q->reader_nesting_count == 0 && q->writer_nesting_count == 0)
+ {
+ /* This pthread_rwlock_unlock() call really unlocks the rwlock. Save */
+ /* the current vector clock of the thread such that it is available */
+ /* when this rwlock is locked again. */
+
+ DRD_(thread_get_latest_segment)(&q->last_unlock_segment, drd_tid);
+ DRD_(thread_new_segment)(drd_tid);
+ DRD_(s_rwlock_segment_creation_count)++;
+ }
}
/**
@@ -574,22 +577,22 @@ void DRD_(rwlock_pre_unlock)(const Addr rwlock)
static void rwlock_delete_thread(struct rwlock_info* const p,
const DrdThreadId tid)
{
- struct rwlock_thread_info* q;
- if (DRD_(rwlock_is_locked_by)(p, tid))
- {
- RwlockErrInfo REI = { p->a1 };
- VG_(maybe_record_error)(VG_(get_running_tid)(),
- RwlockErr,
- VG_(get_IP)(VG_(get_running_tid)()),
- "Reader-writer lock still locked at thread exit",
- &REI);
- q = DRD_(lookup_or_insert_node)(p->thread_info, tid);
- q->reader_nesting_count = 0;
- q->writer_nesting_count = 0;
- }
+ struct rwlock_thread_info* q;
+ if (DRD_(rwlock_is_locked_by)(p, tid))
+ {
+ RwlockErrInfo REI = { p->a1 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ RwlockErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
+ "Reader-writer lock still locked at thread exit",
+ &REI);
+ q = DRD_(lookup_or_insert_node)(p->thread_info, tid);
+ q->reader_nesting_count = 0;
+ q->writer_nesting_count = 0;
+ }
}
ULong DRD_(get_rwlock_segment_creation_count)(void)
{
- return DRD_(s_rwlock_segment_creation_count);
+ return DRD_(s_rwlock_segment_creation_count);
}