locking & synchronization page
authoralexh <alexh@web>
Fri, 2 Apr 2010 03:06:18 +0000 (20:06 -0700)
committerCharlie <root@leaf.dragonflybsd.org>
Fri, 2 Apr 2010 03:06:18 +0000 (20:06 -0700)
docs/developer/Locking_and_Synchronization/index.mdwn [new file with mode: 0644]

diff --git a/docs/developer/Locking_and_Synchronization/index.mdwn b/docs/developer/Locking_and_Synchronization/index.mdwn
new file mode 100644 (file)
index 0000000..f7a842b
--- /dev/null
@@ -0,0 +1,107 @@
+## Spinlocks
+### Internals
+* they effectively spin until the lock becomes released. In each spin (while iteration) they check if the lock has been released yet; if not, they just spin further.
+* optimization for UP: do nothing.
+* new lock holder spins already, not sleeping, so no need to wakeup
+### Usage
+* very lightweight, but should be held only for *very* short time (as other contenders spin and don't sleep!)
+* read spinlocks (effectively shared) are also available, but not recommended for new implementations
+* can not sleep while holding a spinlock; scheduler will panic about spinlocks being held by yielding thread XXX
+* can never recurse!
+* used to protect structures
+
+----
+
+## LWKT serializing tokens
+### Internals
+* uses atomic_cmpset* internally
+* UP optimization: only check to see if preemption is happening, in which case acquisition of token fails.
+* deeply integrated with lwkt scheduler (lwkt_yield, ...)
+       * scheduler takes care of acquiring the token before rescheduling
+       * so a thread won't run unless the scheduler can acquire all the tokens for it.
+       * tokens are not owned by the thread but by the CPU. threads only get token references
+* no explicit wakeup when yielding a token reference
+### Usage
+* a same thread can acquire multiple token references, but if that's the case, all tokens have to be acquired before the lwkt is scheduled!
+* if thread sleeps while holding token references, other threads can acquire a token reference and run; so not completely safe to sleep
+* used to protect heavier processing than spinlocks; but mostly also to protect data structures. Often used for global lists (allproc, etc)
+* when acquiring token, not available, go to sleep, lose tokens
+
+----
+
+## Lockmgr
+### Internals
+* uses a spinlock inside
+* sleeps while acquiring (at least if NO_WAIT is not specified) XXX
+* heavyweight
+* wakeup used to activate new lock holder
+* no UP optimization
+### Usage
+* supports shared locks or exclusive locks, shared locks can be upgraded, exclusive can be downgraded
+* can be acquired recursively, if the thread is the same and LK_CANRECURSE is specified
+* can sleep while holding the lock.
+* used when there is a requirement or possibility of blocking/sleep/recursion/...
+
+----
+
+## MTX
+### Internals
+* based around atomic_cmpset_int instead of spinlocks
+* uses wakeup to activate new lock holder
+* much more lightweight than lockmgr (faster, much less space)
+* no UP optimization
+### Usage
+* can always be recursive
+* can be shared/exclusive, so upgradable
+* can be held across blocking/sleeps
+* can pass lock ownership directly to new owner, so no wakeup needed and is guaranteed to reach the intended destination
+
+----
+
+## MPLock
+### Internals
+* internally uses atomic_cmpset
+* logs when the mplock is contended to KTR
+* clogs performance inmensely
+### Usage
+* should be avoided at all cost
+* must be held as little as possible
+* one for the whole system (all CPUs!!)
+       
+----
+
+## LWKT Messages
+### Internals
+* messages are passed by queueing them to the destination thread's message queue, then waking up the listener.
+* messages have to be allocated/deallocated (typically using objcache_*)
+       * (usually use a drain to deallocate; set the replyport to be the drain and then just reply to the message)
+* rather lightweight, except for inter-processor messages
+### Usage
+* isn't a locking mechanism, rather serialization as everything can be processed in one thread if the others just send it to that one
+* can be used to avoid races: just do all the processing in one single thread
+* send all the work from other threads/entry points to that one thread using lwkt messages.
+* requires no locking
+
+----
+       
+## Critical Sections
+### Internals
+* Changes priority of current thread to TDPRIT_CRIT, effectively avoiding preemption of the thread
+* are per-cpu
+### Usage
+* avoid anything else happening on that CPU due to the disabled preemption
+* are no synchronization/locking between different CPUs!
+* should be used if some code has to run uninterruptedly
+
+----
+
+## Condvars
+### Internals
+* XXX: current implementation is incorrect, need to use lksleep!!
+* XXX: currently not yet in the main repository
+* uses spinlocks internally on the condvar
+### Usage
+* can interlock sleep when given a lockmgr lock to avoid missing changes to it, or just regular tsleep
+* used to wait for conditions to happen (threads doing this are waiters)
+* can wakeup all waiters or just one, effectively notifying that a change has occured
+