summaryrefslogtreecommitdiff
path: root/src/kernel/page.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/page.c')
-rw-r--r--src/kernel/page.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/src/kernel/page.c b/src/kernel/page.c
index 0b286a4..c79b1fa 100644
--- a/src/kernel/page.c
+++ b/src/kernel/page.c
@@ -100,7 +100,6 @@ void fix_stack() {
:"r"(PA_OFFSET));
while(frame->next != 0) {
- printf("%p\n", frame->function_base);
frame->next = PHYS_TO_VIRT((void *)frame->next);
frame = frame->next;
}
@@ -171,14 +170,13 @@ void debug_pmap() {
}
}
-//TODO I know you don't want to, but you need to thoroughly check this.
void pfree(void *addr, size_t size) {
int blevel = 0;
uint64_t *onbyte;
uint64_t page_bitloc;
int bbitlen;
int lshift;
- pmap_t *pmap = first_pmap;
+ pmap_t *pmap;
/* note: there's no security check to see if the page is actually allocated,
* or if we are freeing the table itself.
@@ -192,10 +190,13 @@ void pfree(void *addr, size_t size) {
return;
}
size /= 0x1000;
- for(; pmap != 0; pmap = pmap->next) {
+ for(pmap = first_pmap; pmap; pmap = pmap->next) {
page_bitloc = (addr - (void *)pmap) / 0x1000;
onbyte = pmap->buddy[0] + (page_bitloc / 64);
- if((addr >= (void *)pmap) && onbyte < pmap->buddy[1]) break;
+ if((addr >= (void *)pmap) && onbyte < pmap->buddy[1]) {
+ lock(&pmap->mutex);
+ break;
+ }
}
while(blevel < MAX_BUDDY_ORDER) {
@@ -241,6 +242,7 @@ void pfree(void *addr, size_t size) {
blevel++;
}
}
+ unlock(&pmap->mutex);
}
@@ -276,13 +278,10 @@ void *palloc(size_t size) {
self_alloc = false;
min_blevel = 63 - __builtin_clzl(size);
if(size & (size - 1)) min_blevel++;
- if(min_blevel > MAX_BUDDY_ORDER - 1) return 0;
+ if(min_blevel > MAX_BUDDY_ORDER - 1) PANIC(KERNEL_PANIC_PALLOC_TOO_LARGE);
}
for(blevel = min_blevel; blevel < MAX_BUDDY_ORDER; blevel++) {
- //for(pmap = first_pmap; pmap != 0; pmap = pmap->next) {
- //while(!unlocked_pmaps_searched ||
- // is_empty(waiting_pmaps[core_id], sizeof(&pmap) * pmap_count)) {
pmap = first_pmap;
while(pmap) {
@@ -329,12 +328,13 @@ void *palloc(size_t size) {
return ret;
}
}
-get_next_pmap:
pmap->mutex = 0;
+get_next_pmap:
if(unlocked_pmaps_searched) {
pmap = 0;
for(searchingp_i = waitingp_i + 1; searchingp_i < pmap_count; searchingp_i++) {
if(waiting_pmaps[waitlist_i(searchingp_i)]) {
+ waitingp_i = searchingp_i;
pmap = waiting_pmaps[waitlist_i(searchingp_i)];
break;
}
@@ -342,6 +342,7 @@ get_next_pmap:
if(!pmap) {
for(searchingp_i = 0; searchingp_i <= waitingp_i; searchingp_i++) {
if(waiting_pmaps[waitlist_i(searchingp_i)]) {
+ waitingp_i = searchingp_i;
pmap = waiting_pmaps[waitlist_i(searchingp_i)];
break;
}
@@ -350,6 +351,7 @@ get_next_pmap:
}
else {
if(!pmap->next) {
+ waitingp_i = 0;
pmap = waiting_pmaps ? waiting_pmaps[waitlist_i(0)] : 0;
unlocked_pmaps_searched = true;
}
@@ -515,3 +517,18 @@ void *init_pmap(size_t pagetable_size) {
}
return pmap;
}
+
+void lock_all_maps() {
+ pmap_t *pmap;
+ for(pmap = first_pmap; pmap; pmap = pmap->next) pmap->mutex = 1;
+ pmap = first_pmap;
+ pmap_count++;
+ for(pmap = first_pmap;;pmap = pmap->next) {
+ if(!pmap->next) {
+ pmap->next = malloc(sizeof(pmap_t));
+ pmap->next->mutex = 1;
+ break;
+ }
+ }
+ first_pmap->mutex = 0;
+}