diff options
author | bart <bart@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2009-03-26 19:07:15 +0000 |
---|---|---|
committer | bart <bart@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2009-03-26 19:07:15 +0000 |
commit | bedfd237fbdc80d0c917cfcb85a94b5561c92633 (patch) | |
tree | ca3765f5de096ac686cb53fa0bc47585b031c373 /drd/drd_rwlock.c | |
parent | cd7bfdf7393ca23803c4097b540e214b3aca01c4 (diff) | |
download | valgrind-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.c | 757 |
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); } |