aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Bebenita <[email protected]>2010-08-09 08:06:08 -0700
committerMichael Bebenita <[email protected]>2010-08-09 08:06:08 -0700
commit5917ca35190b526b65b4d26ad0b98024ce9e0b09 (patch)
treec4076864029ecc75fd53fd4385caba4656d80080 /src
parentAdded peek() to ptr_vec. (diff)
downloadrust-5917ca35190b526b65b4d26ad0b98024ce9e0b09.tar.xz
rust-5917ca35190b526b65b4d26ad0b98024ce9e0b09.zip
Fixed deadlock in the scheduler caused by condition variables.
Diffstat (limited to 'src')
-rw-r--r--src/rt/rust_dom.cpp17
-rw-r--r--src/rt/rust_dom.h3
-rw-r--r--src/rt/rust_internal.h1
-rw-r--r--src/rt/rust_task.cpp3
4 files changed, 13 insertions, 11 deletions
diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp
index f0739097..b66fca82 100644
--- a/src/rt/rust_dom.cpp
+++ b/src/rt/rust_dom.cpp
@@ -262,8 +262,6 @@ void rust_dom::send_message(rust_message *message) {
this);
A(this, message->dom == this, "Message owned by non-local domain.");
_incoming_message_queue.enqueue(message);
- _incoming_message_pending.signal();
- _progress.signal();
}
/**
@@ -398,9 +396,11 @@ rust_dom::start_main_loop()
"all tasks are blocked, waiting for progress ...");
if (_log.is_tracing(rust_log::TASK))
log_state();
- _progress.wait();
log(rust_log::TASK,
- "progress made, resuming ...");
+ "all tasks are blocked, scheduler yielding ...");
+ sync::yield();
+ log(rust_log::TASK,
+ "scheduler resuming ...");
continue;
}
@@ -450,7 +450,14 @@ rust_dom::start_main_loop()
}
if (_incoming_message_queue.is_empty()) {
- _incoming_message_pending.wait();
+ log(rust_log::DOM,
+ "waiting for %d dead tasks to become dereferenced, "
+ "scheduler yielding ...",
+ dead_tasks.length());
+ if (_log.is_tracing(rust_log::TASK)) {
+ log_state();
+ }
+ sync::yield();
} else {
drain_incoming_message_queue();
}
diff --git a/src/rt/rust_dom.h b/src/rt/rust_dom.h
index 4f3a91dc..5a3278b9 100644
--- a/src/rt/rust_dom.h
+++ b/src/rt/rust_dom.h
@@ -34,13 +34,10 @@ struct rust_dom
rust_task *curr_task;
int rval;
- condition_variable _progress;
-
hash_map<rust_task *, rust_proxy<rust_task> *> _task_proxies;
hash_map<rust_port *, rust_proxy<rust_port> *> _port_proxies;
// Incoming messages from other domains.
- condition_variable _incoming_message_pending;
lock_free_queue _incoming_message_queue;
#ifndef __WIN32__
diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h
index 4f2d8902..46ea843f 100644
--- a/src/rt/rust_internal.h
+++ b/src/rt/rust_internal.h
@@ -38,6 +38,7 @@ extern "C" {
#error "Platform not supported."
#endif
+#include "sync/sync.h"
#include "sync/condition_variable.h"
#ifndef __i386__
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 63724bbb..c8831e8e 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -556,9 +556,6 @@ rust_task::wakeup(rust_cond *from)
A(dom, cond == from, "Cannot wake up blocked task on wrong condition.");
transition(&dom->blocked_tasks, &dom->running_tasks);
- // TODO: Signaling every time the task is awaken is kind of silly,
- // do this a nicer way.
- dom->_progress.signal();
I(dom, cond == from);
cond = NULL;
}