return old->get_return_value();
}
+uint64_t ModelChecker::switch_thread(ModelAction *act)
+{
+ if (modellock) {
+ static bool fork_message_printed = false;
+
+ if (!fork_message_printed) {
+ model_print("Fork handler or dead thread trying to call into model checker...\n");
+ fork_message_printed = true;
+ }
+ delete act;
+ return 0;
+ }
+ DBG();
+ Thread *old = thread_current();
+ ASSERT(!old->get_pending());
+
+ if (inspect_plugin != NULL) {
+ inspect_plugin->inspectModelAction(act);
+ }
+
+ old->set_pending(act);
+ //Thread *next;
+ /*do {
+ curr_thread_num++;
+ thread_id_t tid = int_to_id(curr_thread_num);
+ next = get_thread(tid);
+
+ } while (next->is_model_thread() || next->is_complete() || next->get_pending() && curr_thread_num < get_num_threads());
+ */
+ Thread *next;
+ curr_thread_num++;
+ while (curr_thread_num < get_num_threads) {
+ thread_id_t tid = int_to_id(curr_thread_num);
+ next = get_thread(tid);
+ if (!next->is_model_thread() && !next->is_complete() && !next->get_pending())
+ break;
+ curr_thread_num++;
+ }
+ if (curr_thread_num < get_num_threads()) {
+ scheduler->set_current_thread(next);
+ if (Thread::swap(old, next) < 0) {
+ perror("swap threads");
+ exit(EXIT_FAILURE);
+ }
+ if (next->is_waiting_on(next))
+ assert_bug("Deadlock detected (thread %u)", curr_thread_num);
+ } else {
+ scheduler->set_current_thread(NULL);
+ if (Thread::swap(old, &system_context) < 0) {
+ perror("swap threads");
+ exit(EXIT_FAILURE);
+ }
+ }
+ return old->get_return_value();
+}
+
static void runChecker() {
model->run();
delete model;
* thread which just took a step--plus the first step
* for any newly-created thread
*/
+ curr_thread_num = 0;
+ thread_id_t tid = int_to_id(0);
+ Thread *thr = get_thread(tid);
+ switch_from_master(tid);
+ /*
for (unsigned int i = 0;i < get_num_threads();i++) {
thread_id_t tid = int_to_id(i);
Thread *thr = get_thread(tid);
assert_bug("Deadlock detected (thread %u)", i);
}
}
-
+ */
/* Don't schedule threads which should be disabled */
for (unsigned int i = 0;i < get_num_threads();i++) {
Thread *th = get_thread(int_to_id(i));
}
void modelexit() {
- model->switch_to_master(new ModelAction(THREAD_FINISH, std::memory_order_seq_cst, thread_current()));
+ model->switch_thread(new ModelAction(THREAD_FINISH, std::memory_order_seq_cst, thread_current()));
}
void initMainThread() {
return model_swapcontext(ctxt, &t->context);
}
+int Thread::swap(Thread *t, Thread *t2)
+{
+ t->set_state(THREAD_READY);
+ t2->set_state(THREAD_RUNNING);
+#ifdef TLS
+ if (t2->tls != NULL)
+ set_tls_addr((uintptr_t)t2->tls);
+#endif
+ return model_swapcontext(&t->context, &t2->context);
+}
/** Terminate a thread and free its stack. */
void Thread::complete()