/** Initializes a CycleGraph object. */
CycleGraph::CycleGraph() :
discovered(new HashTable<const CycleNode *, const CycleNode *, uintptr_t, 4, model_malloc, model_calloc, model_free>(16)),
- queue(new std::vector< const CycleNode *, ModelAlloc<const CycleNode *> >()),
+ queue(new ModelVector<const CycleNode *>()),
hasCycles(false),
oldCycles(false)
{
* @return True if the element was found; false otherwise
*/
template <typename T>
-static bool vector_remove_node(std::vector<T, SnapshotAlloc<T> >& v, const T n)
+static bool vector_remove_node(SnapVector<T>& v, const T n)
{
for (unsigned int i = 0; i < v.size(); i++) {
if (v[i] == n) {
#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<const Promise *> > promise_list_t;
+typedef ModelVector<const Promise *> promise_list_t;
/** @brief A graph of Model Actions for tracking cycles. */
class CycleGraph {
bool mergeNodes(CycleNode *node1, CycleNode *node2);
HashTable<const CycleNode *, const CycleNode *, uintptr_t, 4, model_malloc, model_calloc, model_free> *discovered;
- std::vector< const CycleNode *, ModelAlloc<const CycleNode *> > * queue;
+ ModelVector<const CycleNode *> * queue;
/** @brief A table for mapping ModelActions to CycleNodes */
HashTable<const Promise *, CycleNode *, uintptr_t, 4> promiseToNode;
#if SUPPORT_MOD_ORDER_DUMP
- std::vector< CycleNode *, SnapshotAlloc<CycleNode *> > nodeList;
+ SnapVector<CycleNode *> nodeList;
#endif
bool checkReachable(const CycleNode *from, const CycleNode *to) const;
bool hasCycles;
bool oldCycles;
- std::vector< CycleNode *, SnapshotAlloc<CycleNode *> > rollbackvector;
- std::vector< CycleNode *, SnapshotAlloc<CycleNode *> > rmwrollbackvector;
+ SnapVector<CycleNode *> rollbackvector;
+ SnapVector<CycleNode *> rmwrollbackvector;
};
/**
const Promise *promise;
/** @brief The edges leading out from this node */
- std::vector< CycleNode *, SnapshotAlloc<CycleNode *> > edges;
+ SnapVector<CycleNode *> edges;
/** @brief The edges leading into this node */
- std::vector< CycleNode *, SnapshotAlloc<CycleNode *> > back_edges;
+ SnapVector<CycleNode *> back_edges;
/** Pointer to a RMW node that reads from this node, or NULL, if none
* exists */
#include "action.h"
struct ShadowTable *root;
-std::vector<struct DataRace *> unrealizedraces;
+SnapVector<struct DataRace *> unrealizedraces;
void *memory_base;
void *memory_top;
#ifndef DATARACE_H
#include "config.h"
#include <stdint.h>
-#include <vector>
#include "modeltypes.h"
+#include "stl-model.h"
/* Forward declaration */
class ClockVector;
bool checkDataRaces();
void assert_race(struct DataRace *race);
-extern std::vector<struct DataRace *> unrealizedraces;
+extern SnapVector<struct DataRace *> unrealizedraces;
/** Basic encoding idea:
* (void *) Either:
unsigned int next_thread_id;
modelclock_t used_sequence_numbers;
ModelAction *next_backtrack;
- std::vector< bug_message *, SnapshotAlloc<bug_message *> > bugs;
+ SnapVector<bug_message *> bugs;
struct execution_stats stats;
bool failed_promise;
bool too_many_reads;
obj_map(new HashTable<const void *, action_list_t *, uintptr_t, 4>()),
lock_waiters_map(new HashTable<const void *, action_list_t *, uintptr_t, 4>()),
condvar_waiters_map(new HashTable<const void *, action_list_t *, uintptr_t, 4>()),
- obj_thrd_map(new HashTable<void *, std::vector<action_list_t> *, uintptr_t, 4 >()),
- promises(new std::vector< Promise *, SnapshotAlloc<Promise *> >()),
- futurevalues(new std::vector< struct PendingFutureValue, SnapshotAlloc<struct PendingFutureValue> >()),
- pending_rel_seqs(new std::vector< struct release_seq *, SnapshotAlloc<struct release_seq *> >()),
- thrd_last_action(new std::vector< ModelAction *, SnapshotAlloc<ModelAction *> >(1)),
- thrd_last_fence_release(new std::vector< ModelAction *, SnapshotAlloc<ModelAction *> >()),
+ obj_thrd_map(new HashTable<void *, SnapVector<action_list_t> *, uintptr_t, 4 >()),
+ promises(new SnapVector<Promise *>()),
+ futurevalues(new SnapVector<struct PendingFutureValue>()),
+ pending_rel_seqs(new SnapVector<struct release_seq *>()),
+ thrd_last_action(new SnapVector<ModelAction *>(1)),
+ thrd_last_fence_release(new SnapVector<ModelAction *>()),
node_stack(new NodeStack()),
priv(new struct model_snapshot_members()),
mo_graph(new CycleGraph())
return tmp;
}
-static std::vector<action_list_t> * get_safe_ptr_vect_action(HashTable<void *, std::vector<action_list_t> *, uintptr_t, 4> * hash, void * ptr)
+static SnapVector<action_list_t> * get_safe_ptr_vect_action(HashTable<void *, SnapVector<action_list_t> *, uintptr_t, 4> * hash, void * ptr)
{
- std::vector<action_list_t> *tmp = hash->get(ptr);
+ SnapVector<action_list_t> *tmp = hash->get(ptr);
if (tmp == NULL) {
- tmp = new std::vector<action_list_t>();
+ tmp = new SnapVector<action_list_t>();
hash->put(ptr, tmp);
}
return tmp;
* load-acquire
* or
* load --sb-> fence-acquire */
- std::vector< ModelAction *, ModelAlloc<ModelAction *> > acquire_fences(get_num_threads(), NULL);
- std::vector< ModelAction *, ModelAlloc<ModelAction *> > prior_loads(get_num_threads(), NULL);
+ ModelVector<ModelAction *> acquire_fences(get_num_threads(), NULL);
+ ModelVector<ModelAction *> prior_loads(get_num_threads(), NULL);
bool found_acquire_fences = false;
for ( ; rit != list->rend(); rit++) {
ModelAction *prev = *rit;
bool ModelChecker::process_write(ModelAction *curr)
{
/* Readers to which we may send our future value */
- std::vector< ModelAction *, ModelAlloc<ModelAction *> > send_fv;
+ ModelVector<ModelAction *> send_fv;
bool updated_mod_order = w_modification_order(curr, &send_fv);
int promise_idx = get_promise_to_resolve(curr);
if (!mo_graph->checkReachable(rf, other_rf))
return false;
- std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
+ SnapVector<action_list_t> *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);
curr->get_node()->get_read_from_promise_size() <= 1)
return true;
- std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
+ SnapVector<action_list_t> *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];
template <typename rf_type>
bool ModelChecker::r_modification_order(ModelAction *curr, const rf_type *rf)
{
- std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
+ SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
unsigned int i;
bool added = false;
ASSERT(curr->is_read());
* 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<ModelAction *> > *send_fv)
+bool ModelChecker::w_modification_order(ModelAction *curr, ModelVector<ModelAction *> *send_fv)
{
- std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
+ SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
unsigned int i;
bool added = false;
ASSERT(curr->is_write());
*/
bool ModelChecker::mo_may_allow(const ModelAction *writer, const ModelAction *reader)
{
- std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, reader->get_location());
+ SnapVector<action_list_t> *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++) {
release_heads->push_back(fence_release);
int tid = id_to_int(rf->get_tid());
- std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, rf->get_location());
+ SnapVector<action_list_t> *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;
bool ModelChecker::resolve_release_sequences(void *location, work_queue_t *work_queue)
{
bool updated = false;
- std::vector< struct release_seq *, SnapshotAlloc<struct release_seq *> >::iterator it = pending_rel_seqs->begin();
+ SnapVector<struct release_seq *>::iterator it = pending_rel_seqs->begin();
while (it != pending_rel_seqs->end()) {
struct release_seq *pending = *it;
ModelAction *acquire = pending->acquire;
if (uninit)
action_trace->push_front(uninit);
- std::vector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, act->get_location());
+ SnapVector<action_list_t> *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);
void *mutex_loc = (void *) act->get_value();
get_safe_ptr_action(obj_map, mutex_loc)->push_back(act);
- std::vector<action_list_t> *vec = get_safe_ptr_vect_action(obj_thrd_map, mutex_loc);
+ SnapVector<action_list_t> *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);
*/
bool ModelChecker::resolve_promise(ModelAction *write, unsigned int promise_idx)
{
- std::vector< ModelAction *, ModelAlloc<ModelAction *> > actions_to_check;
+ ModelVector<ModelAction *> actions_to_check;
Promise *promise = (*promises)[promise_idx];
for (unsigned int i = 0; i < promise->get_num_readers(); i++) {
*/
void ModelChecker::build_may_read_from(ModelAction *curr)
{
- std::vector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
+ SnapVector<action_list_t> *thrd_lists = get_safe_ptr_vect_action(obj_thrd_map, curr->get_location());
unsigned int i;
ASSERT(curr->is_read());
#include "workqueue.h"
#include "config.h"
#include "modeltypes.h"
+#include "stl-model.h"
/* Forward declaration */
class Node;
struct model_snapshot_members;
/** @brief Shorthand for a list of release sequence heads */
-typedef std::vector< const ModelAction *, ModelAlloc<const ModelAction *> > rel_heads_list_t;
+typedef ModelVector<const ModelAction *> rel_heads_list_t;
-typedef std::list< ModelAction *, SnapshotAlloc<ModelAction *> > action_list_t;
+typedef SnapList<ModelAction *> action_list_t;
/**
* Model checker parameter structure. Holds run-time configuration options for
/** @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<const ModelAction *> writes;
+ SnapVector<const ModelAction *> writes;
};
/** @brief The central structure for model-checking */
template <typename rf_type>
bool r_modification_order(ModelAction *curr, const rf_type *rf);
- bool w_modification_order(ModelAction *curr, std::vector< ModelAction *, ModelAlloc<ModelAction *> > *send_fv);
+ bool w_modification_order(ModelAction *curr, ModelVector<ModelAction *> *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);
* to a trace of all actions performed on the object. */
HashTable<const void *, action_list_t *, uintptr_t, 4> * const condvar_waiters_map;
- HashTable<void *, std::vector<action_list_t> *, uintptr_t, 4 > * const obj_thrd_map;
- std::vector< Promise *, SnapshotAlloc<Promise *> > * const promises;
- std::vector< struct PendingFutureValue, SnapshotAlloc<struct PendingFutureValue> > * const futurevalues;
+ HashTable<void *, SnapVector<action_list_t> *, uintptr_t, 4 > * const obj_thrd_map;
+ SnapVector<Promise *> * const promises;
+ SnapVector<struct PendingFutureValue> * const futurevalues;
/**
* List of pending release sequences. Release sequences might be
* are established. Each entry in the list may only be partially
* filled, depending on its pending status.
*/
- std::vector< struct release_seq *, SnapshotAlloc<struct release_seq *> > * const pending_rel_seqs;
+ SnapVector<struct release_seq *> * const pending_rel_seqs;
- std::vector< ModelAction *, SnapshotAlloc<ModelAction *> > * const thrd_last_action;
- std::vector< ModelAction *, SnapshotAlloc<ModelAction *> > * const thrd_last_fence_release;
+ SnapVector<ModelAction *> * const thrd_last_action;
+ SnapVector<ModelAction *> * const thrd_last_fence_release;
NodeStack * const node_stack;
/** Private data members that should be snapshotted. They are grouped
#include "mymemory.h"
#include "schedule.h"
#include "promise.h"
+#include "stl-model.h"
class ModelAction;
class Thread;
Node * const parent;
const int num_threads;
- std::vector< bool, ModelAlloc<bool> > explored_children;
- std::vector< bool, ModelAlloc<bool> > backtrack;
- std::vector< struct fairness_info, ModelAlloc< struct fairness_info> > fairness;
+ ModelVector<bool> explored_children;
+ ModelVector<bool> backtrack;
+ ModelVector<struct fairness_info> fairness;
int numBacktracks;
enabled_type_t *enabled_array;
* 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<const ModelAction *> read_from_past;
unsigned int read_from_past_idx;
- std::vector< const ModelAction *, ModelAlloc<const ModelAction *> > read_from_promises;
+ ModelVector<const ModelAction *> read_from_promises;
int read_from_promise_idx;
- std::vector< struct future_value, ModelAlloc<struct future_value> > future_values;
+ ModelVector<struct future_value> future_values;
int future_index;
- std::vector< bool, ModelAlloc<bool> > resolve_promise;
+ ModelVector<bool> resolve_promise;
int resolve_promise_idx;
- std::vector< const ModelAction *, ModelAlloc<const ModelAction *> > relseq_break_writes;
+ ModelVector<const ModelAction *> relseq_break_writes;
int relseq_break_index;
int misc_index;
int * yield_data;
};
-typedef std::vector< Node *, ModelAlloc< Node * > > node_list_t;
+typedef ModelVector<Node *> node_list_t;
/**
* @brief A stack of nodes
#define __PROMISE_H__
#include <inttypes.h>
-#include <vector>
#include "modeltypes.h"
#include "mymemory.h"
+#include "stl-model.h"
class ModelAction;
private:
/** @brief Thread ID(s) for thread(s) that potentially can satisfy this
* promise */
- std::vector< bool, SnapshotAlloc<bool> > available_thread;
+ SnapVector<bool> available_thread;
int num_available_threads;
const future_value fv;
/** @brief The action(s) which read the promised future value */
- std::vector< ModelAction *, SnapshotAlloc<ModelAction *> > readers;
+ SnapVector<ModelAction *> readers;
const ModelAction *write;
};
#include <unistd.h>
#include <cstring>
#include <inttypes.h>
-#include <vector>
#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) */
MEMALLOC
private:
- std::vector<struct snapshot_entry, ModelAlloc<struct snapshot_entry> > stack;
+ ModelVector<struct snapshot_entry> stack;
};
static SnapshotStack *snap_stack;
--- /dev/null
+#ifndef __STL_MODEL_H__
+#define __STL_MODEL_H__
+
+#include <vector>
+#include <list>
+#include "mymemory.h"
+
+template<typename _Tp>
+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<typename _Tp>
+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<typename _Tp>
+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<typename _Tp>
+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__ */
#include <ucontext.h>
#include <stdint.h>
-#include <vector>
#include "mymemory.h"
#include <threads.h>
#include "modeltypes.h"
+#include "stl-model.h"
struct thread_params {
thrd_start_t func;
* list is used for thread joins, where another Thread waits for this
* Thread to complete
*/
- std::vector< ModelAction *, SnapshotAlloc<ModelAction *> > wait_list;
+ SnapVector<ModelAction *> wait_list;
/**
* The value returned by the last action in this thread
#include <list>
#include "mymemory.h"
+#include "stl-model.h"
class ModelAction;
};
/** @brief typedef for the work queue type */
-typedef std::list< WorkQueueEntry, ModelAlloc<WorkQueueEntry> > work_queue_t;
+typedef ModelList<WorkQueueEntry> work_queue_t;
#endif /* __WORKQUEUE_H__ */