Thursday, 9 October 2014

How to control or check the status of threads generated by fork

In a complex TB designs, if multiple fork-join blocks are involved, it becomes difficult to manage threads generated by all the forks. SV provides a way to check the status of these threads or to suspend or kill threads. ( we are aware of only 'wait fork' and 'disable fork' commands to control fork-join)

A process is a built-in class that allows one process to access and control another process once it has started.Users can declare variables of type process and safely pass them through tasks or incorporate them into other objects. The prototype for the process class is as follows:

class process;
   typedef enum { FINISHED, RUNNING, WAITING, SUSPENDED, KILLED }state;
   static function process self();
   function state status();
   function void kill();
   task await();
   function void suspend();
   function void resume();
   function void srandom( int seed );
   function string get_randstate();
   function void set_randstate( string state );
endclass


Objects of type process are created internally when processes are spawned. Users cannot create objects of type process; attempts to call new shall not create a new process and shall instead result in an error. The process class cannot be extended. Attempts to extend it shall result in a compilation error. Objects of type process are unique; they become available for reuse once the underlying process terminates and all references to the object are discarded.
The self() function returns a handle to the current process, that is, a handle to the process making the call. The status() function returns the process status, as defined by the state enumeration:

— FINISHED means the process terminated normally.
— RUNNING means the process is currently running (not in a blocking statement).
— WAITING means the process is waiting in a blocking statement.
— SUSPENDED means the process is stopped awaiting a resume.
— KILLED means the process was forcibly killed (via kill or disable).
The kill() function terminates the given process and all its subprocesses, that is, processes spawned using fork statements by the process being killed. If the process to be terminated is not blocked waiting on some other condition, such as an event, wait expression, or a delay, then the process shall be terminated at some unspecified time in the current time step.

The await() task allows one process to wait for the completion of another process. It shall be an error to call this task on the current process, i.e., a process cannot wait for its own completion.

The suspend() function allows a process to suspend either its own execution or that of another process. If the process to be suspended is not blocked waiting on some other condition, such as an event, wait expression, or a delay, then the process shall be suspended at some unspecified time in the current time step.
Calling this method more than once, on the same (suspended) process, has no effect.

The resume() function restarts a previously suspended process. Calling resume on a process that was suspended while blocked on another condition shall resensitize the process to the event expression or to wait for the wait condition to become true or for the delay to expire. If the wait condition is now true or the
original delay has transpired, the process is scheduled onto the Active or Reactive region to continue its execution in the current time step. Calling resume on a process that suspends itself causes the process to continue to execute at the statement following the call to suspend.

The methods kill() , await() , suspend() , and resume() shall be restricted to a process created by an initial procedure, always procedure, or fork block from one of those procedures.

The following example starts an arbitrary number of processes, as specified by the task argument N. Next, the task waits for the last process to start executing and then waits for the first process to terminate. At that point, the parent process forcibly terminates all forked processes that have not yet completed.



task automatic do_n_way( int N );
   process job[] = new [N];
   foreach (job[j])
   fork
      automatic int k = j;
      begin
         job[k] = process::self(); ... ;
      end
   join_none
  foreach (job[j])
     wait( job[j] != null ); // wait for all processes to start
      job[1].await(); // wait for first process to finish
  foreach (job[j]) begin
     if ( job[j].status != process::FINISHED )
     job[j].kill();
end
endtask

For more info: refer SV LRM

No comments:

Post a Comment