3 ms·
Because this book was written more than a year ago, it spends some time on Windows Slim Reader Writer Locks, SRWLocks which at that time of its writing were how
by tialaramex 2y ago
Because this book was written more than a year ago, it spends some time on Windows Slim Reader Writer Locks, SRWLocks which at that time of its writing were how Rust's Mutex and RwLock were implemented on Windows (by the author in fact IIRC).
Since then, two important things happened.
1. On Windows 8 and beyond Rust moved to WaitOnAddress with an API similar to the futex on several other systems.
2. We found out SRWLocks have a significant (arguably fatal, but depending on your use case it may seem irrelevant) difference between how they actually work and what Microsoft's API said about them. This bug is fixed... in Microsoft's own version control, not in released Windows versions.
Specifically SRWLocks may silently give you a Write Lock, even if you asked only for a Read Lock, in the case where the lock was just released at the moment you asked. If you were expecting other threads to also get a read lock, which would ordinarily be possible - too bad, you've secretly been given the exclusive write lock so read locks are unavailable until you release it.
The actual reason seems to be this: SRWLocks are small (a single pointer, with some low bits stolen to hide metadata) and the authors forgot that they actually know (because it's a different function call) whether you asked for a read or a write lock. Since they didn't have anywhere to store this single bit (read or write) they just assumed they don't know in this edge case where the lock happens to be available immediately, and since they "don't know" they always give you a write lock anyway. Oops.
[Edited to make minor clarifications]
- forrestthewoods 2y ago> Specifically SRWLocks may silently give you a Write Lock, even if you asked only for a Read Lock, in the case where the lock was just released at the moment you asked. Oh hey, I reported that bug and behavior! One of my proudest reports. Not too often you find a legit bug, or at least documentation oversight, in such a core API.
- tialaramex 2y agoYeah, I've also only very rarely seen real bugs in core system features (deadlock inside glibc's allocator a decade or more ago in my case IIRC) and I must say you got a much healthier reaction. It's definitely an actual bug not a doc bug. I've explained this a few times to people and it does seem like the natural inclination is to assume SRWLock must be supposed to do that, but I was glad to see internally Microsoft did fix this, because it's clearly the Wrong Thing™. I see two common defences for this bug. One is "Actually, it's supposed to be unfair, you don't understand why that's a good idea". Which assumes I'm expecting a fair lock and I'm unhappy not to get it. Giving a reader the reader lock when there's a writer waiting would be unfair - and probably a bad idea but I'm open to it if somebody presents benchmarks - but giving them the writer lock is just a bug. Another is "Actually, there is a writer waiting, and this way that writer gets the lock faster". As you wrote the example code you know that's false, there is no writer waiting, there are only readers and (in the buggy scenario) they're blocked forever for no reason.
- forrestthewoods 2y ago> I must say you got a much healthier reaction. I definitely spent a lot of time carefully crafting the message and iterating on a minimal repro. Writing on the internet requires a LOT of defensive effort. It’s very annoying but is what it is. I write blog posts and my secret goal is “high views, low comments”. Because most comments are “well ackchyually“. For the Reddit thread it helped that I tagged u/STL and he responded quickly in agreement. That was very intentional on my part! I’m still a little sad I didn’t get a Raymond Chen comment though!
- tialaramex 2y agoDoes Raymond comment on Reddit? That would feel like a personal achievement indeed. One of the smallest pieces of work I'm proud of is a tool that automates the labor of Raymond's "The poor man's way of identifying memory leaks". The part where you need to be familiar with how your data types look in memory isn't automated, that's on you, but my tool (leakdice because it replaces the hexadecimal dice I previously used for this in real life) picks a random page of heap in a chosen (Linux) process and shows you what's in it, the rest is up to you as Raymond explains.
- forrestthewoods 2y ago> Does Raymond comment on Reddit? Not to my knowledge. But I kinda called him out for having a potentially false blog post so I was hoping he'd do a follow-up!
- saghm 2y agoDefinitely sounds like a legit bug to me! I'd only call this a "documentation oversight" in the sense that they could have the docs-equivalent of the fast-talking disclaimers at the end of commercials saying something like "notactuallyareadwritelockmayormaynotallowconcurrentreadsdonotusewhenpregnantorbreastfeeedinguseatyourownrisk"
- OptionOfT 2y agoI've looked in the Rust issue tracker for SRWLocks but could only find older posts. Can you share some links?
- tialaramex 2y agoSRWLocks are a Windows feature, not a Rust feature, so you're looking in the wrong place. Here's STL's (nominative determinism at work) GitHub issue for Microsoft's C++ stdlib implementation about this https://github.com/microsoft/STL/issues/4448 https://github.com/microsoft/STL/issues/4448 Here's the C++ Reddit thread where the bug was shown: https://www.reddit.com/r/cpp/comments/1b55686/maybe_possible_bug_in_stdshared_mutex_on_windows/ https://www.reddit.com/r/cpp/comments/1b55686/maybe_possible... Here's the Rust change which was merged for 1.78: https://github.com/rust-lang/rust/pull/121956/ https://github.com/rust-lang/rust/pull/121956/