📄 qm.c
字号:
/************************************************************************/
/* */
/* Copyright 1990-1992 by Accelerated Technology */
/* */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the */
/* subject matter of this material. All manufacturing, reproduction, */
/* use, and sales rights pertaining to this subject matter are */
/* governed by the license agreement. The buyer or recipient of this */
/* package, implicitly accepts the terms of the license. */
/* */
/************************************************************************/
/************************************************************************/
/* */
/* FILE DESCRIPTION */
/* */
/* This file contains routines that facilitate information transfer */
/* between nucleus tasks. */
/* */
/* ROUTINES */
/* */
/* QM_Initialize Queue Manager Initialization*/
/* QM_Place_On_List Place on suspension list */
/* QM_Remove_From_List Remove from suspension list */
/* QM_Retrieve_Item Get an item from the queue */
/* QM_Place_Item Place item in the queue */
/* QM_Force_Item_In_Front Force an item on the front */
/* QM_Wait_To_Place Wait to place an item */
/* QM_Wait_To_Retrieve Wait to retrieve an item */
/* QM_Wait_To_Retrieve_Mult Wait to retrieve an item */
/* from multiple queues */
/* QM_Max_Queues Returns the maximum queues */
/* QM_Retrieve_Status Returns the queue status */
/* */
/* NOTES */
/* */
/* Routines except for QM_Max_Queues and QM_Retrieve_Status */
/* expect that interrupts are locked out upon invocation. */
/* */
/************************************************************************/
/* Define necessary include files. */
#include "nu_defs.h" /* General constants */
#include "in_extr.h" /* Initialize references */
#include "qm_defs.h" /* Data structure defns */
#include "sk_extr.h" /* Scheduler routine defs */
/* Define global data structures to the queue manager. */
/* The pointer "QM_QCB_List" is used to point to the list of
sequentially allocated Queue Control blocks. */
struct QM_QUEUE_CONTROL_STRUCT *QM_QCB_List;
/* The signed variable "QM_Total_Queues" contains the total number of
system queues, as derived from the queue definition list. */
signed int QM_Total_Queues;
/* Declare internal function prototypes. */
void QM_Place_On_List(struct QM_SUSPENSION_STRUCT **ptr_head_ptr,
struct QM_SUSPENSION_STRUCT **ptr_tail_ptr,
struct QM_SUSPENSION_STRUCT *suspend_ptr);
void QM_Remove_From_List(struct QM_SUSPENSION_STRUCT **ptr_head_ptr,
struct QM_SUSPENSION_STRUCT **ptr_tail_ptr,
struct QM_SUSPENSION_STRUCT *suspend_ptr);
/************************************************************************/
/* */
/* FUNCTION "QM_Initialize" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function is used to allocate and initialize all of the */
/* queue control blocks and the total number of queues variable. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* INP_Initialize High level initialization */
/* */
/* ROUTINES CALLED */
/* */
/* INP_Memory_Alloc Allocate initial memory */
/* IND_Major_System_Error System error */
/* */
/* INPUTS */
/* */
/* IN_System_Queues Queue definition structure */
/* */
/* OUTPUTS */
/* */
/* QM_QCB_List[] Queue Control Blocks */
/* QM_Total_Queues Total number of queues */
/* */
/************************************************************************/
void QM_Initialize(struct IN_QUEUE_DEFINITION_STRUCT *queue_list)
{
int i; /* Working variable */
int bytes; /* Number of bytes to alloc */
/* Initialize the queue management variables. */
QM_Total_Queues = 0; /* Initially, no queues */
/* Figure out how many queues there are in the system. */
while (queue_list[QM_Total_Queues].in_number_of_items != END_OF_LIST)
{
/* Increment the total queue count. */
QM_Total_Queues++;
}
if (QM_Total_Queues)
{
/* Allocate memory for all of the QCBs. */
bytes = sizeof(struct QM_QUEUE_CONTROL_STRUCT) * QM_Total_Queues;
QM_QCB_List = (struct QM_QUEUE_CONTROL_STRUCT *)
INP_Memory_Alloc(bytes);
}
/* Initialize each QCB. This includes allocation of the actual queue
area. */
for (i = 0; i < QM_Total_Queues; i++)
{
/* Initialize the QCB entry. */
QM_QCB_List[i].qm_queue_id = i;
QM_QCB_List[i].qm_queue_items = queue_list[i].in_number_of_items;
QM_QCB_List[i].qm_item_size = queue_list[i].in_size_of_item;
QM_QCB_List[i].qm_queued = 0;
QM_QCB_List[i].qm_queue_full = NU_FALSE;
/* Check the item size for a bad value. */
if (queue_list[i].in_size_of_item == 0)
IND_Major_System_Error(NU_QUEUE_ITEM_SIZE);
/* Allocate the memory for the actual queue. */
bytes = sizeof(unsigned int) * queue_list[i].in_number_of_items *
queue_list[i].in_size_of_item;
/* Initialize the pointers into the memory. */
QM_QCB_List[i].qm_queue_start =
(unsigned int *) INP_Memory_Alloc(bytes);
QM_QCB_List[i].qm_queue_front = QM_QCB_List[i].qm_queue_start;
QM_QCB_List[i].qm_queue_back = QM_QCB_List[i].qm_queue_start;
QM_QCB_List[i].qm_queue_end = QM_QCB_List[i].qm_queue_start +
queue_list[i].in_number_of_items * queue_list[i].in_size_of_item;
/* Finish initializing the rest of the structure. */
QM_QCB_List[i].qm_full_wait_head = NU_NULL;
QM_QCB_List[i].qm_full_wait_tail = NU_NULL;
QM_QCB_List[i].qm_empty_wait_head = NU_NULL;
QM_QCB_List[i].qm_empty_wait_tail = NU_NULL;
}
} /* end of QM_Initialize */
/************************************************************************/
/* */
/* FUNCTION "QM_Place_On_List" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function is used to link a suspension structure on a */
/* specified linked list. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* QM_Wait_To_Place Wait to place an item */
/* QM_Wait_To_Retrieve Wait to retrieve an item */
/* */
/* ROUTINES CALLED */
/* */
/* None */
/* */
/* INPUTS */
/* */
/* ptr_head_ptr Pointer to list head ptr */
/* ptr_tail_ptr Pointer to list tail ptr */
/* suspend_ptr Pointer to suspend block */
/* */
/* OUTPUTS */
/* */
/* Suspension List */
/* */
/************************************************************************/
void QM_Place_On_List(struct QM_SUSPENSION_STRUCT **ptr_head_ptr,
struct QM_SUSPENSION_STRUCT **ptr_tail_ptr,
struct QM_SUSPENSION_STRUCT *suspend_ptr)
{
/* Determine if there is another suspension block to update. */
if (*ptr_tail_ptr != NU_NULL)
{
/* Yup, there are others currently suspended, place the new
suspension request at the end. */
(*ptr_tail_ptr) -> qm_next_susp = suspend_ptr;
suspend_ptr -> qm_prev_susp = *ptr_tail_ptr;
suspend_ptr -> qm_next_susp = NU_NULL;
*ptr_tail_ptr = suspend_ptr;
}
else
{
/* Place the suspension request right up front. */
*ptr_head_ptr = suspend_ptr;
*ptr_tail_ptr = suspend_ptr;
suspend_ptr -> qm_prev_susp = NU_NULL;
suspend_ptr -> qm_next_susp = NU_NULL;
}
} /* end of QM_Place_On_List */
/************************************************************************/
/* */
/* FUNCTION "QM_Remove_From_List" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function is used to unlink a suspension structure from a */
/* specified linked list. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* QM_Retrieve_Item Get an item from the queue */
/* QM_Place_Item Place item in the queue */
/* */
/* ROUTINES CALLED */
/* */
/* None */
/* */
/* INPUTS */
/* */
/* ptr_head_ptr Pointer to list head ptr */
/* ptr_tail_ptr Pointer to list tail ptr */
/* suspend_ptr Pointer to suspend block */
/* */
/* OUTPUTS */
/* */
/* Suspension List */
/* */
/************************************************************************/
void QM_Remove_From_List(struct QM_SUSPENSION_STRUCT **ptr_head_ptr,
struct QM_SUSPENSION_STRUCT **ptr_tail_ptr,
struct QM_SUSPENSION_STRUCT *suspend_ptr)
{
/* Determine if this suspension block is still linked in. */
if ((suspend_ptr -> qm_prev_susp != NU_NULL) ||
(suspend_ptr -> qm_next_susp != NU_NULL) ||
(suspend_ptr == *ptr_head_ptr))
{
/* Check the previous pointers. */
if (suspend_ptr -> qm_prev_susp != NU_NULL)
{
/* Link the previous suspension block to the next. */
(suspend_ptr -> qm_prev_susp) -> qm_next_susp =
suspend_ptr -> qm_next_susp;
}
else
{
/* We are deleting the head node, adjust the head pointer. */
*ptr_head_ptr = suspend_ptr -> qm_next_susp;
/* Adjust the head of the list. */
if (*ptr_head_ptr != NU_NULL)
(*ptr_head_ptr) -> qm_prev_susp = NU_NULL;
}
/* Check the next pointers. */
if (suspend_ptr -> qm_next_susp != NU_NULL)
{
/* Link the next suspension block to the previous. */
(suspend_ptr -> qm_next_susp) -> qm_prev_susp =
suspend_ptr -> qm_prev_susp;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -