#include "common.h"
#include "clockvector.h"
#include "cyclegraph.h"
+#include "promise.h"
#define INITIAL_THREAD_ID 0
diverge(NULL),
nextThread(THREAD_ID_T_NONE),
action_trace(new action_list_t()),
- thread_map(new std::map<int, Thread *>),
- obj_map(new std::map<const void *, action_list_t>()),
- obj_thrd_map(new std::map<void *, std::vector<action_list_t> >()),
+ thread_map(new HashTable<int, Thread *, int>()),
+ obj_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 *>(1)),
thrd_last_action(new std::vector<ModelAction *>(1)),
node_stack(new NodeStack()),
next_backtrack(NULL),
/** @brief Destructor */
ModelChecker::~ModelChecker()
{
- std::map<int, Thread *>::iterator it;
+ /* std::map<int, Thread *>::iterator it;
for (it = thread_map->begin(); it != thread_map->end(); it++)
- delete (*it).second;
+ delete (*it).second;*/
delete thread_map;
delete obj_thrd_map;
Thread *t;
if (nextThread == THREAD_ID_T_NONE)
return NULL;
- t = (*thread_map)[id_to_int(nextThread)];
+ t = thread_map->get(id_to_int(nextThread));
ASSERT(t != NULL);
*/
thread_id_t ModelChecker::get_next_replay_thread()
{
- ModelAction *next;
thread_id_t tid;
/* Have we completed exploring the preselected path? */
return THREAD_ID_T_NONE;
/* Else, we are trying to replay an execution */
- next = node_stack->get_next()->get_action();
+ ModelAction * next = node_stack->get_next()->get_action();
if (next == diverge) {
Node *nextnode = next->get_node();
return NULL;
}
/* linear search: from most recent to oldest */
- action_list_t *list = &(*obj_map)[act->get_location()];
+ action_list_t *list = obj_map->ensureptr(act->get_location());
action_list_t::reverse_iterator rit;
for (rit = list->rbegin(); rit != list->rend(); rit++) {
ModelAction *prev = *rit;
if (!already_added)
add_action_to_lists(curr);
- /* Do not split atomic actions. */
- if (curr->is_rmwr()) {
- nextThread = thread_current()->get_id();
- return;
- }
-
/* Is there a better interface for setting the next thread rather
than this field/convoluted approach? Perhaps like just returning
it or something? */
- nextThread = get_next_replay_thread();
+ /* Do not split atomic actions. */
+ if (curr->is_rmwr()) {
+ nextThread = thread_current()->get_id();
+ } else {
+ nextThread = get_next_replay_thread();
+ }
Node *currnode = curr->get_node();
Node *parnode = currnode->get_parent();
* @param rf The action that curr reads from. Must be a write.
*/
void ModelChecker::r_modification_order(ModelAction * curr, const ModelAction *rf) {
- std::vector<action_list_t> *thrd_lists = &(*obj_thrd_map)[curr->get_location()];
+ std::vector<action_list_t> *thrd_lists = obj_thrd_map->ensureptr(curr->get_location());
unsigned int i;
ASSERT(curr->is_read());
* @param curr The current action. Must be a write.
*/
void ModelChecker::w_modification_order(ModelAction * curr) {
- std::vector<action_list_t> *thrd_lists = &(*obj_thrd_map)[curr->get_location()];
+ std::vector<action_list_t> *thrd_lists = obj_thrd_map->ensureptr(curr->get_location());
unsigned int i;
ASSERT(curr->is_write());
int tid = id_to_int(act->get_tid());
action_trace->push_back(act);
- (*obj_map)[act->get_location()].push_back(act);
+ obj_map->ensureptr(act->get_location())->push_back(act);
- std::vector<action_list_t> *vec = &(*obj_thrd_map)[act->get_location()];
+ std::vector<action_list_t> *vec = obj_thrd_map->ensureptr(act->get_location());
if (tid >= (int)vec->size())
vec->resize(next_thread_id);
(*vec)[tid].push_back(act);
*/
ModelAction * ModelChecker::get_last_seq_cst(const void *location)
{
- action_list_t *list = &(*obj_map)[location];
+ action_list_t *list = obj_map->ensureptr(location);
/* Find: max({i in dom(S) | seq_cst(t_i) && isWrite(t_i) && samevar(t_i, t)}) */
action_list_t::reverse_iterator rit;
for (rit = list->rbegin(); rit != list->rend(); rit++)
*/
void ModelChecker::build_reads_from_past(ModelAction *curr)
{
- std::vector<action_list_t> *thrd_lists = &(*obj_thrd_map)[curr->get_location()];
+ std::vector<action_list_t> *thrd_lists = obj_thrd_map->ensureptr(curr->get_location());
unsigned int i;
ASSERT(curr->is_read());
}
if (!initialized) {
- /* TODO: need a more informative way of reporting errors */
+ /** @todo Need a more informative way of reporting errors. */
printf("ERROR: may read from uninitialized atomic\n");
}
int ModelChecker::add_thread(Thread *t)
{
- (*thread_map)[id_to_int(t->get_id())] = t;
+ thread_map->put(id_to_int(t->get_id()), t);
scheduler->add_thread(t);
return 0;
}