You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Statically allocated pool providing a std-like Box, with hability to asynchronously wait for a pool slot to become available.
5
+
Statically allocated pool providing a std-like Box, allowing to asynchronously await for a pool slot to become available.
6
6
7
-
This crate is tailored to be used with no-std async runtimes, like [Embassy](https://embassy.dev/), but can also be used in std environments (check examples).
7
+
It is tailored to be used with no-std async runtimes, like [Embassy](https://embassy.dev/), but can also be used in std environments (check examples).
8
+
9
+
The most common use-case is sharing large memory regions on constrained devices (e.g. microcontrollers), where multiple tasks may need to use the memory for buffering an I/O or performing calculations, and having separate static buffers would be too costly.
10
+
11
+
It is important to know that waiting forever for a memory slot to be available may dead-lock your code if done wrong. With that in mind, you should consider using a timeout when allocating asynchronously (e.g. [embassy_time::with_timeout](https://docs.rs/embassy-time/0.3.2/embassy_time/fn.with_timeout.html)).
8
12
9
13
## Dependencies
10
14
11
-
This crate uses the `AtomicWaker` functionality from `embassy-sync` crate, which in turn requires a critical section implementation. Check [critical-section](https://crates.io/crates/critical-section).
15
+
This crate requires a critical section implementation. Check [critical-section](https://crates.io/crates/critical-section).
16
+
17
+
## Example
18
+
19
+
```
20
+
use async_pool::{pool, Box};
21
+
22
+
struct Buffer([u8; 256]);
23
+
24
+
// A maximum of 2 Packet instances can be allocated at a time.
25
+
// A maximum of 3 futures can be waiting at a time.
26
+
pool!(BufferPool: [Buffer; 2], 3);
27
+
28
+
async fn run() {
29
+
// Allocate non-blocking (will return None if no data slot is available)
30
+
let box1 = Box::<BufferPool>::new(Buffer([0; 256]));
31
+
32
+
// Allocate asynchronously (will wait if no data slot is available)
33
+
// This can return None if all future slots are taken
34
+
let box2 = Box::<BufferPool>::new_async(Buffer([0; 256])).await;
Copy file name to clipboardExpand all lines: src/lib.rs
+41-2Lines changed: 41 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,46 @@
1
+
//! Statically allocated pool providing a std-like Box,
2
+
//! allowing to asynchronously await for a pool slot to become available.
3
+
//!
4
+
//! It is tailored to be used with no-std async runtimes, like [Embassy](https://embassy.dev/), but
5
+
//! can also be used in std environments (check examples).
6
+
//!
7
+
//! The most common use-case is sharing large memory regions on constrained
8
+
//! devices (e.g. microcontrollers), where multiple tasks may need to use the
9
+
//! memory for buffering an I/O or performing calculations, and having
10
+
//! separate static buffers would be too costly.
11
+
//!
12
+
//! It is important to know that waiting forever for a memory slot to be
13
+
//! available may dead-lock your code if done wrong. With that in mind,
14
+
//! you should consider using a timeout when allocating asynchronously (e.g. [embassy_time::with_timeout](https://docs.rs/embassy-time/0.3.2/embassy_time/fn.with_timeout.html)).
15
+
//!
16
+
//! #### Dependencies
17
+
//!
18
+
//! This crate requires a critical section implementation. Check [critical-section](https://crates.io/crates/critical-section).
19
+
//!
20
+
//! #### Example
21
+
//!
22
+
//! ```
23
+
//! use async_pool::{pool, Box};
24
+
//!
25
+
//!struct Buffer([u8; 256]);
26
+
//!
27
+
//!// A maximum of 2 Packet instances can be allocated at a time.
28
+
//!// A maximum of 3 futures can be waiting at a time.
29
+
//!pool!(BufferPool: [Buffer; 2], 3);
30
+
//!
31
+
//!async fn run() {
32
+
//! // Allocate non-blocking (will return None if no data slot is available)
33
+
//! let box1 = Box::<BufferPool>::new(Buffer([0; 256]));
34
+
//!
35
+
//! // Allocate asynchronously (will wait if no data slot is available)
36
+
//! // This can return None if all future slots are taken
37
+
//! let box2 = Box::<BufferPool>::new_async(Buffer([0; 256])).await;
38
+
//!}
39
+
//! ```
1
40
#![cfg_attr(not(test), no_std)]
2
41
3
42
mod atomic_bitset;
4
43
5
-
use portable_atomic::AtomicU32;
6
44
use core::cell::UnsafeCell;
7
45
use core::future::{poll_fn,Future};
8
46
use core::hash::{Hash,Hasher};
@@ -11,6 +49,7 @@ use core::ops::{Deref, DerefMut};
11
49
use core::task::Poll;
12
50
use core::{cmp, mem, ptr::NonNull};
13
51
use embassy_sync::waitqueue::AtomicWaker;
52
+
use portable_atomic::AtomicU32;
14
53
15
54
usecrate::atomic_bitset::AtomicBitset;
16
55
@@ -299,7 +338,7 @@ where
299
338
}
300
339
301
340
/// Create a item pool of a given type and size, as well as a waker pool of a given length.
302
-
///
341
+
///
303
342
/// The waker pool is used to wake up tasks waiting for an item to become available in the data pool.
304
343
/// Its length should be at least the number of tasks that can be waiting for an item at the same time.
0 commit comments