Next: Switching Adaptive or Random Behavior of a Multinode Model, Previous: Setting Instruction Classes Weights, Up: Executing a Multinode Model [Contents][Index]
The node call stack contains information about nodes that received control but have not yet returned it.
A node can occur in multiple stack frames if calls to the node are recursive.
The field stack_sz_max
of qsmm_desc_s
structure specifies a limit on the number of frames in the stack.
The function qsmm_get_stack_sz_max
returns this limit.
The following function returns the current number of frames in the stack.
This function returns the current number of frames in the node call stack of a multinode model. A returned value is always non-negative.
A system stack frame is the system part of a frame of node call stack. Each system stack frame contains the following information:
qsmm_node_call_default
on processing an instruction class invocation to transfer control to a node described by the next stack frame.
qsmm_node_call_default
, and that function transferred control to a node described by the next stack frame.
Use the following functions to fetch the aforementioned pieces of information from the system part of a node call stack frame at specified depth.
This function returns the non-negative identifier of a called node stored in the system part of a frame of node call stack of a multinode model at depth. Depth 0 corresponds to the current stack frame, depth 1 corresponds to the previous stack frame, and so on.
On failure, the function returns a negative error code. Currently, the function can return the following error codes.
QSMM_ERR_UNTIMELY
The node call stack is empty.
QSMM_ERR_INVAL
The argument depth is negative or greater than or equal to the number of frames in the node call stack returned by the function qsmm_get_stack_sz
.
This function returns the non-negative index of a node state stored in the system part of a frame of node call stack of a multinode model at depth.
The environment state identification engine has identified this node state.
If the state is yet unknown (this is the case if the event handler of an instruction class set called this function on processing an event QSMM_EVT_NODE_ENTER
), the function returns 0.
Depth 0 corresponds to the current stack frame, depth 1 corresponds to the previous stack frame, and so on.
On failure, the function returns a negative error code. Currently, the function can return the following error codes.
QSMM_ERR_UNTIMELY
The node call stack is empty.
QSMM_ERR_INVAL
The argument depth is negative or greater than or equal to the number of frames in the node call stack returned by the function qsmm_get_stack_sz
.
This function retrieves the index of instruction class of last instruction invoked by a node of a multinode model.
The function fetches that index from the system part of a frame of node call stack at depth.
If idx_p is not NULL
, the function sets *idx_p to a fetched index.
If the node did not yet invoke any instructions since creating the frame in the node call stack, the fetched index is -1.
Depth 0 corresponds to the current stack frame, depth 1 corresponds to the previous stack frame, and so on.
The function returns a non-negative value on success or a negative error code on failure. Currently, the function can return the following error codes.
QSMM_ERR_UNTIMELY
The node call stack is empty.
QSMM_ERR_INVAL
The argument depth is negative or greater than or equal to the number of frames in the node call stack returned by the function qsmm_get_stack_sz
.
See Registering Instruction Classes, for the means of obtaining information about an instruction class specified by its index.
A user stack frame is the user part of a frame of node call stack. The user stack frame contains application-specific information associated with a called node for handling instruction invocations—the execution context of this node.
A user stack frame is typically an instance of a structure declared in an application program.
The purpose of functions described below is to query or set the size of this frame.
You should set the size of a user stack frame before creating the model instance by the function qsmm_engine_create
.
This function returns the size (in bytes) of the user part of each frame in the node call stack of a multinode model. If the model does not use that user part, the function returns 0.
This function sets the size of the user part of each frame in the node call stack of a multinode model to sz bytes. Size 0 means that the model does not use the user part.
The function returns a non-negative value on success or negative error code QSMM_ERR_UNTIMELY
if the model instance already exists.
The function qsmm_create
initializes to 0 the size of the user part of each frame in the node call stack.
On calling a node, the function qsmm_node_call_default
creates a new frame in the node call stack and initializes the user part of this frame with zero bytes.
The new frame becomes the current stack frame.
The function qsmm_get_stack_sz
returns the total number of frames in the node call stack.
After creating the current stack frame, qsmm_node_call_default
sends an event QSMM_EVT_NODE_ENTER
to the instruction class set of a called node.
The event handler of that instruction class set can process the event to perform application-specific initialization of that current frame.
For example, the event handler may allocate dynamic arrays or copy the parameters of calling the node to the frame.
A pointer to those parameters is an argument of qsmm_node_call_default
, and this function passes this pointer to the event handler via its argument qsmm_param_p
.
While executing the node, qsmm_node_call_default
sends events QSMM_EVT_ACTIVATE
to the instruction meta-classes of instructions selected for invocation by the instruction emitting engine.
The event handler of an instruction meta-class can call the function qsmm_return_to_caller_node
to return control from the node or the function qsmm_set_continue
with flag
equal to 0 or the macro QSMM_TERMINATE
to return control from all nodes in the node call stack.
On returning control from the node, qsmm_node_call_default
sends an event QSMM_EVT_NODE_LEAVE
to the instruction class set of that node.
The event handler of that instruction class set can use the content of the current stack frame to compute the results of node invocation and return those results via a memory block addressed by qsmm_param_p
.
If necessary, the event handler performs application-specific uninitialization of the current frame—for example, frees allocated dynamic arrays.
After sending the event QSMM_EVT_NODE_LEAVE
, qsmm_node_call_default
destroys the current stack frame and exits.
If after this destruction the node call stack is not empty, the previous frame in the stack becomes the current frame.
Use the following function to get a pointer to the user part of a frame in the node call stack.
This function retrieves a pointer to the user part of a frame in the node call stack of a multinode model at depth.
If frame_pp is not NULL
, the function sets *frame_pp equal to this pointer.
A program can access a memory block with size in bytes returned by the function qsmm_get_stack_frame_sz
addressed by the pointer.
Depth 0 corresponds to the current stack frame, depth 1 corresponds to the previous stack frame, and so on.
The function returns a non-negative value on success or a negative error code on failure. Currently, the function can return the following error codes.
QSMM_ERR_NOUSTACK
The model does not have user part in the frames of node call stack.
Use the function qsmm_set_stack_frame_sz
to specify positive size of that user part before creating the model instance.
QSMM_ERR_UNTIMELY
The node call stack is empty.
QSMM_ERR_INVAL
The argument depth is negative or greater than or equal to the number of frames in the node call stack returned by the function qsmm_get_stack_sz
.
If the structure stack_frame_s
holds a user stack frame, use the following call to set the size of this frame:
qsmm_set_stack_frame_sz(qsmm,sizeof(struct stack_frame_s));
To get a pointer to a current stack frame, use these lines:
struct stack_frame_s *stack_frame_p=0; qsmm_get_stack_frame(qsmm,0,(void **) &stack_frame_p);