It is best to start from the root thread, which is started by an initial or always block.
module top;
initial begin : i1
fork : f1
#10 $display("f1")
join_none
t1();
end
endmodule
The disable fork statements kills the children of the currently running thread. (i.e the thread executing the disable fork statement).
In this example, the parent thread is enclosed by the scope i1. It starts a child thread f1, then calls task t1. Inside task t1, the first fork starts threads a1 and a2, then the second fork starts a3 and a3. Since the second fork has join_any, it waits for one of the threads to complete before executing the disable fork statement.
The disable fork will not execute until thread a3 completes at time 5, and only threads f1 and a4 are still active and will be killed. Had you used join_none instead of join_any, or used longer delays then the disable fork statement would have also killed threads a1, a2 and a3.
The threads a4 and a5 are forked after the disable fork, so it has no effect on those threads.