Get gdax to not crash
authorBrian Demsky <bdemsky@uci.edu>
Wed, 26 Jun 2019 23:29:31 +0000 (16:29 -0700)
committerBrian Demsky <bdemsky@uci.edu>
Wed, 26 Jun 2019 23:29:31 +0000 (16:29 -0700)
1  2 
Makefile
action.h
cmodelint.cc
execution.cc
history.cc
history.h
include/cmodelint.h
model.cc
model.h

diff --combined Makefile
index b62e72a9de19225ab7bcc57a9da8cd8d6465a4b5,72b2f5266fdfc05d8f0ded9bf328b392f43503cd..00b99cc45a12d0b89e0c4d447b3a2fb1ef4d4c84
+++ b/Makefile
@@@ -5,7 -5,7 +5,7 @@@ OBJECTS := libthreads.o schedule.o mode
           datarace.o impatomic.o cmodelint.o \
           snapshot.o malloc.o mymemory.o common.o mutex.o conditionvariable.o \
           context.o execution.o libannotate.o plugins.o pthread.o futex.o fuzzer.o \
--         sleeps.o
++         sleeps.o history.o
  
  CPPFLAGS += -Iinclude -I.
  LDFLAGS := -ldl -lrt -rdynamic
@@@ -36,6 -36,8 +36,8 @@@ README.html: README.m
  malloc.o: malloc.c
        $(CC) -fPIC -c malloc.c -DMSPACES -DONLY_MSPACES -DHAVE_MMAP=0 $(CPPFLAGS) -Wno-unused-variable
  
+ futex.o: futex.cc
+       $(CXX) -fPIC -c futex.cc -std=c++11 $(CPPFLAGS)
  
  %.o : %.cc
        $(CXX) -MMD -MF .$@.d -fPIC -c $< $(CPPFLAGS)
diff --combined action.h
index cebbec1beb6ba7d3f409673e92a214b792c8e623,a2a947bde582b0c925a1ee713483a9b961d4c432..c7703094d99ffe12213ec59a44b8c9ef0fdcc7a3
+++ b/action.h
@@@ -86,6 -86,7 +86,7 @@@ class ModelAction 
  public:
        ModelAction(action_type_t type, memory_order order, void *loc, uint64_t value = VALUE_NONE, Thread *thread = NULL);
        ModelAction(action_type_t type, memory_order order, void *loc, uint64_t value, int size);
+       ModelAction(action_type_t type, const char * position, memory_order order, void *loc, uint64_t value, int size);
        ModelAction(action_type_t type, const char * position, memory_order order, void *loc, uint64_t value = VALUE_NONE, Thread *thread = NULL);
        ~ModelAction();
        void print() const;
        /* to accomodate pthread create and join */
        Thread * thread_operand;
        void set_thread_operand(Thread *th) { thread_operand = th; }
 -      MEMALLOC
 +      SNAPSHOTALLOC
  private:
        const char * get_type_str() const;
        const char * get_mo_str() const;
diff --combined cmodelint.cc
index b9eb214a5cffe4918939407a50526c28afedc925,5be511c86f0574b5a707a9ddabaa9e90156348eb..9ea1b681c32d20c7adb9f62aff78f9aab21d480d
@@@ -1,9 -1,11 +1,12 @@@
  #include <stdio.h>
+ #include <string>
  #include "model.h"
  #include "execution.h"
  #include "action.h"
+ #include "history.h"
  #include "cmodelint.h"
 +#include "snapshot-interface.h"
  #include "threads-model.h"
  
  memory_order orders[6] = {
        memory_order_release, memory_order_acq_rel, memory_order_seq_cst
  };
  
 +#define ensureModel(action) \
 +      if (!modelchecker_started) {                  \
 +              if (!model) { \
 +                      snapshot_system_init(10000, 1024, 1024, 40000); \
 +                      model = new ModelChecker(); \
 +              } \
 +              model->get_execution()->check_current_action(action); \
 +      }else { \
 +              model->switch_to_master(action); \
 +      }
 +
 +
 +#define ensureModelValue(action, type)          \
 +      if (!modelchecker_started) { \
 +              if (!model) { \
 +                      snapshot_system_init(10000, 1024, 1024, 40000); \
 +                      model = new ModelChecker(); \
 +              } \
 +              model->get_execution()->check_current_action(action); \
 +              return (type) thread_current()->get_return_value();   \
 +      } else { \
 +              return (type) model->switch_to_master(action);        \
 +      }
 +
  /** Performs a read action.*/
  uint64_t model_read_action(void * obj, memory_order ord) {
        return model->switch_to_master(new ModelAction(ATOMIC_READ, ord, obj));
@@@ -86,39 -64,47 +89,41 @@@ void model_fence_action(memory_order or
  
  /* ---  helper functions --- */
  uint64_t model_rmwrcas_action_helper(void *obj, int atomic_index, uint64_t oldval, int size, const char *position) {
-       ensureModelValue(new ModelAction(ATOMIC_RMWRCAS, position, orders[atomic_index], obj), uint64_t);
 -      return model->switch_to_master(
 -              new ModelAction(ATOMIC_RMWRCAS, position, orders[atomic_index], obj, oldval, size)
++      ensureModelValue(
++              new ModelAction(ATOMIC_RMWRCAS, position, orders[atomic_index], obj, oldval, size), uint64_t
+               );
  }
  
  uint64_t model_rmwr_action_helper(void *obj, int atomic_index, const char *position) {
 -      return model->switch_to_master(
 -              new ModelAction(ATOMIC_RMWR, position, orders[atomic_index], obj)
 -              );
 +      ensureModelValue(new ModelAction(ATOMIC_RMWR, position, orders[atomic_index], obj), uint64_t);
  }
  
  void model_rmw_action_helper(void *obj, uint64_t val, int atomic_index, const char * position) {
 -      model->switch_to_master(
 -              new ModelAction(ATOMIC_RMW, position, orders[atomic_index], obj, val)
 -              );
 +      ensureModel(new ModelAction(ATOMIC_RMW, position, orders[atomic_index], obj, val));
  }
  
  void model_rmwc_action_helper(void *obj, int atomic_index, const char *position) {
 -      model->switch_to_master(
 -              new ModelAction(ATOMIC_RMWC, position, orders[atomic_index], obj)
 -              );
 +      ensureModel(new ModelAction(ATOMIC_RMWC, position, orders[atomic_index], obj));
  }
  
  // cds atomic inits
  void cds_atomic_init8(void * obj, uint8_t val, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)
                );
  }
  void cds_atomic_init16(void * obj, uint16_t val, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)
                );
  }
  void cds_atomic_init32(void * obj, uint32_t val, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)
                );
  }
  void cds_atomic_init64(void * obj, uint64_t val, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, val)
                );
  }
  
  // cds atomic loads
  uint8_t cds_atomic_load8(void * obj, int atomic_index, const char * position) {
 -      return (uint8_t) ( model->switch_to_master(
 -                                                                                       new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj))
 -                                                                               );
 +      ensureModelValue(
 +              new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj), uint8_t);
  }
  uint16_t cds_atomic_load16(void * obj, int atomic_index, const char * position) {
 -      return (uint16_t) ( model->switch_to_master(
 -                                                                                              new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj))
 -                                                                                      );
 +      ensureModelValue(
 +              new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj), uint16_t);
  }
  uint32_t cds_atomic_load32(void * obj, int atomic_index, const char * position) {
 -      return (uint32_t) ( model->switch_to_master(
 -                                                                                              new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj))
 -                                                                                      );
 +      ensureModelValue(
 +              new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj), uint32_t
 +              );
  }
  uint64_t cds_atomic_load64(void * obj, int atomic_index, const char * position) {
 -      return model->switch_to_master(
 -              new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj)
 -              );
 +      ensureModelValue(
 +              new ModelAction(ATOMIC_READ, position, orders[atomic_index], obj), uint64_t);
  }
  
  // cds atomic stores
  void cds_atomic_store8(void * obj, uint8_t val, int atomic_index, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)
                );
  }
  void cds_atomic_store16(void * obj, uint16_t val, int atomic_index, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)
                );
  }
  void cds_atomic_store32(void * obj, uint32_t val, int atomic_index, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)
                );
  }
  void cds_atomic_store64(void * obj, uint64_t val, int atomic_index, const char * position) {
 -      model->switch_to_master(
 +      ensureModel(
                new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, val)
                );
  }
@@@ -373,3 -362,34 +378,34 @@@ void cds_atomic_thread_fence(int atomic
          __old__ = __old__;  Silence clang (-Wunused-value)                    \
           })
   */
 -        Thread * th = thread_current();
+ void cds_func_entry(const char * funcName) {
+       if (!model) return;
 -        Thread * th = thread_current();
++      Thread * th = thread_current();
+       uint32_t func_id;
+       ModelHistory *history = model->get_history();
+       if ( !history->getFuncMap()->contains(funcName) ) {
+               func_id = history->get_func_counter();
+               history->incr_func_counter();
+               history->getFuncMap()->put(funcName, func_id);
+       } else {
+               func_id = history->getFuncMap()->get(funcName);
+       }
+       history->enter_function(func_id, th->get_id());
+ }
+ void cds_func_exit(const char * funcName) {
+       if (!model) return;
++      Thread * th = thread_current();
+       uint32_t func_id;
+       ModelHistory *history = model->get_history();
+       func_id = history->getFuncMap()->get(funcName);
+       history->exit_function(func_id, th->get_id());
+ }
diff --combined execution.cc
index 2c08711eee0d1a655272bd56f1adf0d900ef599d,d75499f1349a4e24c69a1c01c90aa8bb599240d5..2e7442515b4cf47556817f727ba3bd8a7e65b466
@@@ -64,7 -64,7 +64,7 @@@ ModelExecution::ModelExecution(ModelChe
        thrd_last_fence_release(),
        node_stack(node_stack),
        priv(new struct model_snapshot_members ()),
--                       mo_graph(new CycleGraph()),
++      mo_graph(new CycleGraph()),
        fuzzer(new Fuzzer())
  {
        /* Initialize a model-checker thread, for special ModelActions */
@@@ -778,6 -778,9 +778,6 @@@ bool ModelExecution::r_modification_ord
  
        /* Last SC fence in the current thread */
        ModelAction *last_sc_fence_local = get_last_seq_cst_fence(curr->get_tid(), NULL);
 -      ModelAction *last_sc_write = NULL;
 -      if (curr->is_seqcst())
 -              last_sc_write = get_last_seq_cst_write(curr);
  
        int tid = curr->get_tid();
        ModelAction *prev_same_thread = NULL;
diff --combined history.cc
index 0000000000000000000000000000000000000000,ca52209d6ff17b5a95ebe29a6cfaecb546e2de89..e0560bad79df58a452ad0c9f566ead7e160e773c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,36 +1,36 @@@
 -      func_id(1), /* function id starts with 1 */
+ #include <inttypes.h>
+ #include "history.h"
+ #include "action.h"
+ ModelHistory::ModelHistory() :
++      func_id(1),     /* function id starts with 1 */
+       func_map(),
+       func_history(),
+       work_list()
+ {}
+ void ModelHistory::enter_function(const uint32_t func_id, thread_id_t tid)
+ {
+       if ( !work_list.contains(tid) ) {
+               // This thread has not been pushed to work_list
+               SnapList<uint32_t> * func_list = new SnapList<uint32_t>();
+               func_list->push_back(func_id);
+               work_list.put(tid, func_list);
+       } else {
+               SnapList<uint32_t> * func_list = work_list.get(tid);
+               func_list->push_back(func_id);
+       }
+ }
+ void ModelHistory::exit_function(const uint32_t func_id, thread_id_t tid)
+ {
+       SnapList<uint32_t> * func_list = work_list.get(tid);
+       uint32_t last_func_id = func_list->back();
+       if (last_func_id == func_id) {
+               func_list->pop_back();
+       } else {
+               model_print("trying to exit with a wrong function id\n");
+               model_print("--- last_func: %d, func_id: %d\n", last_func_id, func_id);
+       }
+ }
diff --combined history.h
index 0000000000000000000000000000000000000000,fff5712629057311811bebde6401a42f57bf56db..441a999f46f2ab6cb6e7f1f4124ae1e90b156e77
mode 000000,100644..100644
--- /dev/null
+++ b/history.h
@@@ -1,0 -1,39 +1,39 @@@
 -      
+ #include "stl-model.h"
+ #include "common.h"
+ #include "hashtable.h"
+ #include "modeltypes.h"
+ /* forward declaration */
+ class ModelAction;
+ typedef ModelList<ModelAction *> action_mlist_t;
+ class ModelHistory {
+ public:
+       ModelHistory();
 -        uint32_t get_func_counter() { return func_id; }
 -        void incr_func_counter() { func_id++; }
++
+       void enter_function(const uint32_t func_id, thread_id_t tid);
+       void exit_function(const uint32_t func_id, thread_id_t tid);
 -        HashTable<const char *, uint32_t, uintptr_t, 4> * getFuncMap() { return &func_map; }
++      uint32_t get_func_counter() { return func_id; }
++      void incr_func_counter() { func_id++; }
 -        /* map function names to integer ids */ 
 -        HashTable<const char *, uint32_t, uintptr_t, 4> func_map;
++      HashTable<const char *, uint32_t, uintptr_t, 4> * getFuncMap() { return &func_map; }
+       HashTable<uint32_t, action_mlist_t *, uintptr_t, 4> * getFuncHistory() { return &func_history; }
+       void print();
+ private:
+       uint32_t func_id;
 -       * the functions that thread i has entered and yet to exit from 
++      /* map function names to integer ids */
++      HashTable<const char *, uint32_t, uintptr_t, 4> func_map;
+       HashTable<uint32_t, action_mlist_t *, uintptr_t, 4> func_history;
+       /* work_list stores a list of function ids for each thread
+        * SnapList<uint32_t> is intended to be used as a stack storing
++       * the functions that thread i has entered and yet to exit from
+        */
+       HashTable<thread_id_t, SnapList<uint32_t> *, uintptr_t, 4> work_list;
+ };
diff --combined include/cmodelint.h
index 7bc6a253c9b5fedd61b7574558c647399f0207a3,9e82c030900c4ab2e89a8a8c4b2575e908d03ce1..78da6bd8003691255c9a67449f81d5a92cca513c
  #if __cplusplus
  using std::memory_order;
  extern "C" {
 +#else
 +typedef int bool;
  #endif
  
 +  
  uint64_t model_read_action(void * obj, memory_order ord);
  void model_write_action(void * obj, memory_order ord, uint64_t val);
  void model_init_action(void * obj, uint64_t val);
@@@ -101,6 -98,9 +101,9 @@@ bool cds_atomic_compare_exchange64_v2(v
  // cds atomic thread fence
  void cds_atomic_thread_fence(int atomic_index, const char * position);
  
+ void cds_func_entry(const char * funcName);
+ void cds_func_exit(const char * funcName);
  #if __cplusplus
  }
  #endif
diff --combined model.cc
index 80d8845fed99714d9ba1dcd93cab9f40efcc5806,3235f5c488461dda1918fb2cd1bc5293441effa1..0a7913bfd5571163364f8de9b30055e03b9df0b5
+++ b/model.cc
  #include "output.h"
  #include "traceanalysis.h"
  #include "execution.h"
+ #include "history.h"
  #include "bugmessage.h"
 +#include "params.h"
  
 -ModelChecker *model;
 +ModelChecker *model = NULL;
 +bool modelchecker_started = false;
 +
 +/** Wrapper to run the user's main function, with appropriate arguments */
 +void user_main_wrapper(void *)
 +{
 +      user_main(model->params.argc, model->params.argv);
 +}
  
  /** @brief Constructor */
  ModelChecker::ModelChecker() :
        scheduler(new Scheduler()),
        node_stack(new NodeStack()),
        execution(new ModelExecution(this, scheduler, node_stack)),
+       history(new ModelHistory()),
        execution_number(1),
        trace_analyses(),
        inspect_plugin(NULL)
  {
        memset(&stats,0,sizeof(struct execution_stats));
 +      init_thread = new Thread(execution->get_next_id(), (thrd_t *) malloc(sizeof(thrd_t)), &user_main_wrapper, NULL, NULL);  // L: user_main_wrapper passes the user program
 +      execution->add_thread(init_thread);
 +      scheduler->set_current_thread(init_thread);
 +      execution->setParams(&params);
 +      param_defaults(&params);
  }
  
  /** @brief Destructor */
@@@ -56,8 -45,9 +58,8 @@@ ModelChecker::~ModelChecker(
  }
  
  /** Method to set parameters */
 -void ModelChecker::setParams(struct model_params params) {
 -      this->params = params;
 -      execution->setParams(&params);
 +model_params * ModelChecker::getParams() {
 +      return &params;
  }
  
  /**
@@@ -66,6 -56,8 +68,6 @@@
   */
  void ModelChecker::reset_to_initial_state()
  {
 -      DEBUG("+++ Resetting to initial state +++\n");
 -      node_stack->reset_execution();
  
        /**
         * FIXME: if we utilize partial rollback, we will need to free only
@@@ -161,7 -153,7 +163,7 @@@ void ModelChecker::print_bugs() cons
                                                        bugs->size(),
                                                        bugs->size() > 1 ? "s" : "");
        for (unsigned int i = 0;i < bugs->size();i++)
--              (*bugs)[i]->print();
++              (*bugs)[i] -> print();
  }
  
  /**
   */
  void ModelChecker::record_stats()
  {
--      stats.num_total++;
++      stats.num_total ++;
        if (!execution->isfeasibleprefix())
--              stats.num_infeasible++;
++              stats.num_infeasible ++;
        else if (execution->have_bug_reports())
--              stats.num_buggy_executions++;
++              stats.num_buggy_executions ++;
        else if (execution->is_complete_execution())
--              stats.num_complete++;
++              stats.num_complete ++;
        else {
--              stats.num_redundant++;
++              stats.num_redundant ++;
  
                /**
                 * @todo We can violate this ASSERT() when fairness/sleep sets
@@@ -261,15 -253,16 +263,15 @@@ bool ModelChecker::next_execution(
                return true;
        }
  // test code
--      execution_number++;
++      execution_number ++;
        reset_to_initial_state();
 -      node_stack->full_reset();
        return false;
  }
  
  /** @brief Run trace analyses on complete trace */
  void ModelChecker::run_trace_analyses() {
--      for (unsigned int i = 0;i < trace_analyses.size();i++)
--              trace_analyses[i]->analyze(execution->get_action_trace());
++      for (unsigned int i = 0;i < trace_analyses.size();i ++)
++              trace_analyses[i] -> analyze(execution->get_action_trace());
  }
  
  /**
@@@ -322,11 -315,10 +324,11 @@@ uint64_t ModelChecker::switch_to_master
        Thread *old = thread_current();
        scheduler->set_current_thread(NULL);
        ASSERT(!old->get_pending());
 -/* W: No plugin
 -        if (inspect_plugin != NULL) {
 -                inspect_plugin->inspectModelAction(act);
 -        }*/
 +
 +      if (inspect_plugin != NULL) {
 +              inspect_plugin->inspectModelAction(act);
 +      }
 +
        old->set_pending(act);
        if (Thread::swap(old, &system_context) < 0) {
                perror("swap threads");
        return old->get_return_value();
  }
  
 -/** Wrapper to run the user's main function, with appropriate arguments */
 -void user_main_wrapper(void *)
 -{
 -      user_main(model->params.argc, model->params.argv);
 -}
 -
  bool ModelChecker::should_terminate_execution()
  {
        /* Infeasible -> don't take any more steps */
@@@ -358,6 -356,7 +360,6 @@@ void ModelChecker::do_restart(
  {
        restart_flag = false;
        reset_to_initial_state();
 -      node_stack->full_reset();
        memset(&stats,0,sizeof(struct execution_stats));
        execution_number = 1;
  }
@@@ -369,9 -368,11 +371,9 @@@ void ModelChecker::run(
        char random_state[256];
        initstate(423121, random_state, sizeof(random_state));
  
--      for(int exec = 0;exec < params.maxexecutions;exec++) {
 -              thrd_t user_thread;
 -              Thread *t = new Thread(execution->get_next_id(), &user_thread, &user_main_wrapper, NULL, NULL); // L: user_main_wrapper passes the user program
 -              execution->add_thread(t);
 -              //Need to seed random number generator, otherwise its state gets reset
++      for(int exec = 0;exec < params.maxexecutions;exec ++) {
 +              Thread * t = init_thread;
 +
                do {
                        /*
                         * Stash next pending action(s) for thread(s). There
diff --combined model.h
index dc325d71744398e28b75d2cfa0929c34d78e9cc8,4d8558e270613e968cccb01ea282f4af04d36a70..8983d017f80fa1c5a17d53bd03edb49cedea102b
+++ b/model.h
@@@ -33,7 -33,7 +33,7 @@@ class ModelChecker 
  public:
        ModelChecker();
        ~ModelChecker();
 -      void setParams(struct model_params params);
 +      model_params * getParams();
        void run();
  
        /** Restart the model checker, intended for pluggins. */
@@@ -46,6 -46,7 +46,7 @@@
        ucontext_t * get_system_context() { return &system_context; }
  
        ModelExecution * get_execution() const { return execution; }
+       ModelHistory * get_history() const { return history; }
  
        int get_execution_number() const { return execution_number; }
  
@@@ -63,6 -64,7 +64,7 @@@
        model_params params;
        void add_trace_analysis(TraceAnalysis *a) {     trace_analyses.push_back(a); }
        void set_inspect_plugin(TraceAnalysis *a) {     inspect_plugin=a;       }
        MEMALLOC
  private:
        /** Flag indicates whether to restart the model checker. */
@@@ -72,7 -74,7 +74,8 @@@
        Scheduler * const scheduler;
        NodeStack * const node_stack;
        ModelExecution *execution;
 +      Thread * init_thread;
+       ModelHistory *history;
  
        int execution_number;
  
  };
  
  extern ModelChecker *model;
 -
 +extern bool modelchecker_started;
  #endif        /* __MODEL_H__ */