📄 vm.c
字号:
/* Major problem here... someone has slicked some pointers. */
IND_Major_System_Error(NU_MEMORY_SLICKED);
}
/* Determine if the next block is free. */
if (other_header_ptr -> vm_in_use == NU_FALSE)
{
/* The next header is free, merge it with the current
block. */
/* Update the block size to include the next block. */
header_ptr -> vm_block_size =
header_ptr -> vm_block_size +
sizeof(struct VM_BLOCK_HEADER_STRUCT)/sizeof(unsigned int) +
sizeof(struct VM_BLOCK_TRAILER_STRUCT)/sizeof(unsigned int)+
other_header_ptr -> vm_block_size;
/* Update the next tail pointer to point at the
current header. */
other_trailer_ptr -> vm_header_ptr = header_ptr;
/* Remove the next block from the available list,
temporarily. */
VM_Remove_From_List(
(struct VM_LIST_STRUCT **) &VM_Available_Head,
(struct VM_LIST_STRUCT **) &VM_Available_Tail,
(struct VM_LIST_STRUCT *) other_header_ptr);
/* Slick the header and trailer pointers so subsequent
deallocation requests to the same block do not find
good headers and trailers. */
other_header_ptr -> vm_pattern_1 = NU_NULL;
other_header_ptr -> vm_pattern_2 = NU_NULL;
other_header_ptr -> vm_in_use = NU_FALSE;
trailer_ptr -> vm_pattern_1= NU_NULL;
trailer_ptr -> vm_pattern_2= NU_NULL;
/* Adjust the trailer pointer. */
trailer_ptr = other_trailer_ptr;
/* Add a little extra to the total available memory to
account for the two control structures given back. */
VM_Total_Available_Memory = VM_Total_Available_Memory +
sizeof(struct VM_BLOCK_HEADER_STRUCT)/sizeof(unsigned int) +
sizeof(struct VM_BLOCK_TRAILER_STRUCT)/sizeof(unsigned int);
}
}
/* In any case add the deallocated block to the available list. */
VM_Place_On_List((struct VM_LIST_STRUCT **) &VM_Available_Head,
(struct VM_LIST_STRUCT **) &VM_Available_Tail,
(struct VM_LIST_STRUCT *) header_ptr);
/* Walk the suspended list to see if any of the allocations can be
made. */
suspend_ptr = VM_Suspend_Head;
context_switches = 0;
while (suspend_ptr != NU_NULL)
{
/* Check to see if it is even reasonable to call the allocate
routine to attempt an allocation. */
if (suspend_ptr -> vm_request <= VM_Total_Available_Memory)
{
/* Call "VM_Allocate_Memory" to attempt getting the memory. */
*(suspend_ptr -> vm_return_addr) =
VM_Allocate_Memory(((suspend_ptr -> vm_request) *
sizeof(unsigned int)));
/* Determine if the request was granted. If so, the task
suspended needs to be resumed. */
if (*(suspend_ptr -> vm_return_addr) != NU_NULL)
{
/* Get the next suspension block pointer prior to
deallocation of this one. */
temp_susp_ptr = suspend_ptr -> vm_next_susp;
/* Remove the suspension pointer. */
VM_Remove_From_List(
(struct VM_LIST_STRUCT **) &VM_Suspend_Head,
(struct VM_LIST_STRUCT **) &VM_Suspend_Tail,
(struct VM_LIST_STRUCT *) suspend_ptr);
/* Lift the suspension on the task. */
context_switches = context_switches +
SKP_Ready_Task(suspend_ptr -> vm_task_id);
/* Update the suspend pointer with the previous next
suspend pointer. */
suspend_ptr = temp_susp_ptr;
}
else
{
/* The allocation attempt failed, examine the next
suspension block. */
suspend_ptr = suspend_ptr -> vm_next_susp;
}
}
else
{
/* The total available memory is less than what the suspended
task needs, continue to examine tasks. */
suspend_ptr = suspend_ptr -> vm_next_susp;
}
}
/* Check for possible context switching. */
if (context_switches)
{
/* Leave this task temporarily. */
SKD_Leave_Task();
}
/* Return a good status. */
status = NU_SUCCESS;
}
else
{
/* Return an appropriate status. */
status = NU_NOT_INUSE;
}
/* Return the status to the caller. */
return(status);
} /* end VM_Deallocate_Memory */
/************************************************************************/
/* */
/* FUNCTION "VM_Wait_For_Memory" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function suspends the task on the memory not available */
/* list. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* Service routines that wait for dynamic memory */
/* */
/* ROUTINES CALLED */
/* */
/* VM_Place_On_List Place a suspend block on lst*/
/* VM_Remove_From_List Remove suspend block */
/* SKP_Suspend_Task Suspend the task */
/* */
/* INPUTS */
/* */
/* task_id Task identification */
/* memory_request Memory size request */
/* */
/* OUTPUTS */
/* */
/* return(memory_ptr) */
/* */
/************************************************************************/
unsigned int *VM_Wait_For_Memory(signed int task_id,
unsigned long memory_request)
{
struct VM_SUSPENSION_STRUCT
suspend_block; /* Suspension control block */
unsigned int *memory_ptr; /* Memory partition pointer */
/* Initialize the memory_ptr to a null. If the memory becomes
available prior to the timeout, this is set to the memory ptr. */
memory_ptr = NU_NULL;
/* Build the suspension block. */
suspend_block.vm_task_id = task_id;
suspend_block.vm_request =
(memory_request + (sizeof(unsigned int) - 1))/sizeof(unsigned int);
suspend_block.vm_return_addr = &memory_ptr;
suspend_block.vm_next_susp = NU_NULL;
suspend_block.vm_prev_susp = NU_NULL;
/* Place the suspend block on the memory full suspension list. */
VM_Place_On_List((struct VM_LIST_STRUCT **) &VM_Suspend_Head,
(struct VM_LIST_STRUCT **) &VM_Suspend_Tail,
(struct VM_LIST_STRUCT * ) &suspend_block);
/* Suspend the task. */
SKP_Suspend_Task(task_id, NU_MEMORY_SUSPEND);
/* Check to see if a timeout occurred. In this case the suspend block
is still part of the list, remove it! */
if (memory_ptr == NU_NULL)
{
/* Remove the suspend block from the list. */
VM_Remove_From_List((struct VM_LIST_STRUCT **) &VM_Suspend_Head,
(struct VM_LIST_STRUCT **) &VM_Suspend_Tail,
(struct VM_LIST_STRUCT *) &suspend_block);
}
/* Return the memory pointer to the caller. */
return(memory_ptr);
} /* end of VM_Wait_For_Memory */
/************************************************************************/
/* */
/* FUNCTION "VM_Available" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function returns the total number of available bytes in */
/* system. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* Service routines that request memory */
/* */
/* ROUTINES CALLED */
/* */
/* None */
/* */
/* INPUTS */
/* */
/* None */
/* */
/* OUTPUTS */
/* */
/* return(VM_Total_Available_Memory) */
/* */
/************************************************************************/
unsigned long VM_Available()
{
/* Return the number of available bytes in the system. */
return(VM_Total_Available_Memory * sizeof(unsigned int));
} /* end of VM_Available */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -