Skip to content

embassy-sync: add ResourcePool#5742

Draft
martin2250 wants to merge 2 commits intoembassy-rs:mainfrom
martin2250:main
Draft

embassy-sync: add ResourcePool#5742
martin2250 wants to merge 2 commits intoembassy-rs:mainfrom
martin2250:main

Conversation

@martin2250
Copy link
Copy Markdown

@martin2250 martin2250 commented Mar 27, 2026

I think this would be a good addition to embassy-sync. I see two main uses:

  • Managing similar peripherals (although in most cases it probably does matter which specific one you end up with)
  • Managing larger buffers, similar to zerocopy_channel

I've mostly created it for the second case, because I needed to get around the limitations of zerocopy_channel.

The idea is that you can dynamically acquire a smart pointer to a shared resource, similar to MutexGuard, which you can then pass around between tasks.

Right now, the documentation is still incomplete because I want to ask for feedback first. Is this something you'd consider merging into embassy?

For a code example, see examples/stm32g4/src/bin/resource_pool.rs

Some TODOs:

  • double-check the soundness of the implementation and lifetimes
  • add proper documentation
  • add map() function like Mutex?
  • add dynamic versions of everything like DynamicChannel
  • make new() const?
  • reduce the size of the state by replacing the available Vec with an array of u32 and bit-masking (the reason I have not implemented that are that generic_const_exprs for calculating the number of u32s (ie. ceil(N/32)) are still unstable.

Copy link
Copy Markdown
Contributor

@diondokter diondokter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation looks fine to me. Got a couple of questions and notes though.

Whether this PR is actually accepted, well I'm not the endboss :P

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to add tests & more docs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, absolutely!

Comment on lines +115 to +118
pub fn map<U: ?Sized>(
orig: Self,
fun: impl FnOnce(&mut T) -> &mut U,
) -> MappedResourceGuard<'guard, 'buffer, M, T, U, N> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a weird API to me... When would you use this?
Especially the &mut U is weird to me. Where would the U be stored? In the closure? But then you get lifetime issues.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

embassy is already doing this with MutexGuard. It allows you to "narrow-down" a reference, eg. from a slice to only a sub-slice.

The main use I see here would be taking a buffer (eg. &mut [u8; 1024]), reading some data into it and then passing on a slice (&buffer[..n_bytes_read]) to the next part of your software. This works because the rust compiler will use fat pointers for pointers to slices (eg *mut/const [u8])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I guess. It's fine to have and the impl is fine. Just doesn't seem that useful to me

@martin2250 martin2250 marked this pull request as draft April 1, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants