X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=model.h;h=74cb4e1f29aaf2c649fce027fc9dd10c714eb562;hb=130a35155171503883aaf18e57f8957ce63d06e8;hp=ca1de85c980cfa19b2179f9f68ee779bc90097e7;hpb=d48c1867f8e5b2a3f9695a6bc8f1b5394dcda8e7;p=model-checker.git diff --git a/model.h b/model.h index ca1de85..74cb4e1 100644 --- a/model.h +++ b/model.h @@ -1,113 +1,113 @@ +/** @file model.h + * @brief Core model checker. + */ + #ifndef __MODEL_H__ #define __MODEL_H__ -#include -#include #include +#include + +#include "mymemory.h" +#include "hashtable.h" +#include "config.h" +#include "modeltypes.h" +#include "stl-model.h" +#include "context.h" +#include "params.h" + +/* Forward declaration */ +class Node; +class NodeStack; +class CycleGraph; +class Promise; +class Scheduler; +class Thread; +class ClockVector; +class TraceAnalysis; +class ModelExecution; +class ModelAction; + +typedef SnapList action_list_t; + +/** @brief Model checker execution stats */ +struct execution_stats { + int num_total; /**< @brief Total number of executions */ + int num_infeasible; /**< @brief Number of infeasible executions */ + int num_buggy_executions; /** @brief Number of buggy executions */ + int num_complete; /**< @brief Number of feasible, non-buggy, complete executions */ + int num_redundant; /**< @brief Number of redundant, aborted executions */ +}; -#include "schedule.h" -#include "libthreads.h" -#include "libatomic.h" -#include "threads.h" -#include "tree.h" +/** @brief The central structure for model-checking */ +class ModelChecker { +public: + ModelChecker(struct model_params params); + ~ModelChecker(); -#define VALUE_NONE -1 + void run(); -typedef enum action_type { - THREAD_CREATE, - THREAD_YIELD, - THREAD_JOIN, - ATOMIC_READ, - ATOMIC_WRITE -} action_type_t; + /** @returns the context for the main model-checking system thread */ + ucontext_t * get_system_context() { return &system_context; } -typedef std::list action_list_t; + ModelExecution * get_execution() const { return execution; } -class ModelAction { -public: - ModelAction(action_type_t type, memory_order order, void *loc, int value); - void print(void); + int get_execution_number() const { return execution_number; } - thread_id_t get_tid() { return tid; } - action_type get_type() { return type; } - memory_order get_mo() { return order; } - void * get_location() { return location; } + Thread * get_thread(thread_id_t tid) const; + Thread * get_thread(const ModelAction *act) const; - TreeNode * get_node() { return node; } - void set_node(TreeNode *n) { node = n; } -private: - action_type type; - memory_order order; - void *location; - thread_id_t tid; - int value; - TreeNode *node; -}; + Thread * get_current_thread() const; -class Backtrack { -public: - Backtrack(ModelAction *d, action_list_t *t) { - diverge = d; - actionTrace = t; - iter = actionTrace->begin(); - } - ModelAction * get_diverge() { return diverge; } - action_list_t * get_trace() { return actionTrace; } - void advance_state() { iter++; } - ModelAction * get_state() { - return iter == actionTrace->end() ? NULL : *iter; + void switch_from_master(Thread *thread); + uint64_t switch_to_master(ModelAction *act); + + bool assert_bug(const char *msg, ...); + void assert_user_bug(const char *msg); + + const model_params params; + void add_trace_analysis(TraceAnalysis *a) { + trace_analyses.push_back(a); } + + MEMALLOC private: - ModelAction *diverge; - action_list_t *actionTrace; - /* points to position in actionTrace as we replay */ - action_list_t::iterator iter; -}; + /** The scheduler to use: tracks the running/ready Threads */ + Scheduler * const scheduler; + NodeStack * const node_stack; + ModelExecution *execution; -class ModelChecker { -public: - ModelChecker(); - ~ModelChecker(); - class Scheduler *scheduler; - Thread *system_thread; + int execution_number; - void add_system_thread(Thread *t); + unsigned int get_num_threads() const; - void set_current_action(ModelAction *act) { current_action = act; } - void check_current_action(void); - void print_trace(void); - Thread * schedule_next_thread(); + void execute_sleep_set(); - int add_thread(Thread *t); - void remove_thread(Thread *t); - Thread * get_thread(thread_id_t tid) { return thread_map[tid]; } + bool next_execution(); + bool should_terminate_execution(); - int get_next_id(); + Thread * get_next_thread(); + void reset_to_initial_state(); - int switch_to_master(ModelAction *act); - bool next_execution(); -private: - int used_thread_id; - int num_executions; - - ModelAction * get_last_conflict(ModelAction *act); - void set_backtracking(ModelAction *act); - thread_id_t advance_backtracking_state(); - thread_id_t get_next_replay_thread(); - - class ModelAction *current_action; - Backtrack *exploring; - thread_id_t nextThread; - - action_list_t *action_trace; - std::map thread_map; - class TreeNode *rootNode, *currentNode; - std::list backtrack_list; + ModelAction *diverge; + ModelAction *earliest_diverge; + + ucontext_t system_context; + + ModelVector trace_analyses; + + /** @brief The cumulative execution stats */ + struct execution_stats stats; + void record_stats(); + void run_trace_analyses(); + void print_bugs() const; + void print_execution(bool printbugs) const; + void print_stats() const; + + friend void user_main_wrapper(); }; extern ModelChecker *model; -int thread_switch_to_master(ModelAction *act); - #endif /* __MODEL_H__ */