Synchronisation Primitives
description
Transcript of Synchronisation Primitives
Operating Systems: Sema
1
Synchronisation Primitives
Hardware Approach–modifying a shared variable must be made an indivisible operation - atomic
•test-and-set
test-and-set (int lock) {int temp;temp = lock;lock = 1;return temp;
}
–mutual exclusion achieved by:
while (TRUE) {while ( test-and-set(lock) == 1) { /* wait */ }critical sectionlock = 0;. . . .
}
Operating Systems: Sema
2
•swap
swap (int a, b) {int temp;temp = a;a = b;b = temp;
}
– mutual exclusion achieved by:
while (TRUE) {key = 1;while ( key == 1) { swap( lock, key ); }critical sectionlock = 0;. . . .
}
•increment-and-test with test-and-decrement
–for counting how many processes waiting to enter a critical section
Operating Systems: Sema
3
Motorola 68000
Operating Systems: Sema
4
Intel x86
Operating Systems: Sema
5
Intel x86
Operating Systems: Sema
6
Intel x86
Operating Systems: Sema
7
Sparc
Operating Systems: Sema
8
ICL2900
Operating Systems: Sema
9
ICL2900
Operating Systems: Sema
10
•hardware approach
–applicable to any number of processes on single or multi-processor
–simple and easy to verify
–can support multiple critical sections, each with their own control variable
•problems
–busy-waiting
–deadlock
–starvation
Operating Systems: Sema
11
•Bounded-waiting solution possible (Silberschatz & Galvin):
shared variable : waiting [0:n-1] = 0(n), lock = 0;process Ivariable key = 0;while (TRUE) {
waiting [I] = 1;key = 1;while ( waiting [I]==1 && key==1) {
key = test-and-set (lock);}waiting [I] = 0;critical section ij = (I+1) % n;while ( j!=i && waiting [j]==0) { j = (j+1)%n; }if (j==i) lock = 0; else waiting [j] = 0;. . . .
}
Operating Systems: Sema
12
Abstract approach : Semaphores (Dijkstra)
•Definition: A semaphore is a non-negative integer which can only be acted upon by the operations P and V, both of which are atomic
P : decrement the semaphore by 1 as soon as the result would be non-negative
V : increment the semaphore by 1
For a semaphore s :
P(s) :while (s==0) { /*wait */ }s = s-1;
V(s) :s = s+1;
–busy-waiting still implied for P(s)
Operating Systems: Sema
13
•Mutual exclusion
semaphore mutex = 1;processwhile (TRUE) {
P(mutex);critical sectionV(mutex);. . . .
}
–mutex = 0 when process in its critical section= 1 when outside
–binary semaphore only takes the values 0 and 1
–general or counting semaphores take any non-negative value
Operating Systems: Sema
14
•Synchronisation
–example: statement S1 of process 1 must be executed before statement S2 of process 2 :
semaphore : synch = 0;process 1 process 2
S1; P(synch);V(synch); S2;. . . . . . . .
–example: producer/consumer using unbounded buffer :
semaphore : items = 0;producer process consumer processwhile (TRUE) { while (TRUE) {
produce item P(items);put item in buffer take item from bufferV(items); consume item
} }
»items is a counting semaphore
Operating Systems: Sema
15
For a bounded circular buffer producer/consumer :
semaphore : items = 0, space = max;producer process consumer processwhile (TRUE) { while (TRUE) {
produce item P(items);P(space); new item = buffer [get];buffer [put] = new item; get = (get+1) % max;put = (put+1) % max; V(space);V(items); consume item
} }
Operating Systems: Sema
16
•Semaphores are used in real operating systems
–to protect access to shared areas e.g. file directories, kernel tables
–to synchronise process and I/O devices
»input device driver producer/consumer model, user process producing output, device-driver consuming it
–client/server model:
server synchronised by semaphore s, user by semaphore u
server process user process
P(s) . . . .. . . . V(s). . . . P(u)V(u) . . . .
–system call to create semaphores when required
–in practice, semaphores always implemented so as to avoid busy waiting
Operating Systems: Sema
17
•Counting semaphores
–can be implemented by a binary semaphore and a count variable
–relevant when atomic machine instructions only implement binary semaphores
semaphore : buff = 1, delay = 0;int items = 0;producer process consumer processwhile (TRUE) { while (TRUE) {
produce item P(delay);P(buff); P(buff);put item in buffer take item from bufferitems =items+1; items = items -1;if (items==1) V(delay); if (items>0) V(delay);V(buff); V(buff);
} consume item}
–buff protects use of shared variable items
Operating Systems: Sema
18
Implementation of Semaphores
•Using hardware instructions
–for binary semaphores :
P(s) : while ( test-and-set (s) == 1) { /* wait */ }
or
P(s) : ss = 1;while ( ss == 1) { swap (s, ss); }
V(s) : s = 0;
–for counting semaphores
»test instructions set a condition code register, cc
P(s) : wait: test-and-decrement (s);if ( cc <= 0 ) { increment-and-test (s); goto wait; }
V(s) : increment-and-test (s)
Operating Systems: Sema
19
•ICL 2900 used INCT and TDEC in reverse :
-1 : semaphore free
0 : semaphore claimed but no-one waiting
>0 : number of process waiting
–INCT used for P operation, TDEC used for V operation
–condition code tested the values:
> 0 = 0 -1 < -1
–used to synchronise CPU with peripheral I/O channel and device controllers
•Machines sometimes have built-in semaphore instructions
•Busy-waiting potentially very wasteful of CPU time and inefficient
•Semaphores most often implemented by system calls to kernel
–can avoid busy-waiting by using process scheduling queues
Operating Systems: Sema
20
Removal of Busy-waiting
•Kernel process scheduling functions include :
–maintaining a run queue of processes ready to run
–maintaining priority queues of processes e.g. background jobs
–maintaining queues of blocked processes, waiting on some event
–suspending processes and preserving their context
–re-activating processes - the dispatcher
•Events that can block processes include :
–page and segment faults
–completion of I/O transfers
–awaiting a signal of some sort
–awaiting an inter-process message
–process swapped out to disc
–awaiting a semaphore
Operating Systems: Sema
21
•Implementation of semaphores by system calls to the OS kernel
–semaphore variable held by the kernel
–each semaphore has its own scheduling queue
–P and V operations now modified :
P(s) : if ( s>0 ) s = s-1;else suspend process and enqueue it
V(s) : if ( queue empty ) s = s+1;else unqueue next waiting process and enqueue on ‘run’ queue
–dispatcher will re-activate released process in due course
Operating Systems: Sema
22
Suspend process
•to preserve to the complete state of the process - its context
•process can be resumed later without any effect except gap in time
•preserve the processes virtual memory contents :
–all programs, shells, libraries, stack, heap and data areas, comms buffers etc.
–option 1 : leave in situ
–option 2 : swap out to disc
Operating Systems: Sema
23
•preserve the volatile context
–processor registers :
»program counter, stack pointers etc.
»general purpose and floating point registers
»status registers, interrupt masks, condition codes etc.
•preserve per process kernel data
–segment and page virtual memory tables
–location of process swap area on disc
–scheduling status information
–IDs - user, group, parent etc.
–accounting data
–pending signals, events
–open files, sockets etc.
Operating Systems: Sema
24
Process Context Block (PCB)
•Process context is all held in a PCB (or referenced from it)
process number
program counter
stack pointer
status register, cc etc.
GP + FP registers
swap area on disc
pointer to VM tables
pointers to other kernel data
scheduling queue link
Operating Systems: Sema
25
•Some machines have replicated sets of registers for each mode
–one set for normal user execution
–another set for interrupt mode
–example : ICL 4-75 had 4 sets registers
»two full sets of 16 for user and kernel
»two more reduced sets for interrupt response modes
–example : the ARM processor has 6 modes:
»user - normal execution
»FIQ - Fast Interrupt reQuest
»IRQ - normal interrupt request
»Supervisor - protected and privileged for kernel execution
»Abort - after a data or instruction abort
»Undefined - after an undefined op. Code executed
Operating Systems: Sema
26
ARM
Operating Systems: Sema
27
•for machines without parallel register sets, the complete volatile context is often dumped automatically into memory :
–on interrupt
–on mode change
–either into a dedicated memory area
–or onto the top of the stack
–example : Intel x86 TSS (Task State Segment)
•sometimes, just the PC and status registers are dumped
–the new mode has to preserve the GP and FP registers itself
»often single instructions to do this
»example : STM (store multiple registers) on the ARM (with LDM for reloading)
–very careful programming usually required!
»often needs to be in assembly code to avoid conflicts of register use from compiled code
Operating Systems: Sema
28
Intel x86 Task State Segment
Operating Systems: Sema
29
•linked PCBs often form the scheduling queues :
run queue
I/O blocked queue
semaphore queue
Operating Systems: Sema
30
•Changing from one process to another can be very costly :
–preserving and reloading the volatile context
–possibly swapping memory image out and in from disc
–kernel mode change
–loss of virtual memory context - TLB
–loss of CPU execution pipeline contents
–loss of cache context
»instructions and data caches relate to execution of previous process
•a significant loss of overall performance can result
–rate of changing between processes must be controlled
–for P and V operations between processes, context changing unavoidable
–use of threads can help considerably
•system calls can also consume significant amounts of CPU time
•total kernel overheads can be alarmingly large!
–not always as much concern as it should be!
Operating Systems: Sema
31
•Scheduler Run Queue
–the V semaphore operation releases a process waiting for a semaphore
–its PCB transferred from the semaphore queue :
»to the run queue if it is still memory resident and ready to go
»to a blocked queue while it is swapped back in from disc
•Scheduler
–organises PCB queues
»which priority queue
»which blocked queue - awaiting disc transfer, semaphore etc.
»and in what order - probably first-come-first-served
–tries to work ahead of currently running process
»so that there is always another process ready to run
»may need to reschedule memory usage ahead of time
»may need to initiate swapping in a process from disc
»may need to ensure process causing blockage is run
»possibility of deadlocks occurring otherwise
Operating Systems: Sema
32
–important to avoid CPU wastage
–overall scheduling strategy to meet particular objectives
»batch streams
»single user systems
»shared server systems
»real-time systems
•Dispatcher
–takes next PCB off run queue
–reloads its volatile context
–exits the kernel to continue the re-activated process
–‘return-from-interrupt’ instruction often provided
»like a ‘return-from-subroutine’ instruction buts reloads context also
Operating Systems: Sema
33
•In more detail, semaphore ops are now :
P(s) : if (s>0) { s = s-1; continue to run * }
else { preserve process context in PCB
goto dispatcher }
V(s) : if (semaphore queue empty) { s = s+1; continue to run * }
else { take PCB off semaphore list
put PCB on Run queue
continue to run * }
– * instead of continue to run, could have instead :
preserve context
goto dispatcher
–i.e. process issuing P or V is also rescheduled
»gives the kernel more control - an extra opportunity to reschedule
Operating Systems: Sema
34
•Example: ICL 2900 semaphores
-1 : free 0 : claimed >0 : number of processes waiting
P(s) : INCT (s)if (cc > 0) SVC (enqueue this process on semaphore s queue)
V(s) : TDEC (s)if (cc > 0) SVC (unqueue next process on semaphore s queue)
–potential problem ?
–advantage : no SVC overhead if no contention for semaphore
–disadvantage : kernel doesn’t know who has the semaphore
Operating Systems: Sema
35
•Example : device-driver
semaphore : dd, request, requestor
user process device-driver process
set up request data while (TRUE) {V(request); P(request);P(requestor); start transferuse transferred data P(dd);
deal with transfer termination interruptV(requestor)
–interrupt vector table consists of entry point addresses for each device :
. . . . .
goto serialgoto parallel. . . . .
–code for each device :
serial: V(serial_dd); parallel: V(parallel_dd);goto dispatcher goto dispatcher
Operating Systems: Sema
36
Intel x86
Operating Systems: Sema
37
Intel x86
Operating Systems: Sema
38
•Deadlocks very possible using semaphores :
process 1 process 2
P(s) P(t)P(t) P(s). . . . . . . .V(s) V(t)V(t) V(s)
–depending on the exact order of statement execution, each process could claim their first semaphore and then wait forever to get the other
–deadlock loops can involve any number of processes :
process 1 process 2 process 3
P(s) P(t) P(u)P(t) P(u) P(s). . . . . . . . . . . .V(s) V(t) V(u)V(t) V(u) V(s)
–need to be very careful to avoid deadlocks