demote 'system_thread' to just 'system_context'
[cdsspec-compiler.git] / model.h
1 #ifndef __MODEL_H__
2 #define __MODEL_H__
3
4 #include <list>
5 #include <map>
6 #include <cstddef>
7 #include <ucontext.h>
8
9 #include "schedule.h"
10 #include "libthreads.h"
11 #include "libatomic.h"
12 #include "threads.h"
13 #include "tree.h"
14
15 #define VALUE_NONE -1
16
17 typedef enum action_type {
18         THREAD_CREATE,
19         THREAD_YIELD,
20         THREAD_JOIN,
21         ATOMIC_READ,
22         ATOMIC_WRITE
23 } action_type_t;
24
25 typedef std::list<class ModelAction *> action_list_t;
26
27 class ModelAction {
28 public:
29         ModelAction(action_type_t type, memory_order order, void *loc, int value);
30         void print(void);
31
32         thread_id_t get_tid() { return tid; }
33         action_type get_type() { return type; }
34         memory_order get_mo() { return order; }
35         void * get_location() { return location; }
36
37         TreeNode * get_node() { return node; }
38         void set_node(TreeNode *n) { node = n; }
39 private:
40         action_type type;
41         memory_order order;
42         void *location;
43         thread_id_t tid;
44         int value;
45         TreeNode *node;
46 };
47
48 class Backtrack {
49 public:
50         Backtrack(ModelAction *d, action_list_t *t) {
51                 diverge = d;
52                 actionTrace = t;
53                 iter = actionTrace->begin();
54         }
55         ModelAction * get_diverge() { return diverge; }
56         action_list_t * get_trace() { return actionTrace; }
57         void advance_state() { iter++; }
58         ModelAction * get_state() {
59                 return iter == actionTrace->end() ? NULL : *iter;
60         }
61 private:
62         ModelAction *diverge;
63         action_list_t *actionTrace;
64         /* points to position in actionTrace as we replay */
65         action_list_t::iterator iter;
66 };
67
68 class ModelChecker {
69 public:
70         ModelChecker();
71         ~ModelChecker();
72         class Scheduler *scheduler;
73
74         void set_system_context(ucontext_t *ctxt) { system_context = ctxt; }
75         ucontext_t * get_system_context(void) { return system_context; }
76
77         void set_current_action(ModelAction *act) { current_action = act; }
78         void check_current_action(void);
79         void print_summary(void);
80         Thread * schedule_next_thread();
81
82         int add_thread(Thread *t);
83         void remove_thread(Thread *t);
84         Thread * get_thread(thread_id_t tid) { return thread_map[tid]; }
85
86         int get_next_id();
87
88         int switch_to_master(ModelAction *act);
89
90         bool next_execution();
91 private:
92         int used_thread_id;
93         int num_executions;
94
95         ModelAction * get_last_conflict(ModelAction *act);
96         void set_backtracking(ModelAction *act);
97         thread_id_t advance_backtracking_state();
98         thread_id_t get_next_replay_thread();
99         Backtrack * get_next_backtrack();
100         void reset_to_initial_state();
101
102         class ModelAction *current_action;
103         Backtrack *exploring;
104         thread_id_t nextThread;
105
106         ucontext_t *system_context;
107         action_list_t *action_trace;
108         std::map<thread_id_t, class Thread *> thread_map;
109         class TreeNode *rootNode, *currentNode;
110         std::list<class Backtrack *> backtrack_list;
111 };
112
113 extern ModelChecker *model;
114
115 #endif /* __MODEL_H__ */