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

📄 fdi_que.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ###########################################################################
###  Intel Confidential 
###  Copyright (c) Intel Corporation 1995-2002
###  All Rights Reserved.
###  -------------------------------------------------------------------------
###  Project: Flash Data Integrator
###
###  Module: QUEUE.C - FDI Data Queue - prioritized message queue
###                    currently uses malloc, has scanning capabilities.
###
###  $Archive: /FDI/SRC/COMMON/fdi_que.c $
###  $Revision: 77 $
###  $Date: 10/21/04 11:40a $
###  $Author: Pcmcgint $
###  $NoKeywords $
########################################################################### */

/*                                                               
 *****************************************************************
 * NOTICE OF LICENSE AGREEMENT                                    
 *                                                                
 * This code is provided by Intel Corp., and the use is governed  
 * under the terms of a license agreement. See license agreement  
 * for complete terms of license.                                 
 *                                                                
 * YOU MAY ONLY USE THE SOFTWARE WITH INTEL FLASH PRODUCTS.  YOUR 
 * USE OF THE SOFTWARE WITH ANY OTHER FLASH PRODUCTS IS EXPRESSLY 
 * PROHIBITED UNLESS AND UNTIL YOU APPLY FOR, AND ARE GRANTED IN  
 * INTEL'S SOLE DISCRETION, A SEPARATE WRITTEN SOFTWARE LICENSE   
 * FROM INTEL LICENSING ANY SUCH USE.                             
 *****************************************************************
 */                                                               


/* ### Include Files
 * ################################# */

#include "fdi_type.h"
#ifdef CUSTOM_SEM_MTX
#include "fdi_mutx.h"
#endif
#include "fdi_ext.h"
#include "fdi_int.h"
#include "fdi_que.h"
/*#undef RESERVED_FIX*/

/* ### Local Declarations
 * ################################# */

#ifndef WORD_LOW
#define  WORD_LOW(x)          (WORD)((x) & 0xffff)
#endif

#if (PACKET_DATA == TRUE)
#include "fdi_pckt.h"
#endif /* PACKET_DATA */

/* This mask is used to round values down to the nearest multiple of 4
 */
#define   Q_DWORD_MASK   0xFFFC

/*
 * This define is used to calculate the absolute minimum number of bytes
 * needed to implement a queue of two items of one byte in size.  If the
 * Q_ALIGN_CHECKING option is set, an extra three bytes will be added to
 * this value to allow for possible alignment shifting.
 */
/* E.5.1.762 Start */
/* Moved Q_MIN_SIZE to que.h */
/*
#if (Q_ERROR_CHECKING == TRUE)
#if (Q_ALIGN_CHECKING == FALSE)
#define   Q_MIN_SIZE  (sizeof(Q_DESCRIPTOR) + sizeof(Q_PRIORITY_HEADER) + \
                         (((sizeof(Q_ITEM_INFO) + 3) & Q_DWORD_MASK) * 2))
#else
#define   Q_MIN_SIZE  (sizeof(Q_DESCRIPTOR) + sizeof(Q_PRIORITY_HEADER) + \
                         (((sizeof(Q_ITEM_INFO) + 3) & Q_DWORD_MASK) * 2) + 3)
#endif
#endif
*/
/* E.5.1.762 End */

#if (Q_VERIFICATION == TRUE)
#define VALID_QUEUE_PTR(x)  (BYTE)((x != NULL) && \
                                   (x->queue_id ==WORD_LOW( (DWORD)x)) && \
                                   (x->queue_signature == WORD_LOW(~(DWORD)x)))
#endif

/*
 * Maximum number of queue items that can be in the queue at any given time.
 * Used to reserve allocation control arrays
 */
/*
 * Calculate the maximum number of queue items that is possible.  This is used
 * used to determine the size of, and manage, the queue control structures.
 * Two worst case possibilities exist: 1) All zero data COMMAND items w/
 * PRIORITY_HEADERs, 2) All zero data COMMAND items w/o PRIORITY_HEADERs.  If
 * the size of PRIORITY_HEADER is less than that of COMMAND plus
 * Q_ITEM_INFO, then case 1 is the worst case, otherwise case 2. Two or Three
 * is added to account for the q_descriptor and q_priority_header, plus 1 for
 * rounding.
 */
 /* E.5.0.690 Begin */ 
/*remove MAX_QUEUE_ITEMS, now defined in fdi_que.h*/
/*   #define MAX_QUEUE_ITEMS ( (sizeof(Q_PRIORITY_HEADER) < (sizeof(COMMAND) + \
                         sizeof(Q_ITEM_INFO))) ? \
    ((((FDI_QUEUE_SIZE - sizeof(Q_DESCRIPTOR)) / \
                        ((sizeof(Q_PRIORITY_HEADER) + \
                         sizeof(COMMAND)) + \
                         sizeof(Q_ITEM_INFO))) * \
                         2) + \
                         2) : \
      (((FDI_QUEUE_SIZE - sizeof(Q_DESCRIPTOR)) - \
                         sizeof(Q_PRIORITY_HEADER)) / \
                        (sizeof(COMMAND) + \
                         sizeof(Q_ITEM_INFO)) + \
                         3) )
                         */
/* E.5.0.690 End */ 
/* ### Type Definitions
 * ################################# */

/*
 * Node Control for FindItem
 */
typedef enum
{
   Q_FIND_LAST,
   Q_VISIT_EACH
}  Q_NODE_CNTRL;


/* ### Local Declarations
 * ################################# */
/* Queue buffer and allocation/free controls */
static BYTE      Queue[FDI_QUEUE_SIZE];
static BYTE_PTR  QitemPtr[MAX_QUEUE_ITEMS];
static WORD      QitemSize[MAX_QUEUE_ITEMS];
static BYTE      QitemFree[MAX_QUEUE_ITEMS];

/* ### Local Functions
 * ################################# */

static Q_ERROR
FindItem(Q_DESC_PTR, VOID_PTR_PTR, WORD_PTR, Q_HDR_PTR *, BYTE, Q_NODE_CNTRL);


/* ### Global Declarations
 * ################################# */
/*E.5.0.603.START*/ 
/* define these semaphores for static creation by GSM_MS initialization */

#if(SEM_CREATE_DESTROY == FALSE)
   SEM_ID SEM_cntrl_sync;              /* true when an item is in queue */
   SEM_MTX_ID SEM_cntrl_mutex;         /* mutex queue protection */
#endif
/*E.5.0.603.END*/

/* ### Global Functions
 * ################################# */

#if (PERF_TEST == TRUE)
extern SEM_ID PERF_SEM_Bkgd;           
#endif

/*############################################################################
 *### Q_Create
 *###
 *### DESCRIPTION:
 *###    This function is used to create a new message queue.  The capacity
 *###    of queue is given by the "max_queue_size" input parameter.  The
 *###    maximum queue size is 65532 bytes, and the minumum size is 32 bytes.
 *###    The size includes both the space required for storing messages in
 *###    the queue, as well as space for the internal control structures
 *###    needed to manage the queue.  The size should be an even multiple of
 *###    of 4 bytes -- if it is not, it will be rounded down to the nearest
 *###    multiple.
 *###
 *###    If the application wants to control where the queue gets its memory
 *###    from, it can supply a pointer to memory for the queue to use in the
 *###    "queue_memory" input parameter.  If the "queue_memory" parameter
 *###    is NULL, the queue code will attempt to allocate its own
 *###    memory by using the MALLOC macro.  Allowing the queue to manage
 *###    its own memory is the preferred method, since it better protects the
 *###    queue's data from other processes, though this may not be possible
 *###    (or feasible) on every system.
 *###
 *###    An error code will be returned indicating the success or failure
 *###    of the queue creation in the parameter "status_ptr".
 *###
 *###    The queue's identifier is returned from the function as a Q_ID type.
 *###
 *### PARAMETERS:
 *###    IN:
 *###       max_queue_size    -  The maximum total size of the queue (bytes)
 *###       queue_memory_ptr  -  Address of memory to use for queue
 *###    OUT:
 *###    Returns the following errors codes in the status_ptr
 *###       Q_ERR_NONE
 *###       Q_ERR_INVALID_SIZE
 *###       Q_ERR_NO_MEMORY
 *###       Q_ERR_SEMAPHORE
 *###
 *### RETURNS:
 *###       the queue's identifier
 *###*/
Q_ID
Q_Create(WORD max_queue_size, VOID_PTR queue_memory_ptr, Q_ERROR * status_ptr)
{
   register BYTE_PTR queue_ptr = (BYTE_PTR) queue_memory_ptr;
#if (Q_ALIGN_CHECKING == TRUE)
   WORD alignment_size;
#endif

   /* Initialize queue allocation controls */
   WORD i;

   QitemFree[0] = 1;
   QitemPtr [0] = Queue;
   QitemSize[0] = FDI_QUEUE_SIZE;
   for (i=1 ; i<MAX_QUEUE_ITEMS ; i++)
   {
     QitemFree[i] = 0;
     QitemPtr [i] = NULL;
     QitemSize[i] = 0;
   }

   *status_ptr = Q_ERR_NONE;

/* E.5.1.762 Start */
   /* 
      Make sure the requested queue size is not too big.  This can
      prevent users from adding more than FFFF items to the queue. 
   */
#if (Q_ERROR_CHECKING == TRUE)
   if (max_queue_size > Q_MAX_SIZE)
   {
      *status_ptr = Q_ERR_INVALID_SIZE;
   }
/* E.5.1.762 End */

   /* Make sure the requested queue size is not too small */
   if (max_queue_size < Q_MIN_SIZE)
   {
      *status_ptr = Q_ERR_INVALID_SIZE;
   }
#endif

   if (*status_ptr == Q_ERR_NONE)
   {
      /*
       * If a memory region was supplied by the caller, store its address in
       * the memory referenced by the "queue_id_ptr" input parameter.
       */
      if (queue_memory_ptr != NULL)
      {
         queue_ptr = (BYTE_PTR) queue_memory_ptr;
      }
      /*
       * Otherwise, try to allocate the memory needed for a  queue of the
       * requested size, and store its address.
       */
      else
      {
#if (Q_ALIGN_CHECKING == FALSE)
         /* Allocate descriptor */

         queue_ptr = (BYTE_PTR) FDI_MALLOC(sizeof(Q_DESCRIPTOR));
#else
         /*
          * Add 3 to the MALLOC size to ensure that we will be able to align
          * our data regardless of where the memory is allocated from.  If the
          * memory is not available, return an error.
          */

         queue_ptr = (BYTE_PTR) FDI_MALLOC(sizeof(Q_DESCRIPTOR) + 3);
#endif
         /* If the memory is not available, return an error */
         if (queue_ptr == NULL)
         {
            *status_ptr = Q_ERR_NO_MEMORY;
            return (Q_ID) queue_ptr;
         }
      }                                /* ENDELSE queue_memory == NULL */

#if (Q_ALIGN_CHECKING == TRUE)
      /*
       * Make sure that the queue memory is DWORD aligned.  The number of
       * bytes that the memory pointer is advanced will be stored in
       * alignment_size.
       */
      alignment_size = (WORD) ((4 - (DWORD) queue_ptr) & 3);
      queue_ptr += alignment_size;
      /*
       * If the memory was provided externally, subract the shift count  from
       * the total known size of the provided memory region.
       */
      if (queue_memory_ptr != NULL)
      {
         max_queue_size -= alignment_size;
      }
#endif

      max_queue_size &= Q_DWORD_MASK;
      /*
       * keep track of the free space in the descriptor table with the field
       * free_count
       */
/* Queue align checking was not originally used to adjust free count here */
#if (Q_ALIGN_CHECKING == FALSE)
      ((Q_DESC_PTR) queue_ptr)->free_count = max_queue_size -
       sizeof(Q_DESCRIPTOR);
#else
      ((Q_DESC_PTR) queue_ptr)->free_count = max_queue_size -
       (sizeof(Q_DESCRIPTOR) +3);
#endif
      /*
       * Indicate whether the memory was allocated or provided by the caller,
       * and how far the pointer was shifted for alignment.
       */
/* E.5.1.762 Start */
#if (Q_ALIGN_CHECKING == TRUE)
      if (queue_memory_ptr != NULL)
      {
         ((Q_DESC_PTR) queue_ptr)->alignment_shift = 0;
      }
      else
      {
         ((Q_DESC_PTR) queue_ptr)->alignment_shift = (BYTE) alignment_size;
      }
#endif
/* E.5.1.762 End */

#if (Q_VERIFICATION == TRUE)
      /* Set up the validation entries in the queue descriptor */
      ((Q_DESC_PTR) queue_ptr)->queue_id = WORD_LOW((DWORD) queue_ptr);
      ((Q_DESC_PTR) queue_ptr)->queue_signature = WORD_LOW(~(DWORD) queue_ptr);
#endif

#if(SEM_CREATE_DESTROY == TRUE)
      /* create a binary semaphore for the sem_queue_cntrl_sync field of queue_ptr */
        /*E.5.0.702.Start*/
       ((Q_DESC_PTR) queue_ptr)->sem_queue_cntrl_sync = SEM_BIN_CREATE();
        /*E.5.0.702.End*/
#else /* SEM_CREATE_DESTROY */
      /*E.5.0.702.Start*/
      ((Q_DESC_PTR) queue_ptr)->sem_queue_cntrl_sync = SEM_cntrl_sync;
       /*E.5.0.702.End*/
#endif /* SEM_CREATE_DESTROY */
       /*E.5.0.702.Start*/
      if (((Q_DESC_PTR) queue_ptr)->sem_queue_cntrl_sync == NULL)
       /*E.5.0.702.End*/
      {
         *status_ptr = Q_ERR_SEMAPHORE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -