Channel operation invocation
SYNOPSIS#include <udi.h>void udi_mei_call ( udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops_num, udi_index_t vec_idx, ... );
ARGUMENTS gcb is a pointer to the control block passed to the actual channel operation.
meta_info is a pointer to this metalanguage's udi_meta_info structure, which can be used to uniquely identify this metalanguage.
meta_ops_num is the metalanguage-defined identifier for the ops vector type to which this operation belongs. (See udi_mei_ops_vec_template_t.)
vec_idx is the index into the ops vector identified by meta_ops_num that corresponds to this operation, starting from zero. (A vec_idx of zero corresponds to the udi_channel_event_ind_op_t at the beginning of every ops vector type, and is not actually used in metalanguage libraries.)
... are zero or more additional metalanguage-specific parameters for this channel operation. This will be passed to the callee-side entry point in the target driver, immediately following the control block argument.
DESCRIPTION This function is called from within a portable front-end stub to implement a channel operation. udi_mei_call prepares the control block for transfer to the target region, possibly reallocating the space for the control block and/or its scratch space. It also arranges for the corresponding entry point to be called in the target region, either "directly" (w/o queuing) or as a queued or cross-domain indirect operation.
If the environment chooses to (and is able to) make a direct call, udi_mei_call will make use of the corresponding direct-call stub in the metalanguage library to make the actual call to the target region with the appropriate parameters. This is the highest performance path and is thus specially optimized. The direct-call stub (of type udi_mei_direct_stub_t) simply takes the arguments pointed to by the var-args arglist, and calls the indicated function with these arguments.
There are many reasons why the environment might not use a direct call. Some of these include excess call depth, busy regions and domain crossings. All other things being equal, ownership transfer for transferable objects can be handled with the direct case.
If udi_mei_call does not make a direct call, it must first marshal any call-dependent parameters into the marshalling space of the control block. It can determine the number and type of these parameters from the marshal_layout in the ops template for this operation. The ops template can be located by a combination of either gcb->channel and vec_idx or meta_init and meta_ops_num. (Providing both of these sets of values to udi_mei_call allows for a double-check that the correct types of channel and control block were passed to the channel operation.)
After the control block is queued, copied across domains, or subject to any further processing needed by the environment, it will eventually need to be passed to the target region with the appropriate call-dependent parameters. This is done by calling the appropriate back-end stub (of type udi_mei_backend_stub_t) in the metalanguage library. The back-end stub unmarshals the parameters from the marshalling space (pointed to by marshal_space) and calls the driver entry point with these parameters
references udi_mei_ops_vec_template_t, udi_channel_event_ind, udi_mei_direct_stub_t, udi_mei_backend_stub_t, UDI_MEI_STUBS