Difficulty: Medium · Puzzle 4 of 6 · Topic: Deadlock Scenario Puzzles: Objection and Phase Stalls
Collector thread blocks forever on mailbox get(). Producer thread silently died earlier. Find the control-flow interaction that causes permanent stall.
mailbox #(pkt) mbx = new();
task run_phase(uvm_phase phase);
fork
begin : producer
repeat (100) begin
pkt p = new();
build_pkt(p);
mbx.put(p);
end
end
begin : consumer
forever begin
pkt q;
mbx.get(q); // blocks forever after producer dies
process_pkt(q);
end
end
join_any
disable producer; // bug: kills producer early, consumer still infinite
endtaskjoin_any plus asymmetric disable is a common stall generator.
1) Inspect fork control semantics and note consumer is unbounded forever loop.
2) Observe join_any returns as soon as either branch exits.
3) disable producer can terminate source while consumer continues blocking on empty mailbox.
4) Introduce termination protocol: sentinels, stop event, or bounded consumer loop.
5) Use try_get with wait/event/backoff if producer lifetime is dynamic.Answer: Bug: fork control kills producer while consumer remains infinite blocking on mailbox.get. Fix: define explicit shutdown handshake or bounded loops so both threads terminate coherently.
The stall is in TB orchestration, not mailbox implementation.
How would you redesign this with one supervisor thread owning both producer/consumer lifetime?