📄 fdi_que.c
字号:
* ELSE the first header is not the same priority look at the next and
* succeeding headers always looking ahead incase we need to remove the
* priority header of the item
*/
/* assign header_ptr to first_header_ptr in queue_id */
header_ptr = queue_ptr->first_header_ptr;
/* DO WHILE header_ptr is not NULL */
while (header_ptr != NULL)
{
/* IF the next priority item is the item we what to remove. THEN */
if (header_ptr->next_header_ptr->first_item_ptr == item_ptr)
{
/*
* decrement accum_dirty from for only WRITE_DELETE's
*/
if (((COMMAND_PTR)(data_ptr))->sub_command == WRITE_DELETE)
{
header_ptr->next_header_ptr->accum_dirty -= TOTALGRAN(
((COMMAND_PTR)(data_ptr))->gran_needed);
}
else
{
/*
* decrement from accum_free for all but WRITE_MODIFY
*/
if (((COMMAND_PTR)(data_ptr))->sub_command != WRITE_MODIFY)
{
header_ptr->next_header_ptr->accum_free -= TOTALGRAN(
((COMMAND_PTR)(data_ptr))->gran_needed);
}
/*
* decrement from accum_dirty for WRITE_REPLACE or appends that
* do not grow in size, but just replace within existing
* granularity.
*/
if ((((COMMAND_PTR)(data_ptr))->sub_command ==
WRITE_REPLACE) || (append_to_replace == TRUE))
{
header_ptr->next_header_ptr->accum_dirty -= TOTALGRAN(
((COMMAND_PTR)(data_ptr))->gran_needed);
}
/* added this condition for recording accum_dirty */
/*
* Test for appending to an existing single instance object and
* decrement the accum_dirty count by the existing object's
* data_offset
*/
else if (((((COMMAND_PTR)data_ptr)->sub_command ==
WRITE_APPEND) || (((COMMAND_PTR)data_ptr)->sub_command ==
WRITE_RESERVED)) &&
(((COMMAND_PTR)data_ptr)->data_offset != 0) &&
(((COMMAND_PTR)data_ptr)->data_offset <
TO_BYTES(MAX_NUM_UNITS_PER_FRAG)))
{
header_ptr->next_header_ptr->accum_dirty -=
TO_GRAN(((COMMAND_PTR)data_ptr)->data_offset);
} /* ENDIF appending to single inst */
}
/*
* IF there are no more items in this priority THEN remove the
* priority header
*/
if (item_ptr->next_item_ptr == NULL)
{
removed_header_ptr = header_ptr->next_header_ptr;
/*
* IF the subcommand is WRITE_RESERVE then we did not add the
* data onto the bottom of the COMMAND structure, therefore we
* only count the sizeof(COMMAND) and not the size pointed to by
* the Q_ITEM_INFO structure.
*/
#if (PACKET_DATA == TRUE)
if ((((COMMAND_PTR)data_ptr)->sub_command == WRITE_RESERVED) ||
(((COMMAND_PTR)data_ptr)->sub_command == WRITE_RSRVPCKT) )
#else /* PACKET_DATA */
if (((COMMAND_PTR)data_ptr)->sub_command == WRITE_RESERVED)
#endif /* PACKET_DATA */
{
/* increment the free count of the queue descriptor pointer.
*/
queue_ptr->free_count += (sizeof(Q_ITEM_INFO) +
sizeof(Q_PRIORITY_HEADER) +
sizeof(COMMAND));
}
else /* ELSE NOT WRITE_RESERVE */
{
/* increment the free count of the queue descriptor pointer.
*/
queue_ptr->free_count += (sizeof(Q_ITEM_INFO) +
sizeof(Q_PRIORITY_HEADER) +
header_ptr->next_header_ptr->first_item_ptr->item_size);
}
/* connect to the next header in line if available */
header_ptr->next_header_ptr =
header_ptr->next_header_ptr->next_header_ptr;
/* delete the priority queue of this item */
FDI_FREE((BYTE_PTR) removed_header_ptr);
}
else
{
/*
* IF the subcommand is WRITE_RESERVE then we did not add the
* data onto the bottom of the COMMAND structure, therefore we
* only count the sizeof(COMMAND) and not the size pointed to by
* the Q_ITEM_INFO structure.
*/
#if (PACKET_DATA == TRUE)
if ((((COMMAND_PTR)data_ptr)->sub_command == WRITE_RESERVED) ||
(((COMMAND_PTR)data_ptr)->sub_command == WRITE_RSRVPCKT) )
#else /* PACKET_DATA */
if (((COMMAND_PTR)data_ptr)->sub_command == WRITE_RESERVED)
#endif /* PACKET_DATA */
{
/* increment the free count of the queue descriptor pointer.
*/
queue_ptr->free_count += (sizeof(Q_ITEM_INFO) +
sizeof(COMMAND));
}
else /* ELSE NOT WRITE_RESERVE */
{
/* increment the free count of the queue descriptor pointer.
*/
queue_ptr->free_count += (sizeof(Q_ITEM_INFO) +
header_ptr->next_header_ptr->first_item_ptr->item_size);
}
/* connect to the next item in the priority */
header_ptr->next_header_ptr->first_item_ptr =
item_ptr->next_item_ptr;
}
break;
} /* ENDIF first_item_ptr is item */
/* assign header_ptr to the next header pointer */
header_ptr = header_ptr->next_header_ptr;
} /* ENDDO WHILE */
} /* ENDIF not first_header_ptr */
/* deallocate the memory for the item structure now */
FDI_FREE((BYTE_PTR) item_ptr);
/* decrement the queue item count */
queue_ptr->number_items--;
/*
* IF the number of items in the queue is zero THEN lock the sem_cntrl_sync
* semaphore
*/
if (queue_ptr->number_items == 0)
{
#if (PACKET_DATA == TRUE) /* PACKET_DATA */
#if (OPTIMAL_TASKDELAY == TRUE) /* OPTIMAL_TASKDELAY */
SEM_POST(SEM_QueueEmpty);
#endif /* OPTIMAL_TASKDELAY */
#endif /* PACKET_DATA */
SEM_TRY_WAIT(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);
#if (PERF_TEST == TRUE)
SEM_POST(PERF_SEM_Bkgd);
#endif
return Q_ERR_NONE;
} /* END Q_Remove */
/*############################################################################
*### FindItem
*###
*### DESCRIPTION:
*### Scans the queue looking for the header associated with the "priority"
*### parameter. If there are no priority headers, the descriptor table
*### pointer is returned in "data_ptr". If there are no headers of the
*### input "priority", the priority header before it is returned in
*### "data_ptr". If a header and the input "priority" match and the
*### input "data_ptr" is NULL then the first item object is returned in
*### input "data_ptr". If there is a priority match and the input
*### "data_ptr" is not NULL then the item info structure is found and the
*### next item object is returned. If the node control input is Q_FIND_LAST
*### the last item object in the priority is returned. If the node control
*### input is Q_VISIT_EACH then the process depends on the data_ptr input.
*### If the data_ptr is NULL the first item in the priority is returned in
*### data_ptr. If the data_ptr is not NULL then the next item after the
*### item in data_ptr is returned.
*###
*### PARAMETERS:
*### IN:
*### queue_ptr - address of queue with this handle
*### data_ptr - ptr to address of the header/item/descriptor
*### priority - priority level to search for item in queue
*### node_cntrl - modifies the function's processing of nodes
*### OUT:
*### found_header_ptr - ptr to priority queue header
*### data_size_ptr - pointer to WORD to store object size in
*### data_ptr - points to three types Q_DESC_PTR, Q_HDR_PTR,
*### Q_ITEM_PTR
*###
*### RETURNS:
*### Returns the following errors codes:
*### Q_ERR_NONE - if we found the last item in priority
*### node_cntrl = Q_FIND_LAST,
*### data_ptr returns the last item Q_ITEM_PTR
*### - if we found an item at all
*### node_cntrl = Q_VISIT_EACH,
*### data_ptr return an item Q_ITEM_PTR type
*### Q_ERR_NO_PRIORITY - if there are no more headers that match
*### data_ptr points to last header Q_HDR_PTR
*### Q_ERR_EMPTY - there are no priority headers in queue
*### data_ptr returns queue_ptr Q_DESC_PTR type
*### - the first header is higher priority
*### data_ptr returns queue_ptr Q_DESC_PTR type
*### Q_ERR_INVALID_HANDLE - the "queue_ptr" is invalid, bad, very bad
*###*/
static Q_ERROR
FindItem(Q_DESC_PTR queue_ptr,
void **data_ptr,
WORD_PTR data_size_ptr,
Q_HDR_PTR *found_header_ptr,
BYTE priority,
Q_NODE_CNTRL node_cntrl)
{
register Q_HDR_PTR header_ptr;
register Q_ITEM_PTR item_ptr;
*data_ptr = queue_ptr; /* save queue_id for no headers */
if (queue_ptr->first_header_ptr == NULL)
{
return Q_ERR_EMPTY;
}
/* assign header_ptr to first_header_ptr in queue_id */
header_ptr = queue_ptr->first_header_ptr;
/* DO UNTIL header_ptr is NULL */
while (header_ptr != NULL)
{
/* IF priority field of header_ptr is equal to parameter priority */
if (header_ptr->priority == priority)
{
/* assign item_ptr to first_item_ptr field of header_ptr */
item_ptr = header_ptr->first_item_ptr;
if (node_cntrl == Q_FIND_LAST)
{
/* DO UNTIL item_ptr is NULL */
while (item_ptr != NULL)
{
*data_ptr = item_ptr; /* stores the last item */
item_ptr = item_ptr->next_item_ptr;
}
item_ptr = (Q_ITEM_PTR) * data_ptr; /* last item in priority */
}
else
{ /* visit_each is TRUE */
/*
* assign parameter data_ptr to address of sum of item_ptr +
* sizeof(Q_ITEM_INFO)
*/
*data_ptr = (BYTE_PTR) item_ptr + sizeof(Q_ITEM_INFO);
}
/*
* assign item_size field of item_ptr to value of parameter
* data_size_ptr
*/
*data_size_ptr = item_ptr->item_size;
*found_header_ptr = header_ptr; /* return priority header pointer */
return Q_ERR_NONE; /* found item */
}
/*
* ELSE IF priority field of this header is greater than the parameter
* priority
*/
else if (header_ptr->priority > priority)
{
/*
* IF the data_ptr is pointing to the descriptor THEN return
* Q_ERR_EMPTY to insert the header first
*/
if (*data_ptr == queue_ptr)
{
return Q_ERR_EMPTY;
}
/*
* ELSE data_ptr contains pointer to last priority header in order to
* add a priority header afterward
*/
else
{
return Q_ERR_NO_PRIORITY;
}
}
/* ELSE move on to the next priority header */
*data_ptr = header_ptr; /* save this header */
header_ptr = ((Q_HDR_PTR) * data_ptr)->next_header_ptr;
} /* ENDDO UNTIL */
return Q_ERR_NO_PRIORITY;
} /* END Q_FindItem */
/*############################################################################
*### Q_Status
*###
*### DESCRIPTION:
*### Checks the number of items in the queue and returns appropriate status
*### to indicate an empty queue and a non_empty queue.
*###
*### PARAMETERS:
*### IN:
*### queue_ptr - address of queue with this handle
*###
*### OUT:
*### status - Q_STATUS
*###
*### RETURNS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -