NAME
import_data -- nst interprocess communication
export_data -- nst interprocess communication
PROTOTYPES
unitptr export_data( char *pcKey, int iNumInp, char *apcInp[])
unitptr import_data( char *pcKey, int iNumOut, char *apcOut[], unitptr uHost)
ARGUMENTS
- char *pcKey
- name of shared mem segment
- int iNumInp
- nr of input fields
- char *apcInp[]
- iNumInp field formats
- int iNumOut
- nr of input fields
- char *apcOut[]
- iNumOut field formats
- unitptr uHost
- host unit
RETURN VALUE:
A pointer to the created unit or NULL in the case of an error.
SYNOPSIS:
These units allow to transfer the contents of an NST interface
between Unix processes, using named shared memory segments.
The export_data unit writes the contents of its input interface
to a named shared memory segment. The written data can be read
from any other (or the same) process via a corresponding
import_data unit (which must have been created with a matching
output interface). The export_data unit is always non-blocking,
while the input_data unit blocks when it has detected a matching
export_data unit which has not yet written any data that
the input_data unit has not yet read. This allows simple
process synchronization. On a multiprocessor machine, these
units can be used to parallelize the operation of a NST circuit.
INTERFACE OF CREATED UNIT:
The export_data unit has iNumInp input fields whose structure
is defined by the iNumInp field formats pointed to by array
apcInp[0..iNumInp-1]. Similarly, the import_data unit
has iNumOut output fields whose structure
is defined by the iNumOut field formats pointed to by array
apcOut[0..iNumOut-1].
EXECUTION OF CREATED UNIT:
Execution of the export_data unit makes the values at its
inputs available for reading by any import_data unit that
was created with the same key and with a matching interface.
The execution call of an export_data unit is always non-blocking.
The effect of execution of the import_data unit depends on
whether an export_data unit for the same key and with a matching
interface exists and has been executed since the creation of
the import_data unit. If so, the import_data unit returns at its
output pins the values that were valid at the input pins of
the matching export_data unit when it was last executed.
However, if the last execution of the matching export_data unit was
prior to the last execution call of the import_data unit
(i.e., if no new data were written by the matching export_unit
since the last invocation of the import_data unit)
the import_data unit blocks to wait until a new execution call
of the export_data unit and then returns the values valid
at the inputs of the export_data unit at that moment.
If no matching export_data unit exists the call to the
import_data unit is non-blocking and
returns without changing the values at its
output pins. If an export_data unit is deleted,
all input_data units that were waiting for this export_data
unit become unblocked and return (with their old output values
unchanged).
DESCRIPTION:
The export_data and import_data units provide the building blocks
for simple interprocess communication via shared memory segments
that can be referenced by textual names. They can be also used
within a single process to provide `global variables'' for
NST-units.
A named shared memory segment is created with each import_data unit
for which a new name was specified (if the given name is already in
use, the memory window associated with this name will be shared
by the new unit). The created memory segment is of sufficient size
to accomodate the values that the import_unit wants to read. When an
import_unit is executed, it reads its associated memory segment
and copies the contents to its output pins.
The contents in any such named memory segment
can be written by one or
more matching export_data unit(s).
This requires (1) that all output fields/pins
of the import_data unit match the corresponding input fields/pins
of the associated export_data unit in their number, order,
type and size and (2) that the import_unit and the output_unit
have specified the same name for the memory segment.
Thus, for each set of export-import units communicating in this
way the structure of the exchanged data is restricted to a fixed
struct that can contain any mixture of elements
from the five basic types float, variable
length char string, char vector, short int vector and float vector.
When an export_unit or an import_unit is created, it is not necessary
that a counterpart unit already exists. In general, execution of the
created unit first has the effect to check whether a matching counterpart
unit already exists (this is achieved via another shared memory segment that
keeps track of all existing export and import units). If not,
execution ends without any further overhead, if yes, execution
proceeds with copying or retrieving of the segment contents.
Process synchronization:
Process synchronization is achieved through the blocking behavior
of the import_units (executing an export_unit is always non-blocking).
Executing an import_unit is non-blocking as long as no matching
export_unit exists. However, as soon as a matching export_unit exists
execution of this import_unit will always wait until the export_unit
has at least been executed once since the last execution
of the import_unit. This
ensures that each execution of an import_unit is guaranteed to
return with a newly written data set.
To guarantee that between successive returns of executing an
import_unit there is precisely one execution of the
associated export_unit can be achieved with an additional
export_unit - input_unit pair in the opposite direction:
process 1: loop { export A import B }
process 2: loop { import A export B }
With this scheme, each new execution of export A can only
occur after import B has returned. Since import B has
to wait for export B and thus for import A,
both loops are kept synchronized. The additional export_unit--
import_unit pair need not transfer any data, i.e., its
two units can be created without any pins for input/output.
PARALLELIZATION:
On a two-processor machine, the export_data unit can
be used to split the processing stream into two halves
and execute them in parallel in different processes.
The necessary synchronization is automatically
achieved with a export_unit/import_unit-pair at the
start of the split, and a second such pair at its end:
process 1: export H2 process H1 import H2
process 2: import H2 process H2 export H2
Access groups:
The environment variable NSTDOMAIN can be used to restrict
access to exported data to only those processes for which
NSTDOMAIN has the same value. If NSTDOMAIN is not defined,
this value is taken to be the empty string. (This is not
yet implemented)
C-interface:
The functions
import_var, export_var (to be used in conjunction
with open_import, open_export, ipc_close)
allow to read exported values into
or to export values from C-variables (instead of pins
of an NST-unit).
Implementation notes:
In addition to the memory segments for all memory
segments that are in use there is one additional memory segment
which provides global information about each used memory segment.
This global memory segment is accessed by all import and export
units to determine which memory segments need to be maintained
and which are no longer in use. When the last export or import
unit disappears, this global memory segment is also destroyed.
STATUS:
Preliminary.
SEE ALSO:
open_export, open_import, export_var, import_var, ipc_close
FILE
/amnt/loge/users/nistaff02/nistaff/rhaschke/nst7/man/../o.linux//../foldersrc/nst_ipc.c