d04fa6208a35a5498c4e8bc54c1067afa5078187
[model-checker.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
40         bool is_read();
41         bool is_write();
42         bool is_acquire();
43         bool is_release();
44         bool same_var(ModelAction *act);
45         bool same_thread(ModelAction *act);
46         bool is_dependent(ModelAction *act);
47 private:
48         action_type type;
49         memory_order order;
50         void *location;
51         thread_id_t tid;
52         int value;
53         TreeNode *node;
54 };
55
56 class Backtrack {
57 public:
58         Backtrack(ModelAction *d, action_list_t *t) {
59                 diverge = d;
60                 actionTrace = t;
61                 iter = actionTrace->begin();
62         }
63         ModelAction * get_diverge() { return diverge; }
64         action_list_t * get_trace() { return actionTrace; }
65         void advance_state() { iter++; }
66         ModelAction * get_state() {
67                 return iter == actionTrace->end() ? NULL : *iter;
68         }
69 private:
70         ModelAction *diverge;
71         action_list_t *actionTrace;
72         /* points to position in actionTrace as we replay */
73         action_list_t::iterator iter;
74 };
75
76 class ModelChecker {
77 public:
78         ModelChecker();
79         ~ModelChecker();
80         class Scheduler *scheduler;
81
82         void set_system_context(ucontext_t *ctxt) { system_context = ctxt; }
83         ucontext_t * get_system_context(void) { return system_context; }
84
85         void set_current_action(ModelAction *act) { current_action = act; }
86         void check_current_action(void);
87         void print_summary(void);
88         Thread * schedule_next_thread();
89
90         int add_thread(Thread *t);
91         void remove_thread(Thread *t);
92         Thread * get_thread(thread_id_t tid) { return thread_map[tid]; }
93
94         int get_next_id();
95
96         int switch_to_master(ModelAction *act);
97
98         bool next_execution();
99 private:
100         int used_thread_id;
101         int num_executions;
102
103         ModelAction * get_last_conflict(ModelAction *act);
104         void set_backtracking(ModelAction *act);
105         thread_id_t advance_backtracking_state();
106         thread_id_t get_next_replay_thread();
107         Backtrack * get_next_backtrack();
108         void reset_to_initial_state();
109
110         class ModelAction *current_action;
111         Backtrack *exploring;
112         thread_id_t nextThread;
113
114         ucontext_t *system_context;
115         action_list_t *action_trace;
116         std::map<thread_id_t, class Thread *> thread_map;
117         class TreeNode *rootNode, *currentNode;
118         std::list<class Backtrack *> backtrack_list;
119 };
120
121 extern ModelChecker *model;
122
123 #endif /* __MODEL_H__ */