@@ -120,7 +120,7 @@ where
120120 /// Attempt to take a `Producer` from the `BBBuffer` to gain access to the
121121 /// buffer. If a producer has already been taken, an error will be returned.
122122 ///
123- /// NOTE: When splitting , the underlying buffer will be explicitly initialized
123+ /// NOTE: When taking the producer , the underlying buffer will be explicitly initialized
124124 /// to zero. This may take a measurable amount of time, depending on the size
125125 /// of the buffer. This is necessary to prevent undefined behavior. If the buffer
126126 /// is placed at `static` scope within the `.bss` region, the explicit initialization
@@ -135,12 +135,11 @@ where
135135 }
136136
137137 unsafe {
138- // TODO: do we need to zero buffer here, like try_split?
139- // // Explicitly zero the data to avoid undefined behavior.
140- // // This is required, because we hand out references to the buffers,
141- // // which mean that creating them as references is technically UB for now
142- // let mu_ptr = self.0.buf.get();
143- // (*mu_ptr).as_mut_ptr().write_bytes(0u8, 1);
138+ // Explicitly zero the data to avoid undefined behavior.
139+ // This is required, because we hand out references to the buffers,
140+ // which mean that creating them as references is technically UB for now
141+ let mu_ptr = self . 0 . buf . get ( ) ;
142+ ( * mu_ptr) . as_mut_ptr ( ) . write_bytes ( 0u8 , 1 ) ;
144143
145144 let nn1 = NonNull :: new_unchecked ( self as * const _ as * mut _ ) ;
146145
@@ -154,12 +153,6 @@ where
154153 /// Attempt to take a `Consumer` from the `BBBuffer` to gain access to the
155154 /// buffer. If a consumer has already been taken, an error will be returned.
156155 ///
157- /// NOTE: When splitting, the underlying buffer will be explicitly initialized
158- /// to zero. This may take a measurable amount of time, depending on the size
159- /// of the buffer. This is necessary to prevent undefined behavior. If the buffer
160- /// is placed at `static` scope within the `.bss` region, the explicit initialization
161- /// will be elided (as it is already performed as part of memory initialization)
162- ///
163156 /// NOTE: If the `thumbv6` feature is selected, this function takes a short critical section
164157 /// while splitting.
165158 pub fn try_take_consumer ( & ' a self ) -> Result < Consumer < ' a , N > > {
@@ -169,13 +162,6 @@ where
169162 }
170163
171164 unsafe {
172- // TODO: do we need to zero buffer here, like try_split?
173- // // Explicitly zero the data to avoid undefined behavior.
174- // // This is required, because we hand out references to the buffers,
175- // // which mean that creating them as references is technically UB for now
176- // let mu_ptr = self.0.buf.get();
177- // (*mu_ptr).as_mut_ptr().write_bytes(0u8, 1);
178-
179165 let nn1 = NonNull :: new_unchecked ( self as * const _ as * mut _ ) ;
180166
181167 Ok ( Consumer {
@@ -281,8 +267,9 @@ where
281267
282268 /// Attempt to release the `Producer`.
283269 ///
284- /// This re-initializes the buffer so it may be split in a different mode at a later
285- /// time. There must be no read or write grants active, or an error will be returned.
270+ /// This re-initializes the buffer if the consumer was already released so it may be
271+ /// split in a different mode at a later time. There must be no read or write grants
272+ /// active, or an error will be returned.
286273 ///
287274 /// The `Producer` ust be from THIS `BBBuffer`, or an error will be returned.
288275 ///
@@ -338,11 +325,13 @@ where
338325 // Drop the producer
339326 drop ( prod) ;
340327
341- // Re-initialize the buffer (not totally needed, but nice to do)
342- self . 0 . write . store ( 0 , Release ) ;
343- self . 0 . read . store ( 0 , Release ) ;
344- self . 0 . reserve . store ( 0 , Release ) ;
345- self . 0 . last . store ( 0 , Release ) ;
328+ // Re-initialize the buffer if consumer is already released (not totally needed, but nice to do)
329+ if self . 0 . split_prod_cons . load ( Release ) & BIT_CONSUMER == 0 {
330+ self . 0 . write . store ( 0 , Release ) ;
331+ self . 0 . read . store ( 0 , Release ) ;
332+ self . 0 . reserve . store ( 0 , Release ) ;
333+ self . 0 . last . store ( 0 , Release ) ;
334+ }
346335
347336 // Mark the buffer as ready to retake producer
348337 atomic:: fetch_and ( & self . 0 . split_prod_cons , !BIT_PRODUCER , Release ) ;
@@ -352,8 +341,9 @@ where
352341
353342 /// Attempt to release the `Consumer`.
354343 ///
355- /// This re-initializes the buffer so it may be split in a different mode at a later
356- /// time. There must be no read or write grants active, or an error will be returned.
344+ /// This re-initializes the buffer if the producer was already released so it may be
345+ /// split in a different mode at a later time. There must be no read or write grants
346+ /// active, or an error will be returned.
357347 ///
358348 /// The `Consumer` must be from THIS `BBBuffer`, or an error will be returned.
359349 ///
@@ -409,11 +399,13 @@ where
409399 // Drop the consumer
410400 drop ( cons) ;
411401
412- // Re-initialize the buffer (not totally needed, but nice to do)
413- self . 0 . write . store ( 0 , Release ) ;
414- self . 0 . read . store ( 0 , Release ) ;
415- self . 0 . reserve . store ( 0 , Release ) ;
416- self . 0 . last . store ( 0 , Release ) ;
402+ // Re-initialize the buffer if producer is already released (not totally needed, but nice to do)
403+ if self . 0 . split_prod_cons . load ( Release ) & BIT_PRODUCER == 0 {
404+ self . 0 . write . store ( 0 , Release ) ;
405+ self . 0 . read . store ( 0 , Release ) ;
406+ self . 0 . reserve . store ( 0 , Release ) ;
407+ self . 0 . last . store ( 0 , Release ) ;
408+ }
417409
418410 // Mark the buffer as ready to retake consumer
419411 atomic:: fetch_and ( & self . 0 . split_prod_cons , !BIT_CONSUMER , Release ) ;
0 commit comments