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