38
38
use core:: cell:: { Cell , UnsafeCell } ;
39
39
use core:: mem:: { self , ManuallyDrop } ;
40
40
use core:: num:: Wrapping ;
41
- use core:: ptr;
41
+ use core:: { ptr, fmt } ;
42
42
use core:: sync:: atomic;
43
43
use core:: sync:: atomic:: Ordering ;
44
44
45
- use arrayvec:: ArrayVec ;
46
45
use crossbeam_utils:: CachePadded ;
47
46
48
47
use atomic:: { Shared , Owned } ;
@@ -60,10 +59,10 @@ const MAX_OBJECTS: usize = 64;
60
59
const MAX_OBJECTS : usize = 4 ;
61
60
62
61
/// A bag of deferred functions.
63
- #[ derive( Default , Debug ) ]
64
62
pub struct Bag {
65
63
/// Stashed objects.
66
- deferreds : ArrayVec < [ Deferred ; MAX_OBJECTS ] > ,
64
+ deferreds : [ Deferred ; MAX_OBJECTS ] ,
65
+ len : usize
67
66
}
68
67
69
68
/// `Bag::try_push()` requires that it is safe for another thread to execute the given functions.
@@ -77,7 +76,7 @@ impl Bag {
77
76
78
77
/// Returns `true` if the bag is empty.
79
78
pub fn is_empty ( & self ) -> bool {
80
- self . deferreds . is_empty ( )
79
+ self . len == 0
81
80
}
82
81
83
82
/// Attempts to insert a deferred function into the bag.
@@ -89,7 +88,13 @@ impl Bag {
89
88
///
90
89
/// It should be safe for another thread to execute the given function.
91
90
pub unsafe fn try_push ( & mut self , deferred : Deferred ) -> Result < ( ) , Deferred > {
92
- self . deferreds . try_push ( deferred) . map_err ( |e| e. element ( ) )
91
+ if self . len < MAX_OBJECTS {
92
+ self . deferreds [ self . len ] = deferred;
93
+ self . len += 1 ;
94
+ Ok ( ( ) )
95
+ } else {
96
+ Err ( deferred)
97
+ }
93
98
}
94
99
95
100
/// Seals the bag with the given epoch.
@@ -98,15 +103,53 @@ impl Bag {
98
103
}
99
104
}
100
105
106
+ impl Default for Bag {
107
+ fn default ( ) -> Self {
108
+ // TODO: [no_op; MAX_OBJECTS] syntax blocked by https://github.com/rust-lang/rust/issues/49147
109
+ #[ cfg( not( feature = "sanitize" ) ) ]
110
+ return Bag { len : 0 , deferreds :
111
+ [ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
112
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
113
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
114
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
115
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
116
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
117
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
118
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
119
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
120
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
121
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
122
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
123
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
124
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
125
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ,
126
+ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ]
127
+ } ;
128
+ #[ cfg( feature = "sanitize" ) ]
129
+ return Bag { len : 0 , deferreds : [ Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) , Deferred :: new ( no_op_func) ] } ;
130
+ }
131
+ }
132
+
101
133
impl Drop for Bag {
102
134
fn drop ( & mut self ) {
103
135
// Call all deferred functions.
104
- for deferred in self . deferreds . drain ( ..) {
136
+ for i in 0 ..self . len {
137
+ let no_op = Deferred :: new ( no_op_func) ;
138
+ let deferred = mem:: replace ( & mut self . deferreds [ i] , no_op) ;
105
139
deferred. call ( ) ;
106
140
}
107
141
}
108
142
}
109
143
144
+ // can't #[derive(Debug)] because Debug is not implemented for arrays 64 items long
145
+ impl fmt:: Debug for Bag {
146
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
147
+ f. debug_struct ( "Bag" ) . field ( "deferreds" , & & self . deferreds [ ..self . len ] ) . finish ( )
148
+ }
149
+ }
150
+
151
+ fn no_op_func ( ) { }
152
+
110
153
/// A pair of an epoch and a bag.
111
154
#[ derive( Default , Debug ) ]
112
155
struct SealedBag {
0 commit comments