A question about disable ... fork

Hi,

Following code are coming from the book “Systemverilog For Verification”



task wait_for_tr(Transaction tr);
  fork
    begin
      // Wait for response, or some maximum delay
      fork : timeout_block
        wait (bus.cb.addr != tr.addr);
        #TIME_OUT $display("@%0d: Error: timeout", $time);
      join_any
      disable timeout_block;
      $display("@%0d: Addr match %d", $time, tr.addr);
    end
  join_none
endtask

initial begin
  wait_for_tr(tr0); // Spawn thread 0
  // Create a thread to limit scope of disable
  fork
    begin
      wait_for_tr(tr1);   // Spawn thread 2
      fork                // Spawn thread 3
        wait_for_tr(tr2); // Spawn thread 4
      join
      // Stop threads 1 & 2, but leave 0 alone
      #(TIME_OUT/2) disable fork;
    end
  join
end

I remembered that disable fork can’t disable grandchildren thread … however the book tell that Thread 2, 3, 4 will be disabled. Seems to me that thread 4 is grandchildren thread, so why it will be disabled as well ?

Please feel free to correct me,

Thanks,

WangYang

In reply to caowangyang:

The LRM states

If task enable statements are nested (that is, one task enables another, and that one enables yet another), then disabling a task within the chain shall disable all tasks downward on the chain.

and

The disable fork statement terminates all descendants of the calling process as well as the descendants of the process’s descendants. In other words, if any of the child processes have descendants of their own, the disable fork statement shall terminate them as well.”.

I’d say the description is pretty clear.

In reply to Tudor Timi:

Hi, Tim,

Thanks for your reply, a quick question is that, what happened if we are trying to terminates threads which all surrounded via fork … join_none ?

For example :


fork 
  fork
    task1
  join_none
 
  for loop begin
    fork
      task2
    join_none
  for loop end     
                                                                                                                                                          
  fork
    task3
  join_none                                                                                                                                                                                                                                                                                                             join // how about if we change this to join_none ?
 
@reset event 
disable fork  

Can disable fork still kill all of threads above ? Besides, how about if we change the final join to join_none ?

Thanks,

WangYang

In reply to caowangyang:

You should be able to answer this yourself by figuring out which thread the disable fork is in, and how they are related to the threads in the fork. It might be helpful to create a graph.

In reply to dave_59:

Hi, Dave,

The reason I have this question because I saw your comments in another questions, you said the disable fork won’t work, but I think the disable fork will kill all threads here, that is why I want to double check here.

Thanks

In reply to caowangyang:

It would help to provide a link to the other comments in question. I know that I have said that disable fork does not kill threads in a sibling processes. but that is not the case. here.

In reply to dave_59:

Hi, Dave,

Please refer to :

https://verificationacademy.com/forums/systemverilog/killing-fork-joinnone-present-loop#answer-43503

There are comments from you as “disable fork only kills the direct children threads, not the grandchildren.”, please feel free to correct me if I was wrong somewhere, just a little confused.

Thanks,

WangYang

In reply to caowangyang:

OK, I can see how that might be confusing confusing. What I was trying to say there as disable fork only kills the direct children of the process containing the the disable fork, which in turn kills of all the descendants of those threads. In that particular comment you linked to, the direct child processes were already terminated. The disable fork does not try to find the descendent processes - it only goes after the immediate children, so the grandchildren are left alone.

In reply to dave_59:

Thanks for your clarify, Dave, so it means we must be careful when we use disable fork with thread generated by fork … join_none, is that right ? If the direct children of the process (containing the disable fork) is ending by join … none, in which case, disable fork won’t work, since the thread has already finished, is that right ?