BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 6217f0db2c8f2513994f4cc773aaa4171a049963 / memory / region.c

// Related

Nucleus

Barry Kernel threads + threads share address space 6217f0d (3 years, 1 month ago)
diff --git a/memory/region.c b/memory/region.c
index 26cbc37..469f6b4 100644
--- a/memory/region.c
+++ b/memory/region.c
@@ -17,6 +17,7 @@ static void vm_copy(Object *, Object *);
 static void region_new(Object *);
 static void region_delete(Object *);
 static void region_copy(Object *, Object *);
+static int region_compare(void *, void *);
 
 /* Virtual Memory Namespace object type */
 ObjectType virtualMemoryType = {
@@ -40,7 +41,17 @@ static void
 vm_new(Object *obj)
 {
 	VirtualMemory *vm = (void *) obj;
-	vm->regions = create_list(&vmRegionType, LIST_NORMAL);
+	vm->regions = create_list(&vmRegionType, LIST_ORDERED, region_compare);
+
+	/* Create stack region */
+	VMRegion *stack = new(&vmRegionType);
+	stack->start = 0xDFC00000;
+	stack->end = 0xE0000000;
+	stack->prot = PROT_READ | PROT_WRITE;
+	stack->flags = MAP_PRIVATE | MAP_ANONYMOUS;
+	vm->stack = stack;
+
+	asm volatile("mov %%cr3, %0" : "=r" (vm->pageDir));
 }
 
 /* Destroy a Virtual Memory object */
@@ -49,6 +60,8 @@ vm_delete(Object *obj)
 {
 	VirtualMemory *vm = (void *) obj;
 	destroy_list(vm->regions);
+	if (vm->stack)
+		put(vm->stack);
 }
 
 /* Copy a Virtual Memory object */
@@ -62,6 +75,9 @@ vm_copy(Object *a, Object *b)
 		add(child->regions, insert);
 		put(insert);
 	}
+	if (parent->stack)
+		child->stack = copy(parent->stack);
+	child->pageDir = clone_dir();
 }
 
 /* Delete a Virtual Memory Region */
@@ -105,6 +121,14 @@ region_copy(Object *a, Object *b)
 		child->back = get(parent->back);
 }
 
+/* Compare two regions of memory */
+static int
+region_compare(void *a, void *b)
+{
+	VMRegion *ra = a, *rb = b;
+	return rb->start - ra->start;
+}
+
 /* Remove a range of pages from a region's page cache */
 static void
 remove_cache_range(VMRegion *region, uintptr_t start, uintptr_t end)
@@ -130,6 +154,18 @@ remove_cache_range(VMRegion *region, uintptr_t start, uintptr_t end)
 	}
 }
 
+/* Switch to another virtual memory namespace */
+void
+switch_to_mm(VirtualMemory *vm)
+{
+	if (!current || !current->vm)
+		return;
+	if (!vm->pageDir)
+		return;
+	if (current->vm->pageDir != vm->pageDir)
+		switch_dir(vm->pageDir);
+}
+
 /* Find a Virtual Memory Region by address */
 VMRegion *
 find_region(uintptr_t addr)
@@ -140,7 +176,7 @@ find_region(uintptr_t addr)
 			return region;
 	}
 
-	region = current->stack;
+	region = current->vm->stack;
 	if (region->start <= addr && region->end > addr)
 		return region;
 
@@ -203,14 +239,3 @@ vm_create_region(void *addr, size_t len, int prot, int flags, off_t offset,
 	add(current->vm->regions, region);
 	return region;
 }
-
-/* Create a Virtual Memory Region for the stack */
-VMRegion *
-vm_create_stack(void)
-{
-	VMRegion *stack = vm_create_region((void *) 0xDFC00000, 0x400000,
-	                                   PROT_READ | PROT_WRITE,
-	                                   MAP_PRIVATE | MAP_ANONYMOUS, 0, NULL);
-	remove(current->vm->regions, stack);
-	return stack;
-}