Presentation is loading. Please wait.

Presentation is loading. Please wait.

Synchronization CS470 -- Spring 2002.

Similar presentations


Presentation on theme: "Synchronization CS470 -- Spring 2002."— Presentation transcript:

1 Synchronization CS Spring 2002

2 Overview Concurrency Problems and Mutual Exclusion Requirements
Software methods with busy-wait Hardware Support for Mutual Exclusion Software methods without busy-wait Semaphores Message Passing

3 Concurrency Problems Interleaved & Overlapped computation - both exhibit similar problems Ordering access to global resources - leads to reservation of resources Reservation of resources leads to inefficient use. Lack of reproducibility makes debugging and testing difficult.

4 Example int GetTicket(void) { }
static customerNbr; return customerNbr++; } Fails to give sequential unduplicated tickets

5 Vocabulary Mutual Exclusion protects a critical resource by allowing no more than one thread at a time to execute in a critical section of code which handles that resource. Mutual exclusion can lead to deadlock or starvation

6 Win32 Critical Sections Works for threads in same process
CRITICAL_SECTION data structure InitializeCriticalSection (&cs) or InitializeCriticalSectionAndSpinCount( &cs, cnt) EnterCriticalSection (&cs) or TryEnterCriticalSection(&cs) LeaveCriticalSection(&cs) Implemented with a semaphore

7 Mutual Exclusion Requirements
Mutual exclusion - at most one thread at a time can be in the critical section Threads not in the critical section and not trying to enter it cannot interfere with those trying to enter it No deadlock or starvation possible if no thread dallies in the critical section

8 Software Approaches Standard programming methods are both difficult to code and error prone Some failed approaches Dekker’s Algorithm Peterson’s Algorithm All make inefficient use of processor because they spin in busy-wait loops.

9 Attempt 1 - Taking Turns BOOL turn = FALSE; DoThread(BOOL me) {
DoNonCritical ( ); while (turn != me) ; DoCriticalSection( ); turn = !me; DoMoreNonCritical( ); } Does Mutual Exclusion without deadlock or starvation; but failure outside of critical section can prevent other thread from entering.

10 Attempt 2 - checking other
BOOL inside[2] = {FALSE, FALSE}; DoThread(BOOL me) { DoNonCritical ( ); while (inside[!me]) ; inside[me] = TRUE; DoCriticalSection ( ); inside[me] = FALSE; DoMoreNonCritical ( ); } Does not guarantee mutual exclusion

11 Attempt 3 - early locking
BOOL inside[2] = {FALSE, FALSE}; DoThread(BOOL me) { DoNonCritical ( ); inside[me] = TRUE; while (inside[!me]) ; DoCriticalSection ( ); inside[me] = FALSE; DoMoreNonCritical ( ); } Just swap two lines…. Does mutual exclusion; but can easily deadlock.

12 Attempt 4 - intermittant locks
DoNonCritical ( ); do { inside[me] = FALSE; Sleep(DELAY); inside[me] = TRUE; } while (inside[!me]); DoCriticalSection ( ); DoMoreNonCritical ( ); Mutual exclusion is achieved; but starvation could result.

13 Peterson’s Algorithm BOOL turn, inside[2] = {FALSE, FALSE};
DoThread(BOOL me) { DoNonCritical ( ); inside[me] = TRUE; turn = !me; while (inside[!me] && turn != me) ; DoCriticalSection ( ); inside[me] = FALSE; DoMoreNonCritical ( ); } Simpler Algorithm

14 Hardware: Disabling Interrupts
Method: DisableInterrupts( ); DoCriticalSection ( ); EnableInterrupts ( ); Based on thread context switch being triggered by (clock) interrupt Works only with uniprocessor Reduces total system concurrency Intel: cli and sti instructions Works for n threads

15 Hardware: Test and Set Special atomic instruction:
BOOL TestSet (BOOL *bitPtr) { BOOL ret = *bitPtr; *bitPtr = TRUE; return ret; } Intel 386: lock bts mem, reg/imm where 2nd operand is bit offset in first operand

16 Using Test & Set BOOL bit; DoThread (void *c ) { DoNonCritical ( );
while (TestSet(&bit)) ; DoCriticalSection ( ); bit = FALSE; DoMoreNonCritical ( ); } Starvation could occur; but works for n threads.

17 Hardware: Exchange Special Atomic Instruction:
Exchange(BOOL *a, BOOL *b) { BOOL temp = *a; *a = *b; *b = temp; } Intel 386: lock xchg mem, reg

18 Using Exchange BOOL bit = FALSE; DoThread(void *c) { BOOL key;
DoNonCritical( ); key = TRUE; do {Exchange(bit, key); } while (key); DoCriticalSection ( ); bit = FALSE; DoMoreNonCritical ( ); } Starvation is possible; but works for n threads.

19 Win32 Interlocked Operations
Allows for atomic operations on DWORD by threads in same process or otherwise sharing memory DWORD target must be at even modulo four address on Intel multiprocessor machines

20 Interlocked Operation List
InterlockedIncrement(PLONG) InterlockedDecrement(PLONG) InterlockedExchange(PLONG target, LONG value) InterlockedExchangeAdd(PLONG Addend, LONG increment) InterlockedExchange(PVOID dest, PVOID exchange, PVOID comperand)

21 Hardware Support Summary
Advantages Applies to n threads Simple and easy to verify Different variables give different locks Disadvantages Busy-wait wastes cpu resources Starvation is possible Deadlock is possible -- e.g. waiting on lock held by lower priority process.

22 Counting Semaphores (1 of 2)
struct semaphore { DWORD count; ThreadList tList; } void Wait(struct semaphore *s) { if (- - s  count < 0) { EnqueueAndBlock(self, s  tList); Wait is atomic.

23 Counting Semaphores (2 of 2)
void Signal(struct semaphore *s) { if (++s  count <= 0) { MoveThreadToRunQueueFrom( s  tList); } Signal is atomic.

24 Binary Semaphores (1 of 2)
struct BSemaphore { BOOL value; ThreadList tList; } void BWait(struct BSemaphore *s) { if (s  value == TRUE) { s  value = FALSE; } else { EnqueueAndBlock(self, s  tList); }} BWait is atomic.

25 Binary Semaphores (2 of 2)
void BSignal(struct BSemaphore *s) { if (s  tList == NULL) { s  value = TRUE; } else { MoveThreadToRunQueueFrom( s  tList); } BSignal is atomic.

26 Using Semaphores struct semaphore s; DoThread(void *c) {
DoNonCritical( ); Wait(&s); DoCriticalSection( ); Signal(&s); DoMoreNonCritical( ); } Could use Binary Semaphores. Could have multiple critical sections, etc. Use TestSet, etc. to implement in operating system.

27 Message Passing Message Operations Synchronization
Send (destination, message) Receive (source, message) Synchronization Send - blocking or non-blocking Receive - blocking or non-blocking, may be able to check for arrived messages typical: non-blocking sends, blocking receives with arrival check

28 Message Addressing Direct Indirect via mailboxes
Send has explicit address of addressee Receive explicit address of sender implicit, known only after receipt Indirect via mailboxes static via permanent ports dynamic with connect / disconnect Queuing - FIFO, message priorities

29 Mutual Exclusion via Messages
Initialize mbox with 1 message DoThread(void *c) { DoNonCritical ( ); Receive( mbox, message); DoCriticalSection ( ); Send ( mbox, message); DoMoreNonCritical ( ); }

30 Producer / Consumer (1 of 2)
Initialize mayproduce with n messages, mayconsume as empty Producer(void *c) { MESSAGE pmsg; while (TRUE) { receive(mayproduce, &pmsg); pmsg = Produce( ); send(mayconsume, &pmsg); } }

31 Producer / Consumer (2 of 2)
Consumer(void *c) { MESSAGE cmsg; while (TRUE) { Receive(mayconsume, &cmsg); Consume(&cmsg); Send(mayproduce, &cmsg); } Allows multiple servers and clients


Download ppt "Synchronization CS470 -- Spring 2002."

Similar presentations


Ads by Google