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

Why do volatile operations not suffice? #2

Closed
burdges opened this issue Jan 15, 2017 · 1 comment
Closed

Why do volatile operations not suffice? #2

burdges opened this issue Jan 15, 2017 · 1 comment

Comments

@burdges
Copy link
Contributor

burdges commented Jan 15, 2017

std::ptr::write_volatile says "Volatile operations are intended to act on I/O memory, and are guaranteed to not be elided or reordered by the compiler across other volatile operations." I just used those when I attempted to do do something similar, although lacking your nice stack trick.

@cesarb
Copy link
Owner

cesarb commented Jan 15, 2017

I tried, but the code generated seems to be quite bad (see rust-lang/rust#39001 which I found while writing the stack clearing code). Allowing the compiler to do its normal memset, followed by an empty inline assembly with the right inputs/outputs (or a call to a foreign function) to make it believe the results of the memset (and the memory address itself) are in use, seems to work much better. Once I had the "hide" trick working for the stack clearing, it was a no-brainer to also use it for ClearOnDrop and to prevent inlining.

Also, my main objective with this crate was to show an alternative solution. Others were already using write_volatile, and I had already done inline assembly tricks to fool the optimizer in a different context (the OPTIMIZER_HIDE_VAR Linux kernel macro, mentioned on the hide.rs comment, was my idea), so I wanted to go that way and see what would happen. The names came from an old Rust RFC of mine (rust-lang/rfcs#1496).

I believe that the main problem with write_volatile (and read_volatile) is that it's designed for I/O. When writing an array of sixteen u8, it will do sixteen byte-sized writes, instead of a few larger writes or a memset. This makes sense for I/O memory (where access size and order is important, and the tricks memset might do can cause problems), but not so much for normal cacheable memory.

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