function f (lock A, lock B) { acquire A; ...; acquire B; ...; release A; ...; release B }If f can be run by multiple threads using the same locks, is there a potential deadlock? Explain. If so, how would you fix the code?
Allocation | Request | Available | ||||||||||
U | V | W | X | U | V | W | X | U | V | W | X | |
A | 0 | 0 | 1 | 0 | 2 | 0 | 0 | 1 | 2 | 1 | 0 | 0 |
B | 2 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ||||
C | 0 | 1 | 2 | 0 | 2 | 1 | 0 | 0 |
sem t_p, m_p, t_m; sem done; void smoker(sem* ingredients_needed) { while(1) { P(ingredients_needed); smoke(); V(done); } } void agent() { while(1) { sem* new_ingredients = pick_ingr_pair(); // picks t_p, m_p, or t_m V(new_ingredients); P(done); } }Three threads run smoker with t_p, m_p, and t_m. Another thread runs agent.
Process | Burst Time | Priority |
P1 | 10 | 3 |
P2 | 1 | 1 |
P3 | 2 | 3 |
P4 | 1 | 4 |
P5 | 5 | 2 |
0 | 5 | 10 | 15 | 19 | ||||||||||||||||
FCFS | P1 | P2 | P3 | P4 | P5 | |||||||||||||||
SJF | P2 | P4 | P3 | P5 | P1 | |||||||||||||||
P | P2 | P5 | P1 | P3 | P4 | |||||||||||||||
RR | P1 | P2 | P3 | P4 | P5 | P1 | P3 | P5 | P1 | P5 | P1 | P5 | P1 | P5 | P1 |
P1 | P2 | P3 | P4 | P5 | |
FCFS | 10 | 11 | 13 | 14 | 19 |
SJF | 19 | 1 | 4 | 2 | 9 |
P | 16 | 1 | 18 | 19 | 6 |
RR | 19 | 2 | 7 | 4 | 14 |
P1 | P2 | P3 | P4 | P5 | |
FCFS | 0 | 10 | 11 | 13 | 14 |
SJF | 9 | 0 | 2 | 1 | 4 |
P | 6 | 0 | 16 | 18 | 1 |
RR | 9 | 1 | 5 | 3 | 9 |
Average Waiting Time | |
FCFS | 9.6 |
SJF | 3.2 |
P | 8.2 |
RR | 5.4 |
monitor Account { int balance; procedure void withdraw(int amount) { if(amount > balance) throw new Exception("Insufficient Funds"); balance = balance - amount; } procedure void deposit(int amount) { balance = balance + amount; } procedure void transfer(int amount, Account dest) { self.withdraw(amount); dest.deposit(amount); } }
procedure void transfer(int amount, Account dest) { acquire(transaction_lock); self.withdraw(amount); dest.deposit(amount); release(transaction_lock); }or by moving the transaction outside of the monitor and acquiring the locks in some order:
procedure void transfer(int amount, Account source, Account dest) { if(source < dest) { acquire(source); acquire(dest); } else { acquire(dest); acquire(source); } source.withdraw(amount); dest.deposit(amount); release(source); release(dest); }Incidentally, there is another bug in this monitor. Because it uses signed integers and does not check for insufficient funds upon deposit, transfer (and deposit) may be used to leave an account with a negative balance.