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
endmodule

Hint

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?

Related topics