Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/syscall/sbrk.c
2093 views
1
#include <types.h>
2
#include <lib.h>
3
#include <copyinout.h>
4
#include <proc.h>
5
#include <thread.h>
6
#include <current.h>
7
#include <filedesc.h>
8
#include <addrspace.h>
9
#include <kern/errno.h>
10
#include <vm/page.h>
11
#include <vm/region.h>
12
#include <machine/trapframe.h>
13
#include <synch.h>
14
#include <syscall.h>
15
16
int
17
sys_sbrk( intptr_t inc, void **ptr ) {
18
struct vm_region *vmr_heap;
19
struct addrspace *as;
20
vaddr_t heap_end;
21
vaddr_t heap_start;
22
unsigned new_pages;
23
unsigned current_pages;
24
unsigned covered_range;
25
int res;
26
27
KASSERT( curthread != NULL && curthread->td_proc != NULL );
28
29
as = curthread->t_addrspace;
30
heap_start = as->as_heap_start;
31
32
if( inc == 0 ) {
33
*ptr = (void*)heap_start;
34
as->as_heap_end = heap_start;
35
return 0;
36
}
37
38
inc = ROUNDUP(inc,4);
39
40
//get the region responsible for the heap.
41
vmr_heap = vm_region_find_responsible( as, heap_start );
42
if( vmr_heap == NULL )
43
panic( "sbrk() : could not find heap region." );
44
45
//sanity check.
46
KASSERT( vmr_heap->vmr_base == heap_start );
47
48
//calculate the end of the heap.
49
current_pages = vm_page_array_num( vmr_heap->vmr_pages );
50
heap_end = as->as_heap_end;
51
covered_range = heap_start + current_pages * PAGE_SIZE;
52
53
//if the increase is negative, make sure we wont go below the starting point.
54
if( heap_end + inc < heap_start ) {
55
*ptr = ((void*)-1);
56
return EINVAL;
57
}
58
59
//if we can cover this range without allocation, we are safe.
60
if( heap_end + inc < covered_range ) {
61
as->as_heap_end += inc;
62
*ptr = (void*)heap_end;
63
return 0;
64
}
65
66
new_pages = DIVROUNDUP(((heap_end + inc)-heap_start),PAGE_SIZE);
67
if( new_pages >= PROC_MAX_HEAP_PAGES ) {
68
*ptr = ((void*)-1);
69
return ENOMEM;
70
}
71
72
res = vm_region_resize( vmr_heap, new_pages );
73
if( res ) {
74
*ptr = ((void*)-1);
75
return res;
76
}
77
78
*ptr = (void*)heap_end;
79
as->as_heap_end += inc;
80
return 0;
81
}
82
83
84