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