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

📄 fdi_que.c

📁 Flash file system
💻 C
📖 第 1 页 / 共 5 页
字号:
   {
      /*
       * 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_cntrl_mutex field in queue_id */
   SEM_MTX_WAIT(queue_ptr->sem_cntrl_mutex);

   /*
    * 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)
   {
      SEM_MTX_POST(queue_ptr->sem_cntrl_mutex);
      /* 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_RSRVPCKT) )
 #else /* PACKET_DATA */
   if (((COMMAND_PTR)data1_ptr)->sub_command != WRITE_RESERVED)
 #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 */
            SEM_MTX_POST(queue_ptr->sem_cntrl_mutex);
            /* 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);

         }
         /* 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
             */
            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 < 
               TO_BYTES(MAX_NUM_UNITS_PER_FRAG)))
            {
               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
             */
            header_ptr->next_header_ptr =
             ((Q_HDR_PTR) data_ptr)->next_header_ptr;

            /* connect the created header to the previous header. */
            ((Q_HDR_PTR) data_ptr)->next_header_ptr = header_ptr;

            /* assign the item pointer to the header pointer */
            header_ptr->first_item_ptr = item_ptr;
         }
         /*
          * ELSE the returned pointer is the queue descriptor THEN there are
          * no priority header structures of a higher priority then the
          * current priority or the queue is empty
          */
         else
         {
            /*
             * assign the next_header_ptr to the next priority header if
             * available otherwise its NULL
             */
            header_ptr->next_header_ptr =
             ((Q_DESC_PTR) data_ptr)->first_header_ptr;

            /* connect the created header to the descriptor structure. */
            ((Q_DESC_PTR) data_ptr)->first_header_ptr = header_ptr;

            /* assign the item pointer to the header pointer */
            header_ptr->first_item_ptr = item_ptr;

         }

         status = Q_ERR_NONE;

         /* subtract the free space count by the size of priority header */
         queue_ptr->free_count -= (sizeof(Q_PRIORITY_HEADER));

         break;
      case Q_ERR_NONE:                 /* end of item list */
         /*
          * assign the item pointer to the previous item pointer's next item
          * pointer
          */
         ((Q_ITEM_PTR) data_ptr)->next_item_ptr = item_ptr;

         /* 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);

         }
         /* 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 
             * increment the accum_dirty count by the existing object's 
             * data_offset
             */
            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 < 
               TO_BYTES(MAX_NUM_UNITS_PER_FRAG)))
            {
               header_ptr->accum_dirty += 
                  TO_GRAN(((COMMAND_PTR)data1_ptr)->data_offset);
            }                          /* ENDIF appending to single inst */

         }                             /* end else sub_command not DELETE */

         break;
      case Q_ERR_INVALID_HANDLE:
      case Q_ERR_INVALID_SIZE:
      case Q_ERR_NO_MEMORY:
      case Q_ERR_NO_ITEM:
      case Q_ERR_SEMAPHORE:
      case Q_ERR_NO_SPACE:
      case Q_ERR_PARAM:
      default:
         break;
   }

#if (PACKET_DATA == TRUE) /* PACKET_DATA */

#if (OPTIMAL_TASKDELAY == TRUE) /* OPTIMAL_TASKDELAY */
   SEM_TRY_WAIT(SEM_QueueEmpty);
#endif /* OPTIMAL_TASKDELAY */ 

#endif /* PACKET_DATA */

   /* post a semaphore message to indicate a data item exists in the queue */
   SEM_POST(queue_ptr->sem_cntrl_sync);
   /*
    * unlock the sem_cntrl_mutex field in queue_id to give others access to
    * the queue
    */
   SEM_MTX_POST(queue_ptr->sem_cntrl_mutex);

   return status;
}                                      /* END Q_Add */


/*############################################################################
 *### Q_Peek
 *###
 *### DESCRIPTION:
 *### Does three things:
 *###    1) when "priority" is GET_FIRST_ITEM: gets the highest priority item
 *###       once given access through the sem_cntrl_sync semaphore
 *###    2) when "data_ptr" is NULL: finds the first item of a given priority
 *###    3) when "data_ptr" is not NULL: finds the next item
 *###
 *### It returns a pointer to the data object under the item information
 *### structure (Q_ITEM_INFO).  It also passes back the size of the object.
 *###
 *### PARAMETERS:
 *###    IN:
 *###       queue_id       -  find the item in the queue with this handle
 *###       data_ptr       -  ptr to address of the last item found (or NULL)
 *###       data_size_ptr  -  pointer to WORD to store item size in
 *###       priority       -  priority level to search for item in queue
 *###    OUT:
 *###
 *### RETURNS:
 *###    Returns the following errors codes:
 *###       Q_ERR_NONE
 *###       Q_ERR_INVALID_HANDLE
 *###       Q_ERR_EMPTY
 *###       Q_ERR_NO_PRIORITY
 *###       Q_ERR_NO_ITEM
 *###*/
Q_ERROR
Q_Peek(Q_ID queue_id, void **data_ptr, WORD * data_size_ptr, BYTE priority)
{
   register Q_DESC_PTR queue_ptr = (Q_DESC_PTR) queue_id;

   Q_HDR_PTR header_ptr;               /* temporary storage for priority */

   Q_ERROR status = Q_ERR_NONE;

#if (Q_VERIFICATION == TRUE)
   if (VALID_QUEUE_PTR(queue_ptr) == FALSE)  /* IF call  ValidQueuePtr fails */
      return Q_ERR_INVALID_HANDLE;
#endif
   /*
    * IF the priority parameter is set to GET_FIRST_ITEM then the routine is
    * pending on items coming into the queue and gets a handle to the first
    * data item.
    */
   if (priority == GET_FIRST_ITEM)
   {
      /* DO UNTIL sem_cntrl_sync field in queue_id is asserted ENDDO UNTIL */
      SEM_WAIT(queue_ptr->sem_cntrl_sync);

⌨️ 快捷键说明

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