clean out includes, etc.
[model-checker.git] / clockvector.cc
1 #include <cstring>
2 #include <stdlib.h>
3
4 #include "model.h"
5 #include "action.h"
6 #include "clockvector.h"
7 #include "common.h"
8 #include "threads-model.h"
9
10 /**
11  * Constructs a new ClockVector, given a parent ClockVector and a first
12  * ModelAction. This constructor can assign appropriate default settings if no
13  * parent and/or action is supplied.
14  * @param parent is the previous ClockVector to inherit (i.e., clock from the
15  * same thread or the parent that created this thread)
16  * @param act is an action with which to update the ClockVector
17  */
18 ClockVector::ClockVector(ClockVector *parent, ModelAction *act)
19 {
20         num_threads = model->get_num_threads();
21         clock = (modelclock_t *)snapshot_calloc(num_threads, sizeof(int));
22         if (parent)
23                 std::memcpy(clock, parent->clock, parent->num_threads * sizeof(modelclock_t));
24
25         if (act)
26                 clock[id_to_int(act->get_tid())] = act->get_seq_number();
27 }
28
29 /** @brief Destructor */
30 ClockVector::~ClockVector()
31 {
32         snapshot_free(clock);
33 }
34
35 /**
36  * Merge a clock vector into this vector, using a pairwise comparison. The
37  * resulting vector length will be the maximum length of the two being merged.
38  * @param cv is the ClockVector being merged into this vector.
39  */
40 bool ClockVector::merge(const ClockVector *cv)
41 {
42         ASSERT(cv != NULL);
43         bool changed = false;
44         if (cv->num_threads > num_threads) {
45                 clock = (modelclock_t *)snapshot_realloc(clock, cv->num_threads * sizeof(modelclock_t));
46                 for (int i = num_threads; i < cv->num_threads; i++)
47                         clock[i] = 0;
48                 num_threads = cv->num_threads;
49         }
50
51         /* Element-wise maximum */
52         for (int i = 0; i < cv->num_threads; i++)
53                 if (cv->clock[i] > clock[i]) {
54                         clock[i] = cv->clock[i];
55                         changed = true;
56                 }
57         
58         return changed;
59 }
60
61 /**
62  * Check whether this vector's thread has synchronized with another action's
63  * thread. This effectively checks the happens-before relation (or actually,
64  * happens after), but it's easier to compare two ModelAction events directly,
65  * using ModelAction::happens_before.
66  *
67  * @see ModelAction::happens_before
68  *
69  * @return true if this ClockVector's thread has synchronized with act's
70  * thread, false otherwise. That is, this function returns:
71  * <BR><CODE>act <= cv[act->tid]</CODE>
72  */
73 bool ClockVector::synchronized_since(const ModelAction *act) const
74 {
75         int i = id_to_int(act->get_tid());
76
77         if (i < num_threads)
78                 return act->get_seq_number() <= clock[i];
79         return false;
80 }
81
82 /** Gets the clock corresponding to a given thread id from the clock vector. */
83 modelclock_t ClockVector::getClock(thread_id_t thread) {
84         int threadid = id_to_int(thread);
85
86         if (threadid < num_threads)
87                 return clock[threadid];
88         else
89                 return 0;
90 }
91
92 /** @brief Formats and prints this ClockVector's data. */
93 void ClockVector::print() const
94 {
95         int i;
96         model_print("CV: (");
97         for (i = 0; i < num_threads; i++)
98                 model_print("%2u%s", clock[i], (i == num_threads - 1) ? ")\n" : ", ");
99 }