Skip to content

Commit a9b42f4

Browse files
committed
---
yaml --- r: 148867 b: refs/heads/try2 c: a417de9 h: refs/heads/master i: 148865: 8fc8dbb 148863: 8e5fac5 v: v3
1 parent 7204c26 commit a9b42f4

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: b5f19795adda1bb2daca891e97bca8c7638916e2
8+
refs/heads/try2: a417de94a94429e35afeb0a3eb867c2b1837a484
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libextra/sync.rs renamed to branches/try2/src/libextra/sync/mod.rs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
* in std.
1818
*/
1919

20-
20+
use std::cast;
2121
use std::comm;
22-
use std::unstable::sync::Exclusive;
2322
use std::sync::arc::UnsafeArc;
2423
use std::sync::atomics;
2524
use std::unstable::finally::Finally;
@@ -32,6 +31,10 @@ use arc::MutexArc;
3231
* Internals
3332
****************************************************************************/
3433

34+
pub mod mutex;
35+
pub mod one;
36+
mod mpsc_intrusive;
37+
3538
// Each waiting task receives on one of these.
3639
#[doc(hidden)]
3740
type WaitEnd = Port<()>;
@@ -54,7 +57,7 @@ impl WaitQueue {
5457
comm::Data(ch) => {
5558
// Send a wakeup signal. If the waiter was killed, its port will
5659
// have closed. Keep trying until we get a live task.
57-
if ch.try_send_deferred(()) {
60+
if ch.try_send(()) {
5861
true
5962
} else {
6063
self.signal()
@@ -69,7 +72,7 @@ impl WaitQueue {
6972
loop {
7073
match self.head.try_recv() {
7174
comm::Data(ch) => {
72-
if ch.try_send_deferred(()) {
75+
if ch.try_send(()) {
7376
count += 1;
7477
}
7578
}
@@ -81,36 +84,45 @@ impl WaitQueue {
8184

8285
fn wait_end(&self) -> WaitEnd {
8386
let (wait_end, signal_end) = Chan::new();
84-
assert!(self.tail.try_send_deferred(signal_end));
87+
assert!(self.tail.try_send(signal_end));
8588
wait_end
8689
}
8790
}
8891

8992
// The building-block used to make semaphores, mutexes, and rwlocks.
90-
#[doc(hidden)]
9193
struct SemInner<Q> {
94+
lock: mutex::Mutex,
9295
count: int,
9396
waiters: WaitQueue,
9497
// Can be either unit or another waitqueue. Some sems shouldn't come with
9598
// a condition variable attached, others should.
9699
blocked: Q
97100
}
98101

99-
#[doc(hidden)]
100-
struct Sem<Q>(Exclusive<SemInner<Q>>);
102+
struct Sem<Q>(UnsafeArc<SemInner<Q>>);
101103

102104
#[doc(hidden)]
103105
impl<Q:Send> Sem<Q> {
104106
fn new(count: int, q: Q) -> Sem<Q> {
105-
Sem(Exclusive::new(SemInner {
106-
count: count, waiters: WaitQueue::new(), blocked: q }))
107+
Sem(UnsafeArc::new(SemInner {
108+
count: count,
109+
waiters: WaitQueue::new(),
110+
blocked: q,
111+
lock: mutex::Mutex::new(),
112+
}))
113+
}
114+
115+
unsafe fn with(&self, f: |&mut SemInner<Q>|) {
116+
let Sem(ref arc) = *self;
117+
let state = arc.get();
118+
let _g = (*state).lock.lock();
119+
f(cast::transmute(state));
107120
}
108121

109122
pub fn acquire(&self) {
110123
unsafe {
111124
let mut waiter_nobe = None;
112-
let Sem(ref lock) = *self;
113-
lock.with(|state| {
125+
self.with(|state| {
114126
state.count -= 1;
115127
if state.count < 0 {
116128
// Create waiter nobe, enqueue ourself, and tell
@@ -129,8 +141,7 @@ impl<Q:Send> Sem<Q> {
129141

130142
pub fn release(&self) {
131143
unsafe {
132-
let Sem(ref lock) = *self;
133-
lock.with(|state| {
144+
self.with(|state| {
134145
state.count += 1;
135146
if state.count <= 0 {
136147
state.waiters.signal();
@@ -210,8 +221,7 @@ impl<'a> Condvar<'a> {
210221
let mut out_of_bounds = None;
211222
// Release lock, 'atomically' enqueuing ourselves in so doing.
212223
unsafe {
213-
let Sem(ref queue) = *self.sem;
214-
queue.with(|state| {
224+
self.sem.with(|state| {
215225
if condvar_id < state.blocked.len() {
216226
// Drop the lock.
217227
state.count += 1;
@@ -253,8 +263,7 @@ impl<'a> Condvar<'a> {
253263
unsafe {
254264
let mut out_of_bounds = None;
255265
let mut result = false;
256-
let Sem(ref lock) = *self.sem;
257-
lock.with(|state| {
266+
self.sem.with(|state| {
258267
if condvar_id < state.blocked.len() {
259268
result = state.blocked[condvar_id].signal();
260269
} else {
@@ -276,8 +285,7 @@ impl<'a> Condvar<'a> {
276285
let mut out_of_bounds = None;
277286
let mut queue = None;
278287
unsafe {
279-
let Sem(ref lock) = *self.sem;
280-
lock.with(|state| {
288+
self.sem.with(|state| {
281289
if condvar_id < state.blocked.len() {
282290
// To avoid :broadcast_heavy, we make a new waitqueue,
283291
// swap it out with the old one, and broadcast on the

0 commit comments

Comments
 (0)