Skip to content

Commit da5757a

Browse files
committed
add examples and cfail tests
1 parent 054f291 commit da5757a

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

src/lib.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,148 @@
11
//! `static` friendly data structures that don't require dynamic memory
22
//! allocation
3+
//!
4+
//! # Examples
5+
//!
6+
//! ## `Vec`
7+
//!
8+
//! ```
9+
//! use heapless::Vec;
10+
//!
11+
//! let mut xs: Vec<u8, [u8; 4]> = Vec::new();
12+
//!
13+
//! assert!(xs.push(0).is_ok());
14+
//! assert!(xs.push(1).is_ok());
15+
//! assert!(xs.push(2).is_ok());
16+
//! assert!(xs.push(3).is_ok());
17+
//! assert!(xs.push(4).is_err()); // full
18+
//!
19+
//! assert_eq!(xs.pop(), Some(3));
20+
//! ```
21+
//!
22+
//! ## `RingBuffer`
23+
//!
24+
//! ```
25+
//! use heapless::RingBuffer;
26+
//!
27+
//! let mut rb: RingBuffer<u8, [u8; 4]> = RingBuffer::new();
28+
//!
29+
//! assert!(rb.enqueue(0).is_ok());
30+
//! assert!(rb.enqueue(1).is_ok());
31+
//! assert!(rb.enqueue(2).is_ok());
32+
//! assert!(rb.enqueue(3).is_err()); // full
33+
//!
34+
//! assert_eq!(rb.dequeue(), Some(0));
35+
//! ```
36+
//!
37+
//! ### Single producer single consumer mode
38+
//!
39+
//! For use in *single core* systems like microcontrollers
40+
//!
41+
//! ```
42+
//! use heapless::RingBuffer;
43+
//!
44+
//! static mut RB: RingBuffer<Event, [Event; 4]> = RingBuffer::new();
45+
//!
46+
//! enum Event { A, B }
47+
//!
48+
//! fn main() {
49+
//! // NOTE(unsafe) beware of aliasing the `consumer` end point
50+
//! let mut consumer = unsafe { RB.split().1 };
51+
//!
52+
//! loop {
53+
//! // `dequeue` is a lockless operation
54+
//! match consumer.dequeue() {
55+
//! Some(Event::A) => { /* .. */ },
56+
//! Some(Event::B) => { /* .. */ },
57+
//! None => { /* sleep */},
58+
//! }
59+
//! # break
60+
//! }
61+
//! }
62+
//!
63+
//! // this is a different execution context that can preempt `main`
64+
//! fn interrupt_handler() {
65+
//! // NOTE(unsafe) beware of aliasing the `producer` end point
66+
//! let mut producer = unsafe { RB.split().0 };
67+
//! # let condition = true;
68+
//!
69+
//! // ..
70+
//!
71+
//! if condition {
72+
//! producer.enqueue(Event::A).unwrap();
73+
//! } else {
74+
//! producer.enqueue(Event::B).unwrap();
75+
//! }
76+
//!
77+
//! // ..
78+
//! }
79+
//! ```
80+
//!
81+
//! # `Send`-ness
82+
//!
83+
//! Collections of `Send`-able things are `Send`
84+
//!
85+
//! ```
86+
//! use heapless::{RingBuffer, Vec};
87+
//! use heapless::ring_buffer::{Consumer, Producer};
88+
//!
89+
//! struct IsSend;
90+
//!
91+
//! unsafe impl Send for IsSend {}
92+
//!
93+
//! fn is_send<T>() where T: Send {}
94+
//!
95+
//! is_send::<Consumer<IsSend, [IsSend; 4]>>();
96+
//! is_send::<Producer<IsSend, [IsSend; 4]>>();
97+
//! is_send::<RingBuffer<IsSend, [IsSend; 4]>>();
98+
//! is_send::<Vec<IsSend, [IsSend; 4]>>();
99+
//! ```
100+
//!
101+
//! Collections of not `Send`-able things are *not* `Send`
102+
//!
103+
//! ``` compile_fail
104+
//! use std::marker::PhantomData;
105+
//! use heapless::ring_buffer::Consumer;
106+
//!
107+
//! type NotSend = PhantomData<*const ()>;
108+
//!
109+
//! fn is_send<T>() where T: Send {}
110+
//!
111+
//! is_send::<Consumer<NotSend, [NotSend; 4]>>();
112+
//! ```
113+
//!
114+
//! ``` compile_fail
115+
//! use std::marker::PhantomData;
116+
//! use heapless::ring_buffer::Producer;
117+
//!
118+
//! type NotSend = PhantomData<*const ()>;
119+
//!
120+
//! fn is_send<T>() where T: Send {}
121+
//!
122+
//! is_send::<Producer<NotSend, [NotSend; 4]>>();
123+
//! ```
124+
//!
125+
//! ``` compile_fail
126+
//! use std::marker::PhantomData;
127+
//! use heapless::RingBuffer;
128+
//!
129+
//! type NotSend = PhantomData<*const ()>;
130+
//!
131+
//! fn is_send<T>() where T: Send {}
132+
//!
133+
//! is_send::<RingBuffer<NotSend, [NotSend; 4]>>();
134+
//! ```
135+
//!
136+
//! ``` compile_fail
137+
//! use std::marker::PhantomData;
138+
//! use heapless::Vec;
139+
//!
140+
//! type NotSend = PhantomData<*const ()>;
141+
//!
142+
//! fn is_send<T>() where T: Send {}
143+
//!
144+
//! is_send::<Vec<NotSend, [NotSend; 4]>>();
145+
//! ```
3146
4147
#![deny(missing_docs)]
5148
#![feature(const_fn)]

src/ring_buffer/spsc.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ where
5656
}
5757
}
5858

59+
unsafe impl<T, A> Send for Consumer<T, A>
60+
where
61+
A: Unsize<[T]>,
62+
T: Send,
63+
{
64+
}
5965

6066
/// A ring buffer "producer"; it can enqueue items into the ring buffer
6167
// NOTE the producer semantically owns the `tail` pointer of the ring buffer
@@ -94,6 +100,13 @@ where
94100
}
95101
}
96102

103+
unsafe impl<T, A> Send for Producer<T, A>
104+
where
105+
A: Unsize<[T]>,
106+
T: Send,
107+
{
108+
}
109+
97110
#[cfg(test)]
98111
mod tests {
99112
use RingBuffer;

0 commit comments

Comments
 (0)