I like to think of thread synchronization as bottom up, where the processor and operating system provide a design primitive for more complex ones.
At the processor level, you have CAS and LL / SC that allow you to run the test and store in one atomic operation ... you also have other processor designs that allow you to disable and enable interruption (however, they are considered dangerous ... for certain circumstances you have no choice but to use them)
operating system
provides the ability to switch context between tasks that can occur every time a thread uses its time slice ... or it can happen due to other reasons (I will come to this)
then there are constructions of a higher level, such as mutexes, which use these primitive mechanisms provided by the processor (I think, a rotating mutex) ... which will constantly wait until the condition becomes true and check this condition atomically
then these rotating mutex can use the functionality provided by the OS (context switch and system calls, such as the output that gives control to another thread) and gives us mutexes
these constructs are then used by higher-level constructs such as conditional variables (which can track how many threads the mutex expects and which thread to resolve first when the mutex becomes available)
These constructs, which can be used further to provide more complex synchronization constructs ... example: semaphores, etc.
jsshah Mar 03 2018-10-03T00: 00Z
source share