Doubt regarding wait fork

I want to know in the following piece of code. If check_trans(tr2) has another initial begin…end block and had a set of child threads.I want to know if the “wait fork” statement waits for only check_trans(tr1), check_trans(tr2) and check_trans(tr3) to complete or will it wait for the child threads of check_trans(tr2) also to complete.

task run_t;
fork
check_trans(tr1);
check_trans(tr2);
check_trans(tr3);
join_none
wait fork;
endtask

In reply to Ravi007:

No. It wait for all the child process for finish

In reply to kranthi445:

In reply to Ravi007:
No. It wait for all the child process for finish

That is not correct.

9.6.1 Wait fork statement[br]
The wait fork statement blocks process execution flow until all immediate child subprocesses (processes created by the current process, excluding their descendants) have completed their execution.

The key phrase is immediate child subprocesses which includes active child processes that might have been spawned before calling run_t.

In reply to dave_59:

In the above code wait fork is for waiting for the threads and its descendants which are triggered in the current task(which is “a” in the attached code), it is not waiting for the thread which is spawned before (which is “e” in the attached code). Correct me if am wrong.

Regards
Kranthi

In reply to kranthi445:

That is not correct. (3 out of 4 simulators agree with me)

Calling a task or function does not create independent threads. Only a fork statement can do that.

In reply to dave_59:

I’m super confused. In my statements below, pay special care to my wording to help discern my mistakes. im using the eda design as the example.

task a();
fork
b(); // process p1
c(); // process p2
join_none
wait fork;
$display(“done”);
endtask

The current process (I’ll call p0) creates two child processes (aka sub-processes), one of which calls b(), the other calls c(); The current processes then proceeds down to the wait fork, where it “blocks process execution flow until all immediate child subprocesses (processes created by the current process, excluding their descendants) have completed their execution.”

I would expect the current process to unblock immediately, as process p1, and p2 have no blocking statements, as the processes that THEY initiate are descendants to the current process. and done would be printed at time 0.

In reply to bmorris:

The wait fork is not not waiting for p1 or p2.
The point of the example was to show the effect of processes spawned before calling task a. The current process (p0) is the root process spawned by the initial block. It first calls task e, and the process it spawns is still active when the wait fork executes.

In reply to dave_59:

What about disable fork ?

Does the same happen in the case of disable fork ?

task run_t;
  fork // MAIN THREAD
    check_trans(tr1);
    check_trans(tr2);
    check_trans(tr3);
  join_none
  disable fork;
endtask

If check_trans(tr2) has another initial begin…end block and had a set of child threads.I want to know if the “disable fork” statement disables only the threads spawned (// MAIN THREAD) or will it disable the threads spawned by child threads of check_trans(tr2).

In reply to Ravi007:

it disables the threads spawned by child threads of check_trans(tr2) as well as all the decsendants of the MAIN Thread.

In reply to dave_59:

IN kranthi’s code can I say there is a RACE Condition between the 4 $displays at TIME 0 for b,c,d & e
OR Do the Descendants ( tasks b , c , d ) get Priority over Active Child Process ( task e )

In reply to Have_A_Doubt:

Tasks are not processes. Only the initial block and the individual statements or blocks inside a fork are processes. In that example, all the $display statements are separate descendant processes with the exception of the $display(“done”). That is in the parent initial block process. The b,c, and e without delay are sibling processes and in a race situation. The d without delay is another descendent level down in the process hierarchy, so it should be the last to display at time 0.

In reply to dave_59:

I added $time in each of the $displays ( AT TIME 0 )and I get

AT 0 b without delay
AT 0 d without delay
AT 0 c without delay
AT 0 e without delay

I get the same OUTPUT on Questa 10.6_1 as well as NC 15.20

Also if i were to Reverse the task calls inside initial begin i.e I call a() first then e()
I get the following

AT 0 b without delay
AT 0 d without delay
AT 0 done
AT 0 e without delay
AT 0 c without delay

I was expecting:

AT 0 b without delay // RACE
AT 0 c without delay // RACE
AT 0 done // Waits ONLY FOR Immediate Child Process so d doesn’t count
AT 0 e without delay // As its Part of Child process , sibling of b & c
AT 0 d without delay // LAST Since its a Descendant