|
| 1 | +//! This example demonstrates the use of the `async_pool` crate with the `embassy` executor. |
| 2 | +//! The example is meant to be run on std (println, process::exit), but can easily be adapted to run on a no_std environment. |
| 3 | +
|
| 4 | +use embassy_executor::Spawner; |
| 5 | +use embassy_futures::join::join5; |
| 6 | +use embassy_time::Timer; |
| 7 | + |
| 8 | +use core::mem; |
| 9 | + |
| 10 | +use async_pool::{pool, Box}; |
| 11 | + |
| 12 | +#[derive(Debug)] |
| 13 | +#[allow(dead_code)] |
| 14 | +struct Packet(u32); |
| 15 | + |
| 16 | +// A maximum of 2 Packet instances can be allocated at a time. |
| 17 | +// A maximum of 1 future can be waiting at a time. |
| 18 | +pool!(PacketPool: [Packet; 2], 1); |
| 19 | + |
| 20 | +#[embassy_executor::task] |
| 21 | +async fn run() { |
| 22 | + // Allocate non-blocking |
| 23 | + let fut1 = async { |
| 24 | + println!("1 - allocating async..."); |
| 25 | + let box1 = Box::<PacketPool>::new(Packet(1)); |
| 26 | + println!("1 - allocated: {:?}", box1); |
| 27 | + Timer::after_millis(100).await; |
| 28 | + println!("1 - dropping allocation..."); |
| 29 | + mem::drop(box1); |
| 30 | + }; |
| 31 | + |
| 32 | + // Allocate asynchronously |
| 33 | + let fut2 = async { |
| 34 | + Timer::after_millis(5).await; |
| 35 | + println!("2 - allocating sync..."); |
| 36 | + let box2 = Box::<PacketPool>::new_async(Packet(2)).await; |
| 37 | + println!("2 - allocated: {:?}", box2); |
| 38 | + Timer::after_millis(150).await; |
| 39 | + println!("2 - dropping allocation..."); |
| 40 | + mem::drop(box2); |
| 41 | + }; |
| 42 | + |
| 43 | + // Allocate non-blocking (fails, data pool is full) |
| 44 | + let fut3 = async { |
| 45 | + Timer::after_millis(10).await; |
| 46 | + println!("3 - allocating sync..."); |
| 47 | + let box3 = Box::<PacketPool>::new(Packet(3)); |
| 48 | + println!( |
| 49 | + "3 - allocation fails because the data pool is full: {:?}", |
| 50 | + box3 |
| 51 | + ); |
| 52 | + }; |
| 53 | + |
| 54 | + // Allocate asynchronously (waits for a deallocation) |
| 55 | + let fut4 = async { |
| 56 | + Timer::after_millis(15).await; |
| 57 | + println!("4 - allocating async..."); |
| 58 | + let box4 = Box::<PacketPool>::new_async(Packet(4)).await; |
| 59 | + println!("4 - allocated: {:?}", box4); |
| 60 | + Timer::after_millis(100).await; |
| 61 | + println!("4 - dropping allocation..."); |
| 62 | + }; |
| 63 | + |
| 64 | + // Allocate asynchronously (fails, waker pool is full) |
| 65 | + let fut5 = async { |
| 66 | + Timer::after_millis(20).await; |
| 67 | + println!("5 - allocating async..."); |
| 68 | + let box5 = Box::<PacketPool>::new_async(Packet(5)).await; |
| 69 | + println!( |
| 70 | + "5 - allocation fails because the waker pool is full: {:?}", |
| 71 | + box5 |
| 72 | + ); |
| 73 | + }; |
| 74 | + |
| 75 | + join5(fut1, fut2, fut3, fut4, fut5).await; |
| 76 | + std::process::exit(0); // Exit the executor |
| 77 | +} |
| 78 | + |
| 79 | +#[embassy_executor::main] |
| 80 | +async fn main(spawner: Spawner) { |
| 81 | + spawner.spawn(run()).unwrap(); |
| 82 | +} |
0 commit comments