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

/local/homes/rhaschke/nst7/man/../o.linx86//../foldersrc/nst_ipc.c