Skip to content

Commit

Permalink
Fixed race in the rust kernel.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbebenita committed Sep 8, 2010
1 parent de611a3 commit 7f6d8b9
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 20 deletions.
47 changes: 30 additions & 17 deletions src/rt/rust_kernel.cpp
Expand Up @@ -129,20 +129,25 @@ rust_kernel::log(uint32_t type_bits, char const *fmt, ...) {
}

void
rust_kernel::start_kernel_loop() {
while (_interrupt_kernel_loop == false) {
message_queues.global.lock();
for (size_t i = 0; i < message_queues.length(); i++) {
rust_message_queue *queue = message_queues[i];
if (queue->is_associated() == false) {
rust_message *message = NULL;
while (queue->dequeue(&message)) {
message->kernel_process();
delete message;
}
rust_kernel::pump_message_queues() {
message_queues.global.lock();
for (size_t i = 0; i < message_queues.length(); i++) {
rust_message_queue *queue = message_queues[i];
if (queue->is_associated() == false) {
rust_message *message = NULL;
while (queue->dequeue(&message)) {
message->kernel_process();
delete message;
}
}
message_queues.global.unlock();
}
message_queues.global.unlock();
}

void
rust_kernel::start_kernel_loop() {
while (_interrupt_kernel_loop == false) {
pump_message_queues();
}
}

Expand All @@ -153,16 +158,24 @@ rust_kernel::run() {
log(rust_log::KERN, "finished kernel loop");
}

void
rust_kernel::terminate_kernel_loop() {
_interrupt_kernel_loop = true;
join();
}

rust_kernel::~rust_kernel() {
K(_srv, domains.length() == 0,
"Kernel has %d live domain(s), join all domains before killing "
"the kernel.", domains.length());

// If the kernel loop is running, interrupt it, join and exit.
if (is_running()) {
_interrupt_kernel_loop = true;
join();
}
terminate_kernel_loop();

// It's possible that the message pump misses some messages because
// of races, so pump any remaining messages here. By now all domain
// threads should have been joined, so we shouldn't miss any more
// messages.
pump_message_queues();

free_handles(_task_handles);
free_handles(_port_handles);
Expand Down
3 changes: 3 additions & 0 deletions src/rt/rust_kernel.h
Expand Up @@ -60,6 +60,9 @@ class rust_kernel : public rust_thread {
*/
spin_lock _message_queues_lock;

void terminate_kernel_loop();
void pump_message_queues();

public:

/**
Expand Down
9 changes: 7 additions & 2 deletions src/rt/sync/sync.cpp
Expand Up @@ -11,6 +11,10 @@ void sync::yield() {
#endif
}

rust_thread::rust_thread() : _is_running(false) {
// Nop.
}

#if defined(__WIN32__)
static DWORD WINAPI
#elif defined(__GNUC__)
Expand All @@ -36,6 +40,7 @@ rust_thread::start() {
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&thread, &attr, rust_thread_start, (void *) this);
#endif
_is_running = true;
}

void
Expand All @@ -46,10 +51,10 @@ rust_thread::join() {
pthread_join(thread, NULL);
#endif
thread = 0;
_is_running = false;
}

bool
rust_thread::is_running() {
// TODO: This may be broken because of possible races.
return thread;
return _is_running;
}
3 changes: 3 additions & 0 deletions src/rt/sync/sync.h
Expand Up @@ -15,12 +15,15 @@ class sync {
* Thread utility class. Derive and implement your own run() method.
*/
class rust_thread {
private:
volatile bool _is_running;
public:
#if defined(__WIN32__)
HANDLE thread;
#else
pthread_t thread;
#endif
rust_thread();
void start();

virtual void run() {
Expand Down
3 changes: 2 additions & 1 deletion src/test/run-pass/task-comm-9.rs
Expand Up @@ -16,7 +16,8 @@ io fn test00() {
let port[int] p = port();
let int number_of_messages = 10;

let task t0 = spawn thread test00_start(chan(p), number_of_messages);
let task t0 = spawn thread "child"
test00_start(chan(p), number_of_messages);

let int i = 0;
while (i < number_of_messages) {
Expand Down

0 comments on commit 7f6d8b9

Please sign in to comment.