📄 fdi_que.c
字号:
*/
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);
}
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
* increment the accum_dirty count by 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 */
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 */
/*E.5.0.702.Start*/
SEM_POST(queue_ptr->sem_queue_cntrl_sync);
/*E.5.0.702.End*/
/*
* unlock the sem_queue_cntrl_mutex field in queue_id to give others access to
* the queue
*/
/*E.5.0.702.START*/
SEM_MTX_POST(queue_ptr->sem_queue_cntrl_mutex);
/*E.5.0.702.End*/
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_queue_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_queue_cntrl_sync field in queue_id is asserted ENDDO UNTIL */
/*E.5.0.702.Start*/
SEM_WAIT(queue_ptr->sem_queue_cntrl_sync);
/*E.5.0.702.End*/
/* 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*/
/* look in the first priority header for the first data info structure */
/*
* assume there is a data item to get since the semaphore was unlocked.
* assign the data_ptr parameter to the first item element address
*/
*data_ptr = queue_ptr->first_header_ptr->first_item_ptr;
/* assign the data_size_ptr value to the sizeof the first item data */
*data_size_ptr = ((Q_ITEM_PTR) * data_ptr)->item_size;
/* we must look below the Q_ITEM_INFO for the data_ptr return value */
*data_ptr = (BYTE_PTR) * data_ptr + sizeof(Q_ITEM_INFO);
/*
* deassert the sem_queue_cntrl_sync field in queue_id because we did not take
* the item out
*/
/*E.5.0.702.Start*/
SEM_POST(queue_ptr->sem_queue_cntrl_sync);
/*E.5.0.702.End*/
/*
* unlock the sem_queue_cntrl_mutex field in queue_id to give others access to
* the queue
*/
/*E.5.0.702.START*/
SEM_MTX_POST(queue_ptr->sem_queue_cntrl_mutex);
/*E.5.0.702.End*/
} /* priority == GET_FIRST_ITEM */
else
{
/*
* IF the priority parameter is not GET_FIRST_ITEM the routine finds the
* first item if data_ptr parameter is NULL or finds the next item if
* not.
*/
/* 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*/
/*
* IF the input parameter data_ptr is NULL THEN find the first item of
* the priority parameter
*/
if (*data_ptr == NULL)
{
/* Q_VISIT_EACH means to match the priority */
status = FindItem(queue_ptr, data_ptr, data_size_ptr, &header_ptr,
priority, Q_VISIT_EACH);
}
else
{ /* look for the next data item */
/*
* assign this item to the beginning of the Q_ITEM_INFO structure by
* subtracting the address of data_ptr by the sizeof the Q_ITEM_INFO
* structure.
*/
*data_ptr = (BYTE_PTR) * data_ptr - sizeof(Q_ITEM_INFO);
if ((((Q_ITEM_PTR) (*data_ptr))->next_item_ptr) != NULL)
{
/*
* assign item_size field of this item to value of parameter
* data_size_ptr
*/
*data_size_ptr = ((Q_ITEM_PTR)*data_ptr)->next_item_ptr->item_size;
/*
* assign parameter data_ptr to address of sum of this item with
* an offset of the size of Q_ITEM_INFO structure.
*/
*data_ptr = (BYTE_PTR) (((Q_ITEM_PTR) * data_ptr)->next_item_ptr) +
sizeof(Q_ITEM_INFO);
status = Q_ERR_NONE;
}
else
{ /* next_item_ptr == NULL */
status = Q_ERR_NO_ITEM;
}
} /* ENDIF data_ptr == NULL */
/*
* unlock the sem_queue_cntrl_mutex field in queue_id to give others access to
* the queue
*/
/*E.5.0.702.START*/
SEM_MTX_POST(queue_ptr->sem_queue_cntrl_mutex);
/*E.5.0.702.End*/
} /* ENDIF priority != BYTEMAX */
return status;
} /* END Q_Peek */
/*############################################################################
*### Q_Delete
*###
*### DESCRIPTION:
*### This function frees any memory allocated by the queue code for the
*### specified queue.
*###
*### PARAMETERS:
*### IN:
*### queue_id - handle to the queue to be deleted
*### OUT:
*###
*### RETURNS:
*### Returns the following errors codes:
*### Q_ERR_NONE
*### Q_ERR_INVALID_HANDLE
*###*/
Q_ERROR
Q_Delete(Q_ID queue_id)
{
register Q_DESC_PTR queue_ptr = (Q_DESC_PTR) queue_id;
VOID_PTR removed_ptr;
#if (Q_VERIFICATION == TRUE)
if (VALID_QUEUE_PTR(queue_ptr) == FALSE) /* IF call ValidQueuePtr fails */
return Q_ERR_INVALID_HANDLE;
#endif
#if(SEM_CREATE_DESTROY == TRUE)
/* destroy the sem_queue_cntrl_mutex semaphore */
/*E.5.0.702.START*/
SEM_MTX_DESTROY(queue_ptr->sem_queue_cntrl_mutex);
/*E.5.0.702.End*/
/* destroy the sem_queue_cntrl_sync semaphore */
/*E.5.0.702.Start*/
SEM_DESTROY(queue_ptr->sem_queue_cntrl_sync);
/*E.5.0.702.End*/
#endif /* SEM_CREATE_DESTROY */
#if (Q_VERIFICATION == TRUE)
/* wipe out the queue's signature so others will see that it is corrupt */
((Q_DESC_PTR) queue_ptr)->queue_signature = WORD_LOW((DWORD) queue_ptr);
#endif
/* DO WHILE there are priority headers */
while (queue_ptr->first_header_ptr != NULL)
{
/* DO WHILE there are items */
while (queue_ptr->first_header_ptr->first_item_ptr != NULL)
{
/* save the first item pointer */
removed_ptr = queue_ptr->first_header_ptr->first_item_ptr;
/* reattach the next item pointer to the priority header */
queue_ptr->first_header_ptr->first_item_ptr =
queue_ptr->first_header_ptr->first_item_ptr->next_item_ptr;
/* deallocate memory for the item pointer */
FDI_FREE((BYTE_PTR) removed_ptr);
} /* ENDDO WHILE there are items */
/* save the first priority header pointer */
removed_ptr = queue_ptr->first_header_ptr;
/* reattach the next priority header pointer to the descriptor */
queue_ptr->first_header_ptr =
queue_ptr->first_header_ptr->next_header_ptr;
/* deallocate memory for the priority header pointer */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -