Wrapped DRD_() macro around all vector clock function names.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9159
This commit is contained in:
Bart Van Assche 2009-02-14 16:55:19 +00:00
parent 498c9afeb5
commit c5f4cc3cf1
12 changed files with 174 additions and 150 deletions

View File

@ -23,7 +23,7 @@
*/
// Barrier state information.
/* Barrier state information. */
#ifndef __DRD_BARRIER_H
@ -32,7 +32,6 @@
#include "drd_clientreq.h" // BarrierT
#include "drd_thread.h" // DrdThreadId
#include "drd_vc.h"
#include "pub_tool_basics.h" // Addr

View File

@ -35,4 +35,7 @@
#define DRD_(str) VGAPPEND(vgDrd_, str)
typedef UInt DrdThreadId;
#endif /* __DRD_BASICS_H */

View File

@ -24,6 +24,7 @@
#include "drd_bitmap.h"
#include "drd_thread_bitmap.h"
#include "drd_vc.h" /* DRD_(vc_snprint)() */
/* Include several source files here in order to allow the compiler to */
/* do more inlining. */
@ -73,7 +74,7 @@ void DRD_(trace_mem_access)(const Addr addr, const SizeT size,
if (DRD_(is_any_traced)(addr, addr + size))
{
char vc[80];
vc_snprint(vc, sizeof(vc), thread_get_vc(thread_get_running_tid()));
DRD_(vc_snprint)(vc, sizeof(vc), thread_get_vc(thread_get_running_tid()));
VG_(message)(Vg_UserMsg,
"%s 0x%lx size %ld (vg %d / drd %d / vc %s)",
access_type == eLoad

View File

@ -35,7 +35,6 @@
#include "drd_semaphore.h"
#include "drd_suppression.h"
#include "drd_thread.h"
#include "drd_vc.h"
#include "libvex_guest_offsets.h"
#include "pub_drd_bitmap.h"
#include "pub_tool_vki.h" // Must be included before pub_tool_libcproc

View File

@ -29,7 +29,6 @@
#include "drd_clientreq.h" // MutexT
#include "drd_thread.h" // DrdThreadId
#include "drd_vc.h"
#include "pub_tool_basics.h" // Addr

View File

@ -32,7 +32,6 @@
#include "drd_clientobj.h" // struct rwlock_info
#include "drd_thread.h" // DrdThreadId
#include "drd_vc.h"
#include "pub_tool_basics.h" // Addr

View File

@ -73,10 +73,10 @@ void sg_init(Segment* const sg,
sg->stacktrace = 0;
if (creator_sg)
vc_copy(&sg->vc, &creator_sg->vc);
DRD_(vc_copy)(&sg->vc, &creator_sg->vc);
else
vc_init(&sg->vc, 0, 0);
vc_increment(&sg->vc, created);
DRD_(vc_init)(&sg->vc, 0, 0);
DRD_(vc_increment)(&sg->vc, created);
sg->bm = bm_new();
if (drd_trace_segment)
@ -88,7 +88,7 @@ void sg_init(Segment* const sg,
? DrdThreadIdToVgThreadId(created)
: DRD_INVALID_THREADID,
created);
vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
DRD_(vc_snprint)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&sg->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
@ -101,7 +101,7 @@ void sg_cleanup(Segment* const sg)
tl_assert(sg);
tl_assert(sg->refcnt == 0);
vc_cleanup(&sg->vc);
DRD_(vc_cleanup)(&sg->vc);
bm_delete(sg->bm);
sg->bm = 0;
}
@ -131,7 +131,7 @@ void sg_delete(Segment* const sg)
char msg[256];
VG_(snprintf)(msg, sizeof(msg),
"Discarding the segment with vector clock ");
vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
DRD_(vc_snprint)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&sg->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
@ -175,7 +175,7 @@ void sg_put(Segment* const sg)
VG_(snprintf)(msg, sizeof(msg),
"Decrementing segment reference count %d -> %d with vc ",
sg->refcnt, sg->refcnt - 1);
vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
DRD_(vc_snprint)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&sg->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
@ -201,11 +201,11 @@ void sg_merge(const Segment* const sg1, Segment* const sg2)
char msg[256];
VG_(snprintf)(msg, sizeof(msg), "Merging segments with vector clocks ");
vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
DRD_(vc_snprint)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&sg1->vc);
VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
" and ");
vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
DRD_(vc_snprint)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&sg2->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
@ -220,7 +220,7 @@ void sg_print(const Segment* const sg)
{
tl_assert(sg);
VG_(printf)("vc: ");
vc_print(&sg->vc);
DRD_(vc_print)(&sg->vc);
VG_(printf)("\n");
bm_print(sg->bm);
}

View File

@ -31,7 +31,6 @@
#include "drd_thread.h" // DrdThreadId
#include "drd_vc.h"
#include "pub_tool_basics.h" // Addr

View File

@ -257,8 +257,8 @@ void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee)
{
VG_(snprintf)(msg + VG_(strlen)(msg), msg_size - VG_(strlen)(msg),
", new vc: ");
vc_snprint(msg + VG_(strlen)(msg), msg_size - VG_(strlen)(msg),
thread_get_vc(drd_joiner));
DRD_(vc_snprint)(msg + VG_(strlen)(msg), msg_size - VG_(strlen)(msg),
thread_get_vc(drd_joiner));
}
VG_(message)(Vg_DebugMsg, "%s", msg);
VG_(free)(msg);
@ -568,9 +568,9 @@ static void thread_compute_minimum_vc(VectorClock* vc)
if (latest_sg)
{
if (first)
vc_assign(vc, &latest_sg->vc);
DRD_(vc_assign)(vc, &latest_sg->vc);
else
vc_min(vc, &latest_sg->vc);
DRD_(vc_min)(vc, &latest_sg->vc);
first = False;
}
}
@ -589,9 +589,9 @@ static void thread_compute_maximum_vc(VectorClock* vc)
if (latest_sg)
{
if (first)
vc_assign(vc, &latest_sg->vc);
DRD_(vc_assign)(vc, &latest_sg->vc);
else
vc_combine(vc, &latest_sg->vc);
DRD_(vc_combine)(vc, &latest_sg->vc);
first = False;
}
}
@ -609,25 +609,25 @@ static void thread_discard_ordered_segments(void)
s_discard_ordered_segments_count++;
vc_init(&thread_vc_min, 0, 0);
DRD_(vc_init)(&thread_vc_min, 0, 0);
thread_compute_minimum_vc(&thread_vc_min);
if (sg_get_trace())
{
char msg[256];
VectorClock thread_vc_max;
vc_init(&thread_vc_max, 0, 0);
DRD_(vc_init)(&thread_vc_max, 0, 0);
thread_compute_maximum_vc(&thread_vc_max);
VG_(snprintf)(msg, sizeof(msg),
"Discarding ordered segments -- min vc is ");
vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&thread_vc_min);
DRD_(vc_snprint)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&thread_vc_min);
VG_(snprintf)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
", max vc is ");
vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&thread_vc_max);
DRD_(vc_snprint)(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
&thread_vc_max);
VG_(message)(Vg_UserMsg, "%s", msg);
vc_cleanup(&thread_vc_max);
DRD_(vc_cleanup)(&thread_vc_max);
}
for (i = 0; i < sizeof(s_threadinfo) / sizeof(s_threadinfo[0]); i++)
@ -635,13 +635,13 @@ static void thread_discard_ordered_segments(void)
Segment* sg;
Segment* sg_next;
for (sg = s_threadinfo[i].first;
sg && (sg_next = sg->next) && vc_lte(&sg->vc, &thread_vc_min);
sg && (sg_next = sg->next) && DRD_(vc_lte)(&sg->vc, &thread_vc_min);
sg = sg_next)
{
thread_discard_segment(i, sg);
}
}
vc_cleanup(&thread_vc_min);
DRD_(vc_cleanup)(&thread_vc_min);
}
/** Merge all segments that may be merged without triggering false positives
@ -690,7 +690,7 @@ static void thread_merge_segments(void)
* @param new_sg Pointer to the most recent segment of thread tid.
*/
static Bool conflict_set_update_needed(const DrdThreadId tid,
const Segment* const new_sg)
const Segment* const new_sg)
{
#if 0
unsigned i;
@ -721,19 +721,19 @@ static Bool conflict_set_update_needed(const DrdThreadId tid,
/* If the expression below evaluates to false, this expression will */
/* also evaluate to false for all subsequent iterations. So stop */
/* iterating. */
if (vc_lte(&q->vc, &old_sg->vc))
if (DRD_(vc_lte)(&q->vc, &old_sg->vc))
break;
/* If the vector clock of the 2nd the last segment is not ordered */
/* to the vector clock of segment q, and the last segment is, ask */
/* the caller to update the conflict set. */
if (! vc_lte(&old_sg->vc, &q->vc))
if (! DRD_(vc_lte)(&old_sg->vc, &q->vc))
{
return True;
}
/* If the vector clock of the last segment is not ordered to the */
/* vector clock of segment q, ask the caller to update the conflict */
/* set. */
if (! vc_lte(&q->vc, &new_sg->vc) && ! vc_lte(&new_sg->vc, &q->vc))
if (! DRD_(vc_lte)(&q->vc, &new_sg->vc) && ! DRD_(vc_lte)(&new_sg->vc, &q->vc))
{
return True;
}
@ -785,7 +785,7 @@ void thread_combine_vc(DrdThreadId joiner, DrdThreadId joinee)
&& joinee != DRD_INVALID_THREADID);
tl_assert(s_threadinfo[joiner].last);
tl_assert(s_threadinfo[joinee].last);
vc_combine(&s_threadinfo[joiner].last->vc, &s_threadinfo[joinee].last->vc);
DRD_(vc_combine)(&s_threadinfo[joiner].last->vc, &s_threadinfo[joinee].last->vc);
thread_discard_ordered_segments();
if (joiner == s_drd_running_tid)
@ -804,7 +804,7 @@ void thread_combine_vc2(DrdThreadId tid, const VectorClock* const vc)
&& tid != DRD_INVALID_THREADID);
tl_assert(s_threadinfo[tid].last);
tl_assert(vc);
vc_combine(&s_threadinfo[tid].last->vc, vc);
DRD_(vc_combine)(&s_threadinfo[tid].last->vc, vc);
thread_compute_conflict_set(&s_conflict_set, tid);
thread_discard_ordered_segments();
s_conflict_set_combine_vc_count++;
@ -940,9 +940,9 @@ thread_report_conflicting_segments_segment(const DrdThreadId tid,
// decreasing vector clocks, if q->vc <= p->vc, then
// q->next->vc <= p->vc will also hold. Hence, break out of the
// loop once this condition is met.
if (vc_lte(&q->vc, &p->vc))
if (DRD_(vc_lte)(&q->vc, &p->vc))
break;
if (! vc_lte(&p->vc, &q->vc))
if (! DRD_(vc_lte)(&p->vc, &q->vc))
{
if (bm_has_conflict_with(q->bm, addr, addr + size, access_type))
{
@ -1030,9 +1030,9 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
VG_(snprintf)(msg, sizeof(msg),
"computing conflict set for thread %d/%d with vc ",
DrdThreadIdToVgThreadId(tid), tid);
vc_snprint(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&s_threadinfo[tid].last->vc);
DRD_(vc_snprint)(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&s_threadinfo[tid].last->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
@ -1047,9 +1047,9 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
VG_(snprintf)(msg, sizeof(msg),
"conflict set: thread [%d] at vc ",
tid);
vc_snprint(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&p->vc);
DRD_(vc_snprint)(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&p->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
@ -1060,16 +1060,16 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
const Segment* q;
for (q = s_threadinfo[j].last; q; q = q->prev)
{
if (! vc_lte(&q->vc, &p->vc) && ! vc_lte(&p->vc, &q->vc))
if (! DRD_(vc_lte)(&q->vc, &p->vc) && ! DRD_(vc_lte)(&p->vc, &q->vc))
{
if (s_trace_conflict_set)
{
char msg[256];
VG_(snprintf)(msg, sizeof(msg),
"conflict set: [%d] merging segment ", j);
vc_snprint(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&q->vc);
DRD_(vc_snprint)(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&q->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
bm_merge2(*conflict_set, q->bm);
@ -1081,9 +1081,9 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
char msg[256];
VG_(snprintf)(msg, sizeof(msg),
"conflict set: [%d] ignoring segment ", j);
vc_snprint(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&q->vc);
DRD_(vc_snprint)(msg + VG_(strlen)(msg),
sizeof(msg) - VG_(strlen)(msg),
&q->vc);
VG_(message)(Vg_UserMsg, "%s", msg);
}
}

View File

@ -53,7 +53,6 @@
// Type definitions.
typedef UInt DrdThreadId;
typedef UWord PThreadId;
typedef struct

View File

@ -26,25 +26,33 @@
#include "drd_vc.h"
#include "pub_tool_basics.h" // Addr, SizeT
#include "pub_tool_libcassert.h" // tl_assert()
#include "pub_tool_libcbase.h" // VG_(memset), VG_(memmove)
#include "pub_tool_libcbase.h" // VG_(memcpy)
#include "pub_tool_libcprint.h" // VG_(printf)
#include "pub_tool_mallocfree.h" // VG_(malloc), VG_(free)
#include "pub_tool_threadstate.h" // VG_(get_running_tid)
/* Local function declarations. */
static
void vc_reserve(VectorClock* const vc, const unsigned new_capacity);
void DRD_(vc_reserve)(VectorClock* const vc, const unsigned new_capacity);
void vc_init(VectorClock* const vc,
const VCElem* const vcelem,
const unsigned size)
/* Function definitions. */
/**
* Initialize the memory 'vc' points at as a vector clock with size 'size'.
* If the pointer 'vcelem' is not null, it is assumed to be an array with
* 'size' elements and it becomes the initial value of the vector clock.
*/
void DRD_(vc_init)(VectorClock* const vc,
const VCElem* const vcelem,
const unsigned size)
{
tl_assert(vc);
vc->size = 0;
vc->capacity = 0;
vc->vc = 0;
vc_reserve(vc, size);
DRD_(vc_reserve)(vc, size);
tl_assert(size == 0 || vc->vc != 0);
if (vcelem)
{
@ -53,32 +61,32 @@ void vc_init(VectorClock* const vc,
}
}
void vc_cleanup(VectorClock* const vc)
/** Reset vc to the empty vector clock. */
void DRD_(vc_cleanup)(VectorClock* const vc)
{
vc_reserve(vc, 0);
DRD_(vc_reserve)(vc, 0);
}
/** Copy constructor -- initializes *new. */
void vc_copy(VectorClock* const new,
const VectorClock* const rhs)
void DRD_(vc_copy)(VectorClock* const new, const VectorClock* const rhs)
{
vc_init(new, rhs->vc, rhs->size);
DRD_(vc_init)(new, rhs->vc, rhs->size);
}
/** Assignment operator -- *lhs is already a valid vector clock. */
void vc_assign(VectorClock* const lhs,
const VectorClock* const rhs)
void DRD_(vc_assign)(VectorClock* const lhs, const VectorClock* const rhs)
{
vc_cleanup(lhs);
vc_copy(lhs, rhs);
DRD_(vc_cleanup)(lhs);
DRD_(vc_copy)(lhs, rhs);
}
void vc_increment(VectorClock* const vc, ThreadId const threadid)
/** Increment the clock of thread 'tid' in vector clock 'vc'. */
void DRD_(vc_increment)(VectorClock* const vc, DrdThreadId const tid)
{
unsigned i;
for (i = 0; i < vc->size; i++)
{
if (vc->vc[i].threadid == threadid)
if (vc->vc[i].threadid == tid)
{
typeof(vc->vc[i].count) const oldcount = vc->vc[i].count;
vc->vc[i].count++;
@ -88,14 +96,16 @@ void vc_increment(VectorClock* const vc, ThreadId const threadid)
}
}
// The specified thread ID does not yet exist in the vector clock
// -- insert it.
/*
* The specified thread ID does not yet exist in the vector clock
* -- insert it.
*/
{
VCElem vcelem = { threadid, 1 };
const VCElem vcelem = { tid, 1 };
VectorClock vc2;
vc_init(&vc2, &vcelem, 1);
vc_combine(vc, &vc2);
vc_cleanup(&vc2);
DRD_(vc_init)(&vc2, &vcelem, 1);
DRD_(vc_combine)(vc, &vc2);
DRD_(vc_cleanup)(&vc2);
}
}
@ -103,14 +113,14 @@ void vc_increment(VectorClock* const vc, ThreadId const threadid)
* @return True if vector clocks vc1 and vc2 are ordered, and false otherwise.
* Order is as imposed by thread synchronization actions ("happens before").
*/
Bool vc_ordered(const VectorClock* const vc1,
const VectorClock* const vc2)
Bool DRD_(vc_ordered)(const VectorClock* const vc1,
const VectorClock* const vc2)
{
return vc_lte(vc1, vc2) || vc_lte(vc2, vc1);
return DRD_(vc_lte)(vc1, vc2) || DRD_(vc_lte)(vc2, vc1);
}
/** Compute elementwise minimum. */
void vc_min(VectorClock* const result, const VectorClock* const rhs)
void DRD_(vc_min)(VectorClock* const result, const VectorClock* const rhs)
{
unsigned i;
unsigned j;
@ -118,7 +128,7 @@ void vc_min(VectorClock* const result, const VectorClock* const rhs)
tl_assert(result);
tl_assert(rhs);
vc_check(result);
DRD_(vc_check)(result);
/* Next, combine both vector clocks into one. */
i = 0;
@ -145,26 +155,26 @@ void vc_min(VectorClock* const result, const VectorClock* const rhs)
}
}
}
vc_check(result);
DRD_(vc_check)(result);
}
/**
* Compute elementwise maximum.
*/
void vc_combine(VectorClock* const result,
const VectorClock* const rhs)
void DRD_(vc_combine)(VectorClock* const result, const VectorClock* const rhs)
{
vc_combine2(result, rhs, -1);
DRD_(vc_combine2)(result, rhs, -1);
}
/** Compute elementwise maximum.
/**
* Compute elementwise maximum.
*
* @return True if *result and *rhs are equal, or if *result and *rhs only
* differ in the component with thread ID tid.
* @return True if *result and *rhs are equal, or if *result and *rhs only
* differ in the component with thread ID tid.
*/
Bool vc_combine2(VectorClock* const result,
const VectorClock* const rhs,
const ThreadId tid)
Bool DRD_(vc_combine2)(VectorClock* const result,
const VectorClock* const rhs,
const DrdThreadId tid)
{
unsigned i;
unsigned j;
@ -188,13 +198,13 @@ Bool vc_combine2(VectorClock* const result,
shared++;
}
vc_check(result);
DRD_(vc_check)(result);
new_size = result->size + rhs->size - shared;
if (new_size > result->capacity)
vc_reserve(result, new_size);
DRD_(vc_reserve)(result, new_size);
vc_check(result);
DRD_(vc_check)(result);
// Next, combine both vector clocks into one.
i = 0;
@ -251,13 +261,14 @@ Bool vc_combine2(VectorClock* const result,
}
}
}
vc_check(result);
DRD_(vc_check)(result);
tl_assert(result->size == new_size);
return almost_equal;
}
void vc_print(const VectorClock* const vc)
/** Print the contents of vector clock 'vc'. */
void DRD_(vc_print)(const VectorClock* const vc)
{
unsigned i;
@ -272,8 +283,12 @@ void vc_print(const VectorClock* const vc)
VG_(printf)(" ]");
}
void vc_snprint(Char* const str, Int const size,
const VectorClock* const vc)
/**
* Print the contents of vector clock 'vc' to the character array 'str' that
* has 'size' elements.
*/
void DRD_(vc_snprint)(Char* const str, const Int size,
const VectorClock* const vc)
{
unsigned i;
unsigned j = 1;
@ -296,8 +311,15 @@ void vc_snprint(Char* const str, Int const size,
/**
* Invariant test.
*
* The function below tests whether the following two conditions are
* satisfied:
* - size <= capacity.
* - Vector clock elements are stored in thread ID order.
*
* If one of these conditions is not met, an assertion failure is triggered.
*/
void vc_check(const VectorClock* const vc)
void DRD_(vc_check)(const VectorClock* const vc)
{
unsigned i;
tl_assert(vc->size <= vc->capacity);
@ -313,7 +335,7 @@ void vc_check(const VectorClock* const vc)
* block is increased, the newly allocated memory is not initialized.
*/
static
void vc_reserve(VectorClock* const vc, const unsigned new_capacity)
void DRD_(vc_reserve)(VectorClock* const vc, const unsigned new_capacity)
{
tl_assert(vc);
if (new_capacity > vc->capacity)
@ -337,10 +359,11 @@ void vc_reserve(VectorClock* const vc, const unsigned new_capacity)
tl_assert(new_capacity == 0 || vc->vc != 0);
}
#if 0
/**
* Unit test.
*/
void vc_test(void)
void DRD_(vc_test)(void)
{
VectorClock vc1;
VCElem vc1elem[] = { { 3, 7 }, { 5, 8 }, };
@ -378,3 +401,4 @@ void vc_test(void)
vc_cleanup(&vc2);
vc_cleanup(&vc3);
}
#endif

View File

@ -27,67 +27,69 @@
#define __DRD_VC_H
// DRD vector clock implementation:
// - One counter per thread.
// - A vector clock is implemented as multiple pairs of (thread id, counter).
// - Pairs are stored in an array sorted by thread id.
// Semantics:
// - Each time a thread performs an action that implies an ordering between
// intra-thread events, the counter of that thread is incremented.
// - Vector clocks are compared by comparing all counters of all threads.
// - When a thread synchronization action is performed that guarantees that
// new actions of the current thread are executed after the actions of the
// other thread, the vector clock of the synchronization object and the
// current thread are combined (by taking the component-wise maximum).
// - A vector clock is incremented during actions such as
// pthread_create(), pthread_mutex_unlock(), sem_post(). (Actions where
// an inter-thread ordering "arrow" starts).
/*
* DRD vector clock implementation:
* - One counter per thread.
* - A vector clock is implemented as multiple pairs of (thread id, counter).
* - Pairs are stored in an array sorted by thread id.
*
* Semantics:
* - Each time a thread performs an action that implies an ordering between
* intra-thread events, the counter of that thread is incremented.
* - Vector clocks are compared by comparing all counters of all threads.
* - When a thread synchronization action is performed that guarantees that
* new actions of the current thread are executed after the actions of the
* other thread, the vector clock of the synchronization object and the
* current thread are combined (by taking the component-wise maximum).
* - A vector clock is incremented during actions such as
* pthread_create(), pthread_mutex_unlock(), sem_post(). (Actions where
* an inter-thread ordering "arrow" starts).
*/
#include "pub_tool_basics.h" // Addr, SizeT
/** Vector clock element. */
typedef struct
{
ThreadId threadid;
UInt count;
DrdThreadId threadid;
UInt count;
} VCElem;
typedef struct
{
unsigned capacity;
unsigned size;
VCElem* vc;
unsigned capacity; /**< number of elements allocated for array vc. */
unsigned size; /**< number of elements used of array vc. */
VCElem* vc; /**< vector clock elements. */
} VectorClock;
void vc_init(VectorClock* const vc,
const VCElem* const vcelem,
const unsigned size);
void vc_cleanup(VectorClock* const vc);
void vc_copy(VectorClock* const new,
const VectorClock* const rhs);
void vc_assign(VectorClock* const lhs,
const VectorClock* const rhs);
UInt vc_get(VectorClock* const vc, const ThreadId tid);
void vc_increment(VectorClock* const vc, ThreadId const threadid);
void DRD_(vc_init)(VectorClock* const vc,
const VCElem* const vcelem,
const unsigned size);
void DRD_(vc_cleanup)(VectorClock* const vc);
void DRD_(vc_copy)(VectorClock* const new, const VectorClock* const rhs);
void DRD_(vc_assign)(VectorClock* const lhs, const VectorClock* const rhs);
UInt DRD_(vc_get)(VectorClock* const vc, const DrdThreadId tid);
void DRD_(vc_increment)(VectorClock* const vc, DrdThreadId const tid);
static __inline__
Bool vc_lte(const VectorClock* const vc1,
const VectorClock* const vc2);
Bool vc_ordered(const VectorClock* const vc1,
const VectorClock* const vc2);
void vc_min(VectorClock* const result,
const VectorClock* const rhs);
void vc_combine(VectorClock* const result,
const VectorClock* const rhs);
Bool vc_combine2(VectorClock* const result,
const VectorClock* const rhs,
const ThreadId tid);
void vc_print(const VectorClock* const vc);
void vc_snprint(Char* const str, Int const size,
const VectorClock* const vc);
void vc_check(const VectorClock* const vc);
void vc_test(void);
Bool DRD_(vc_lte)(const VectorClock* const vc1,
const VectorClock* const vc2);
Bool DRD_(vc_ordered)(const VectorClock* const vc1,
const VectorClock* const vc2);
void DRD_(vc_min)(VectorClock* const result,
const VectorClock* const rhs);
void DRD_(vc_combine)(VectorClock* const result,
const VectorClock* const rhs);
Bool DRD_(vc_combine2)(VectorClock* const result,
const VectorClock* const rhs,
const DrdThreadId tid);
void DRD_(vc_print)(const VectorClock* const vc);
void DRD_(vc_snprint)(Char* const str, const Int size,
const VectorClock* const vc);
void DRD_(vc_check)(const VectorClock* const vc);
void DRD_(vc_test)(void);
@ -97,7 +99,7 @@ void vc_test(void);
* equal.
*/
static __inline__
Bool vc_lte(const VectorClock* const vc1, const VectorClock* const vc2)
Bool DRD_(vc_lte)(const VectorClock* const vc1, const VectorClock* const vc2)
{
unsigned i;
unsigned j = 0;