Synchronization Disclaimer: some slides are adopted from the book - - PowerPoint PPT Presentation

synchronization
SMART_READER_LITE
LIVE PREVIEW

Synchronization Disclaimer: some slides are adopted from the book - - PowerPoint PPT Presentation

Synchronization Disclaimer: some slides are adopted from the book authors slides with permission 1 Recap Race condition A situation when two or more threads read and write shared data at the same time Correctness depends on the


slide-1
SLIDE 1

Synchronization

1

Disclaimer: some slides are adopted from the book authors’ slides with permission

slide-2
SLIDE 2

Recap

  • Race condition

– A situation when two or more threads read and write shared data at the same time – Correctness depends on the execution order

  • Critical section

– Code sections of potential race conditions

  • Mutual exclusion

– If a thread executes its critical section, no other threads can enter their critical sections

2

slide-3
SLIDE 3

Recap

  • Peterson’s algorithm

– Software-only solution

  • Turn based

– Pros

  • No hardware support
  • Satisfy all requirements

– Mutual exclusion, progress, bounded waiting

– Cons

  • Complicated
  • Assume program order
  • May not work on out-of-order processors

3

slide-4
SLIDE 4

Today

  • Synchronization instructions
  • Lock

–Spinlock –Mutex

4

slide-5
SLIDE 5

Lock

  • General solution

– Protect critical section via a lock – Acquire on enter, release on exit

5

do { acquire lock; critical section release lock; remainder section } while(TRUE);

slide-6
SLIDE 6

How to Implement a Lock?

  • Unicore processor

– No true concurrency

  • ne thread at a time

– Threads are interrupted by the OS

  • scheduling events: timer interrupt, device interrupts
  • Disabling interrupt

– Threads can’t be interrupted

6

do { disable interrupts; critical section enable interrupts; remainder section } while(TRUE);

slide-7
SLIDE 7

How to Implement a Lock?

  • Multicore processor

– True concurrency

  • More than one active threads sharing memory

– Disabling interrupts don’t solve the problem

  • More than one threads are executing at a time
  • Hardware support

– Synchronization instructions

  • Atomic test&set instruction
  • Atomic compare&swap instruction
  • What do we mean by atomic?

– All or nothing

7

slide-8
SLIDE 8

TestAndSet Instruction

  • Pseudo code

8

boolean TestAndSet (boolean *target) { boolean rv = *target; *target = TRUE; return rv: }

slide-9
SLIDE 9

Spinlock using TestAndSet

9

int mutex; init_lock (&mutex); do { lock (&mutex); critical section unlock (&mutex); remainder section } while(TRUE); void init_lock (int *mutex) { *mutex = 0; } void lock (int *mutex) { while(TestAndSet(mutex)) ; } void unlock (int *mutex) { *mutex = 0; }

slide-10
SLIDE 10

CAS (Compare & Swap) Instruction

  • Pseudo code

10

int CAS(int *value, int oldval, int newval) { int temp = *value; if (*value == oldval) *value = newval; return temp; }

slide-11
SLIDE 11

Spinlock using CAS

11

int mutex; init_lock (&mutex); do { lock (&mutex); critical section unlock (&mutex); remainder section } while(TRUE); void init_lock (int *mutex) { *mutex = 0; } void lock (int *mutex) { while(CAS(&mutex, 0, 1) != 0); } void unlock (int *mutex) { *mutex = 0; }

slide-12
SLIDE 12

What’s Wrong With Spinlocks?

  • Very wasteful

– Waiting thread continues to use CPU cycles – While doing absolutely nothing but wait – 100% CPU utilization, but no useful work done – Power consumption, fan noise, …

  • Useful when

– You hold the lock only briefly

  • Otherwise

– A better solution is needed

12

slide-13
SLIDE 13

Mutex – Blocking Lock

  • Instead of spinning

– Let the thread sleep

  • There can be multiple waiting threads

– In the meantime, let other threads use the CPU – When the lock is released, wake-up one thread

  • Pick one if there multiple threads were waiting

13

slide-14
SLIDE 14

14

void mutex_init (mutex_t *lock) { lock->value = 0; list_init(&lock->wait_list); spin_lock_init(&lock->wait_lock); } void mutex_lock (mutex_t *lock) { … while(TestAndSet(&lock->value)) { … … … … … } … } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … }

Thread waiting list More reading: mutex.c in Linux To protect waiting list

slide-15
SLIDE 15

15

void mutex_init (mutex_t *lock) { lock->value = 0; list_init(&lock->wait_list); spin_lock_init(&lock->wait_lock); } void mutex_lock (mutex_t *lock) { … while(TestAndSet(&lock->value)) { current->state = WAITING; list_add(&lock->wait_list, current); … schedule(); … } … } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … }

Thread waiting list Sleep or schedule another thread Thread state change Add the current thread to the waiting list More reading: mutex.c in Linux To protect waiting list

slide-16
SLIDE 16

16

void mutex_init (mutex_t *lock) { lock->value = 0; list_init(&lock->wait_list); spin_lock_init(&lock->wait_lock); } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { current->state = WAITING; list_add(&lock->wait_list, current); … schedule(); … } spin_unlock(&lock->wait_lock); } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … }

Thread waiting list Sleep or schedule another thread Thread state change Add the current thread to the waiting list More reading: mutex.c in Linux To protect waiting list

slide-17
SLIDE 17

17

void mutex_init (mutex_t *lock) { lock->value = 0; list_init(&lock->wait_list); spin_lock_init(&lock->wait_lock); } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { current->state = WAITING; list_add(&lock->wait_list, current); spin_unlock(&lock->wait_lock); schedule(); spin_lock(&lock->wait_lock); } spin_unlock(&lock->wait_lock); } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … }

Thread waiting list Sleep or schedule another thread Thread state change Add the current thread to the waiting list More reading: mutex.c in Linux To protect waiting list

slide-18
SLIDE 18

18

void mutex_init (mutex_t *lock) { lock->value = 0; list_init(&lock->wait_list); spin_lock_init(&lock->wait_lock); } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { current->state = WAITING; list_add(&lock->wait_list, current); spin_unlock(&lock->wait_lock); schedule(); spin_lock(&lock->wait_lock); } spin_unlock(&lock->wait_lock); } void mutex_unlock (mutex_t *lock) { … lock->value = 0; if (!list_empty(&lock->wait_list)) wake_up_process(&lock->wait_list) … }

Thread waiting list Sleep or schedule another thread Thread state change Add the current thread to the waiting list Someone is waiting for the lock Wake-up a waiting thread More reading: mutex.c in Linux To protect waiting list

slide-19
SLIDE 19

19

void mutex_init (mutex_t *lock) { lock->value = 0; list_init(&lock->wait_list); spin_lock_init(&lock->wait_lock); } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { current->state = WAITING; list_add(&lock->wait_list, current); spin_unlock(&lock->wait_lock); schedule(); spin_lock(&lock->wait_lock); } spin_unlock(&lock->wait_lock); } void mutex_unlock (mutex_t *lock) { spin_lock(&lock->wait_lock); lock->value = 0; if (!list_empty(&lock->wait_list)) wake_up_process(&lock->wait_list) spin_unlock(&lock->wait_lock); }

Thread waiting list Sleep or schedule another thread Thread state change Add the current thread to the waiting list Someone is waiting for the lock Wake-up a waiting thread More reading: mutex.c in Linux To protect waiting list