📄 dmc.c
字号:
#endif
#ifdef NU_ENABLE_HISTORY
/* Make an entry that corresponds to this function in the system history
log. */
HIC_Make_History_Entry(NU_DEALLOCATE_MEMORY_ID, (UNSIGNED) memory,
(UNSIGNED) 0, (UNSIGNED) 0);
#endif
/* Initialize the status as successful. */
status = NU_SUCCESS;
/* Pickup the associated pool's pointer. It is inside the header of
each memory. */
header_ptr = (DM_HEADER *) (((BYTE_PTR) memory) - DM_OVERHEAD);
pool = header_ptr -> dm_memory_pool;
/* Protect against simultaneous access to the memory pool. */
TCT_Protect(&(pool -> dm_protect));
/* Mark the memory as available. */
header_ptr -> dm_memory_free = NU_TRUE;
/* Adjust the available number of bytes. */
pool -> dm_available = pool -> dm_available +
(((BYTE_PTR) (header_ptr -> dm_next_memory)) -
((BYTE_PTR) header_ptr)) - DM_OVERHEAD;
/* Determine if the block can be merged with the previous neighbor. */
if ((header_ptr -> dm_previous_memory) -> dm_memory_free)
{
/* Adjust the available number of bytes. */
pool -> dm_available = pool -> dm_available + DM_OVERHEAD;
/* Yes, merge block with previous neighbor. */
(header_ptr -> dm_previous_memory) -> dm_next_memory =
header_ptr -> dm_next_memory;
(header_ptr -> dm_next_memory) -> dm_previous_memory =
header_ptr -> dm_previous_memory;
/* Move header pointer to previous. */
header_ptr = header_ptr -> dm_previous_memory;
/* Adjust the search pointer to the new merged block. */
pool -> dm_search_ptr = header_ptr;
}
/* Determine if the block can be merged with the next neighbor. */
if ((header_ptr -> dm_next_memory) -> dm_memory_free)
{
/* Adjust the available number of bytes. */
pool -> dm_available = pool -> dm_available + DM_OVERHEAD;
/* Yes, merge block with next neighbor. */
new_ptr = header_ptr -> dm_next_memory;
(new_ptr -> dm_next_memory) -> dm_previous_memory =
header_ptr;
header_ptr -> dm_next_memory = new_ptr -> dm_next_memory;
/* Adjust the search pointer to the new merged block. */
pool -> dm_search_ptr = header_ptr;
}
#ifdef INCLUDE_PROVIEW
_RTProf_DumpMemoryPool(RT_PROF_DEALLOCATE_MEMORY,pool,RT_PROF_OK);
#endif /*INCLUDE_PROVIEW*/
/* Determine if another task is waiting for memory from the pool. */
suspend_ptr = pool -> dm_suspension_list;
preempt = 0;
while (suspend_ptr)
{
/* Yes, another task is waiting for memory from the pool. Search
the pool in the same manner as the memory allocation function. */
size = suspend_ptr -> dm_request_size;
header_ptr = pool -> dm_search_ptr;
do
{
/* Determine if the block is free and if it can satisfy the request
of the first task waiting. */
if (header_ptr -> dm_memory_free)
/* Calculate the free block size. */
free_size = (((BYTE_PTR) (header_ptr -> dm_next_memory)) -
((BYTE_PTR) header_ptr)) - DM_OVERHEAD;
else
/* There are no free bytes available. */
free_size = 0;
/* Determine if the search should continue. */
if (free_size < size)
/* Large enough block has not been found. Move the search
pointer to the next block. */
header_ptr = header_ptr -> dm_next_memory;
} while((free_size < size) && (header_ptr != pool -> dm_search_ptr));
/* Determine if the memory is available. */
if (free_size >= size)
{
/* A block that satisfies the request has been found. */
/* Determine if the block needs to be split. */
if (free_size >= (size + DM_OVERHEAD + pool -> dm_min_allocation))
{
/* Yes, split the block. */
new_ptr = (DM_HEADER *) (((BYTE_PTR) header_ptr) + size +
DM_OVERHEAD);
/* Mark the new block as free. */
new_ptr -> dm_memory_free = NU_TRUE;
/* Put the pool pointer into the new block. */
new_ptr -> dm_memory_pool = pool;
/* Build the necessary pointers. */
new_ptr -> dm_previous_memory = header_ptr;
new_ptr -> dm_next_memory = header_ptr -> dm_next_memory;
(new_ptr -> dm_next_memory) -> dm_previous_memory = new_ptr;
header_ptr -> dm_next_memory = new_ptr;
/* Decrement the available byte count. */
pool -> dm_available = pool -> dm_available -
size - DM_OVERHEAD;
}
else
/* Decrement the entire free size from the available bytes
count. */
pool -> dm_available = pool -> dm_available - free_size;
/* Mark the allocated block as not available. */
header_ptr -> dm_memory_free = NU_FALSE;
/* Should the search pointer be moved? */
if (pool -> dm_search_ptr == header_ptr)
/* Move the search pointer to the next free memory slot. */
pool -> dm_search_ptr = header_ptr -> dm_next_memory;
/* Decrement the number of tasks waiting counter. */
pool -> dm_tasks_waiting--;
/* Remove the first suspended block from the list. */
CSC_Remove_From_List((CS_NODE **) &(pool -> dm_suspension_list),
&(suspend_ptr -> dm_suspend_link));
/* Setup the appropriate return value. */
suspend_ptr -> dm_return_status = NU_SUCCESS;
suspend_ptr -> dm_return_pointer = (VOID *)
(((BYTE_PTR) header_ptr) + DM_OVERHEAD);
/* Setup system protect while task is being resumed. */
TCT_System_Protect();
/* Resume the suspended task. */
preempt = preempt |
TCC_Resume_Task((NU_TASK *) suspend_ptr -> dm_suspended_task,
NU_MEMORY_SUSPEND);
/* Switch back to the pool protection. */
TCT_Set_Current_Protect(&(pool -> dm_protect));
/* Release system protection. */
TCT_System_Unprotect();
/* Pickup the next suspension pointer. */
suspend_ptr = pool -> dm_suspension_list;
}
else
/* Not enough memory for suspended task. */
suspend_ptr = NU_NULL;
}
/* Determine if a preempt condition is present. */
if (preempt)
/* Transfer control to the system if the resumed task function
detects a preemption condition. */
TCT_Control_To_System();
/* Release protection of the memory pool. */
TCT_Unprotect();
/* Return the completion status. */
return(status);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* DMC_Cleanup */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for removing a suspension block */
/* from a memory pool. It is not called unless a timeout or */
/* a task terminate is in progress. Note that protection is */
/* already in effect - the same protection at suspension time. */
/* */
/* AUTHOR */
/* */
/* Accelerated Technology, Inc. */
/* */
/* CALLED BY */
/* */
/* TCC_Timeout Task timeout */
/* TCC_Terminate Task terminate */
/* */
/* CALLS */
/* */
/* CSC_Remove_From_List Remove suspend block from */
/* the suspension list */
/* */
/* INPUTS */
/* */
/* information Pointer to suspend block */
/* */
/* OUTPUTS */
/* */
/* None */
/* */
/* HISTORY */
/* */
/* DATE REMARKS */
/* */
/* 03-01-1993 Created initial version 1.0 */
/* 04-19-1993 Verified version 1.0 */
/* */
/*************************************************************************/
VOID DMC_Cleanup(VOID *information)
{
DM_SUSPEND *suspend_ptr; /* Suspension block pointer */
/* Use the information pointer as a suspend pointer. */
suspend_ptr = (DM_SUSPEND *) information;
/* By default, indicate that the service timed-out. It really does not
matter if this function is called from a terminate request since
the task does not resume. */
suspend_ptr -> dm_return_status = NU_TIMEOUT;
suspend_ptr -> dm_return_pointer = NU_NULL;
/* Decrement the number of tasks waiting counter. */
(suspend_ptr -> dm_memory_pool) -> dm_tasks_waiting--;
/* Unlink the suspend block from the suspension list. */
CSC_Remove_From_List((CS_NODE **)
&((suspend_ptr -> dm_memory_pool) -> dm_suspension_list),
&(suspend_ptr -> dm_suspend_link));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -