logoalt Hacker News

Spinning around: Please don't – Common problems with spin locks

63 pointsby bdashtoday at 4:48 PM25 commentsview on HN

Comments

pizlonatortoday at 10:52 PM

TFA lists WebKit as a project that "does it wrong".

The author should read https://webkit.org/blog/6161/locking-in-webkit/ so that they understand what they are talking about.

WebKit does it right in the sense that:

- It as an optimal amount of spinning

- Threads wait (instead of spinning) if the lock is not available immediately-ish

And we know that the algorithms are optimal based on rigorous experiments.

jcranmertoday at 7:52 PM

The basic rule of writing your own cross-thread datastructures like mutexes or condition variables is... don't, unless you have very good reason not to. If you're in that rare circumstance where you know the library you're using isn't viable for some reason, then the next best rule is to use your OS's version of a futex as the atomic primitive, since it's going to solve most of the pitfalls for you automatically.

The only time I've manually written my own spin lock was when I had to coordinate between two different threads, one of which was running 16-bit code, so using any library was out of the question, and even relying on syscalls was sketchy because making sure the 16-bit code is in the right state to call a syscall itself is tricky. Although in this case, since I didn't need to care about things like fairness (only two threads are involved), the spinlock core ended up being simple:

    "thunk_spin:",
        "xchg cx, es:[{in_rv}]",
        "test cx, cx",
        "jnz thunk_has_data",
        "pause",
        "jmp thunk_spin",
    "thunk_has_data:",
show 4 replies
rdtsctoday at 10:24 PM

> Notice that in the Skylake Client microarchitecture the RDTSC instruction counts at the machine’s guaranteed P1 frequency independently of the current processor clock (see the INVARIANT TSC property), and therefore, when running in Intel® Turbo-Boost-enabled mode, the delay will remain constant, but the number of instructions that could have been executed will change.

rdtsc may execute out of order, so sometimes an lfence (previously cpuid) can be used and there is also rdtscp

See https://github.com/torvalds/linux/blob/master/arch/x86/inclu...

And just because rdtsc is constant doesn't mean the processor clock will be constant that could be fluctuating.

a-dubtoday at 9:56 PM

i always got the sense that spinlocks were about maximum portability and reliability in the face of unreliable event driven approaches. the dumb inefficient thing that makes the heads of the inexperienced explode, but actually just works and makes the world go 'round.

jeffbeetoday at 9:23 PM

"Unfair" paragraph is way too short. This is the main problem! The outlier starvation you get from contended spinlocks is extraordinary and, hypothetically, unbounded.

show 1 reply
CamperBob2today at 7:14 PM

Sheesh. Can something this complicated ever truly be said to work?

show 4 replies
gafferongamestoday at 7:09 PM

Great article! Thanks for posting this.