synchronization
play

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


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

  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

  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

  4. Today • Synchronization instructions • Lock – Spinlock – Mutex 4

  5. Lock • General solution – Protect critical section via a lock – Acquire on enter, release on exit do { acquire lock; critical section release lock; remainder section } while(TRUE); 5

  6. How to Implement a Lock? • Unicore processor – No true concurrency one thread at a time – Threads are interrupted by the OS • scheduling events: timer interrupt, device interrupts • Disabling interrupt do { – Threads can’t be disable interrupts ; interrupted critical section enable interrupts ; remainder section } while(TRUE); 6

  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

  8. TestAndSet Instruction • Pseudo code boolean TestAndSet (boolean *target) { boolean rv = *target; *target = TRUE; return rv: } 8

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

  10. CAS (Compare & Swap) Instruction • Pseudo code int CAS(int *value, int oldval, int newval) { int temp = *value; if (*value == oldval) *value = newval; return temp; } 10

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

  12. What’s Wrong With Spin locks? • 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

  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

  14. void mutex_init (mutex_t *lock) More reading: mutex.c in Linux { lock->value = 0; list_init(&lock->wait_list); Thread waiting list spin_lock_init(&lock->wait_lock); To protect waiting list } void mutex_lock (mutex_t *lock) { … while(TestAndSet(&lock->value)) { … … … … … } … } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … 14 }

  15. void mutex_init (mutex_t *lock) More reading: mutex.c in Linux { lock->value = 0; list_init(&lock->wait_list); Thread waiting list spin_lock_init(&lock->wait_lock); To protect waiting list } void mutex_lock (mutex_t *lock) { … while(TestAndSet(&lock->value)) { Thread state change current->state = WAITING; list_add(&lock->wait_list, current); Add the current thread to the … waiting list schedule(); Sleep or schedule another thread … } … } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … 15 }

  16. void mutex_init (mutex_t *lock) More reading: mutex.c in Linux { lock->value = 0; list_init(&lock->wait_list); Thread waiting list spin_lock_init(&lock->wait_lock); To protect waiting list } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { Thread state change current->state = WAITING; list_add(&lock->wait_list, current); Add the current thread to the … waiting list schedule(); Sleep or schedule another thread … } spin_unlock(&lock->wait_lock); } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … 16 }

  17. void mutex_init (mutex_t *lock) More reading: mutex.c in Linux { lock->value = 0; list_init(&lock->wait_list); Thread waiting list spin_lock_init(&lock->wait_lock); To protect waiting list } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { Thread state change current->state = WAITING; list_add(&lock->wait_list, current); Add the current thread to the spin_unlock(&lock->wait_lock); waiting list schedule(); Sleep or schedule another thread spin_lock(&lock->wait_lock); } spin_unlock(&lock->wait_lock); } void mutex_unlock (mutex_t *lock) { … lock->value = 0; … … … 17 }

  18. void mutex_init (mutex_t *lock) More reading: mutex.c in Linux { lock->value = 0; list_init(&lock->wait_list); Thread waiting list spin_lock_init(&lock->wait_lock); To protect waiting list } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { Thread state change current->state = WAITING; list_add(&lock->wait_list, current); Add the current thread to the spin_unlock(&lock->wait_lock); waiting list schedule(); Sleep or schedule another thread 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)) Someone is waiting for the lock wake_up_process(&lock->wait_list) Wake-up a waiting thread … 18 }

  19. void mutex_init (mutex_t *lock) More reading: mutex.c in Linux { lock->value = 0; list_init(&lock->wait_list); Thread waiting list spin_lock_init(&lock->wait_lock); To protect waiting list } void mutex_lock (mutex_t *lock) { spin_lock(&lock->wait_lock); while(TestAndSet(&lock->value)) { Thread state change current->state = WAITING; list_add(&lock->wait_list, current); Add the current thread to the spin_unlock(&lock->wait_lock); waiting list schedule(); Sleep or schedule another thread 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)) Someone is waiting for the lock wake_up_process(&lock->wait_list) Wake-up a waiting thread spin_unlock(&lock->wait_lock); 19 }

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend