📄 dmc.c
字号:
#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 to user mode */ NU_USER_MODE(); /* 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. *//* *//* 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 */NU_SUPERV_USER_VARIABLES /* Switch to supervisor mode */ NU_SUPERVISOR_MODE(); /* 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)); /* Return to user mode */ NU_USER_MODE();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -