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

📄 fdi_que.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 5 页
字号:
#if (Q_ALIGN_CHECKING == TRUE)
         alignment_size = ((Q_DESC_PTR) queue_ptr)->alignment_shift;
         queue_ptr -= alignment_size;
#endif
         FDI_FREE(queue_ptr);

         /* Set the queue pointer to NULL and return */
         queue_ptr = NULL;

         /* Return NULL as status */
         return (Q_ID) queue_ptr;
      }

#if(SEM_CREATE_DESTROY == TRUE)
      /* create a mutex semaphore for the sem_queue_cntrl_mutex field of queue_ptr */
      /*E.5.0.702.START*/
      ((Q_DESC_PTR) queue_ptr)->sem_queue_cntrl_mutex = SEM_MTX_CREATE();
      /*E.5.0.702.End*/
#else /* SEM_CREATE_DESTROY */
      /* set the sem_queue_cntrl_mutex field equal to previously created mutex */
      /*E.5.0.702.START*/
      ((Q_DESC_PTR) queue_ptr)->sem_queue_cntrl_mutex = SEM_cntrl_mutex;
      /*E.5.0.702.End*/
#endif /* SEM_CREATE_DESTROY */

      /*E.5.0.702.START*/
      if (((Q_DESC_PTR) queue_ptr)->sem_queue_cntrl_mutex == NULL)
      /*E.5.0.702.End*/
      {
         *status_ptr = Q_ERR_SEMAPHORE;
#if(SEM_CREATE_DESTROY == TRUE)
       /* destroy the binary semaphore just created */
       /*E.5.0.702.Start*/
       SEM_DESTROY(((Q_DESC_PTR) queue_ptr)->sem_queue_cntrl_sync);
       /*E.5.0.702.End*/
      #endif /* SEM_CREATE_DESTROY */

         /* free the queue space allocated */

#if (Q_ALIGN_CHECKING == TRUE)
         alignment_size = ((Q_DESC_PTR) queue_ptr)->alignment_shift;
         queue_ptr -= alignment_size;
#endif
         FDI_FREE(queue_ptr);

         /* Set the queue pointer to NULL and return */
         queue_ptr = NULL;
      }

      /* assign the first_header_ptr field of queue_ptr to NULL */
      /* DM Lint */
      if (queue_ptr != NULL)
      {
         ((Q_DESC_PTR) queue_ptr)->first_header_ptr = NULL;
         ((Q_DESC_PTR) queue_ptr)->number_items = 0;  /* no items in queue */
      }
      /* DM Lint */

   }                                   /* ENDIF *status_ptr == Q_ERR_NONE */
   return (Q_ID) queue_ptr;

}                                      /* END Q_Create */


/*############################################################################
 *### Q_Add
 *###
 *### DESCRIPTION:
 *### Q_Add inserts two data objects into a data queue.  A check is made to
 *### see if the "queue_id" input is valid and if the objects fit in the
 *### predefined sized data queue.  Q_Add allocates memory for the item
 *### information structure and each data object.  The item information
 *### structure (Q_ITEM_INFO) is a queue structure that controls the objects
 *### in the queue.  The item information structure, "data1_ptr" info and
 *### "data2_ptr" info are copied into the new item structure buffer.
 *### The queue is locked with the sem_queue_cntrl_mutex semaphore and the object
 *### count in the queue is incremented.  The free count in the queue is
 *### decremented by the size of the new item structure created.  Q_Add calls
 *### FindItem to locate:
 *###    a) the last item of the same priority
 *### or b) the priority header before the item's priority header
 *### or c) the last priority header in the queue
 *### or d) the descriptor structure because there are no priority headers
 *### If the priority does not exist the priority header is allocated and
 *### the data object is attached as the first item pointer.  The new
 *### priority header either points to the next header or NULL and is
 *### connected to the previous header or descriptor structure.
 *### If the object is a item then the new item object is attached to the
 *### returned object's next item pointer.
 *### The sem_queue_cntrl_sync semaphore is asserted to acknowledge to the
 *### pending back ground task that an item is in the queue.  The
 *### sem_queue_cntrl_mutex semaphore is unlocked to allow others to access
 *### the queue.
 *###
 *### PARAMETERS:
 *###    IN:
 *###       queue_id    -  add item to the queue with this handle
 *###       data1_ptr   -  address of the first data item to add into queue
 *###       data2_ptr   -  address of the second data item to add into queue
 *###       data1_size  -  size of first data item to add into queue
 *###       data2_size  -  size of second data item to add into queue
 *###       priority    -  priority level to add item into queue
 *###       append_to_replace - flag; if true indicates the append is within
 *###                           an existing granularity, similar to replace
 *###    OUT:
 *###
 *### RETURNS:
 *###    Returns the following errors codes:
 *###       Q_ERR_NONE
 *###       Q_ERR_NO_SPACE
 *###       Q_ERR_INVALID_HANDLE
 *###       Q_ERR_NO_MEMORY
 *###*/
Q_ERROR
Q_Add(Q_ID queue_id,
/* E.5.0.652 Begin */
      VOID * data1_ptr,
      VOID * data2_ptr,
/* E.5.0.652 End */
      WORD data1_size,
      WORD data2_size,
      BYTE priority,
      BYTE append_to_replace)
{
   Q_HDR_PTR header_ptr;               /* temporary storage for priority */
   Q_ITEM_PTR item_ptr;                /* temporary storage for item */
   VOID_PTR data_ptr = NULL;           /* header or item ptr */
   register Q_DESC_PTR queue_ptr = (Q_DESC_PTR) queue_id;   /* ptr to queue */
   union uwords
   {
      WORD of_data_item;               /* keeps track of data item size */
      WORD of_item_info_stuff;         /* the item info package */
   }  usize;
   Q_ERROR status = Q_ERR_NONE;        /* returned status */

   WORD free_count;

#if (Q_VERIFICATION == TRUE)

   if (VALID_QUEUE_PTR(queue_ptr) == FALSE)  /* IF call ValidQueuePtr fails */
   {
      return Q_ERR_INVALID_HANDLE;
   }

#endif

   /*
    * IF the sub_command is WRITE_RESERVE do not allocate the
    * data2_size space in the queue memory
    */
#if (PACKET_DATA == TRUE)
   if (((COMMAND_PTR)data1_ptr)->sub_command == WRITE_RESERVED ||
        ((COMMAND_PTR)data1_ptr)->sub_command == WRITE_RSRVPCKT )
#else /* PACKET_DATA */
   if (((COMMAND_PTR)data1_ptr)->sub_command == WRITE_RESERVED)
#endif /* PACKET_DATA */
   {
      usize.of_item_info_stuff = data1_size + sizeof(Q_ITEM_INFO);
   }
   else if (((COMMAND_PTR)data1_ptr)->sub_command == WRITE_TRUNCATE)
   {
       usize.of_item_info_stuff = data1_size + sizeof(Q_ITEM_INFO);
   }
   else
   {
      /*
       * check is there is available space to place the data item and
       * associated structures in the queue.
       */
      if (data2_size > ((((FDI_QUEUE_SIZE - data1_size) -
                        sizeof(Q_DESCRIPTOR)) - sizeof(Q_PRIORITY_HEADER)) -
                        sizeof(Q_ITEM_INFO)))
      {
         return Q_ERR_PARAM;
      }
      usize.of_item_info_stuff = data1_size + data2_size + sizeof(Q_ITEM_INFO);
   }

   if ((usize.of_item_info_stuff + sizeof(Q_PRIORITY_HEADER)) >
      queue_ptr->free_count)
   {
      return Q_ERR_NO_SPACE;
   }

   /*
    * Moved above malloc to utilize semaphore for malloc/free control
    * protection
    */
   /* lock the sem_queue_cntrl_mutex field in queue_id */
   /*E.5.0.702.START*/
   SEM_MTX_WAIT(queue_ptr->sem_queue_cntrl_mutex);
   /*E.5.0.702.End*/
   
   /*
    * Allocate memory to build the data information structure Locate the
    * Q_ITEM_INFO structure first in the memory followed by data1 stuff and
    * then data2 stuff.  It will look like so: - Q_ITEM_INFO - data1 stuff -
    * data2 stuff
    */

   if ((item_ptr = (Q_ITEM_PTR) FDI_MALLOC(usize.of_item_info_stuff)) == NULL)
   {
      /*E.5.0.702.START*/
      SEM_MTX_POST(queue_ptr->sem_queue_cntrl_mutex);
      /*E.5.0.702.End*/
      /* Q full situation for local malloc */
      return Q_ERR_NO_SPACE;
   }

   /* Add the Q_ITEM_INFO data to the buffer at item_ptr */
   item_ptr->item_size = data1_size + data2_size;
   item_ptr->next_item_ptr = NULL;
   /*
    * Add the data1 information to the buffer at item_ptr +
    * sizeof(Q_ITEM_INFO)
    */
   MemoryMove(sizeof(Q_ITEM_INFO) + (BYTE_PTR) item_ptr, (BYTE *) data1_ptr,
              data1_size);

   /*
    * IF the sub_command is WRITE_RESERVE do not allocate the
    * data2_size space in the queue memory
    */
#if (PACKET_DATA == TRUE)
   if ( (((COMMAND_PTR)data1_ptr)->sub_command != WRITE_RESERVED) &&
        (((COMMAND_PTR)data1_ptr)->sub_command != WRITE_TRUNCATE) &&
           (((COMMAND_PTR)data1_ptr)->sub_command != WRITE_RSRVPCKT) )
 #else /* PACKET_DATA */
/* E.5.3.878 Start */
   if ((((COMMAND_PTR)data1_ptr)->sub_command != WRITE_RESERVED) 
       && (((COMMAND_PTR)data1_ptr)->sub_command != WRITE_TRUNCATE)
       )
/* E.5.3.878 End */
 #endif /* PACKET_DATA */
   {
      /*
       * Add the data2 information to the buffer at item_ptr +
       * sizeof(Q_ITEM_INFO) + data1_size
       */
      MemoryMove((sizeof(Q_ITEM_INFO) + (BYTE_PTR) item_ptr) + data1_size,
                 (BYTE *)data2_ptr, data2_size);
   }


   /* Original location of mutex wait */

   /* increment the number of items count in the descriptor table */
   queue_ptr->number_items++;

   /* Save the free count in case it needs to be restored */
   free_count = queue_ptr->free_count;

   /*
    * subtract the free space count by the size of data1, data2 and the
    * sizeof Q_ITEM_INFO structure
    */
   queue_ptr->free_count -= usize.of_item_info_stuff;

   /*
    * Find the priority and end of the item list. Return last item pointer in
    * data_ptr if priority exists, otherwise return the priority pointer at
    * the spot to insert the priority header.
    */

   status = FindItem(queue_ptr, &data_ptr, &usize.of_data_item, &header_ptr,
                     priority, Q_FIND_LAST);


   switch (status)
   {
      case Q_ERR_EMPTY:                /* priority does not exist or the queue
                                        * is empty */
      case Q_ERR_NO_PRIORITY:          /* priority does not exist */
         /*
          * IF the allocation of a priority header fails THEN free the item
          * pointer created and set the status
          */

         if ((header_ptr = (Q_HDR_PTR) FDI_MALLOC(sizeof(Q_PRIORITY_HEADER))) ==
             NULL)
         {
            /* Restore the queue ptr variables */
            queue_ptr->number_items--;
            queue_ptr->free_count = free_count;

            FDI_FREE((BYTE_PTR) item_ptr); /* free the item data space */
            /* Release queue and return error */
            /*E.5.0.702.START*/
            SEM_MTX_POST(queue_ptr->sem_queue_cntrl_mutex);
            /*E.5.0.702.End*/
            /* Q full situation for local malloc */
            return Q_ERR_NO_SPACE;
         }

         /* assign the parameter priority to this priority header */
         header_ptr->priority = priority;
         header_ptr->accum_free = 0;
         header_ptr->accum_dirty = 0;

         /* if item is being deleted set accumulated dirty space to the deleted
          * granularity */
         if (((COMMAND_PTR)data1_ptr)->sub_command == WRITE_DELETE)
         {
            header_ptr->accum_dirty = TOTALGRAN (((COMMAND_PTR)data1_ptr)->gran_needed);

         }
         else if (((COMMAND_PTR)data1_ptr)->sub_command == WRITE_TRUNCATE)
         {
            header_ptr->accum_dirty = TOTALGRAN (((COMMAND_PTR)data1_ptr)->gran_needed);
/* E.5.5.993 Start */
            /* header_ptr->accum_free = ((COMMAND_PTR)data1_ptr)->gran_needed.grp_needed + 1; */
/* E.5.5.993 End */
         }
         /* item in the queue is a write */
         else
         {
            /* set the accumulated space in the queue based on needed_space */
            if (((COMMAND_PTR)data1_ptr)->sub_command != WRITE_MODIFY)
            {
               header_ptr->accum_free = TOTALGRAN(((COMMAND_PTR)data1_ptr)->gran_needed);
            }
            /* IF this command is a replace THEN the same space is dirtied */
            if ((((COMMAND_PTR)data1_ptr)->sub_command == WRITE_REPLACE) ||
               (append_to_replace == TRUE))
            {
               header_ptr->accum_dirty = TOTALGRAN(((COMMAND_PTR)data1_ptr)->gran_needed);
            }
            /* added this condition for recording accum_dirty */
            /*
             * Test for appending to an existing single instance object and 
             * assign the accum_dirty count the existing object's data_offset
             */
             /* E.5.1.759 Begin */
            else if (((((COMMAND_PTR)data1_ptr)->sub_command == WRITE_APPEND) ||
                      (((COMMAND_PTR)data1_ptr)->sub_command == WRITE_RESERVED)) &&
               (((COMMAND_PTR)data1_ptr)->data_offset != 0) &&
               (((COMMAND_PTR)data1_ptr)->data_offset < 
               FDI_MAX_FRAG_SIZE ))
            /* E.5.1.759 End */
            {
               header_ptr->accum_dirty = 
                  TO_GRAN(((COMMAND_PTR)data1_ptr)->data_offset);
            }                          /* ENDIF appending to single inst */

         }                             /* end else sub_command not DELETE */

         /*
          * IF the returned pointer is a priority header structure THEN there
          * are no priority header structures of the current priority
          */
         if (status == Q_ERR_NO_PRIORITY)
         {
            /*
             * assign the next_header_ptr to the next priority header if
             * available otherwise its NULL

⌨️ 快捷键说明

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