if (p->recursion_count == 0)
{
- const DrdThreadId last_owner = p->owner;
-
- DRD_(thread_new_segment)(drd_tid);
- s_mutex_segment_creation_count++;
-
- if (last_owner != drd_tid && last_owner != DRD_INVALID_THREADID)
+ if (p->owner != drd_tid && p->owner != DRD_INVALID_THREADID)
{
tl_assert(p->last_locked_segment);
- DRD_(thread_combine_vc_sync)(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++;
p->owner = drd_tid;
p->acquiry_time_ms = VG_(read_millisecond_timer)();
tl_assert(sg);
if (sg)
{
- DRD_(thread_new_segment)(tid);
- s_semaphore_segment_creation_count++;
-
if (p->last_sem_post_tid != tid
&& p->last_sem_post_tid != DRD_INVALID_THREADID)
{
- DRD_(thread_combine_vc_sync)(tid, sg);
+ DRD_(thread_new_segment_and_combine_vc)(tid, sg);
}
+ else
+ DRD_(thread_new_segment)(tid);
+ s_semaphore_segment_creation_count++;
DRD_(sg_put)(sg);
}
}
DRD_(vc_copy)(&old_vc, &DRD_(g_threadinfo)[joiner].last->vc);
DRD_(vc_combine)(&DRD_(g_threadinfo)[joiner].last->vc,
- &DRD_(g_threadinfo)[joinee].last->vc);
+ &DRD_(g_threadinfo)[joinee].last->vc);
DRD_(thread_update_conflict_set)(joiner, &old_vc);
s_update_conflict_set_join_count++;
DRD_(vc_cleanup)(&old_vc);
else
{
DRD_(vc_combine)(&DRD_(g_threadinfo)[joiner].last->vc,
- &DRD_(g_threadinfo)[joinee].last->vc);
+ &DRD_(g_threadinfo)[joinee].last->vc);
}
thread_discard_ordered_segments();
/**
* Update the vector clock of the last segment of thread tid with the
- * the vector clock of segment sg. Call this function after thread tid had
- * to wait because of thread synchronization until the memory accesses in the
- * segment sg finished.
+ * the vector clock of segment sg.
*/
-void DRD_(thread_combine_vc_sync)(DrdThreadId tid, const Segment* sg)
+static void thread_combine_vc_sync(DrdThreadId tid, const Segment* sg)
{
const VectorClock* const vc = &sg->vc;
}
}
+/**
+ * Create a new segment for thread tid and update the vector clock of the last
+ * segment of this thread with the the vector clock of segment sg. Call this
+ * function after thread tid had to wait because of thread synchronization
+ * until the memory accesses in the segment sg finished.
+ */
+void DRD_(thread_new_segment_and_combine_vc)(DrdThreadId tid, const Segment* sg)
+{
+ tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
+ && tid != DRD_INVALID_THREADID);
+ tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid)));
+ tl_assert(sg);
+
+ thread_append_segment(tid, DRD_(sg_new)(tid, tid));
+
+ thread_combine_vc_sync(tid, sg);
+
+ if (s_segment_merging
+ && ++s_new_segments_since_last_merge >= s_segment_merge_interval)
+ {
+ thread_discard_ordered_segments();
+ thread_merge_segments();
+ }
+}
+
/**
* Call this function whenever a thread is no longer using the memory
* [ a1, a2 [, e.g. because of a call to free() or a stack pointer
if (*conflict_set)
{
- DRD_(bm_delete)(*conflict_set);
+ DRD_(bm_cleanup)(*conflict_set);
+ DRD_(bm_init)(*conflict_set);
+ }
+ else
+ {
+ *conflict_set = DRD_(bm_new)();
}
- *conflict_set = DRD_(bm_new)();
if (s_trace_conflict_set)
{
void DRD_(thread_get_latest_segment)(Segment** sg, const DrdThreadId tid);
void DRD_(thread_combine_vc_join)(const DrdThreadId joiner,
const DrdThreadId joinee);
-void DRD_(thread_combine_vc_sync)(const DrdThreadId tid, const Segment* sg);
+void DRD_(thread_new_segment_and_combine_vc)(DrdThreadId tid,
+ const Segment* sg);
void DRD_(thread_update_conflict_set)(const DrdThreadId tid,
const VectorClock* const old_vc);