-
-
Notifications
You must be signed in to change notification settings - Fork 174
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
Implement more ergonomic CPU-local storage #1012
Conversation
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good, i left a few questions
Signed-off-by: Klimenty Tsoutsman <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left one major question about the atomicity of increment+load and load+decrement.
Also, can you add (or restore) typical things like crate-level docs, authorship/description fields in the toml, etc? thanks.
Everything else looks good.
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
Signed-off-by: Klimenty Tsoutsman <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left one comment as a suggestion to try out in #1015
use crate::cpu_local::{CpuLocal, CpuLocalField, PerCpuField}; | ||
use no_drop::NoDrop; | ||
#![no_std] | ||
#![feature(negative_impls, thread_local)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note for next PR: i think we can avoid the need for every user of cls_macro
to declare #![feature(thread_local)]
by using the #[allow_internal_unstable(...)]
attribute in the cls_macro
crate, either on the proc macro definition or as a crate-level attribute. I recall using that attribute in the thread_local_macro
crate, based on std
's thread_local!()
macro trickery.
This isn't a blocker to merging/approving this PR, but we should try to improve that rough edge, especially once we have dozens of CPU local vars everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(i just realized this is intended for regular macros, not procedural macros, but you should try it anyway)
* The new `cls` crate offers a `#[cpu_local]` attribute that can be applied to a static variable to declare it as Cpu-Local Storage (CLS), much like `#[thread_local]` and Thread-Local Storage (TLS). * The `cls_macro` crate provides a procedural macro that implements the `#[cpu_local]` attribute. Currently, this only supports basic primitive types: `u8`, `u16`, `u32`, `u64`. More coming later. * The API for accessing CPU-local primitive types is quite simple: only `load`, `fetch_add`, `fetch_sub`. Note that these functions are implemented as atomic with respect to ONLY the single current CPU, not atomic with respect to all memory accesses across all other CPUs. This is intentional as it is more efficient, and CPU-local variables are only accessible to a single CPU and not by another "foreign" CPU. * Currently this is only used for the preemption counter on each CPU, but it will be used for more variables in future PRs. * This simplifies the implementation of `preemption` management, as we can rely on the `#[cpu_local]` API's semantics to be atomic with respect to the current CPU. * This also avoids a minor latent bug that existed in the old preemption implementation which made it theoretically possible for a task migration to occur between accessing the CPU-local preemption count and modifying that count. This wasn't a problem since Theseus does not yet perform task migration, but the new design makes this interleaving impossible and is thus future-proof for later task migration support. * Re-separate `preemption` and `cpu_local` into two different crates, as they previously were. This is possible because the preemption count now uses the new `#[cpu_local]` attribute, which allows `preemption` and `cpu_local` to not have cyclic dependencies on each other. * This is responsible for most of the changes in this PR: changing `cpu_local_preemption` back to `cpu_local` or `preemption`. * Another current limitation is that we must use the `#[cpu_local]` attribute to _manually_ specify the offset of each CPU-local variable from the start of the `PerCpuData` storage type. This will be removed in a future PR. Signed-off-by: Klimenty Tsoutsman <[email protected]> Co-authored-by: Kevin Boos <[email protected]> 1f620ac
…us-os#1012) * The new `cls` crate offers a `#[cpu_local]` attribute that can be applied to a static variable to declare it as Cpu-Local Storage (CLS), much like `#[thread_local]` and Thread-Local Storage (TLS). * The `cls_macro` crate provides a procedural macro that implements the `#[cpu_local]` attribute. Currently, this only supports basic primitive types: `u8`, `u16`, `u32`, `u64`. More coming later. * The API for accessing CPU-local primitive types is quite simple: only `load`, `fetch_add`, `fetch_sub`. Note that these functions are implemented as atomic with respect to ONLY the single current CPU, not atomic with respect to all memory accesses across all other CPUs. This is intentional as it is more efficient, and CPU-local variables are only accessible to a single CPU and not by another "foreign" CPU. * Currently this is only used for the preemption counter on each CPU, but it will be used for more variables in future PRs. * This simplifies the implementation of `preemption` management, as we can rely on the `#[cpu_local]` API's semantics to be atomic with respect to the current CPU. * This also avoids a minor latent bug that existed in the old preemption implementation which made it theoretically possible for a task migration to occur between accessing the CPU-local preemption count and modifying that count. This wasn't a problem since Theseus does not yet perform task migration, but the new design makes this interleaving impossible and is thus future-proof for later task migration support. * Re-separate `preemption` and `cpu_local` into two different crates, as they previously were. This is possible because the preemption count now uses the new `#[cpu_local]` attribute, which allows `preemption` and `cpu_local` to not have cyclic dependencies on each other. * This is responsible for most of the changes in this PR: changing `cpu_local_preemption` back to `cpu_local` or `preemption`. * Another current limitation is that we must use the `#[cpu_local]` attribute to _manually_ specify the offset of each CPU-local variable from the start of the `PerCpuData` storage type. This will be removed in a future PR. Signed-off-by: Klimenty Tsoutsman <[email protected]> Co-authored-by: Kevin Boos <[email protected]> 1f620ac
MVP of a
cpu_local
attribute.Limitations that will be addressed in a future PR:
Draft PR because the macro needs to be implemented foraarch64
.