1 / 31

Synchronization

Synchronization. CS470 -- Spring 2002. 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. Concurrency Problems.

elden
Download Presentation

Synchronization

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Synchronization CS470 -- 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 ( ); inside[me] = FALSE; 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 Starvation is possible; but works for n threads. BOOL bit = FALSE; DoThread(void *c) { BOOL key; DoNonCritical( ); key = TRUE; do {Exchange(bit, key); } while (key); DoCriticalSection ( ); bit = FALSE; DoMoreNonCritical ( ); }

  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 Could use Binary Semaphores. Could have multiple critical sections, etc. Use TestSet, etc. to implement in operating system. struct semaphore s; DoThread(void *c) { DoNonCritical( ); Wait(&s); DoCriticalSection( ); Signal(&s); DoMoreNonCritical( ); }

  27. Message Passing • Message Operations • 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 • 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

More Related