21 - Concurrency II (1)OutlineSleep and WakeupProducer-Consumer with Sleep / WakeupSemaphoresMidterm TopicsAnnouncementsReading:Producer-Consumer with Sleep / WakeupSemaphoresMidterm TopicsProcessesAddress SpaceFilesSystem CallsKernelProcessorMechanismProcess SwitchingCreation / TerminationMechanismPreemptive vs NonpreemptiveCategories / GoalsFCFSSJF / SRTNRound RobinPriority SchedulingMultiple QueuesReal-Time SchedulabilityRate MonotonicEarliest Deadline FirstApproachesRace ConditionsCritical SectionsInterrupt DisableLock VariablesStrict AlternationPeterson's Solution40% MCQOne, double-sided, 8.5 x 11 page handwritten notes15% Processes/Threads15% Concurrency30% SchedulingBusy-Waiting SolutionsThread Control BlockAdvantages / DisadvantagesAmdahl's LawCreation / TerminationProcess StateProcess Control BlockCPU UtilizationMemory AccessMemoryI/O DevicesBusesOS Concepts and StructuresMidterm FormatComputer HardwareSystem CallsProcessesThreadsSchedulingConcurrencyRecap: Busy WaitingBusy Waiting wastes CPU cycles.What if we simply stop the process instead?Putting the process to sleep:Almost same as "yield" for threadsNote: processes may also be woken up by signalsRecap: Producer-Consumer ProblemOne solution: Wakeup-Waiting BitThe old incorrect solution:Becomes:Do we still have a problem here?We still have a race condition on count.Problem: this doesn't generalize with moreprocesses.A semaphore is a shared data type that acts as ashared counter variable.How can we use this for the producer consumerproblem?decrements the semaphore, or suspendsexecution if semaphore is already 0increments the semaphore, or wakes up asuspended process if one is presentactual semaphore implementations vary bykernel APIFor this lecture, we'll treat the semaphore asa shared integer for simplicity, but theygenerally have much more associated state.Add a bit to the PCB that saves a wakeup call.The next time the process calls sleep, it will onlysleep if the bit was not set.Wakeup signal is ignored if a process is alreadyawake, so both processes may end up sleepingforever.The issue is the lost wakeup signal!Again, consider a single producer and singleconsumer with a buffer size > 1Software-Only Lock(incorrect solution)TSL LockproducerconsumerSleep / WakeupMid-semester feedback survey is out.2 extra points on the midterm for 70% completion(by section)PA 2 grade release has been a bit delayed.PA 3 autograder will be fixed later today.Midterm on Friday1)3)4)2)MOS 2.4.1 - 2.4.3while (1) { while (lock != 0); lock = 1; do_critical(); lock = 0; do_noncritical();}while (1) {enter_critical: asm(TSL r1, lock); asm(CMP r1, #0); asm(JNE enter_critical); do_critical();exit_critical: asm(MOV lock, #0); do_noncritical();}--Move the process to the blocked queue until itis woken up again.caller yields CPU until another processwakes it upcaller wakes up another sleeping process(can't wake itself up)(wakeup ignored if redundant)This requires syscalls, since moving a processbetween states can only be done by the kernel.sleepwakeupGiven:Producers and consumers share the buffera fixed-size buffer B with N elementscounts number of available shared resources2 allowed operations:Pseudocode:Note:Example:counts number of events (e.g. pending wakeups)P producer processesproducers put data in the bufferconsumers remove data from the bufferC consumer processes---------ProducerConsumerConsumerConsumerProducerProducerN itemsbuffer B// shared variablesconst int size;int count = 0;item_t buffer[size];// shared variablesconst int size;int count = 0;item_t buffer[size];// init:buffer = []count = 0(p) line 2: A = produce()(p) line 3: if (count == N)(p) line 5: push(buffer, A)(p) line 6: count++(p) line 7: if (count == 1)(p) line 8: wakeup(consumer)(c) line 2: if (count == 0)(c) line 2: sleep()// producerwhile (1) { item_t A = produce(); while (count == size); push(buffer, A); count++;}// producerwhile (1) { item_t A = produce(); if (count == size) sleep(); push(buffer, A); count++; if (count == 1) wakeup(consumer);}atomic down(semaphore) if semaphore == 0: sleep(semaphore) else: semaphore-- endifatomic up(semaphore) if semaphore == 0 and has_sleeping(semaphore): wakeup(semaphore) else: semaphore++ endifif (count == N) sleep();0:1:2:3:4:5:6:7:8:9:3:4:0:1:2:3:4:5:6:7:8:9:// consumerwhile (1) { while (count == 0); item_t A = pop(buffer); count--; consume(A);}// consumerwhile (1) { if (count == 0) sleep(); item_t A = pop(buffer); count--; if (count == size-1) wakeup(producer); consume(A);}producerconsumer// init:buffer = []count = 0(p) line 2: A = produce()(p) line 3: if (count == N)(p) line 5: push(buffer, A)(p) line 6: count++(p) line 7: if (count == 1)(p) line 8: wakeup(consumer)(c) line 2: if (count == 0)(c) line 2: sleep()downupinit: s = 2proc1: down(&s)proc1: down(&s)proc1: down(&s)proc2: up(&s)proc2: up(&s)proc1: down(&s)proc1proc2Complete the diagram:PCB and TCB separate unless otherwise statedTime of Check,Time of Userunningblockedconsumer ignores wakeupconsumer sleepsWW bit setno sleep, unset WW bits = 1s = 1s = 0s = 0proc 1 sleepsproc 1 wakeup (s = 0)