[SystemVerilog] Difference between `wait(cb.signal == 1'b1)` and `@(cb iff cb.signal == 1'b1)`

In reply to harsh pandya:

This race is very similar to the following example

module top;
  bit a,b;
  initial begin
    wait(a)
    @(b)
    $display("done1");
  end
  initial begin
    #20 
    a = 1; 
    b = 1;
    $display("done2");
  end
endmodule

Because the two assignments to a and b execute in the same region, the SystemVerilog LRM section 4.7 Nondeterminsim allows the wait statement to proceed as soon as the first assignment to a occurs, or it could proceed after the display of “done2”. If it chooses the latter, the change to b has already happened and @(b) never resumes.

If I put a #0 between the two assignments, or use a non-blocking assignment to b, then @(b) is guaranteed to execute before the change to b, so “done1” will be displayed.