41

Is spinlock and polling the same thing?

Wikipedia:

a spinlock is a lock which causes a thread trying to acquire it to simply wait in a loop ("spin") while repeatedly checking if the lock is available

This sounds awfully lot like:

while(!ready);

I was taught to avoid polling whenever possible as it was throughly sub-optimal. So, is spinlock a fancy name for bad old polling? How is a spinlock different from polling?

Lord Loh.
  • 1,767
  • 1
  • 14
  • 22

5 Answers5

85

Polling refers to repeatedly checking whether a resource (any kind of resource) is ready.

A spinlock is when the resource you are polling is a lock.

Note that polling is not bad. In particular, polling is efficient when there is usually data ready when you poll. Polling is only inefficient if you do it without then getting any data in return.

On the other hand, interrupts are inefficient if there is so much data that you constantly get interrupted. They are efficient if data arrives rarely enough that you can actually get some useful work done before getting interrupted.

I can give you a real-life example from my own experience: 15 years ago, I had my email program set up to interrupt me every time a new email comes in. Which happened once or twice a week. Constantly checking my inbox would have been a colossal waste of time.

Nowadays, I have all notifications turned off. I know that whenever I look into my inbox, there'll be new emails there. Polling is much more efficient now.

Spinlocks are efficient when a) the likelihood that the lock is taken is low, and b) if the lock is taken, it will only be held for a short time. In other words: it is efficient for mostly uncontended fine-grained locks, but inefficient for highly contended coarse-grained locks.

(And of course, spinlocks only work when there is true parallelism, otherwise the other thread won't have a chance to release the lock. I guess that's kind of obvious, but I wanted to state it anyway.)

Matthew
  • 1,976
  • 3
  • 18
  • 26
Jörg W Mittag
  • 101,921
  • 24
  • 218
  • 318
  • Don't forget that certain spinlocks also have performance penalties if implemented naively (i.e. TAS vs. TTAS). – JAB Nov 06 '15 at 21:50
  • 5
    Spinlocks can be perfectly sensible in a cooperatively multitasked environment. You just have to make sure you're yielding control in the loop. – Kevin Nov 07 '15 at 00:15
  • 4
    Great example with emails. Reminds me of [you always have email](https://pbs.twimg.com/media/Bjg4vm1CQAA-r2b.png)... – Petr Nov 07 '15 at 20:01
  • @Jörg W Mittag - Great example and a great explanation. Thank you. – Lord Loh. Nov 07 '15 at 23:04
  • @Kevin let's just hope you're not met with an operating system that ignores the yield requests. – John Dvorak Nov 08 '15 at 14:18
  • 2
    @Kevin: I have a very puristic idea of a spinlock, literally a lock that just spins in an empty loop. (`atomically_do { while (lock.is_locked?); lock.acquire! }`) If it yields, it's not an empty loop and thus not a spinlock in that puristic view :-D But of course some hybridization with other types of locks or relaxations/additions to the platonic ideal make perfect sense in the real world. – Jörg W Mittag Nov 08 '15 at 16:25
  • can someone explain the last part of the answer: "spinlocks only work when there is true parallelisim..." – bubakazouba Nov 09 '15 at 20:30
  • 3
    @bubakazouba: A spinlock works by literally "spinning" in an empty loop and checking "Is the lock released yet? Is the lock released yet? Is the lock released yet? Is the lock released yet? Is the lock released yet?" over and over again. If there is no parallelism, then there is no other thread running at the same time that could release the lock, so you effectively have an endless loop! See the comment directly above yours. – Jörg W Mittag Nov 09 '15 at 20:38
  • @Kevin Spin locks are usually used at such a low layer in the software stack, that yielding isn't possible. For example it is quite likely that inside the implementation of the yield function you will find a spin lock. However inside a spin lock at such a low level you may find architecture specific instructions like the PAUSE instruction which is kind of like yield for hyperthreading. – kasperd Dec 27 '15 at 19:33
  • @kasperd: If your system is *cooperatively* multitasked, yielding should not require any locking. I fail to see how you could possibly have concurrency issues in that case. – Kevin Dec 27 '15 at 19:35
  • @Kevin Some locking will be required if you have multiple cores. Something has to prevent two cores from simultaneously scheduling the same process/thread. – kasperd Dec 27 '15 at 19:38
  • @kasperd: The word "scheduling" implies preemptive multitasking. So does multiple cores, for that matter. At least, I've never heard of a multi-core cooperative multitasking system. – Kevin Dec 27 '15 at 19:38
  • @Kevin The word "scheduling" describes the choice of which process gets to use the CPU next. It doesn't say anything about whether the previous process to use the CPU yielded or was preempted. So no, neither scheduling nor multiple cores imply preemptive multitasking. – kasperd Dec 27 '15 at 19:43
  • 1
    @kasperd: I still don't see how you could sensibly implement a cooperatively multitasking system with multiple cores. – Kevin Dec 27 '15 at 19:45
  • @Kevin That is no different from any other concurrent system. you need locks. None of that solves the inherent problem with cooperative multitasking, namely the risk of a thread locking up the system. And that's why general purpose operating systems no longer use cooperative multitasking. – kasperd Dec 27 '15 at 20:15
  • 2
    @kasperd: You can still see cooperative multitasking in event-driven server software like nginx. In that case, there is one thread and no locking, which means you only get to exploit one core. To the best of my knowledge, there are literally *no real-world examples* of true multicore cooperative multitasking. Such a system would be stupid, since you would get all the downsides of cooperative multitasking without the upside of no locks. – Kevin Dec 27 '15 at 21:02
10

A spinlock is a type of lock, specifically, one achieved via polling.

Polling is a method of checking the status of something (by asking for the status, as opposed to waiting to be told the status).

Not all polling is a spinlock, for example, polling the status of keyboard keys.


Also, polling isn't inherently bad. Very short periods of polling can avoid expensive context shifts that use of interrupts would require, not to mention that polling can sometimes be simpler to implement and thus easier to maintain, especially at lower levels. As usual, absolutes are a terrible thing, and you should use the method that gives the appropriate performance/complexity trade off for your needs as you have measured them, rather than blindly using or discarding options.

8bittree
  • 5,637
  • 3
  • 27
  • 37
5

Spinlock is different from polling because it only occurs for a very short period of time, on the order of a few milliseconds or less. Polling can go on indefinitely.

In parallel programming, a brief episode of spinning is often preferable to blocking, as it avoids the cost of context switching and kernel transitions.

Further Reading
SpinLock and SpinWait in C#
Spinlocks and Read-Write Locks in C

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • 1
    I think you meant to say microseconds. For a lock that lasts an entire millisecond we should use a lock implementation that makes a kernel call on contention. – Peter Nov 09 '15 at 10:11
  • @Peter Perhaps that's what Albahari meant. That's what his text says. – Robert Harvey Nov 09 '15 at 15:43
4

The difference is that a spinlock is (hopefully) only used in situations where it is appropriate, and in these situations it is very efficient.

You use a spinlock if you expect that a resource will only be locked for a very short time - for example if a lock is only used to update a variable. The spinlock polls the lock at maximum speed, but hopefully for less than microseconds. A normal mutex would require on OS call. IF the lock is only held for a tiny amount of time, then the spinlock only uses a tiny amount of CPU time, while the OS call will take longer. But if this expectation is wrong, then the spinlock is very inefficient - it will use 100% CPU time on one CPU, while the normal mutex only takes the time for entering the OS and returning.

Sometimes both are combined; you run the spin lock for a short time and switch to a different strategy if the spinlock doesn't work.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
2

Excessive polling is something you should not do because it wastes system resources. It follows that polling is fine if it doesn't waste system resources.

For example excessive polling will get CPU load to 100% in cases where the actual work would only result in a 2% load.

Polling can be used for other things than while(!ready). For example it means checking regularly if the user pressed a key. A sane implementation will check at most once every 15 milliseconds, so it's one check every ~20 million clock cycles. That kind of polling is great, because it doesn't waste system resources.

A SpinLock is not a special case. If we have a SpinLock and one thread enters the lock, and another has to wait, the SpinLock is the wrong choice if and only if the waiting thread wastes system resources. The waiting thread will waste system resources if and only if it has to wait for a significant amount of time before it can acquire the lock.

Therefore, using a SpinLock to protect a anything that requires a couple thousand clock cycles or more before it unlocks again (e.g. compiling and executing a piece of javascript on the fly) is bad, exactly for the reason you stated. But using a SpinLock to protect something that completes quickly, like accessing a properly implemented hash map is fine because the waiting thread will only spin 2 or 3 times and therefore doesn't waste system resources.

Peter
  • 3,718
  • 1
  • 12
  • 20
  • of course, it's also fine to waste 98% of the CPU *if* you are a microcontroller, you aren't running on battery power, you only needed 2% anyway, *and* it makes the design simpler. – user253751 Nov 05 '20 at 15:51