-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Simplify core::hint::spin_loop
#115547
Simplify core::hint::spin_loop
#115547
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -175,34 +175,27 @@ pub fn spin_loop() { | |
unsafe { crate::arch::x86_64::_mm_pause() }; | ||
} | ||
|
||
// RISC-V platform spin loop hint implementation | ||
#[cfg(target_arch = "riscv32")] | ||
{ | ||
// RISC-V RV32 and RV64 share the same PAUSE instruction, but they are located in different | ||
// modules in `core::arch`. | ||
// In this case, here we call `pause` function in each core arch module. | ||
#[cfg(target_arch = "riscv32")] | ||
{ | ||
crate::arch::riscv32::pause(); | ||
} | ||
#[cfg(target_arch = "riscv64")] | ||
{ | ||
crate::arch::riscv64::pause(); | ||
} | ||
crate::arch::riscv32::pause(); | ||
} | ||
|
||
#[cfg(any(target_arch = "aarch64", all(target_arch = "arm", target_feature = "v6")))] | ||
#[cfg(target_arch = "riscv64")] | ||
{ | ||
#[cfg(target_arch = "aarch64")] | ||
{ | ||
// SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets. | ||
unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) }; | ||
} | ||
#[cfg(target_arch = "arm")] | ||
{ | ||
// SAFETY: the `cfg` attr ensures that we only execute this on arm targets | ||
// with support for the v6 feature. | ||
unsafe { crate::arch::arm::__yield() }; | ||
} | ||
crate::arch::riscv64::pause(); | ||
} | ||
|
||
#[cfg(target_arch = "aarch64")] | ||
{ | ||
// SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets. | ||
unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) }; | ||
} | ||
|
||
#[cfg(all(target_arch = "arm", target_feature = "v6"))] | ||
{ | ||
// SAFETY: the `cfg` attr ensures that we only execute this on arm targets | ||
// with support for the v6 feature. | ||
unsafe { crate::arch::arm::__yield() }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This answer on SO seems to suggest that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The SO answer is mistaken. At least, somewhat mistaken. ISB, the "Instruction Synchronization Barrier," flushes the instruction pipeline on the calling processor. It isn't explicitly for use in something as general-purpose as a spin-loop:
When used with the SY option it can cause a "full system barrier operation," which could only be more expensive than plain ISB. I worry that The instruction that best fits the intent of a spin-loop hint is YIELD:
Expanding the use of |
||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a side-note, I've noticed that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was told that we actually do support |
||
|
||
|
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'm not sure those (or any of the above) comments make sense. As far as I can tell, all the functions in
core::arch::...
are cfg-ed anyway, so we would not be able to call them on a wrong arch. Should I delete them?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.
Functions in
core::arch::...
can be called just fine if the relevantcfg(target_feature = "...")
is not true at compile time. In that case you need to do runtime detection to check if it is supported before calling however.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'm not sure how this could be true.
__yield
is defined inarm_shared
.arm_shared
is marked as#[cfg(any(target_arch = "arm", target_arch = "aarch64", doc))]
.__yield
itself is marked as#[cfg(any(target_feature = "v6", target_arch = "aarch64", doc))]
.So this results in
__yield
being available ifcfg(all(any(target_arch = "arm", target_arch = "aarch64", doc), any(target_feature = "v6", target_arch = "aarch64", doc)))
.doc
andtarget_arch = "aarch64"
are not true in this context, so we are left withcfg(all(any(target_arch = "arm"), any(target_feature = "v6")))
, which can be simplified tocfg(all(target_arch = "arm", target_feature = "v6"))
.Unless I'm missing something, this is exactly the same as the
cfg
on this block?...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.
Looks like you are right in this case. For x86 intrinsics this is definitively not the case though. Those are never
cfg
ed on target features.