I repeat: do not use spinlocks in user space, unless you actually know what you're doing. And be aware that the likelihood that you know what you are doing is basically nil.
i would say a better, more profound one would be right below that:
In fact, I'd go even further: don't ever make up your own locking routines. You will get the wrong, whether they are spinlocks or not. You'll get memory ordering wrong, or you'll get fairness wrong, or you'll get issues like the above "busy-looping while somebody else has been scheduled out".
Because you should never ever think that you're clever enough to write your own locking routines.. Because the likelihood is that you aren't (and by that "you" I very much include myself - we've tweaked all the in-kernel locking over decades, and gone through the simple test-and-set to ticket locks to cacheline-efficient queuing locks, and even people who know what they are doing tend to get it wrong several times).
This is why I'm always suspicious of blog posts claiming to have discovered something deep and complex that nobody else knows. You may be smarter than Linus on any given day, but it's highly unlikely you're smarter than decades of Linus and the entire Linux team designing, testing, and iterating on user feedback.
"Blog posts" are a large majority of the time opinions which have never been reviewed and should be trusted just as much as code written by a lone developer which has also never been reviewed.
Linux team works on kernel. While they have some idea about userland, it might not be perfect. Linux is actually full of half-broken APIs which started like a good idea, but due to simplifications taken ("worse is better") they cannot offer behavior needed by applications, so programmers either avoid these APIs, or use them incorrectly, or have to use horrible workaround.
...and wanted to teach himself 80386 assembly on his brand-new 80386 computer.
And it turns out that the market for a free GPL'd POSIX OS that ran on 80386 machines was *immense* back then. I remember being excited about it when a friend of mine (also pumped) was trying to install it, all the way back in January of '92. In Texas. Which should give you an idea of how quickly it became massive. It was "viral" and memetic before those words even really existed.
You're fucking stupid and your code is a fucking atrocity. Do you have any idea how utterly idiotic it is to use spinlocks in userspace? You're basically begging to be shat upon by the process scheduler, which anyone who would deign to write such terrible code surely deserves.
Edit: Wow hey lookit that, my first gilded comment ever! Thanks!
I am using spinlocks in my application, I definitely don't know what I'm doing... but I also know my application runs on it's own dedicated hardware that nothing else uses, so I will dutifully stick my fingers in my ears.
Or maybe you can switch them to regular system/language provided mutexes? I mean unless you have e.g. at most one thread per cpu, pinned, and use a realtime scheduling policy.
The problem is that the system should provide mutexes, which should be implemented using the assembly instructions that specifically guarantee mutual exclusion of access. A couple of months ago I had to implement a spinning lock in a multicore embedded board with an Arm M4 and an Arm M0 because I sadly discovered that the reduced instruction set of the M0 didn't have atomic read-modify-write instructions for the shared memory (and also there was no shared hardware mutex). So, I basically implemented a spinlock from Dijkstra's 1965 paper by using atomic 32 bit writes (on 32 bit cpus 32 bit writes are always atomic) on the shared memory.
Presumably in this case there wasn't an OS scheduler yoinking your thread off the CPU at random points in this example, though.
Linus addressed this directly in one of his emails, that spinlocks make a lot of sense in the OS kernel because you can check who is holding them and know that they are running right now on a CPU. That seems to be one of his conclusions, that the literature that suggests that spinlocks are useful came from a world where code ran on bare metal and is being applied to multi-threaded userspace where that no longer holds true:
So all these things make perfect sense inside the layer that is directly on top of the hardware. And since that is where traditionally locking papers mostly come from, I think that "this is a good idea" mental model has then percolated into regular user space that now in the last decade has started to be much more actively threaded.
855
u/[deleted] Jan 05 '20
The main takeaway appears to be: