@@ -15,33 +15,68 @@ use container::Container;
15
15
use vec:: OwnedVector ;
16
16
use option:: { Option , Some , None } ;
17
17
use cell:: Cell ;
18
- use unstable:: sync:: Exclusive ;
18
+ use unstable:: sync:: { UnsafeAtomicRcBox , LittleLock } ;
19
19
use rt:: sched:: SchedHandle ;
20
20
use clone:: Clone ;
21
21
22
22
pub struct SleeperList {
23
- priv stack : Exclusive < ~[ SchedHandle ] >
23
+ priv state : UnsafeAtomicRcBox < State >
24
+ }
25
+
26
+ struct State {
27
+ count : uint ,
28
+ stack : ~[ SchedHandle ] ,
29
+ lock : LittleLock
24
30
}
25
31
26
32
impl SleeperList {
27
33
pub fn new ( ) -> SleeperList {
28
34
SleeperList {
29
- stack : Exclusive :: new ( ~[ ] )
35
+ state : UnsafeAtomicRcBox :: new ( State {
36
+ count : 0 ,
37
+ stack : ~[ ] ,
38
+ lock : LittleLock :: new ( )
39
+ } )
30
40
}
31
41
}
32
42
33
43
pub fn push ( & mut self , handle : SchedHandle ) {
34
44
let handle = Cell :: new ( handle) ;
35
45
unsafe {
36
- self . stack . with ( |s| s. push ( handle. take ( ) ) ) ;
46
+ let state = self . state . get ( ) ;
47
+ do ( * state) . lock . lock {
48
+ ( * state) . count += 1 ;
49
+ ( * state) . stack . push ( handle. take ( ) ) ;
50
+ }
37
51
}
38
52
}
39
53
40
54
pub fn pop ( & mut self ) -> Option < SchedHandle > {
41
55
unsafe {
42
- do self . stack . with |s| {
43
- if !s. is_empty ( ) {
44
- Some ( s. pop ( ) )
56
+ let state = self . state . get ( ) ;
57
+ do ( * state) . lock . lock {
58
+ if !( * state) . stack . is_empty ( ) {
59
+ ( * state) . count -= 1 ;
60
+ Some ( ( * state) . stack . pop ( ) )
61
+ } else {
62
+ None
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ /// A pop that may sometimes miss enqueued elements, but is much faster
69
+ /// to give up without doing any synchronization
70
+ pub fn casual_pop ( & mut self ) -> Option < SchedHandle > {
71
+ unsafe {
72
+ let state = self . state . get ( ) ;
73
+ // NB: Unsynchronized check
74
+ if ( * state) . count == 0 { return None ; }
75
+ do ( * state) . lock . lock {
76
+ if !( * state) . stack . is_empty ( ) {
77
+ // NB: count is also protected by the lock
78
+ ( * state) . count -= 1 ;
79
+ Some ( ( * state) . stack . pop ( ) )
45
80
} else {
46
81
None
47
82
}
@@ -53,7 +88,7 @@ impl SleeperList {
53
88
impl Clone for SleeperList {
54
89
fn clone ( & self ) -> SleeperList {
55
90
SleeperList {
56
- stack : self . stack . clone ( )
91
+ state : self . state . clone ( )
57
92
}
58
93
}
59
94
}
0 commit comments