diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp index d3b5d2cee89..4527955176c 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_dom.cpp @@ -314,7 +314,7 @@ rust_dom::start_main_loop() { } log(rust_log::TASK, "all tasks are blocked, scheduler yielding ..."); - sync::yield(); + sync::sleep(100); log(rust_log::TASK, "scheduler resuming ..."); continue; diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index ef4220f9129..0dc1369dca6 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -164,9 +164,7 @@ void rust_kernel::terminate_kernel_loop() { log(rust_log::KERN, "terminating kernel loop"); _interrupt_kernel_loop = true; - _kernel_lock.lock(); - _kernel_lock.signal_all(); - _kernel_lock.unlock(); + signal_kernel_lock(); join(); } @@ -217,6 +215,23 @@ rust_kernel::free_handles(hash_map* > &map) { } } +void +rust_kernel::notify_message_enqueued(rust_message_queue *queue, + rust_message *message) { + // The message pump needs to handle this message if the queue is not + // associated with a domain, therefore signal the message pump. + if (queue->is_associated() == false) { + signal_kernel_lock(); + } +} + +void +rust_kernel::signal_kernel_lock() { + _kernel_lock.lock(); + _kernel_lock.signal_all(); + _kernel_lock.unlock(); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index f85d55ac201..3ad7b396575 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -9,6 +9,7 @@ */ class rust_kernel; +class rust_message; template class rust_handle : @@ -90,6 +91,16 @@ public: bool is_deadlocked(); + void signal_kernel_lock(); + + /** + * Notifies the kernel whenever a message has been enqueued . This gives + * the kernel the opportunity to wake up the message pump thread if the + * message queue is not associated. + */ + void + notify_message_enqueued(rust_message_queue *queue, rust_message *message); + /** * Blocks until all domains have terminated. */ diff --git a/src/rt/rust_message.h b/src/rt/rust_message.h index c342e3e411a..e9ce94bfa9e 100644 --- a/src/rt/rust_message.h +++ b/src/rt/rust_message.h @@ -114,6 +114,11 @@ public: bool is_associated() { return this->dom_handle != NULL; } + + void enqueue(rust_message* message) { + lock_free_queue::enqueue(message); + kernel->notify_message_enqueued(this, message); + } }; // diff --git a/src/rt/sync/lock_free_queue.h b/src/rt/sync/lock_free_queue.h index ac0c5b046a0..1c760bff9d4 100644 --- a/src/rt/sync/lock_free_queue.h +++ b/src/rt/sync/lock_free_queue.h @@ -120,7 +120,7 @@ public: return head.node == tail.node; } - void enqueue(T value) { + virtual void enqueue(T value) { // Create a new node to be inserted in the linked list, and set the // next node to NULL.