Skip to content

Commit 10ed396

Browse files
committed
---
yaml --- r: 659 b: refs/heads/master c: f985fde h: refs/heads/master i: 657: c8107d2 655: 1902748 v: v3
1 parent 74d7424 commit 10ed396

File tree

5 files changed

+32
-17
lines changed

5 files changed

+32
-17
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 79dc07d6487612ebf9ac62e43a5729ea774488b9
2+
refs/heads/master: f985fded3ede8a7677ca6c9c77817d27bc9ae492

trunk/src/rt/rust_kernel.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ rust_kernel::create_domain(const rust_crate *crate, const char *name) {
2222
message_queue->associate(handle);
2323
domains.append(dom);
2424
message_queues.append(message_queue);
25-
_kernel_lock.signal();
25+
_kernel_lock.signal_all();
2626
_kernel_lock.unlock();
2727
return handle;
2828
}
@@ -37,7 +37,7 @@ rust_kernel::destroy_domain(rust_dom *dom) {
3737
rust_srv *srv = dom->srv;
3838
delete dom;
3939
delete srv;
40-
_kernel_lock.signal();
40+
_kernel_lock.signal_all();
4141
_kernel_lock.unlock();
4242
}
4343

@@ -91,10 +91,11 @@ rust_kernel::get_port_handle(rust_port *port) {
9191

9292
void
9393
rust_kernel::join_all_domains() {
94-
// TODO: Perhaps we can do this a little smarter. Just spin wait for now.
94+
_kernel_lock.lock();
9595
while (domains.length() > 0) {
96-
sync::yield();
96+
_kernel_lock.wait();
9797
}
98+
_kernel_lock.unlock();
9899
log(rust_log::KERN, "joined domains");
99100
}
100101

@@ -162,7 +163,7 @@ rust_kernel::terminate_kernel_loop() {
162163
log(rust_log::KERN, "terminating kernel loop");
163164
_interrupt_kernel_loop = true;
164165
_kernel_lock.lock();
165-
_kernel_lock.signal();
166+
_kernel_lock.signal_all();
166167
_kernel_lock.unlock();
167168
join();
168169
}

trunk/src/rt/rust_kernel.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ class rust_kernel : public rust_thread {
7575
* live on after their associated domain has died. This way we can safely
7676
* communicate with domains that may have died.
7777
*
78-
* Although the message_queues list is synchronized, each individual
79-
* message queue is lock free.
8078
*/
8179
indexed_list<rust_message_queue> message_queues;
8280

trunk/src/rt/sync/lock_and_signal.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@
1111

1212
#if defined(__WIN32__)
1313
lock_and_signal::lock_and_signal() {
14-
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
14+
// TODO: In order to match the behavior of pthread_cond_broadcast on
15+
// Windows, we create manual reset events. This however breaks the
16+
// behavior of pthread_cond_signal, fixing this is quite involved:
17+
// refer to: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
18+
19+
_event = CreateEvent(NULL, TRUE, FALSE, NULL);
1520
InitializeCriticalSection(&_cs);
1621
}
1722

@@ -33,21 +38,20 @@ lock_and_signal::~lock_and_signal() {
3338

3439
void lock_and_signal::lock() {
3540
#if defined(__WIN32__)
36-
EnterCriticalSection(&_cs);
41+
EnterCriticalSection(&_cs);
3742
#else
38-
pthread_mutex_lock(&_mutex);
43+
pthread_mutex_lock(&_mutex);
3944
#endif
4045
}
4146

4247
void lock_and_signal::unlock() {
4348
#if defined(__WIN32__)
44-
LeaveCriticalSection(&_cs);
49+
LeaveCriticalSection(&_cs);
4550
#else
46-
pthread_mutex_unlock(&_mutex);
51+
pthread_mutex_unlock(&_mutex);
4752
#endif
4853
}
4954

50-
5155
/**
5256
* Wait indefinitely until condition is signaled.
5357
*/
@@ -57,9 +61,9 @@ void lock_and_signal::wait() {
5761

5862
void lock_and_signal::timed_wait(size_t timeout_in_ns) {
5963
#if defined(__WIN32__)
60-
LeaveCriticalSection(&_cs);
61-
WaitForSingleObject(_event, INFINITE);
62-
EnterCriticalSection(&_cs);
64+
LeaveCriticalSection(&_cs);
65+
WaitForSingleObject(_event, INFINITE);
66+
EnterCriticalSection(&_cs);
6367
#else
6468
if (timeout_in_ns == 0) {
6569
pthread_cond_wait(&_cond, &_mutex);
@@ -85,6 +89,17 @@ void lock_and_signal::signal() {
8589
#endif
8690
}
8791

92+
/**
93+
* Signal condition, and resume all waiting threads.
94+
*/
95+
void lock_and_signal::signal_all() {
96+
#if defined(__WIN32__)
97+
SetEvent(_event);
98+
#else
99+
pthread_cond_broadcast(&_cond);
100+
#endif
101+
}
102+
88103

89104
//
90105
// Local Variables:

trunk/src/rt/sync/lock_and_signal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class lock_and_signal {
1818
void wait();
1919
void timed_wait(size_t timeout_in_ns);
2020
void signal();
21+
void signal_all();
2122
};
2223

2324
#endif /* LOCK_AND_SIGNAL_H */

0 commit comments

Comments
 (0)