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

Allow creating initialized StaticCell. #1

Closed
wants to merge 2 commits into from

Conversation

reitermarkus
Copy link
Contributor

@reitermarkus reitermarkus commented Sep 14, 2022

Add StaticCell::new_with_value to create an initialized StaticCell which can be taken and restored.

Example

static DMA_BUF: StaticCell<[u8; 1024]> = StaticCell::new_with_value([0; 1024]);

fn start_dma_transfer(buf: &'static mut [u8; 1024]) {
  // ...
}

fn stop_dma_transfer() -> &'static mut [u8; 1024] {
  // ...
}

fn main() {
  start_dma_transfer(DMA_BUF.take().unwrap());
}

fn interrupt() {
  let buf = stop_dma_transfer();
  DMA_BUF.restore(buf);
}

Also, a question regarding init_with, which claims

The advantage over [StaticCell::init] is that this method allows the closure to construct
the T value in-place directly inside the StaticCell, saving stack space.

Where/how is this guaranteed? Does it depend on the platform or compiler optimizations?

At least with the following example, it clearly doesn't work as described as it results in a stack overflow:

std::thread::Builder::new()
  .name("init_with".to_string())
  .stack_size(512)
  .spawn(|| {
    static BUF: StaticCell<[u8; 4096]> = StaticCell::new();
    let buf = BUF.init_with(|| [1; 4096]);

    let mut count = 0;
    for b in buf {
      count += *b as usize;
    }

    assert_eq!(count, 4096);
  })
  .unwrap()
  .join();

@reitermarkus
Copy link
Contributor Author

@Dirbaio, ping.

@IsaacDynamo
Copy link
Contributor

Nice PR!
I really like the separation of initialization and ownership, via the tri-state.
And it is cool that restore() can be expressed in safe rust.

Can this be considered for inclusion into the StaticCell crate?

@reitermarkus
Copy link
Contributor Author

@Dirbaio, could you have a look at the open PRs here? Thanks.

@Dirbaio
Copy link
Member

Dirbaio commented Jan 2, 2023

Thanks for the PR!

Unfortunately, I don't think this is something that should be in StaticCell. StaticCell has one goal only: to allow initializing static things once at boot time. This PR is targeted at a completely different use case, something like a "Mutex<Option<T>> but with atomics" that allows you to take out and put back the value at runtime.

Where/how is this guaranteed? Does it depend on the platform or compiler optimizations?

It's not guaranteed, it depends on compiler optimizations. It is much more likely to succeed due to creating the value after the flag check. The compiler can't reorder them if creating the value has side effects.

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.

None yet

3 participants