Five parallel thread are running after successfully execution of three i want to kill/disable rest two thread

// 1st > All five thread should start at 0 time
// 2nd > any of 3 will get executed
// 3rd > wanted to disable/kill/terminate rest two thread

module tb;
static int count=0;

task a1();
	$display($realtime, "	a1 start");
	#10;
	count++;
	$display($realtime, "a1 count : %0d",count);

endtask 

task a2();
	$display($realtime, "	a2 start");
	#15;
	count++;
	$display($realtime, "a2 count : %0d",count);
endtask

task a3();
	$display($realtime, "	a3 start");
	#5;
	count++;
	$display($realtime, "a3 count : %0d",count);
endtask 

task a4();
	$display($realtime, "	a4 start");
	#20;
	count++;
	$display($realtime, "a4 count : %0d",count);
endtask 


task a5();
	$display($realtime, "	a5 start");
	#25;
	count++;
	$display($realtime, "a5 count : %0d",count);
endtask 

initial begin
	fork
		a1();
		a2();
		a3();
		a4();
		a5();
	join_none
	wait(count==3)
		disable fork;
		$display("fork disabled");
end
endmodule

Hi Muku_383,

Do you see nay issue in above code? is yes, whats the issue you see?
i am able to start 5 thread and once 3 thread finished , kill the other 2 thread with above code.

Thanks

In reply to muku_383:

The given code seems to work fine with no issues.

In reply to muku_383:

There is no problem with the code shown above because each task finishes at a unique time. But you have race conditions if multiple tasks finish in the same region of a time step. Suppose you change task t4 to have a delay of #15. Then both t2 and t4 finish concurrently. It’s possible for
count
to skip from 2 to 4 and
wait(count==3)
never sees the expression being true.

Another problem is the ++ operator is a non-atomic read-modify-write operation that could be written as
count = count + 1;
. This is always a problem when you have multiple threads accessing the same global variable.

The best way of handling this is using a semaphore. Each thread does a
sema.put(1)
, and replace the
wait
with
sema.get(3);
.


In reply to dave_59:
Hi dave,
// tried to implement sema concept but not working

module tb;

semaphore key = new(1);


task a1();
	key.get(1);
	$display($realtime, " a1 start");
	key.put(1);
	$display($realtime, " a1 finished");
endtask

task a2();
	key.get(1);
	$display($realtime, " a2 start");
	key.put(1);
	$display($realtime, " a1 finished");
endtask

task a3();
	key.get(1);
	$display($realtime, " a3 start");
	key.put(1);
	$display($realtime, " a1 finished");
endtask

task a4();
	key.get(1);
	$display($realtime, " a4 start");
	key.put(1);
	$display($realtime, " a1 finished");
endtask

task a5();
	key.get(1);
	$display($realtime, " a5 start");
	key.put(1);
	$display($realtime, " a1 finished");
endtask

initial begin
	fork
		a1();
		a2();
		a3();	
		a4();
		a5();
	join_none
	key.get(3);
       	begin
		disable fork;
		$display("	fork disabled");
	end
end
endmodule

In reply to muku_383:


// Try this code
module top;

semaphore sema=new();

task a1();
	#10 $display($realtime, "\t Thread a1 compleated");	sema.put(1); 
endtask

task a2();
	#15 $display($realtime, "\t Thread a2 compleated");	sema.put(1); 
endtask

task a3();
	#5 $display($realtime, "\t Thread a3 compleated");	sema.put(1); 
endtask

task a4();
	#20 $display($realtime, "\t Thread a4 compleated");	sema.put(1); 
endtask

task a5();
	#25 $display($realtime, "\t Thread a5 compleated");	sema.put(1);
endtask

initial begin
	fork
		a1();
		a2();
		a3();
		a4();
		a5();
	join_none

	sema.get(3);
	disable fork;
	$display("fork disabled at %0t",$stime);
end

initial #100 $finish();
endmodule

In reply to Raghunandan Reddy:

other way to handle this thread? without delay?

In reply to muku_383:
If there were no delays in this example it wouldn’t make any sense. Every threat would start and end at times zero.

In reply to muku_383:

Inside fork and join_none we have multiple tasks which are generally time consuming events so in that case semaphores are helpful. But in the above program if we use functions or tasks (without any delays) calls then semaphores are not helpful. Since they will executed within zero time it is not possible to handle such threads once when we call them.

In reply to dave_59:

But in actual software, don’t we run threads interleaved and not parallel? So only one process should increment the count variable at a time. We should be able to see count == 3.

In reply to Raghunandan Reddy:

Using a semaphore implies potentially blocking threads. That is as good as time-consuming to solve the problem.
In reply to ledzep_1988:

Let’s say count is 2, and there are two processes scheduled to increment count at the same time. The first process increments count from 2 to 3. That schedules the process waiting for a change on count to wake up and evaluate its wait expression. SystemVerilog does not guarantee the order of process evaluation so it’s possible that the other process increments count to 4 before wait expression gets evaluated.

In reply to dave_59:

Hii dave,
Thanks for the clarification.

In reply to dave_59:

Okay. I get it now. Thanks for the explanantion Dave.

Hi Dave,

Using semaphore also
Suppose we change task t4 to have a delay of #15. Then both t2 and t4 finish concurrently. four thread gets completed instead of 3 expression being true.
Is this is expected.
Please correct me if I am wrong.

Thanks !!!