📄 dms.c
字号:
split_size = next_aligned - address;
}
/* Adjust free_size for result of front split */
if (free_size > split_size)
free_size -= split_size;
else
/* Can't adjust block beginning, so keep searching */
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. */
memory_ptr = memory_ptr -> dm_next_memory;
} while((free_size < size) && (memory_ptr != pool -> dm_search_ptr));
/* Determine if the memory is available. */
if (free_size >= size)
{
/* A block that satisfies the request has been found. */
/* Is a front split required? The front split will represent the chunk
of memory that goes from the last pointer to the aligned address. */
if(address % alignment != 0)
{
/* Not aligned, front split the block, leaving an allocated block. */
new_ptr = (DM_HEADER*)(((UNSIGNED)(memory_ptr)) + split_size);
/* 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 = memory_ptr;
new_ptr -> dm_next_memory = memory_ptr -> dm_next_memory;
(new_ptr -> dm_next_memory) -> dm_previous_memory = new_ptr;
memory_ptr -> dm_next_memory = new_ptr;
/* Decrement the available byte count by one DM_OVERHEAD. */
pool -> dm_available = pool -> dm_available - DM_OVERHEAD;
/* Point to new aligned free block. */
memory_ptr = new_ptr;
}
/* Determine if the remaining block needs to be tail split. */
if (free_size >= (size + DM_OVERHEAD + pool -> dm_min_allocation))
{
/* Yes, split the block. */
new_ptr = (DM_HEADER *) (((BYTE_PTR) memory_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 = memory_ptr;
new_ptr -> dm_next_memory = memory_ptr -> dm_next_memory;
(new_ptr -> dm_next_memory) -> dm_previous_memory = new_ptr;
memory_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. */
memory_ptr -> dm_memory_free = NU_FALSE;
/* Should the search pointer be moved? */
if (pool -> dm_search_ptr == memory_ptr)
/* Move the search pointer to the next free memory slot. */
pool -> dm_search_ptr = memory_ptr -> dm_next_memory;
/* Return a memory address to the caller. */
*return_pointer = (VOID *) (((BYTE_PTR) memory_ptr) + DM_OVERHEAD);
#ifdef NU_PROFILE_PLUS
PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_0
#endif /* NU_PROFILE_PLUS */
}
else
{
/* Enough dynamic memory is not available. Determine if suspension is
required. */
if (suspend)
{
/* Suspension is selected. */
/* Increment the number of tasks waiting. */
pool -> dm_tasks_waiting++;
#ifdef NU_PROFILE_PLUS
PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_1
#endif /* NU_PROFILE_PLUS */
/* Setup the suspend block and suspend the calling task. */
suspend_ptr = &suspend_block;
suspend_ptr -> dm_memory_pool = pool;
suspend_ptr -> dm_request_size = size;
suspend_ptr -> dm_suspend_link.cs_next = NU_NULL;
suspend_ptr -> dm_suspend_link.cs_previous = NU_NULL;
task = (TC_TCB *) TCT_Current_Thread();
suspend_ptr -> dm_suspended_task = task;
/* Determine if priority or FIFO suspension is associated with the
memory pool. */
if (pool -> dm_fifo_suspend)
{
/* FIFO suspension is required. Link the suspend block into
the list of suspended tasks on this memory pool. */
CSC_Place_On_List((CS_NODE **)
&(pool -> dm_suspension_list),
&(suspend_ptr -> dm_suspend_link));
}
else
{
/* Get the priority of the current thread so the suspend block
can be placed in the appropriate place. */
suspend_ptr -> dm_suspend_link.cs_priority =
TCC_Task_Priority(task);
CSC_Priority_Place_On_List((CS_NODE **)
&(pool -> dm_suspension_list),
&(suspend_ptr -> dm_suspend_link));
}
/* Protect against system access. */
TCT_System_Protect();
/* Save the list protection in preparation for suspension. */
TCT_Set_Suspend_Protect(&(pool -> dm_protect));
/* Release protection of dynamic memory pool. */
TCT_Unprotect_Specific(&(pool -> dm_protect));
/* Finally, suspend the calling task. Note that the suspension call
automatically clears the system protection. */
TCC_Suspend_Task((NU_TASK *) task, NU_MEMORY_SUSPEND,
DMC_Cleanup, suspend_ptr, suspend);
/* Pickup the return status. */
status = suspend_ptr -> dm_return_status;
*return_pointer = suspend_ptr -> dm_return_pointer;
#if (NU_PROFILE_PLUS == NU_TRUE)
PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_2
#endif /* NU_PROFILE_PLUS == NU_TRUE */
}
else
{
/* No suspension requested. Simply return an error status. */
status = NU_NO_MEMORY;
*return_pointer = NU_NULL;
#ifdef NU_PROFILE_PLUS
PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_3
#endif /* NU_PROFILE_PLUS */
}
}
/* Release protection of the memory pool. */
TCT_Unprotect();
/* Return to user mode */
NU_USER_MODE();
/* Return the completion status. */
return(status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -