📄 fdi_que.c
字号:
{
/*
* 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 + -