From a4b8c74f9f6e41f40b30cf4ef49ea42a2cee9b4f Mon Sep 17 00:00:00 2001 From: Michael Bebenita Date: Tue, 17 Aug 2010 23:47:11 -0700 Subject: [PATCH] Added simple deadlock detection in the scheduler. --- src/rt/rust_dom.cpp | 27 +++++++++++++++++++++++++++ src/rt/rust_dom.h | 1 + 2 files changed, 28 insertions(+) diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp index 67a1be3644d85..ce6bebf3a8c2f 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_dom.cpp @@ -368,6 +368,31 @@ rust_dom::schedule_task() { return NULL; } +/** + * Checks for simple deadlocks. + */ +bool +rust_dom::is_deadlocked() { + if (_live_domains.size() != 1) { + // We cannot tell if we are deadlocked if other domains exists. + return false; + } + + if (running_tasks.length() != 0) { + // We are making progress and therefore we are not deadlocked. + return false; + } + + if (_incoming_message_queue.is_empty() && blocked_tasks.length() > 0) { + // We have no messages to process, no running tasks to schedule + // and some blocked tasks therefore we are likely in a deadlock. + log_state(); + return true; + } + + return false; +} + void rust_dom::log_all_state() { for (uint32_t i = 0; i < _live_domains.size(); i++) { @@ -427,6 +452,8 @@ rust_dom::start_main_loop() logptr("exit-task glue", root_crate->get_exit_task_glue()); while (n_live_tasks() > 0) { + A(this, is_deadlocked() == false, "deadlock"); + drain_incoming_message_queue(); rust_task *scheduled_task = schedule_task(); diff --git a/src/rt/rust_dom.h b/src/rt/rust_dom.h index d2b6e57033b3d..34d8c69462f2c 100644 --- a/src/rt/rust_dom.h +++ b/src/rt/rust_dom.h @@ -88,6 +88,7 @@ struct rust_dom void reap_dead_tasks(); rust_task *schedule_task(); + bool is_deadlocked(); int start_main_loop(); void log_state();