Make find_vm_area public, so that kheap can use it too.
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "kernel.h"
|
||||
#include "stddef.h"
|
||||
#include "boot.h"
|
||||
#include "stdint.h"
|
||||
|
||||
/// Size of a page.
|
||||
#define PAGE_SIZE 4096U
|
||||
@@ -252,6 +253,12 @@ uint32_t clone_vm_area(mm_struct_t *mm,
|
||||
/// @return 0 if the area was destroyed, or 1 if the operation failed.
|
||||
int destroy_vm_area(mm_struct_t *mm, vm_area_struct_t *area);
|
||||
|
||||
/// @brief Searches for the virtual memory area at the given address.
|
||||
/// @param mm the memory descriptor which should contain the area.
|
||||
/// @param vm_start the starting address of the area we are looking for.
|
||||
/// @return a pointer to the area if we found it, NULL otherwise.
|
||||
vm_area_struct_t *find_vm_area(mm_struct_t *mm, uint32_t vm_start);
|
||||
|
||||
/// @brief Creates the main memory descriptor.
|
||||
/// @param stack_size The size of the stack in byte.
|
||||
/// @return The Memory Descriptor created.
|
||||
|
||||
+8
-37
@@ -161,31 +161,6 @@ static inline block_t *__blkmngr_get_next_block(block_t *block, uint32_t *tail)
|
||||
return block->next;
|
||||
}
|
||||
|
||||
/// @brief Find the current user heap.
|
||||
/// @return The heap structure if heap exists, otherwise NULL.
|
||||
static vm_area_struct_t *__find_user_heap()
|
||||
{
|
||||
// Get the current process.
|
||||
task_struct *task = scheduler_get_current_process();
|
||||
assert(task && "There is no current task!\n");
|
||||
// Get the memory descriptor.
|
||||
mm_struct_t *mm = task->mm;
|
||||
assert(mm && "The mm_struct of the current task is not initialized!\n");
|
||||
// If not set return NULL.
|
||||
if (mm->start_brk) {
|
||||
// Otherwise find the respective heap segment.
|
||||
vm_area_struct_t *segment = NULL;
|
||||
list_for_each_decl(it, &mm->mmap_list)
|
||||
{
|
||||
segment = list_entry(it, vm_area_struct_t, vm_list);
|
||||
if (segment->vm_start == mm->start_brk) {
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// @brief Extends the provided heap of the given increment.
|
||||
/// @param heap_top Current top of the heap.
|
||||
/// @param heap Pointer to the heap.
|
||||
@@ -736,13 +711,11 @@ void *usbrk(int increment)
|
||||
// Get the current process.
|
||||
task_struct *task = scheduler_get_current_process();
|
||||
assert(task && "There is no current task!\n");
|
||||
// Get the memory descriptor.
|
||||
mm_struct_t *mm = task->mm;
|
||||
assert(mm && "The mm_struct of the current task is not initialized!\n");
|
||||
assert(task->mm && "The mm_struct of the current task is not initialized!\n");
|
||||
// Get the top address of the heap.
|
||||
uint32_t *heap_top = &task->mm->brk;
|
||||
// Get the heap.
|
||||
vm_area_struct_t *heap_segment = __find_user_heap();
|
||||
vm_area_struct_t *heap_segment = find_vm_area(task->mm, task->mm->start_brk);
|
||||
// Perform brk.
|
||||
return __do_brk(heap_top, heap_segment, increment);
|
||||
}
|
||||
@@ -755,21 +728,19 @@ void *sys_brk(void *addr)
|
||||
// Get the current process.
|
||||
task = scheduler_get_current_process();
|
||||
assert(task && "There is no current task!\n");
|
||||
// Get the memory descriptor.
|
||||
mm = task->mm;
|
||||
assert(mm && "The mm_struct of the current task is not initialized!\n");
|
||||
assert(task->mm && "The mm_struct of the current task is not initialized!\n");
|
||||
// Get the heap.
|
||||
heap_segment = __find_user_heap();
|
||||
heap_segment = find_vm_area(task->mm, task->mm->start_brk);
|
||||
// Allocate the segment if don't exist.
|
||||
if (heap_segment == NULL) {
|
||||
heap_segment = create_vm_area(
|
||||
mm,
|
||||
task->mm,
|
||||
0x40000000 /*FIXME! stabilize this*/,
|
||||
UHEAP_INITIAL_SIZE,
|
||||
MM_RW | MM_PRESENT | MM_USER | MM_UPDADDR,
|
||||
GFP_HIGHUSER);
|
||||
mm->start_brk = heap_segment->vm_start;
|
||||
mm->brk = heap_segment->vm_start;
|
||||
task->mm->start_brk = heap_segment->vm_start;
|
||||
task->mm->brk = heap_segment->vm_start;
|
||||
// Reserved space for:
|
||||
// 1) First memory block.
|
||||
// static block_t *head = NULL;
|
||||
@@ -777,7 +748,7 @@ void *sys_brk(void *addr)
|
||||
// static block_t *tail = NULL;
|
||||
// 3) All the memory blocks that are freed.
|
||||
// static block_t *freelist = NULL;
|
||||
mm->brk += 3 * sizeof(block_t *);
|
||||
task->mm->brk += 3 * sizeof(block_t *);
|
||||
}
|
||||
// If the address falls inside the memory region, call the free function,
|
||||
// otherwise execute a malloc of the specified amount.
|
||||
|
||||
+14
-18
@@ -75,24 +75,6 @@ void paging_flush_tlb_single(unsigned long addr)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/// @brief Searches for the virtual memory area at the given address.
|
||||
/// @param mm the memory descriptor which should contain the area.
|
||||
/// @param vm_start the starting address of the area we are looking for.
|
||||
/// @return a pointer to the area if we found it, NULL otherwise.
|
||||
static inline vm_area_struct_t *__find_vm_area(mm_struct_t *mm, uintptr_t vm_start)
|
||||
{
|
||||
vm_area_struct_t *segment;
|
||||
// Find the area.
|
||||
list_for_each_prev_decl(it, &mm->mmap_list)
|
||||
{
|
||||
segment = list_entry(it, vm_area_struct_t, vm_list);
|
||||
assert(segment && "There is a NULL area in the list.");
|
||||
if (segment->vm_start == vm_start)
|
||||
return segment;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// @brief
|
||||
/// @param mm
|
||||
/// @param vm_start
|
||||
@@ -277,6 +259,20 @@ int destroy_vm_area(mm_struct_t *mm, vm_area_struct_t *area)
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline vm_area_struct_t *find_vm_area(mm_struct_t *mm, uint32_t vm_start)
|
||||
{
|
||||
vm_area_struct_t *segment;
|
||||
// Find the area.
|
||||
list_for_each_prev_decl(it, &mm->mmap_list)
|
||||
{
|
||||
segment = list_entry(it, vm_area_struct_t, vm_list);
|
||||
assert(segment && "There is a NULL area in the list.");
|
||||
if (segment->vm_start == vm_start)
|
||||
return segment;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __init_pagedir(page_directory_t *pdir)
|
||||
{
|
||||
*pdir = (page_directory_t){ { 0 } };
|
||||
|
||||
Reference in New Issue
Block a user