OS: Windows NT/2000, Sun Solaris 2.5, 2.6, 2.7, HP-UX
10.20
DEFECT #: N/A
PATCH #: N/A
REFERENCES:
N/A
CREATED: 2000.08.24 REVISED: N/A
QUESTION: How can
you create threads dynamically in Rose RealTime?
ANSWER: Dynamic
Thread creation in Rose RealTime models is easily accomplished using two
platform-independent API calls*, one which creates a thread controller, and
another which creates the actual physical thread.
I.
Creating a Thread Controller
All threads in a Rose RealTime model that
will host Capsule references must run an instance of either RTPeerController
or RTCustomController. RTPeerController is the default thread
controller used for most applications. Users who need more control
over the thread may wish to use RTCustomController. More information
about RTCustomController is available in the online help.
The
constructors for RTCustomController and RTPeerController are defined
as:
As you
can see, each constructor requires a pointer to an RTDebugging object,
present in models with Target Observability enabled. The debugger is
available through a call to 'context()->debugger()' In
applications where Target Observability has been compiled-out of the Target
RTS, dynamic thread creation will not be effected. The second
parameter is the symbolic name for the thread on which the controller will
run. This name can be any string the developer deems applicable, and
will not be used in subsequent calls to the RTS.
A complete constructor
call will look like:
RTPeerController * dynController;
char * threadName = "myPhysicalThread" dynController =
new RTPeerController( context()->debugger(), threadName ); //could have
called RTCustomController
From this point on, dynController represents a
valid RTPeerController object.
II Creating a Physical Thread
After
a thread controller is instantiated, it can be used as a starting point at
which to create a physical thread. Physical thread creation is
accomplished by a platform-independent RTThread object. The
constructor for this class is defined as:
RTThread::RTThread( RTJob * job, int stack_size, int prio )
Since both
RTPeerController and RTCustomController classes are derived from the RTJob
class, we pass the RTPeerController * dynController (created above) as the
first parameter. The stack size is user-defined, but the default value
for Rose RealTime models is 20000. The third attribute is the thread
priority. Constants have been defined in
$(ROSERT_HOME)\C++\TargetRTS\target\<targetname>\ RTTarget.h which are
recommended for use here. The default priority for threads in Rose
RealTime models is defined in DEFAULT_MAIN_PRIORITY.
A complete
call to the thread contstructor will look like:
RTThread * dynThread; dynThread = new RTThread(
dynController, 20000, DEFAULT_MAIN_PRIORITY ); //dynController defined
above
III Using The New Physical Threads
Once a thread and its
controller is instantiated, capsules can be instantiated to run on the
thread via calls to the Frame service. An example of a call to the
Frame service is:
RTActorIde( RTActorRef &
capsule_role, const RTTypedValue & info, RTController * log_thread = 0,
int index = -1 )
The first two parameters indicate the capsule role to
be incarnated, and any information to be passed to the newly-instantiated
capsule reference. The third parameter is the RTPeerController
created in step I. The final parameter indicated the index and is
used in case of a replicated capsule reference. A complete Frame
service call is:
frame.incarnate( worker, (void *)0,
dynController, -1 ) //where frame is the name of a Frame port in the
containing capsule reference //where 'worker' is the
name of the capsule reference
IIII Destroying the physical
threads
Before destroying a physical thread, it is recommended that all
capsule references incarnated on the thread be explicitly destroyed by a
call to Frame::destroy.
Threads and their controllers should be
destroyed opposite to their creation order. That is, since the
controller was created first, it should be destroyed last.
Destruction of the controller and thread is as simple as using the delete
command to invoke the class destructor functions. To destroy the thread
and controller created above use:
if
(frame.destroy(worker)) // returns non-zero to indicate successful
destruction { delete
dynThread; delete dynController;
}
IV Example Model
A model demonstrating this technique is
available on the support website or through technical
support.
*Please note that dynamic thread creation uses some calls that
are internal to the TargetRTS. Some of the calls are not part of the public
API and hence, may change without prior notice. Also, if changed, a
migration path might not necessarily be provided by Rational. Use of this
example is at the discretion of the customer and is not officially
supported.
For more information contact Rational Customer Support This report was generated on Sun Dec 3 17:14:27 2000 (Local
server time).