⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qm.c

📁 NecluesRTX RTOS的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/************************************************************************/
/*                                                                      */
/*           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 + -