return rwlock_is_rdlocked_by(p, tid) || rwlock_is_wrlocked_by(p, tid);
}
+/** Either look up or insert a node corresponding to DRD thread id 'tid'. */
static
struct rwlock_thread_info* lookup_or_insert_node(OSet* oset, const UWord 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->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);
}
return q;
}
+/** Combine the vector clock corresponding to the last unlock operation of
+ * reader-writer lock p into the vector clock of thread 'tid'.
+ */
static void rwlock_combine_other_vc(struct rwlock_info* const p,
const DrdThreadId tid,
const Bool readers_too)
}
}
+/** Initialize the rwlock_info data structure *p. */
static
void rwlock_initialize(struct rwlock_info* const p, const Addr rwlock)
{
{
struct rwlock_info* p;
- p = rwlock_get_or_allocate(rwlock);
-
- tl_assert(p);
-
if (s_trace_rwlock)
{
VG_(message)(Vg_UserMsg,
rwlock);
}
+ p = rwlock_get_or_allocate(rwlock);
+ tl_assert(p);
+
if (rwlock_is_wrlocked_by(p, thread_get_running_tid()))
{
VG_(message)(Vg_UserMsg,
}
}
-/**
- * Update rwlock_info state when locking the pthread_rwlock_t mutex.
- * Note: this function must be called after pthread_rwlock_rdlock() has been
- * called, or a race condition is triggered !
+/** Update rwlock_info state when locking the pthread_rwlock_t mutex.
+ * Note: this function must be called after pthread_rwlock_rdlock() has been
+ * called, or a race condition is triggered !
*/
void rwlock_post_rdlock(const Addr rwlock, const Bool took_lock)
{
struct rwlock_info* p;
struct rwlock_thread_info* q;
- p = rwlock_get(rwlock);
-
if (s_trace_rwlock)
{
VG_(message)(Vg_UserMsg,
rwlock);
}
+ p = rwlock_get(rwlock);
+
if (! p || ! took_lock)
return;
if (++q->reader_nesting_count == 1)
{
rwlock_combine_other_vc(p, drd_tid, False);
+ q->last_lock_was_writer_lock = False;
thread_new_segment(drd_tid);
s_rwlock_segment_creation_count++;
}
/**
* Update rwlock_info state when locking the pthread_rwlock_t rwlock.
- * Note: this function must be called after pthread_rwlock_wrlock() has been
- * called, or a race condition is triggered !
+ * Note: this function must be called after pthread_rwlock_wrlock() has
+ * finished, or a race condition is triggered !
*/
void rwlock_post_wrlock(const Addr rwlock, const Bool took_lock)
{
/* this rwlock is locked again. */
thread_get_latest_segment(&q->last_unlock_segment, drd_tid);
- q->last_lock_was_writer_lock = False;
thread_new_segment(drd_tid);
s_rwlock_segment_creation_count++;
}