Next: , Previous: , Up: Executing a Multinode Model   [Contents][Index]


4.3.6 Working with the Node Call Stack

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.

Function: int qsmm_get_stack_sz (qsmm_t model)

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:

Use the following functions to fetch the aforementioned pieces of information from the system part of a node call stack frame at specified depth.

Function: int qsmm_get_stack_node (qsmm_t model, int 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.

Function: int qsmm_get_stack_state (qsmm_t model, int depth)

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.

Function: int qsmm_get_stack_instr_class (qsmm_t model, int depth, int *idx_p)

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.

Function: size_t qsmm_get_stack_frame_sz (qsmm_t model)

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.

Function: int qsmm_set_stack_frame_sz (qsmm_t model, size_t sz)

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.

Function: int qsmm_get_stack_frame (qsmm_t model, int depth, void **frame_pp)

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);

Next: , Previous: , Up: Executing a Multinode Model   [Contents][Index]