cleanup plugin interface a little more.
[cdsspec-compiler.git] / nodestack.h
1 /** @file nodestack.h
2  *  @brief Stack of operations for use in backtracking.
3 */
4
5 #ifndef __NODESTACK_H__
6 #define __NODESTACK_H__
7
8 #include <cstddef>
9 #include <inttypes.h>
10
11 #include "mymemory.h"
12 #include "schedule.h"
13 #include "promise.h"
14 #include "stl-model.h"
15
16 class ModelAction;
17 class Thread;
18
19 struct fairness_info {
20         unsigned int enabled_count;
21         unsigned int turns;
22         bool priority;
23 };
24
25 /**
26  * @brief Types of read-from relations
27  *
28  * Our "may-read-from" set is composed of multiple types of reads, and we have
29  * to iterate through all of them in the backtracking search. This enumeration
30  * helps to identify which type of read-from we are currently observing.
31  */
32 typedef enum {
33         READ_FROM_PAST, /**< @brief Read from a prior, existing store */
34         READ_FROM_PROMISE, /**< @brief Read from an existing promised future value */
35         READ_FROM_FUTURE, /**< @brief Read from a newly-asserted future value */
36         READ_FROM_NONE, /**< @brief A NULL state, which should not be reached */
37 } read_from_type_t;
38
39 #define YIELD_E 1
40 #define YIELD_D 2
41 #define YIELD_S 4
42 #define YIELD_P 8
43 #define YIELD_INDEX(tid1, tid2, num_threads) (tid1*num_threads+tid2)
44
45
46 /**
47  * @brief A single node in a NodeStack
48  *
49  * Represents a single node in the NodeStack. Each Node is associated with up
50  * to one action and up to one parent node. A node holds information
51  * regarding the last action performed (the "associated action"), the thread
52  * choices that have been explored (explored_children) and should be explored
53  * (backtrack), and the actions that the last action may read from.
54  */
55 class Node {
56 public:
57         Node(const struct model_params *params, ModelAction *act, Node *par,
58                         int nthreads, Node *prevfairness);
59         ~Node();
60         /* return true = thread choice has already been explored */
61         bool has_been_explored(thread_id_t tid) const;
62         /* return true = backtrack set is empty */
63         bool backtrack_empty() const;
64
65         void clear_backtracking();
66         void explore_child(ModelAction *act, enabled_type_t *is_enabled);
67         /* return false = thread was already in backtrack */
68         bool set_backtrack(thread_id_t id);
69         thread_id_t get_next_backtrack();
70         bool is_enabled(Thread *t) const;
71         bool is_enabled(thread_id_t tid) const;
72         enabled_type_t enabled_status(thread_id_t tid) const;
73
74         ModelAction * get_action() const { return action; }
75         void set_uninit_action(ModelAction *act) { uninit_action = act; }
76         ModelAction * get_uninit_action() const { return uninit_action; }
77
78         bool has_priority(thread_id_t tid) const;
79         void update_yield(Scheduler *);
80         bool has_priority_over(thread_id_t tid, thread_id_t tid2) const;
81         int get_num_threads() const { return num_threads; }
82         /** @return the parent Node to this Node; that is, the action that
83          * occurred previously in the stack. */
84         Node * get_parent() const { return parent; }
85
86         read_from_type_t get_read_from_status();
87         bool increment_read_from();
88         bool read_from_empty() const;
89         unsigned int read_from_size() const;
90
91         void print_read_from_past();
92         void add_read_from_past(const ModelAction *act);
93         const ModelAction * get_read_from_past() const;
94         const ModelAction * get_read_from_past(int i) const;
95         int get_read_from_past_size() const;
96
97         void add_read_from_promise(const ModelAction *reader);
98         Promise * get_read_from_promise() const;
99         Promise * get_read_from_promise(int i) const;
100         int get_read_from_promise_size() const;
101
102         bool add_future_value(struct future_value fv);
103         struct future_value get_future_value() const;
104
105         void set_promise(unsigned int i);
106         bool get_promise(unsigned int i) const;
107         bool increment_promise();
108         bool promise_empty() const;
109         void clear_promise_resolutions();
110
111         enabled_type_t *get_enabled_array() {return enabled_array;}
112
113         void set_misc_max(int i);
114         int get_misc() const;
115         bool increment_misc();
116         bool misc_empty() const;
117
118         void add_relseq_break(const ModelAction *write);
119         const ModelAction * get_relseq_break() const;
120         bool increment_relseq_break();
121         bool relseq_break_empty() const;
122
123         bool increment_behaviors();
124
125         void print() const;
126
127         MEMALLOC
128 private:
129         void explore(thread_id_t tid);
130         int get_yield_data(int tid1, int tid2) const;
131         bool read_from_past_empty() const;
132         bool increment_read_from_past();
133         bool read_from_promise_empty() const;
134         bool increment_read_from_promise();
135         bool future_value_empty() const;
136         bool increment_future_value();
137         read_from_type_t read_from_status;
138         const struct model_params * get_params() const { return params; }
139
140         ModelAction * const action;
141
142         const struct model_params * const params;
143
144         /** @brief ATOMIC_UNINIT action which was created at this Node */
145         ModelAction *uninit_action;
146
147         Node * const parent;
148         const int num_threads;
149         ModelVector<bool> explored_children;
150         ModelVector<bool> backtrack;
151         ModelVector<struct fairness_info> fairness;
152         int numBacktracks;
153         enabled_type_t *enabled_array;
154
155         /**
156          * The set of past ModelActions that this the action at this Node may
157          * read from. Only meaningful if this Node represents a 'read' action.
158          */
159         ModelVector<const ModelAction *> read_from_past;
160         unsigned int read_from_past_idx;
161
162         ModelVector<const ModelAction *> read_from_promises;
163         int read_from_promise_idx;
164
165         ModelVector<struct future_value> future_values;
166         int future_index;
167
168         ModelVector<bool> resolve_promise;
169         int resolve_promise_idx;
170
171         ModelVector<const ModelAction *> relseq_break_writes;
172         int relseq_break_index;
173
174         int misc_index;
175         int misc_max;
176         int * yield_data;
177 };
178
179 typedef ModelVector<Node *> node_list_t;
180
181 /**
182  * @brief A stack of nodes
183  *
184  * Holds a Node linked-list that can be used for holding backtracking,
185  * may-read-from, and replay information. It is used primarily as a
186  * stack-like structure, in that backtracking points and replay nodes are
187  * only removed from the top (most recent).
188  */
189 class NodeStack {
190 public:
191         NodeStack();
192         ~NodeStack();
193
194         void register_engine(const ModelExecution *exec);
195
196         ModelAction * explore_action(ModelAction *act, enabled_type_t * is_enabled);
197         Node * get_head() const;
198         Node * get_next() const;
199         void reset_execution();
200         void pop_restofstack(int numAhead);
201         int get_total_nodes() { return total_nodes; }
202
203         void print() const;
204
205         MEMALLOC
206 private:
207         node_list_t node_list;
208
209         const struct model_params * get_params() const;
210
211         /** @brief The model-checker execution object */
212         const ModelExecution *execution;
213
214         /**
215          * @brief the index position of the current head Node
216          *
217          * This index is relative to node_list. The index should point to the
218          * current head Node. It is negative when the list is empty.
219          */
220         int head_idx;
221
222         int total_nodes;
223 };
224
225 #endif /* __NODESTACK_H__ */