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


4.12 Working with System and User Stacks

The system stack of called nodes contains information on active nodes, i.e. nodes to which control had been transferred and which did not return it yet. A node can occur in several frames of the stack when the node is called recursively. The number of frames in the stack is limited by a value specified in the field stack_sz_max of structure qsmm_desc_s when creating the multinode model, which is returned by the function qsmm_get_stack_sz_max. The current number of frames in the stack can be retrieved using the following function.

Function: int qsmm_get_stack_sz (qsmm_t model)

This function returns the current number of frames in the stack of called nodes of a multinode model specified by handle model. The returned value is always non-negative.

To get an identifier of called node stored in the system stack at given depth, the following function can be used.

Function: int qsmm_get_stack_node (qsmm_t model, int depth)

This function returns the non-negative identifier of a called node stored in a frame of the system stack of a multinode model specified by handle model. The depth of the frame is specified by depth. The value of depth must be non-negative and less than a value returned by the function qsmm_get_stack_sz. The value of depth equal to 0 corresponds to current stack frame, the value of depth equal to 1 corresponds to the previous stack frame, and so on.

On failure, the function returns a negative error code. Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The node call stack is empty.

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of frames in the node call stack, which is returned by the function qsmm_get_stack_sz.

To every node in the node call stack there corresponds a node state, on the basis of which an instruction was invoked or is to be invoked by the node. The node state can be obtained using the following function.

Function: int qsmm_get_stack_state (qsmm_t model, int depth)

This function returns a non-negative node state index stored in a frame of the system stack of a multinode model specified by handle model. It is a state identified by the environment state identification engine. If the state is not identified yet, then the returned value will be equal to 0.

The depth of the frame is specified by depth. The value of depth must be non-negative and less than a value returned by the function qsmm_get_stack_sz. The value of depth equal to 0 corresponds to current stack frame, the value of depth equal to 1 corresponds to the previous stack frame, and so on.

On failure, the function returns a negative error code. Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The node call stack is empty.

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of frames in the node call stack, which is returned by the function qsmm_get_stack_sz.

To a node there might correspond an instruction class of the last instruction invoked by the node. To fetch that information from the node call stack, the following function can be used.

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

This function sets *idx_p to the index of an instruction class of the latest instruction invoked by a node. That instruction class index is fetched from a frame of the system stack of a multinode model specified by handle model. If idx_p is NULL, then *idx_p will not be set. If the node did not invoke any instruction since the corresponding frame in the stack is created, and idx_p is not NULL, then *idx_p is set to -1.

The depth of the frame is specified by depth. The value of depth must be non-negative and less than a value returned by the function qsmm_get_stack_sz. The value of depth equal to 0 corresponds to current stack frame, the value of depth equal to 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 following error codes can be returned.

QSMM_ERR_UNTIMELY

The node call stack is empty.

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of frames in the node call stack, which is returned by the function qsmm_get_stack_sz.

For the means of obtaining information on an instruction class represented by its index, see Registering Instruction Classes.

Besides the system stack, a multinode model can maintain a user stack, which contains application-specific information associated with called nodes. Ordinarily, that information includes values of variables used by instruction classes, and those values make up the execution context of a node.

A frame of the user stack is typically an instance of a structure or a union defined in an application program. The purpose of functions described below is to query or set the size of the frame. Setting the size of the frame should be performed before creating the model instance by the function qsmm_engine_create.

Function: int qsmm_get_stack_frame_sz (qsmm_t model)

This function returns the size in bytes of every user stack frame of a multinode model specified by handle model. If the user stack is not used, then 0 will be returned. This function never returns negative values.

Function: int qsmm_set_stack_frame_sz (qsmm_t model, int sz)

This function sets the size of every user stack frame of a multinode model specified by handle model to sz bytes. Size equal to 0 indicates that the user stack is not used.

The function returns a non-negative value on success or a negative error code on failure. Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance already exists.

QSMM_ERR_INVAL

The value of sz is negative.

The function qsmm_create initializes the size of user stack frame to 0.

When control is transferred to a node, a new frame in the system stack is created. If the size of user stack frame is greater than 0, then a new frame in the user stack will be also created, and the total number of frames in each stack will be equal to a value returned by the function qsmm_get_stack_sz. After creating a new frame in the user stack, the frame is initialized with zero bytes.

Event QSMM_EVT_NODE_ENTER is triggered for an instruction class set which is a node class of the node. The event handler function of the instruction class set may process that event and perform application-specific initialization of a newly created user stack frame. For example, the function may allocate dynamic arrays or copy parameters of calling the node to the frame. The parameters are usually passed via a memory block addressed by the argument qsmm_param_p of the event handler function.

When the node returns control, event QSMM_EVT_NODE_LEAVE is triggered for the instruction class set. The contents of the current stack frame, which might have been changed while processing events QSMM_EVT_ACTIVATE by event handler functions of instruction meta-classes, can be used to compute results of node invocation. Those results are usually returned via a memory block addressed by the argument qsmm_param_p of the event handler function of instruction class set. If necessary, the event handler function must perform application-specific uninitialization of the frame, e.g. free allocated memory.

To get the pointer to a frame of the user stack, the following function can be used.

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

This function sets *frame_pp to the pointer to a frame of the user stack of a multinode model specified by handle model. If frame_pp is NULL, then *frame_pp will not be set.

The depth of the frame is specified by depth. The value of depth must be non-negative and less than a value returned by the function qsmm_get_stack_sz. The value of depth equal to 0 corresponds to current stack frame, the value of depth equal to 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 following error codes can be returned.

QSMM_ERR_NOUSTACK

The user stack is not used. Most likely, a positive size of user stack frame was not set by the function qsmm_set_stack_frame_sz before creating the model instance.

QSMM_ERR_UNTIMELY

The user stack is empty.

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of frames in the user stack, which is returned by the function qsmm_get_stack_sz.

If a user stack frame is stored in the structure stack_frame_s, then the size of the frame can be set by this call:

qsmm_set_stack_frame_sz(qsmm,sizeof(struct stack_frame_s));

To get a pointer to current stack frame, use lines of code like these:

struct stack_frame_s *stack_frame_p=0;
qsmm_get_stack_frame(qsmm,0,(void **) &stack_frame_p);

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