model/threads: add documentation comments
[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 void ClockVector::merge(const ClockVector *cv)
41 {
42         ASSERT(cv != NULL);
43
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 }
56
57 /**
58  * Check whether this vector's thread has synchronized with another action's
59  * thread. This effectively checks the happens-before relation (or actually,
60  * happens after), but it's easier to compare two ModelAction events directly,
61  * using ModelAction::happens_before.
62  *
63  * @see ModelAction::happens_before
64  *
65  * @return true if this ClockVector's thread has synchronized with act's
66  * thread, false otherwise. That is, this function returns:
67  * <BR><CODE>act <= cv[act->tid]</CODE>
68  */
69 bool ClockVector::synchronized_since(const ModelAction *act) const
70 {
71         int i = id_to_int(act->get_tid());
72
73         if (i < num_threads)
74                 return act->get_seq_number() <= clock[i];
75         return false;
76 }
77
78 /** Gets the clock corresponding to a given thread id from the clock vector. */
79 modelclock_t ClockVector::getClock(thread_id_t thread) {
80         int threadid = id_to_int(thread);
81
82         if (threadid < num_threads)
83                 return clock[threadid];
84         else
85                 return 0;
86 }
87
88 /** @brief Formats and prints this ClockVector's data. */
89 void ClockVector::print() const
90 {
91         int i;
92         model_print("CV: (");
93         for (i = 0; i < num_threads; i++)
94                 model_print("%2u%s", clock[i], (i == num_threads - 1) ? ")\n" : ", ");
95 }