#include "threads-model.h"
#include "bugmessage.h"
+#include <pthread.h>
+
#define INITIAL_THREAD_ID 0
/**
too_many_reads(false),
no_valid_reads(false),
bad_synchronization(false),
+ bad_sc_read(false),
asserted(false)
{ }
bool no_valid_reads;
/** @brief Incorrectly-ordered synchronization was made */
bool bad_synchronization;
+ bool bad_sc_read;
bool asserted;
SNAPSHOTALLOC
mo_graph(new CycleGraph())
{
/* Initialize a model-checker thread, for special ModelActions */
- model_thread = new Thread(get_next_id());
- add_thread(model_thread);
+ model_thread = new Thread(get_next_id()); // L: Create model thread
+ add_thread(model_thread); // L: Add model thread to scheduler
scheduler->register_engine(this);
node_stack->register_engine(this);
}
priv->bad_synchronization = true;
}
+/** @brief Alert the model-checker that an incorrectly-ordered
+ * synchronization was made */
+void ModelExecution::set_bad_sc_read()
+{
+ priv->bad_sc_read = true;
+}
+
bool ModelExecution::assert_bug(const char *msg)
{
priv->bugs.push_back(new bug_message(msg));
thrd_t *thrd = (thrd_t *)curr->get_location();
struct thread_params *params = (struct thread_params *)curr->get_value();
Thread *th = new Thread(get_next_id(), thrd, params->func, params->arg, get_thread(curr));
+ curr->set_thread_operand(th);
+ add_thread(th);
+ th->set_creation(curr);
+ /* Promises can be satisfied by children */
+ for (unsigned int i = 0; i < promises.size(); i++) {
+ Promise *promise = promises[i];
+ if (promise->thread_is_available(curr->get_tid()))
+ promise->add_thread(th->get_id());
+ }
+ break;
+ }
+ case PTHREAD_CREATE: {
+ thrd_t *thrd = (thrd_t *)curr->get_location();
+ struct pthread_params *params = (struct pthread_params *)curr->get_value();
+ Thread *th = new Thread(get_next_id(), thrd, params->func, params->arg, get_thread(curr));
+ curr->set_thread_operand(th);
add_thread(th);
th->set_creation(curr);
/* Promises can be satisfied by children */
updated = true; /* trigger rel-seq checks */
break;
}
+ case PTHREAD_JOIN: {
+ Thread *blocking = curr->get_thread_operand();
+ ModelAction *act = get_last_action(blocking->get_id());
+ synchronize(act, curr);
+ updated = true; /* trigger rel-seq checks */
+ break; // WL: to be add (modified)
+ }
+
case THREAD_FINISH: {
Thread *th = get_thread(curr);
/* Wake up any joining threads */
*
* @return True if this read established synchronization
*/
+
bool ModelExecution::read_from(ModelAction *act, const ModelAction *rf)
{
ASSERT(rf);
if (rf) {
if (r_modification_order(act, rf))
updated = true;
+ if (act->is_seqcst()) {
+ ModelAction *last_sc_write = get_last_seq_cst_write(act);
+ if (last_sc_write != NULL && rf->happens_before(last_sc_write)) {
+ set_bad_sc_read();
+ }
+ }
} else if (promise) {
if (r_modification_order(act, promise))
updated = true;
ptr += sprintf(ptr, "[no valid reads-from]");
if (priv->bad_synchronization)
ptr += sprintf(ptr, "[bad sw ordering]");
+ if (priv->bad_sc_read)
+ ptr += sprintf(ptr, "[bad sc read]");
if (promises_expired())
ptr += sprintf(ptr, "[promise expired]");
if (promises.size() != 0)
priv->no_valid_reads ||
priv->too_many_reads ||
priv->bad_synchronization ||
+ priv->bad_sc_read ||
priv->hard_failed_promise ||
promises_expired();
}
}
}
- /* C++, Section 29.3 statement 3 (second subpoint) */
- if (curr->is_seqcst() && last_sc_write && act == last_sc_write) {
- added = mo_graph->addEdge(act, rf) || added;
- break;
- }
-
/*
* Include at most one act per-thread that "happens
* before" curr
action_list_t::const_iterator it;
model_print("------------------------------------------------------------------------------------\n");
- model_print("# t Action type MO Location Value Rf CV\n");
+ model_print("# t Action type MO Location Value Rf CV\n");
model_print("------------------------------------------------------------------------------------\n");
unsigned int hash = 0;
/* Do not split atomic RMW */
if (curr->is_rmwr())
return get_thread(curr);
+ if (curr->is_write()) {
+// std::memory_order order = curr->get_mo();
+// switch(order) {
+// case std::memory_order_relaxed:
+// return get_thread(curr);
+// case std::memory_order_release:
+// return get_thread(curr);
+// defalut:
+// return NULL;
+// }
+ return NULL;
+ }
+
/* Follow CREATE with the created thread */
+ /* which is not needed, because model.cc takes care of this */
if (curr->get_type() == THREAD_CREATE)
+ return curr->get_thread_operand();
+ if (curr->get_type() == PTHREAD_CREATE) {
return curr->get_thread_operand();
+ }
return NULL;
}