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