In reply to zz8318:
This is exactly the purpose of semaphores
task automatic B; // if this is a class method, it is already automatic
static semaphore s = new(1);
while (!s.try_get) @(posedge clk);
// mutex body of B
#0 s.put();
endtask
The #0 is needed to meet your requirement that only B task execute per cycle. I normally don’t like using #0’s because of their tendency to accumulate, but that won’t happen here if get() is synchronous to a clock edge.