VLSI DV Interview Puzzles · All levels
Deadlock-Free Request Loop with try_put/try_get
Does this pattern avoid deadlock? Explain why it still needs timing control and bounded retries.
Puzzle
Difficulty: Medium · Puzzle 6 of 6 · Topic: Semaphore & Mailbox Puzzles
Does this pattern avoid deadlock? Explain why it still needs timing control and bounded retries.
Code
systemverilog
module tb;
mailbox #(int) req_mb = new(2);
mailbox #(int) rsp_mb = new(2);
semaphore lock = new(1);
task producer();
int rsp;
int sent = 0;
while (!sent) begin
if (req_mb.try_put(7)) sent = 1;
else #1;
end
while (!rsp_mb.try_get(rsp)) #1;
$display("[%0t] rsp=%0d", $time, rsp);
endtask
task consumer();
int req;
while (!req_mb.try_get(req)) #1;
lock.get(1);
rsp_mb.put(req + 1);
lock.put(1);
endtask
initial fork
producer();
consumer();
join
endmoduleHint
No thread holds lock while waiting on mailbox progress.
Step-by-step solution
diagram
1) Producer retries try_put/try_get with #1 backoff, so no zero-delay spin.
2) Consumer acquires lock only around non-blocking short critical section.
3) No circular wait exists between lock and mailbox operations.
4) Pattern is deadlock-resistant but still needs timeout/limits for robustness.Answer
Answer: Yes, this avoids classic lock+blocking-mailbox deadlock. It should print rsp=8 at a finite time, but production code still needs timeout guards.
Why candidates get it wrong
Deadlock-free does not mean livelock-free or starvation-free under all load patterns.
Interviewer follow-up
What timeout and error-report strategy would you add for regression triage?