NAME
thread_box -- create unit for concurrent processing
PROTOTYPE
unitptr thread_box( int iNumInputs, char **ppcInpFmt, int iNumOutputs, char **ppcOutFmt, unitptr uHost)
ARGUMENTS
- int iNumInputs
- - not documented in source --
- char **ppcInpFmt
- - not documented in source --
- int iNumOutputs
- - not documented in source --
- char **ppcOutFmt
- - not documented in source --
- unitptr uHost
- host unit
SYNOPSIS:
Provides a container whose execution will start running
its contents as a detached thread, thus making execution
of the container always non-blocking.
INTERFACE OF CREATED UNIT:
iNumInputs input fields of formats specified in
ppcInpFmt[] and iNumOutputs output fields of formats
specified in ppcOutFmt[].
EXECUTION OF CREATED UNIT:
Any execution call to this unit will be non-blocking.
When the unit is inactive, execution will change the state
to active and create a new thread that runs the subcircuit
contained within the thread_box. The thread will run in detached
mode and concurrently to the operation of other NST units.
While the thread is running, the unit will remain in
active mode. During this time, any further execution calls
will cause no operation (i.e., will not create further
threads). When the last subunit in the thread_box has
completed execution, the thread will terminate and the unit
will return to inactive mode, so that a new thread can be
started with exec_unit(). Under Neo, an active thread_box
cannot be opened in the editor.
CONTROL MODES:
The control mode NST_THREAD_CANCEL, when applied while the
thread_box is active, will send a cancel request to the running
thread. This will terminate the thread at the next cancellation
point (resetting the thread_box back into the inactive state).
At the same time, NST_THREAD_CANCEL is sent to all subunits
recursively.
A cancellation point is reached whenever a subunit has
been executed completely. In addition, subunits may contain
further cancellation points to offer an earlier response to
cancellation.
In Neo, the 'x' field will toggle between execution and
cancellation. When the subcircuit is, e.g., a long loop,
this allows to start/stop the iteration over the subunits.
EXCEPTION HANDLING:
A thread_box confines the propagation of any NST exception that
was thrown by a subunit inside: when the normal NST exception
handling mechanism could not handle the exception by a handler
inside the thread_box, an error message will be issued and
the thread will become cancelled (i.e., the thread_box returns
to the inactive state).
REMOVAL OF ACTIVE THREAD_BOX:
Removing a thread_box in active state (i.e., while its subcircuit
is executing) causes first a cancellation request; after its
thread has terminated, the unit will become removed.
RESTRICTIONS:
The ability of concurrent processing of subunits comes with some
restrictions.
1. Admissible subunits inside a thread_box must have been implemented
as thread-safe. NST recognizes thread-safe units from the property
flag P_is_thread_safe (cf. nst3.h).
An attempt to execute a non-thread-safe subunit within the thread
of a thread box will cause a NST runtime exception.
In Neo, non-thread-safe units inside a thread_box are indicated
by special highlighting.
A container unit is considered as thread-safe by NST
if and only if all of its subunits are thread-safe.
2. There is currently no synchronization scheme for the access of
input and output pins of a thread_box, i.e., outside units may
happen to access values during a read or write operation of
subunits inside the thread_box. Whenever this is a problem,
properly synchronized data exchange is possible with the
thread-safe var_def/var_set/var_get units.
3. references of use_method and use_named units will not be
allowed to cross thread_box boundaries. Referencing inside
the same thread_box is ok and thread safe.
GRAPHICS:
In NST, all graphics currently runs through a single thread.
The only thread-safe graphics units are currently plot_xy,
plot_vec, plot_series, plot3d, draw_sym. If these are
concurrent with a graphics unit (such as input_window) in
the main thread, they will block as long as the main thread
is waiting for input.
The input_window unit is declared as non-thread-safe to
avoid complications that would arise from its embedding in
thread_boxes. However, input_windows can be used in the main
thread and they may embed the windows of the thread-safe
NST plot units. In this way, several active threads may
display their graphics output in a shared input_window
running simultaneously in the main thread.
NESTING OF THREAD_BOX INSTANCES:
Thread boxes can be nested in the obvious manner.
CONCURRENCY AND THE PROG_UNIT
The prog_unit has been made thread-safe in a currently very simple
manner: a mutex ascertains that there can at any time only a
single prog_unit instance be running, i.e., currently prog_unit
calls are treated as "atomic" and will block execution of prog_unit
instances in all other threads for the entire duration of their
execution (this coarse granularity should become reduced down to
individual prog_unit statements somewhen in the future).
This may cause difficulty with recursion!!
MAPPING/UNMAPPING A CIRCUIT UNDER NEO:
When a circuit becomes unmapped, any active thread_boxes
will have their threads unaffected (i.e., these will continue
to run).
IMPLEMENTATION NOTE:
Beware of mutex blocking due to inadvertent cancellation points
(caused, e.g., by system routines such as printf etc. which even
may come from simple debugging statements)
in mutex protected code sections! Will require to push
suitable cleanup routines!
EXAMPLES:
STATUS:
Preliminary.
SEE ALSO:
FILE
/amnt/loge/users/nistaff02/nistaff/rhaschke/nst7/man/../o.linux//../nstsrc/nst_thread_box.c