📄 vm.c
字号:
/* Determine if there is another link block to update. */
if (*ptr_tail_ptr != NU_NULL)
{
/* Yup, there are others currently on the list, place the new
block request at the end. */
(*ptr_tail_ptr) -> vm_next_ptr = block_ptr;
block_ptr -> vm_prev_ptr = *ptr_tail_ptr;
block_ptr -> vm_next_ptr = NU_NULL;
*ptr_tail_ptr = block_ptr;
}
else
{
/* Place the request right up front. */
*ptr_head_ptr = block_ptr;
*ptr_tail_ptr = block_ptr;
block_ptr -> vm_prev_ptr = NU_NULL;
block_ptr -> vm_next_ptr = NU_NULL;
}
} /* end of VM_Place_On_List */
/************************************************************************/
/* */
/* FUNCTION "VM_Remove_From_List" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function is used to unlink a structure from a */
/* specified linked list. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* VM_Deallocate_Memory Deallocate memory */
/* VM_Allocate_Memory Allocate memory */
/* */
/* ROUTINES CALLED */
/* */
/* None */
/* */
/* INPUTS */
/* */
/* ptr_head_ptr Pointer to list head ptr */
/* ptr_tail_ptr Pointer to list tail ptr */
/* block_ptr Pointer to block */
/* */
/* OUTPUTS */
/* */
/* Suspension List */
/* */
/************************************************************************/
void VM_Remove_From_List(struct VM_LIST_STRUCT **ptr_head_ptr,
struct VM_LIST_STRUCT **ptr_tail_ptr,
struct VM_LIST_STRUCT *block_ptr)
{
/* Determine if this block is still linked in. */
if ((block_ptr -> vm_prev_ptr != NU_NULL) ||
(block_ptr -> vm_next_ptr != NU_NULL) ||
(block_ptr == *ptr_head_ptr))
{
/* Check the previous pointers. */
if (block_ptr -> vm_prev_ptr != NU_NULL)
{
/* Link the previous suspension block to the next. */
(block_ptr -> vm_prev_ptr) -> vm_next_ptr =
block_ptr -> vm_next_ptr;
}
else
{
/* We are deleting the head node, adjust the head pointer. */
*ptr_head_ptr = block_ptr -> vm_next_ptr;
/* Adjust the head of the list. */
if (*ptr_head_ptr != NU_NULL)
(*ptr_head_ptr) -> vm_prev_ptr = NU_NULL;
}
/* Check the next pointers. */
if (block_ptr -> vm_next_ptr != NU_NULL)
{
/* Link the next suspension block to the previous. */
(block_ptr -> vm_next_ptr) -> vm_prev_ptr =
block_ptr -> vm_prev_ptr;
}
else
{
/* We are deleting the tail node, adjust the tail pointer. */
*ptr_tail_ptr = block_ptr -> vm_prev_ptr;
/* Adjust the tail of the list. */
if (*ptr_tail_ptr != NU_NULL)
(*ptr_tail_ptr) -> vm_next_ptr = NU_NULL;
}
/* Reset the pointers of the removed suspension block. */
block_ptr -> vm_next_ptr = NU_NULL;
block_ptr -> vm_prev_ptr = NU_NULL;
}
} /* end VM_Remove_From_List */
/************************************************************************/
/* */
/* FUNCTION "VM_Allocate_Memory" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function attempts to allocate memory from dynamic memory. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* Service routines that request dynamic memory allocation */
/* */
/* ROUTINES CALLED */
/* */
/* IND_Major_System_Error Major system error */
/* VM_Remove_From_List Remove memory block from */
/* list */
/* VM_Place_On_List Place memory block on list */
/* SKP_Get_Task_ID Get the current task ID */
/* */
/* INPUTS */
/* */
/* memory_size Size of memory request - in */
/* bytes */
/* */
/* OUTPUTS */
/* */
/* return(memory_ptr) Return memory pointer */
/* */
/************************************************************************/
unsigned int *VM_Allocate_Memory(unsigned long memory_size)
{
unsigned int done; /* Loop done flag */
unsigned int overhead; /* Overhead size */
unsigned int *memory_ptr; /* Pointer to the memory */
struct VM_BLOCK_HEADER_STRUCT
*new_header_ptr, /* Pointer to new header */
*header_ptr; /* Pointer to control block */
struct VM_BLOCK_TRAILER_STRUCT
*new_trailer_ptr, /* Pointer to new trailer */
*trailer_ptr; /* Pointer to the trailer */
/* Initialize the memory pointer. */
memory_ptr = NU_NULL;
/* Convert the number of bytes into the number of unsigned words, while
insuring that unsigned variable alignment is maintained. */
memory_size =
(memory_size + sizeof(unsigned int) - 1)/sizeof(unsigned int);
/* Determine if there is enough memory to satisfy this request. */
if (memory_size <= VM_Total_Available_Memory)
{
/* Yes there is still hope. Now we need to see if we have a
contiguous block that will satisfy the request. */
header_ptr = VM_Available_Head;
done = NU_FALSE;
/* Loop through the available memory chain to see if anything is
there. */
while ((header_ptr != NU_NULL) && (!done))
{
/* Check for a valid header. If it is not valid, chances are that
a task went crazy and wrote past its allocation. */
if ((header_ptr -> vm_pattern_1 != TOP_PATTERN) ||
(header_ptr -> vm_pattern_2 != BOTTOM_PATTERN))
{
/* Major system error. */
IND_Major_System_Error(NU_MEMORY_SLICKED);
}
/* Determine if this block can satisfy the request. Yes, a
first fit algorithm! */
if (header_ptr -> vm_block_size >= memory_size)
{
/* Set the done flag to get out of the loop. */
done = NU_TRUE;
/* Remove the block from the available list. */
VM_Remove_From_List(
(struct VM_LIST_STRUCT **) &VM_Available_Head,
(struct VM_LIST_STRUCT **) &VM_Available_Tail,
(struct VM_LIST_STRUCT *) header_ptr);
/* Mark the header appropriately. */
header_ptr -> vm_task_id = SKP_Get_Task_ID();
header_ptr -> vm_in_use = NU_TRUE;
/* Subtract the amount of memory available. */
VM_Total_Available_Memory = VM_Total_Available_Memory -
header_ptr -> vm_block_size;
/* Determine if the block should be split. The rule
implemented is that a block must be at least as big
as twice the overhead. */
overhead = ((sizeof(struct VM_BLOCK_HEADER_STRUCT) +
sizeof(struct VM_BLOCK_TRAILER_STRUCT))/
sizeof(unsigned int)) * 2;
if ((header_ptr -> vm_block_size - memory_size) > overhead)
{
/* Split the ole block. */
/* Calculate pointers to the old trailer and the new
header and the new trailer. */
memory_ptr = (unsigned int *) header_ptr;
memory_ptr = memory_ptr +
(sizeof(struct VM_BLOCK_HEADER_STRUCT)/
sizeof(unsigned int)) +
header_ptr -> vm_block_size;
/* Trailer is at the very bottom. */
trailer_ptr =
(struct VM_BLOCK_TRAILER_STRUCT *) memory_ptr;
memory_ptr = (unsigned int *) header_ptr +
(sizeof(struct VM_BLOCK_HEADER_STRUCT)/
sizeof(unsigned int)) +
memory_size;
/* New trailer is after the request size. */
new_trailer_ptr = (struct VM_BLOCK_TRAILER_STRUCT *)
memory_ptr;
memory_ptr = memory_ptr +
(sizeof(struct VM_BLOCK_TRAILER_STRUCT)/
sizeof(unsigned int));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -