Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to resize StackFutures #6

Open
eholk opened this issue Aug 8, 2022 · 5 comments
Open

Add a way to resize StackFutures #6

eholk opened this issue Aug 8, 2022 · 5 comments

Comments

@eholk
Copy link
Contributor

eholk commented Aug 8, 2022

It'd be helpful to have a way to shrink (or less commonly, grow) a StackFuture. For example, sometimes you have an object that implements a trait and needs to forward calls to another object that implements the same trait. Right now that's impossible with StackFuture without boxing the child future because otherwise you'd have to have a future contain a future that's the same size as itself. That said, there will usually be some extra space so we might be able to dynamically shrink a StackFuture.

The signature would probably be something like:

fn resize<const NEW_SIZE: usize>(self) -> Result<StackFuture<T, NEW_SIZE>, Self>;

Then using this would look something like:

impl Foo for MyObject {
    fn bar(&self) -> StackFuture<(), 1000> {
        match self.sub_object.bar().resize::<{500}>() {
            Ok(f) => f.await,
            Err(original) => Box::pin(original).await,
        }
    }
}

The idea here is we'd try to fit the future into a smaller container, but if it doesn't fit then the resize returns the original future and we can either decide to pay the allocation cost (as we did in this example) or give up.

@JmPotato
Copy link
Contributor

@eholk Hello, after digging into the code. I found that the main challenge to implementing resize is that we don't store any type info of the inner future in a StackFuture, so there is no way to get the type info to do Self::poll_inner and Self::drop_inner when we are trying to build a new StackFuture with the given new size. So I'm wondering if there is another way that I miss. Thanks for any advice or help!

@eholk
Copy link
Contributor Author

eholk commented Aug 15, 2022

Oh, that's a good point. I thought we'd have enough type information still to do it, but we need to save some more. I think the best way to do this then would be to add another function to StackFuture alongside poll_fn and drop_fn

@JmPotato
Copy link
Contributor

Oh, that's a good point. I thought we'd have enough type information still to do it, but we need to save some more. I think the best way to do this then would be to add another function to StackFuture alongside poll_fn and drop_fn

I don't quite get what the function alongside poll_fn and drop_fn is for. Do you mean implement resize as an inner function inside the StackFuture::from so we can get the type info of F? Since the STACK_SIZE is a const number we need to be known at compilation time, this is another problem we can not bypass.

@eholk
Copy link
Contributor Author

eholk commented Aug 17, 2022

Yeah, I think you'd need a resize_fn implemented as an inner function inside StackFuture::from. I imagine it'd have a signature like fn resize_into(target_size: usize, target: *mut u8), and inside there you can do a dynamic check to see if sizeof::<F>() < target_size. Then the top level StackFuture::resize would pass NEW_SIZE into resize_into.

@JmPotato
Copy link
Contributor

Yeah, I think you'd need a resize_fn implemented as an inner function inside StackFuture::from. I imagine it'd have a signature like fn resize_into(target_size: usize, target: *mut u8), and inside there you can do a dynamic check to see if sizeof::<F>() < target_size. Then the top level StackFuture::resize would pass NEW_SIZE into resize_into.

Thanks a lot! I know how to do this.

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

No branches or pull requests

2 participants