From 5ea8e3d5d861ed363e5ac5f3b20b8181dd197efb Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 7 Mar 2013 14:56:51 -0800 Subject: [PATCH] bugfix - add stl-model.h wrappers, to provide more control over STL We need to provide an operator new/delete for our std::vector and std::list instantiations. So we extend the base classes and add the appropriate new/delete methods. --- cyclegraph.cc | 4 +-- cyclegraph.h | 15 +++++---- datarace.cc | 2 +- datarace.h | 4 +-- model.cc | 50 ++++++++++++++-------------- model.h | 21 ++++++------ nodestack.h | 19 ++++++----- promise.h | 6 ++-- snapshot-interface.cc | 4 +-- stl-model.h | 76 +++++++++++++++++++++++++++++++++++++++++++ threads-model.h | 4 +-- workqueue.h | 3 +- 12 files changed, 144 insertions(+), 64 deletions(-) create mode 100644 stl-model.h diff --git a/cyclegraph.cc b/cyclegraph.cc index e96549f..8d37dea 100644 --- a/cyclegraph.cc +++ b/cyclegraph.cc @@ -8,7 +8,7 @@ /** Initializes a CycleGraph object. */ CycleGraph::CycleGraph() : discovered(new HashTable(16)), - queue(new std::vector< const CycleNode *, ModelAlloc >()), + queue(new ModelVector()), hasCycles(false), oldCycles(false) { @@ -554,7 +554,7 @@ unsigned int CycleNode::getNumBackEdges() const * @return True if the element was found; false otherwise */ template -static bool vector_remove_node(std::vector >& v, const T n) +static bool vector_remove_node(SnapVector& v, const T n) { for (unsigned int i = 0; i < v.size(); i++) { if (v[i] == n) { diff --git a/cyclegraph.h b/cyclegraph.h index 25401d9..9819cf8 100644 --- a/cyclegraph.h +++ b/cyclegraph.h @@ -16,12 +16,13 @@ #include "hashtable.h" #include "config.h" #include "mymemory.h" +#include "stl-model.h" class Promise; class CycleNode; class ModelAction; -typedef std::vector< const Promise *, ModelAlloc > promise_list_t; +typedef ModelVector promise_list_t; /** @brief A graph of Model Actions for tracking cycles. */ class CycleGraph { @@ -68,7 +69,7 @@ class CycleGraph { bool mergeNodes(CycleNode *node1, CycleNode *node2); HashTable *discovered; - std::vector< const CycleNode *, ModelAlloc > * queue; + ModelVector * queue; /** @brief A table for mapping ModelActions to CycleNodes */ @@ -77,7 +78,7 @@ class CycleGraph { HashTable promiseToNode; #if SUPPORT_MOD_ORDER_DUMP - std::vector< CycleNode *, SnapshotAlloc > nodeList; + SnapVector nodeList; #endif bool checkReachable(const CycleNode *from, const CycleNode *to) const; @@ -86,8 +87,8 @@ class CycleGraph { bool hasCycles; bool oldCycles; - std::vector< CycleNode *, SnapshotAlloc > rollbackvector; - std::vector< CycleNode *, SnapshotAlloc > rmwrollbackvector; + SnapVector rollbackvector; + SnapVector rmwrollbackvector; }; /** @@ -124,10 +125,10 @@ class CycleNode { const Promise *promise; /** @brief The edges leading out from this node */ - std::vector< CycleNode *, SnapshotAlloc > edges; + SnapVector edges; /** @brief The edges leading into this node */ - std::vector< CycleNode *, SnapshotAlloc > back_edges; + SnapVector back_edges; /** Pointer to a RMW node that reads from this node, or NULL, if none * exists */ diff --git a/datarace.cc b/datarace.cc index 1ec43be..e678498 100644 --- a/datarace.cc +++ b/datarace.cc @@ -9,7 +9,7 @@ #include "action.h" struct ShadowTable *root; -std::vector unrealizedraces; +SnapVector unrealizedraces; void *memory_base; void *memory_top; diff --git a/datarace.h b/datarace.h index d1f91b2..7c24b6d 100644 --- a/datarace.h +++ b/datarace.h @@ -5,8 +5,8 @@ #ifndef DATARACE_H #include "config.h" #include -#include #include "modeltypes.h" +#include "stl-model.h" /* Forward declaration */ class ClockVector; @@ -47,7 +47,7 @@ void raceCheckRead(thread_id_t thread, const void *location, ClockVector *currCl bool checkDataRaces(); void assert_race(struct DataRace *race); -extern std::vector unrealizedraces; +extern SnapVector unrealizedraces; /** Basic encoding idea: * (void *) Either: diff --git a/model.cc b/model.cc index 0122922..bf60224 100644 --- a/model.cc +++ b/model.cc @@ -61,7 +61,7 @@ struct model_snapshot_members { unsigned int next_thread_id; modelclock_t used_sequence_numbers; ModelAction *next_backtrack; - std::vector< bug_message *, SnapshotAlloc > bugs; + SnapVector bugs; struct execution_stats stats; bool failed_promise; bool too_many_reads; @@ -85,12 +85,12 @@ ModelChecker::ModelChecker(struct model_params params) : obj_map(new HashTable()), lock_waiters_map(new HashTable()), condvar_waiters_map(new HashTable()), - obj_thrd_map(new HashTable *, uintptr_t, 4 >()), - promises(new std::vector< Promise *, SnapshotAlloc >()), - futurevalues(new std::vector< struct PendingFutureValue, SnapshotAlloc >()), - pending_rel_seqs(new std::vector< struct release_seq *, SnapshotAlloc >()), - thrd_last_action(new std::vector< ModelAction *, SnapshotAlloc >(1)), - thrd_last_fence_release(new std::vector< ModelAction *, SnapshotAlloc >()), + obj_thrd_map(new HashTable *, uintptr_t, 4 >()), + promises(new SnapVector()), + futurevalues(new SnapVector()), + pending_rel_seqs(new SnapVector()), + thrd_last_action(new SnapVector(1)), + thrd_last_fence_release(new SnapVector()), node_stack(new NodeStack()), priv(new struct model_snapshot_members()), mo_graph(new CycleGraph()) @@ -137,11 +137,11 @@ static action_list_t * get_safe_ptr_action(HashTable * get_safe_ptr_vect_action(HashTable *, uintptr_t, 4> * hash, void * ptr) +static SnapVector * get_safe_ptr_vect_action(HashTable *, uintptr_t, 4> * hash, void * ptr) { - std::vector *tmp = hash->get(ptr); + SnapVector *tmp = hash->get(ptr); if (tmp == NULL) { - tmp = new std::vector(); + tmp = new SnapVector(); hash->put(ptr, tmp); } return tmp; @@ -642,8 +642,8 @@ ModelAction * ModelChecker::get_last_fence_conflict(ModelAction *act) const * load-acquire * or * load --sb-> fence-acquire */ - std::vector< ModelAction *, ModelAlloc > acquire_fences(get_num_threads(), NULL); - std::vector< ModelAction *, ModelAlloc > prior_loads(get_num_threads(), NULL); + ModelVector acquire_fences(get_num_threads(), NULL); + ModelVector prior_loads(get_num_threads(), NULL); bool found_acquire_fences = false; for ( ; rit != list->rend(); rit++) { ModelAction *prev = *rit; @@ -1080,7 +1080,7 @@ void ModelChecker::add_future_value(const ModelAction *writer, ModelAction *read bool ModelChecker::process_write(ModelAction *curr) { /* Readers to which we may send our future value */ - std::vector< ModelAction *, ModelAlloc > send_fv; + ModelVector send_fv; bool updated_mod_order = w_modification_order(curr, &send_fv); int promise_idx = get_promise_to_resolve(curr); @@ -1704,7 +1704,7 @@ bool ModelChecker::should_read_instead(const ModelAction *curr, const T *rf, con if (!mo_graph->checkReachable(rf, other_rf)) return false; - std::vector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); + SnapVector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); action_list_t *list = &(*thrd_lists)[id_to_int(curr->get_tid())]; action_list_t::reverse_iterator rit = list->rbegin(); ASSERT((*rit) == curr); @@ -1747,7 +1747,7 @@ bool ModelChecker::check_recency(ModelAction *curr, const T *rf) const curr->get_node()->get_read_from_promise_size() <= 1) return true; - std::vector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); + SnapVector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); int tid = id_to_int(curr->get_tid()); ASSERT(tid < (int)thrd_lists->size()); action_list_t *list = &(*thrd_lists)[tid]; @@ -1805,7 +1805,7 @@ bool ModelChecker::check_recency(ModelAction *curr, const T *rf) const template bool ModelChecker::r_modification_order(ModelAction *curr, const rf_type *rf) { - std::vector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); + SnapVector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); unsigned int i; bool added = false; ASSERT(curr->is_read()); @@ -1911,9 +1911,9 @@ bool ModelChecker::r_modification_order(ModelAction *curr, const rf_type *rf) * value. If NULL, then don't record any future values. * @return True if modification order edges were added; false otherwise */ -bool ModelChecker::w_modification_order(ModelAction *curr, std::vector< ModelAction *, ModelAlloc > *send_fv) +bool ModelChecker::w_modification_order(ModelAction *curr, ModelVector *send_fv) { - std::vector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); + SnapVector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); unsigned int i; bool added = false; ASSERT(curr->is_write()); @@ -2057,7 +2057,7 @@ bool ModelChecker::thin_air_constraint_may_allow(const ModelAction *writer, cons */ bool ModelChecker::mo_may_allow(const ModelAction *writer, const ModelAction *reader) { - std::vector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, reader->get_location()); + SnapVector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, reader->get_location()); unsigned int i; /* Iterate over all threads */ for (i = 0; i < thrd_lists->size(); i++) { @@ -2158,7 +2158,7 @@ bool ModelChecker::release_seq_heads(const ModelAction *rf, release_heads->push_back(fence_release); int tid = id_to_int(rf->get_tid()); - std::vector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, rf->get_location()); + SnapVector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, rf->get_location()); action_list_t *list = &(*thrd_lists)[tid]; action_list_t::const_reverse_iterator rit; @@ -2301,7 +2301,7 @@ void ModelChecker::get_release_seq_heads(ModelAction *acquire, bool ModelChecker::resolve_release_sequences(void *location, work_queue_t *work_queue) { bool updated = false; - std::vector< struct release_seq *, SnapshotAlloc >::iterator it = pending_rel_seqs->begin(); + SnapVector::iterator it = pending_rel_seqs->begin(); while (it != pending_rel_seqs->end()) { struct release_seq *pending = *it; ModelAction *acquire = pending->acquire; @@ -2382,7 +2382,7 @@ void ModelChecker::add_action_to_lists(ModelAction *act) if (uninit) action_trace->push_front(uninit); - std::vector *vec = get_safe_ptr_vect_action(obj_thrd_map, act->get_location()); + SnapVector *vec = get_safe_ptr_vect_action(obj_thrd_map, act->get_location()); if (tid >= (int)vec->size()) vec->resize(priv->next_thread_id); (*vec)[tid].push_back(act); @@ -2405,7 +2405,7 @@ void ModelChecker::add_action_to_lists(ModelAction *act) void *mutex_loc = (void *) act->get_value(); get_safe_ptr_action(obj_map, mutex_loc)->push_back(act); - std::vector *vec = get_safe_ptr_vect_action(obj_thrd_map, mutex_loc); + SnapVector *vec = get_safe_ptr_vect_action(obj_thrd_map, mutex_loc); if (tid >= (int)vec->size()) vec->resize(priv->next_thread_id); (*vec)[tid].push_back(act); @@ -2549,7 +2549,7 @@ int ModelChecker::get_promise_to_resolve(const ModelAction *curr) const */ bool ModelChecker::resolve_promise(ModelAction *write, unsigned int promise_idx) { - std::vector< ModelAction *, ModelAlloc > actions_to_check; + ModelVector actions_to_check; Promise *promise = (*promises)[promise_idx]; for (unsigned int i = 0; i < promise->get_num_readers(); i++) { @@ -2724,7 +2724,7 @@ void ModelChecker::compute_relseq_breakwrites(ModelAction *curr) */ void ModelChecker::build_may_read_from(ModelAction *curr) { - std::vector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); + SnapVector *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location()); unsigned int i; ASSERT(curr->is_read()); diff --git a/model.h b/model.h index 96c1ec7..236bbe9 100644 --- a/model.h +++ b/model.h @@ -15,6 +15,7 @@ #include "workqueue.h" #include "config.h" #include "modeltypes.h" +#include "stl-model.h" /* Forward declaration */ class Node; @@ -27,9 +28,9 @@ class ClockVector; struct model_snapshot_members; /** @brief Shorthand for a list of release sequence heads */ -typedef std::vector< const ModelAction *, ModelAlloc > rel_heads_list_t; +typedef ModelVector rel_heads_list_t; -typedef std::list< ModelAction *, SnapshotAlloc > action_list_t; +typedef SnapList action_list_t; /** * Model checker parameter structure. Holds run-time configuration options for @@ -92,7 +93,7 @@ struct release_seq { /** @brief The head of the potential longest release sequence chain */ const ModelAction *release; /** @brief The write(s) that may break the release sequence */ - std::vector writes; + SnapVector writes; }; /** @brief The central structure for model-checking */ @@ -204,7 +205,7 @@ private: template bool r_modification_order(ModelAction *curr, const rf_type *rf); - bool w_modification_order(ModelAction *curr, std::vector< ModelAction *, ModelAlloc > *send_fv); + bool w_modification_order(ModelAction *curr, ModelVector *send_fv); void get_release_seq_heads(ModelAction *acquire, ModelAction *read, rel_heads_list_t *release_heads); bool release_seq_heads(const ModelAction *rf, rel_heads_list_t *release_heads, struct release_seq *pending) const; bool resolve_release_sequences(void *location, work_queue_t *work_queue); @@ -231,9 +232,9 @@ private: * to a trace of all actions performed on the object. */ HashTable * const condvar_waiters_map; - HashTable *, uintptr_t, 4 > * const obj_thrd_map; - std::vector< Promise *, SnapshotAlloc > * const promises; - std::vector< struct PendingFutureValue, SnapshotAlloc > * const futurevalues; + HashTable *, uintptr_t, 4 > * const obj_thrd_map; + SnapVector * const promises; + SnapVector * const futurevalues; /** * List of pending release sequences. Release sequences might be @@ -241,10 +242,10 @@ private: * are established. Each entry in the list may only be partially * filled, depending on its pending status. */ - std::vector< struct release_seq *, SnapshotAlloc > * const pending_rel_seqs; + SnapVector * const pending_rel_seqs; - std::vector< ModelAction *, SnapshotAlloc > * const thrd_last_action; - std::vector< ModelAction *, SnapshotAlloc > * const thrd_last_fence_release; + SnapVector * const thrd_last_action; + SnapVector * const thrd_last_fence_release; NodeStack * const node_stack; /** Private data members that should be snapshotted. They are grouped diff --git a/nodestack.h b/nodestack.h index 8ad329e..394552c 100644 --- a/nodestack.h +++ b/nodestack.h @@ -12,6 +12,7 @@ #include "mymemory.h" #include "schedule.h" #include "promise.h" +#include "stl-model.h" class ModelAction; class Thread; @@ -133,9 +134,9 @@ private: Node * const parent; const int num_threads; - std::vector< bool, ModelAlloc > explored_children; - std::vector< bool, ModelAlloc > backtrack; - std::vector< struct fairness_info, ModelAlloc< struct fairness_info> > fairness; + ModelVector explored_children; + ModelVector backtrack; + ModelVector fairness; int numBacktracks; enabled_type_t *enabled_array; @@ -143,19 +144,19 @@ private: * The set of past ModelActions that this the action at this Node may * read from. Only meaningful if this Node represents a 'read' action. */ - std::vector< const ModelAction *, ModelAlloc< const ModelAction * > > read_from_past; + ModelVector read_from_past; unsigned int read_from_past_idx; - std::vector< const ModelAction *, ModelAlloc > read_from_promises; + ModelVector read_from_promises; int read_from_promise_idx; - std::vector< struct future_value, ModelAlloc > future_values; + ModelVector future_values; int future_index; - std::vector< bool, ModelAlloc > resolve_promise; + ModelVector resolve_promise; int resolve_promise_idx; - std::vector< const ModelAction *, ModelAlloc > relseq_break_writes; + ModelVector relseq_break_writes; int relseq_break_index; int misc_index; @@ -163,7 +164,7 @@ private: int * yield_data; }; -typedef std::vector< Node *, ModelAlloc< Node * > > node_list_t; +typedef ModelVector node_list_t; /** * @brief A stack of nodes diff --git a/promise.h b/promise.h index 0adc3de..90ec1d2 100644 --- a/promise.h +++ b/promise.h @@ -8,10 +8,10 @@ #define __PROMISE_H__ #include -#include #include "modeltypes.h" #include "mymemory.h" +#include "stl-model.h" class ModelAction; @@ -52,14 +52,14 @@ class Promise { private: /** @brief Thread ID(s) for thread(s) that potentially can satisfy this * promise */ - std::vector< bool, SnapshotAlloc > available_thread; + SnapVector available_thread; int num_available_threads; const future_value fv; /** @brief The action(s) which read the promised future value */ - std::vector< ModelAction *, SnapshotAlloc > readers; + SnapVector readers; const ModelAction *write; }; diff --git a/snapshot-interface.cc b/snapshot-interface.cc index 57ac52e..bd1de3e 100644 --- a/snapshot-interface.cc +++ b/snapshot-interface.cc @@ -2,12 +2,12 @@ #include #include #include -#include #include "snapshot-interface.h" #include "snapshot.h" #include "common.h" #include "mymemory.h" +#include "stl-model.h" /* MYBINARYNAME only works because our pathname usually includes 'model' (e.g., * /.../model-checker/test/userprog.o) */ @@ -29,7 +29,7 @@ class SnapshotStack { MEMALLOC private: - std::vector > stack; + ModelVector stack; }; static SnapshotStack *snap_stack; diff --git a/stl-model.h b/stl-model.h new file mode 100644 index 0000000..ae6e8b2 --- /dev/null +++ b/stl-model.h @@ -0,0 +1,76 @@ +#ifndef __STL_MODEL_H__ +#define __STL_MODEL_H__ + +#include +#include +#include "mymemory.h" + +template +class ModelList : public std::list<_Tp, ModelAlloc<_Tp> > +{ + public: + typedef std::list< _Tp, ModelAlloc<_Tp> > list; + + ModelList() : + list() + { } + + ModelList(size_t n, const _Tp& val = _Tp()) : + list(n, val) + { } + + MEMALLOC +}; + +template +class SnapList : public std::list<_Tp, SnapshotAlloc<_Tp> > +{ + public: + typedef std::list<_Tp, SnapshotAlloc<_Tp> > list; + + SnapList() : + list() + { } + + SnapList(size_t n, const _Tp& val = _Tp()) : + list(n, val) + { } + + SNAPSHOTALLOC +}; + +template +class ModelVector : public std::vector<_Tp, ModelAlloc<_Tp> > +{ + public: + typedef std::vector< _Tp, ModelAlloc<_Tp> > vector; + + ModelVector() : + vector() + { } + + ModelVector(size_t n, const _Tp& val = _Tp()) : + vector(n, val) + { } + + MEMALLOC +}; + +template +class SnapVector : public std::vector<_Tp, SnapshotAlloc<_Tp> > +{ + public: + typedef std::vector< _Tp, SnapshotAlloc<_Tp> > vector; + + SnapVector() : + vector() + { } + + SnapVector(size_t n, const _Tp& val = _Tp()) : + vector(n, val) + { } + + SNAPSHOTALLOC +}; + +#endif /* __STL_MODEL_H__ */ diff --git a/threads-model.h b/threads-model.h index b15c409..e77e80c 100644 --- a/threads-model.h +++ b/threads-model.h @@ -7,11 +7,11 @@ #include #include -#include #include "mymemory.h" #include #include "modeltypes.h" +#include "stl-model.h" struct thread_params { thrd_start_t func; @@ -157,7 +157,7 @@ private: * list is used for thread joins, where another Thread waits for this * Thread to complete */ - std::vector< ModelAction *, SnapshotAlloc > wait_list; + SnapVector wait_list; /** * The value returned by the last action in this thread diff --git a/workqueue.h b/workqueue.h index f08f63c..a25e4fe 100644 --- a/workqueue.h +++ b/workqueue.h @@ -8,6 +8,7 @@ #include #include "mymemory.h" +#include "stl-model.h" class ModelAction; @@ -102,6 +103,6 @@ class MOEdgeWorkEntry : public WorkQueueEntry { }; /** @brief typedef for the work queue type */ -typedef std::list< WorkQueueEntry, ModelAlloc > work_queue_t; +typedef ModelList work_queue_t; #endif /* __WORKQUEUE_H__ */ -- 2.34.1