PtThread
defines the interface for threads in Ptolemy. The class PosixThread
provides an implementation based on the POSIX thread standard. Other implementations using AWESIME [Gru91] or Solaris [Pow91] are possible. The class PNThread
is a typedef
that determines which implementation is used in the PN domain. Changing the underlying implementation simply requires changing this typedef
. The class DataFlowProcess
, which is derived from PNThread
, implements a dataflow process. The Star
object associated with an instance of DataFlowProcess
is activated repeatedly, just as a dataflow actor is fired repeatedly to form a process.
10.2.1 The PtThread Class
PtThread
is an abstract base class that defines the interface for all thread objects in Ptolemy. Because it has pure virtual methods, it is not possible to create an instance of PtThread
. All of the methods are virtual so that objects can be referred to as a generic PtThread
, but with the correct implementation-specific functionality.PtThread
has three public methods.
virtual void initialize() = 0;
This method initializes the thread and causes it to begin execution.
virtual void runAll();
This method causes all threads to begin (or continue) execution.
virtual void terminate() = 0;
This method causes execution of the thread to terminate.
PtThread
has one protected method.
virtual void run() = 0;
This method defines the functionality of the thread. It is invoked when the thread begins execution.
PosixThread
provides an implementation for the interface defined by PtThread
. It does not implement the pure virtual method run
, so it is not possible to create an instance of PosixThread
. This class adds one protected method, and one protected data member to those already defined in PtThread
.
static void* runThis(PosixThread*);
This static method invokes the run
method of the referenced thread. This provides a C interface that can be used by the POSIX thread library.
pthread_t thread;
A handle for the POSIX thread associated with the PosixThread
object.
pthread_attr_t attributes;
A handle for the attributes associated with the POSIX thread.
int detach;
A flag to set the detached state of the POSIX thread.
initialize
method shown below initializes attributes, then creates a thread. The thread is created in a non-detached state, which makes it possible to later synchronize with the thread as it terminates. The controlling thread (usually the main thread) invokes the terminate
method of a thread and waits for it to terminate. The priority and scheduling policy for the thread are inherited from the thread that creates it, usually the main thread. A function pointer to the runThis
method and the this
pointer, which points to the current PosixThread
object, are passed as arguments to the pthread_create
function. This creates a thread that executes runThis
, and passes this
as an argument to runThis
. Thus, the run
method of the PosixThread
object is the main function of the thread that is created. The runThis
method is required because it would not be good practice to pass a function pointer to the run
method as an argument to pthread_create
. Although the run
method has an implicit this
pointer argument by virtue of the fact that it is a class method, this is really an implementation detail of the C++ compiler. By using the runThis
method, we make the pointer argument explicit and avoid any dependencies on a particular compiler implementation.
runAll
method, which is shown below, allows all threads to run by lowering the priority of the main thread. If execution of the threads ever stops, control returns to the main thread and its priority is raised again to prevent other threads from continuing.
terminate
method shown below causes the thread to terminate before deleting the PosixThread
object. First it requests that the thread associated with the PosixThread
object terminate, using the pthread_cancel
function. Then the current thread is suspended by pthread_join
to give the cancelled thread an opportunity to terminate. Once termination of that thread is complete, the current thread resumes and deallocates resources used by the terminated thread by calling pthread_detach
. Thus one thread can cause another to terminate by invoking the terminate
method of that thread.
DataFlowProcess
is derived from PosixThread
. It implements the map higher-order function (see the PN Domain chapter in the User's Manual). A DataFlowStar
is associated with each DataFlowProcess
object.
DataFlowStar& star;
This protected data member refers to the dataflow star associated with the DataFlowProcess
object.
star
member to establish the association between the thread and the star.
run
method, shown below, is defined to repeatedly invoke the run
method of the star associated with the thread, just as the map function forms a process from repeated firings of a dataflow actor. Some dataflow stars in the BDF domain can operate with static scheduling or dynamic, run-time scheduling. Under static scheduling, a BDF star assumes that tokens are available on control inputs and appropriate data inputs. This requires that the scheduler be aware of the values of control tokens and the data ports that depend on these values. Because our scheduler has no such special knowledge, these stars must be properly configured for dynamic, multi-threaded execution in the PN domain. Stars in the BDF domain that have been configured for dynamic execution, and stars in the DDF domain dynamically inform the scheduler of data-dependent firing rules by designating a particular input PortHole
with the waitPort
method. Data must be retrieved from the designated input before invoking the star's run
method. The star's run
method is invoked repeatedly, until it indicates an error by returning FALSE
.