What exactly are "spin-locks"?
Asked Answered
C

11

141

I always wondered what they are: every time I hear about them, images of futuristic flywheel-like devices go dancing (rolling?) through my mind...

What are they?

Cockshy answered 24/12, 2009 at 8:34 Comment(0)
L
174

When you use regular locks (mutexes, critical sections etc), operating system puts your thread in the WAIT state and preempts it by scheduling other threads on the same core. This has a performance penalty if the wait time is really short, because your thread now has to wait for a preemption to receive CPU time again.

Besides, kernel objects are not available in every state of the kernel, such as in an interrupt handler or when paging is not available etc.

Spinlocks don't cause preemption but wait in a loop ("spin") till the other core releases the lock. This prevents the thread from losing its quantum and continue as soon as the lock gets released. The simple mechanism of spinlocks allows a kernel to utilize it in almost any state.

That's why on a single core machine a spinlock is simply a "disable interrupts" or "raise IRQL" which prevents thread scheduling completely.

Spinlocks ultimately allow kernels to avoid "Big Kernel Lock"s (a lock acquired when core enters kernel and released at the exit) and have granular locking over kernel primitives, causing better multi-processing on multi-core machines thus better performance.

EDIT: A question came up: "Does that mean I should use spinlocks wherever possible?" and I'll try to answer it:

As I mentioned, Spinlocks are only useful in places where anticipated waiting time is shorter than a quantum (read: milliseconds) and preemption doesn't make much sense (e.g. kernel objects aren't available).

If waiting time is unknown, or if you're in user mode Spinlocks aren't efficient. You consume 100% CPU time on the waiting core while checking if a spinlock is available. You prevent other threads from running on that core till your quantum expires. This scenario is only feasible for short bursts at kernel level and unlikely an option for a user-mode application.

Here is a question on SO addressing that: Spinlocks, How Useful Are They?

Levison answered 24/12, 2009 at 8:55 Comment(12)
does it mean that I should spin-locks (instead of mutex, critical-section etc.) wherever possible?Boys
somebody please correct me if I am wrong, but a spinlock does not disable preemption (ie. re-scheduling). for the simple reason that, if the spinlock is waiting for a resource locked by another process, then that second process must be given a chance to run and to free the resource. or, running the second process requires preempting the first (spinning) process.Chyme
what spinlock does instead is that it does not change the process state from TASK_RUNNING into TASK_INTERRUPTIBLE (which is a sleeping state) and, thus, it does not save everything about that process (memory, cache and so on). instead, the spinning process is preempted, but it never quits the "immediately schedulable" processes: it is kept in memory and the other processes are regularily run until one of them frees the resource that the spinner is waiting for: at that time, the spinlock simply returns and the spinning process is able to continue. it waits in a always TASK_RUNNING state.Chyme
@axeoth: spinlock disables preemption only on single core machines INSTEAD OF waiting in a loop. disabling preemption guarantees lock acquisition and doesn't waste quanta in context switching or loops.Levison
you are right about that (see also this: linuxjournal.com/article/5833), but fact is that locking a ressource and disabling interrupts, although useful to be performed jointly, are otherwise unrelated concepts. you basically want to be sure that you are not using a resource found in an inconsistent state, and this is why you test its lock. disabling interrupts (also preemption) ensures that yes, nobody will mess with your resurce while you are dealing with it. but, for that, you have to be sure that the resource is free when you are acquiring it.Chyme
(then disable interrupts just to be sure that no other task is preempting you and messing with the resource). on UP (uni-processor), this is always the case: the very first (and the subsequent ones) spinlock is simply granted, interrupts (ie preemption) are disabled, and the task using the resource is never preempted: it does all its job with the resource, then enable interrupts (and, thus, preemption). when preemption is enabled, then the resource is already free. basically, on UP, there is no spinlock contention and there is no waiting. on SMP it might be.Chyme
however, all that does not alleviate the problem: on SMP, for example, spinlock and blocklock are different concepts and contention exists (also waiting). but: a spinlock will wait without the overhead of saving the task context but by eating processor time (that is the time share of the spinning task), while a blocklock will wait with the overhead of saving the task context (but by freeing the time share on the processor). interrupt handlers, for ones, have no task context (the execute on the memory pages of the interrupted task), so they are forced to use spinlock (they cannot save).Chyme
but, in any case, spinning does not disable preemption, only context saving. on the particular case of UP, there is no spinning at all, preemption disabling is just a mean to avoid the need for locking (as the resource is guaranteed to be in consistent state when you ask for it, otherwise you cannot ask for it because, well, you are not running, somebody else is). for SMP spinlock vs blocklock difference see here: oocities.org/tzengymtw/eBooks/linux_tips.html (search: "Putting a task to sleep removes its context from the processor's cache")Chyme
i think your answer is right, just this sentence: "This has a performance penalty if the wait time is really short, because your thread now has to wait for a preemption to receive CPU time again." should become "This has a performance penalty if the wait time is really short, because your thread now has to wait for a WAKE to receive CPU time again." (as for preemption, it is always forced to wait, otherwise nobody will get a chance to free the lock that the thread is waiting for)Chyme
and this: "Spinlocks don't cause preemption but wait in a loop" -> "Spinlocks don't cause SLEEPING (or CONTEXT SAVING) but wait in a loop"Chyme
@ssg what do you mean by "Kernel objects are not available?". Does it mean scheduler has not started yet and you want locks?Active
@DarshanPrajapati it means you are in a context where scheduling or paging isn't available (such as inside an interrupt handler, a DPC, interrupts-disabled state etc).Levison
S
38

Say a resource is protected by a lock ,a thread that wants access to the resource needs to acquire the lock first. If the lock is not available, the thread might repeatedly check if the lock has been freed. During this time the thread busy waits, checking for the lock, using CPU, but not doing any useful work. Such a lock is termed as a spin lock.

Sulk answered 24/12, 2009 at 8:40 Comment(1)
Best explanation ever!Swor
C
23

It is pertty much a loop that keeps going till a certain condition is met:

while(cantGoOn) {};
Caddric answered 24/12, 2009 at 8:38 Comment(4)
And/or while(cantGoOn) { sleep(0) };Bronchiectasis
@Bronchiectasis if you put a sleep(0) it would preempt the thread, killing the purpose of using a spinlock in the first place. if you need to yield to other threads, you should be using a regular lock. (i know your comment is very old but wanted to prevent others from seeing this as a suggestion).Levison
"A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution."Bronchiectasis
@Bronchiectasis that's the point - spinlocks don't relinquish.Metachromatism
T
9
 while(something != TRUE ){};
 // it happend
 move_on();
Tarboosh answered 24/12, 2009 at 8:37 Comment(0)
A
5

It's a type of lock that does busy waiting

It's considered an anti-pattern, except for very low-level driver programming (where it can happen that calling a "proper" waiting function has more overhead than simply busy locking for a few cycles).

See for example Spinlocks in Linux kernel.

Allurement answered 24/12, 2009 at 9:25 Comment(0)
C
4

SpinLocks are the ones in which thread waits till the lock is available. This will normally be used to avoid overhead of obtaining the kernel objects when there is a scope of acquiring the kernel object within some small time period.

Ex:

While(SpinCount-- && Kernel Object is not free)
{}

try acquiring Kernel object
Camembert answered 24/12, 2009 at 8:42 Comment(0)
D
3

You would want to use a spinlock when you think it is cheaper to enter a busy waiting loop and pool a resource instead of blocking when the resource is locked.

Spinning can be beneficial when locks are fine grained and large in number (for example, a lock per node in a linked list) as well as when lock hold times are always extremely short. In general, while holding a spin lock, one should avoid blocking, calling anything that itself may block, holding more than one spin lock at once, making dynamically dispatched calls (interface and virtuals), making statically dispatched calls into any code one doesn't own, or allocating memory.

It's also important to note that SpinLock is a value type, for performance reasons. As such, one must be very careful not to accidentally copy a SpinLock instance, as the two instances (the original and the copy) would then be completely independent of one another, which would likely lead to erroneous behavior of the application. If a SpinLock instance must be passed around, it should be passed by reference rather than by value.

Dentelle answered 12/11, 2015 at 12:26 Comment(0)
D
0

It's a loop that spins around until a condition is met.

Deterrent answered 24/12, 2009 at 8:37 Comment(0)
C
0

In nutshell, spinlock employs atomic compare and swap (CAS) or test-and-set like instructions to implement lock free, wait free thread safe idiom. Such structures scale well in multi-core machines.

Chowder answered 24/12, 2009 at 8:43 Comment(1)
By very definition, a spinlock is not used to implement anything lock free or wait free.Rhodolite
D
0

Well, yes - the point of spin locks (vs a traditional critical sections, etc) is that they offer better performance under some circumstances (multicore systems..), because they don't immediately yield the rest of the thread's quantum.

Dodi answered 24/12, 2009 at 8:43 Comment(0)
F
0

Spinlock, is a type of lock, which is non-block able & non-sleep-able. Any thread which want to acquire a spinlock for any shared or critical resource will continuously spin, wasting the CPU processing cycle till it acquire the lock for the specified resource. Once spinlock is acquired, it try to complete the work in its quantum and then release the resource respectively. Spinlock is the highest priority type of lock, simply can say, it is non-preemptive kind of lock.

Flax answered 29/5, 2017 at 8:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.