2.4.6.1. - The Data-Pipe Facility
spec's
data_pipe() function allows integration of external code
with spec.
With the data-pipe facility, spec sends
information to the external program,
allows the external program to execute for a time, and
then receives information back from the external program.
The information can be in the form of a string or a number, and can
also include
the contents of
a spec data group or data array.
The handshaking and data transfer between spec and the data-pipe program
is done in an
overhead module included in the spec distribution that is linked
with the external code.
From spec, access to the data-pipe facility is through
the
data_pipe() function called from the user level.
Usage
is as follows.
data_pipe("?")-
Lists the currently running data-pipe processes with name and process id.
data_pipe(program, "kill")-
Kills the process associated with
program.
data_pipe(program [, args [, grp_out|arr_out [, grp_in|arr_in ]]])-
Initiates or resumes synchronous execution of the special process named
program.
If
program
contains a
/ character, then it contains the complete absolute or relative path name
of the program to run.
Otherwise the program must be in the
SPECD/data_pipe
directory,
where
SPECD is the built-in spec variable containing the path name of spec's
auxiliary file directory.
You can use the string
"." for
program
as an abbreviation for the same program name as used in the last call to
data_pipe().
The string value of
args
is made available to the user code in the program as described in
the next section.
The optional arguments
grp_out
and
grp_in
are data group numbers.
If
grp_out
is present, the contents of that group are sent to the data-pipe
program.
If
grp_in
is present, it is the number of the
data group that will receive values from the
data-pipe program.
The data-pipe program configures the size of
grp_in
for an implicit call to
data_grp()
within
data_pipe(). If the
grp_in
argument is absent, spec will not receive data-group data
from the data-pipe program.
If
grp_out
is also absent, group data won't be sent to the data-pipe program.
Even without group arguments,
the data-pipe program can still return values to spec in
the form of assigning a number or string return value to
data_pipe().
Either or both of
the data group arguments can be replaced with the
array arguments
arr_out
and
arr_in.
The arrays referred to by these arguments must be
the data arrays declared explicitly with
the
array keyword.
When sending array data to the data-pipe program, the array data
is first converted to double precision floating point format.
The received data is always double, but is converted to fit the
declared data type of
arr_in.
Only as much data as will fit into the array will be assigned.
The number of columns in
arr_in
should match the width of the data sent over by the data-pipe program.
If not, the data will still be assigned to the array, but
will be misaligned.
Prior to spec release 4.03.13, only one
data_pipe() function could be active at a time.
The user C code can be complied and linked using the command
dpmake program [UOBJ=...] [LIBS=...] [optional_make_args]
The command
dpmake is a short shell script which invokes the
make
utility using the makefile
data_pipe.mak
in the
SPECD/data_pipe
directory.
The file
program.c
will be compiled and linked with the data-pipe
overhead module, and the result
placed in an executable file named
program.
If additional object modules or libraries need to be linked, they can
be specified with the
UOBJ= or
LIBS= parameters.
If the tools provided are not sufficient, you can create custom
makefiles based on the distributed
data_pipe.mak.
After linking
program,
move it to the
SPECD/data_pipe
directory for easy access by all users.
The subroutines available from the user C code portion of the data-pipe
program are described below.
The skeleton user C-code part of the data-pipe program should contain
the following:
#include <user_pipe.h>
user_code(argc, argv)
char **argv;
{
...
}
The include file
user_pipe.h
contains declarations of the subroutines available in the C code.
The file resides in the
SPECD/data_pipe
directory.
The subroutine
user_code() is called
by the overhead part of the data-pipe program each time
data_pipe() is invoked in spec.
The parameter
argc
is set to the number of space-delimited words present in the
string value of the
args
parameter to
data_pipe(). The parameter
argv
is an array of character pointers
that point to each of the
argc
space-delimited words in the
args
string.
Alternatively, the
get_input_string() function (see below) returns the
args
string in its entirety.
The
user_code() routine will be called every time the
data_pipe() function is called from spec.
The data-pipe program does not exit between calls of
user_code(), so you should be careful about
allocating memory or opening files
each time
user_code() is called without
freeing the memory or closing the files each time
user_code() returns.
Alternatively, you can make sure such things are only done
the first time
user_code() is called.
Besides the
argc, argv technique for accessing the
args
typed in the
data_pipe() call, the following function is available
(as of spec release 4.03.13):
char * get_input_string()-
Returns a pointer to memory holding a copy of the second argument
args
entered with the call to
data_pipe().
If
data_pipe() is sending a data group or array
to the user code, the following subroutines
provide access to the data parameters and values.
int get_group_number()-
Returns the group number specified as the
data_pipe() grp_out
argument.
A -2 is returned if an array was specified.
A -1 is returned if neither data group or array was specified.
int get_group_npts()-
Returns the number of points in the
data_pipe() grp_out
or the number of rows in
arr_out.
int get_group_width()-
Returns the number of elements per point in the
data_pipe() grp_out
or the number of columns in
arr_out.
int get_input_data(double *x, int pts, int wid)-
Transfers data from the
grp_out
or
arr_out
specified in the call to
data_pipe() to the memory area indicated by the pointer
x.
The pointer
x
is treated as an array dimensioned as
x[pts][wid].
If the data group/array has more points/rows than
pts
or more elements/columns than
wid,
only as many points/rows or elements/columns
as are available in the data group/array
are copied.
Data from only a single element/column may be retrieved using
one or more calls of
get_input_elem() below.
If the data in the data group from spec is float rather than
double (which depends on spec's installation configuration),
float-to-double conversion is done within the call to
get_input_data(). The return value is the number of points/rows copied.
int get_input_elem(double *x, int pts, int el)-
Transfers one element of the data from the
grp_out
or
arr_out
specified in the call to
data_pipe() to the memory area indicated by the pointer
x.
No more than
pts
points are copied from element/column
el
of the the data group/array.
If the data in the data group from spec is float rather than
double (which depends on spec's installation configuration),
float-to-double conversion is done within the call to
get_input_data(). The return value is the number of points/rows copied.
The following subroutines allow you to send group/array data back to
spec when
data_pipe() is invoked with a
grp_in
or
arr_in
argument.
For a data group, the call to
data_pipe() will implicitly call
data_grp() to configure the size of the
return group according to the parameters set in the following subroutines.
For an array, the array must already be declared and dimensioned.
There are two ways to send group/array data back to spec.
The subroutine
set_return_data() allows you to send the entire data group in one call that passes both
a pointer to the data and the data group size to the data-pipe program
overhead code.
Alternatively, you can use the
set_return_group() subroutine to configure the data group/array size, followed by one or more
calls to
set_return_elem() to set one element/column of the data group/array at a time.
int get_return_group_number()-
Returns the group number specified as the
data_pipe() grp_in
argument.
A -2 is returned if an array was specified.
A -1 is returned if neither data group or array was specified.
void set_return_data(double *x, int pts, int wid, int last)-
Configures the return data group and copies the data at the same time.
The pointer
x
is considered as an array of dimension
x[pts][wid]
for the purpose of transferring data to the data group.
The argument
last
sets the index number of the last element added to the group, which is
used by
the various data analysis and plotting functions available in spec.
void set_return_group(int pts, int wid)-
Configures the size of the return data group without copying
data.
This subroutine must be called once before calling
set_return_elem() below.
void set_return_elem(double *x, int pts, int el, int last)-
Copies one element to the return data group, which must have been
previously configured by a call of
set_return_group(), above.
If the parameters
pts
or
el
exceed the values configured, or if the return group hasn't been configured,
the subroutine returns -1.
Otherwise zero is returned.
You can set the value that
the
data_pipe() function returns in spec
from the user C code in your
data-pipe
process.
You can have
data_pipe() return a number or a string or, if necessary, reset to command level.
If no explicit return value is assigned in the user C code,
data_pipe() returns zero.
int set_return_string(char *s)-
Sets the return value of
data_pipe() to the string
s.
This subroutine returns -1 if memory could not be obtained for the string
s,
otherwise it returns zero.
void set_return_value(double v)-
Sets the return value of
data_pipe() to the value
v.
void do_error_return()-
Calling this subroutine from the user C code causes control to pass
back to spec without returning data group or array values,
if they have been
set.
The return value of
data_pipe() will be the value set by
set_return_value() above, if such a value has been set, otherwise the return value of
data_pipe() will be -1.
This subroutine does not return.
void do_abort_return()-
Calling this subroutine from the user C code causes control to pass
back to spec without returning data group or array values, if they has been
set.
In spec, there is no return from
data_pipe(), rather spec resets to command level.
This subroutine does not return.
void do_quit_return()-
Calling this subroutine from the user C code causes control to pass
back to spec normally as if
user_code() returned normally, but the data-pipe program will then exit.
This subroutine does not return.
|