Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / lunaix-os / kernel / mm / pmm.c
index 9c0d3eb44272bda83e4fbe931408261a6801ba75..b1cea96d9ee9fc9e766a19274813aa0135b973d2 100644 (file)
@@ -4,24 +4,26 @@
 
 // This is a very large array...
 static struct pp_struct pm_table[PM_BMP_MAX_SIZE];
 
 // This is a very large array...
 static struct pp_struct pm_table[PM_BMP_MAX_SIZE];
+export_symbol(debug, pmm, pm_table);
 
 
-static uintptr_t max_pg;
+static ptr_t max_pg;
+export_symbol(debug, pmm, max_pg);
 
 void
 
 void
-pmm_mark_page_free(uintptr_t ppn)
+pmm_mark_page_free(ptr_t ppn)
 {
     pm_table[ppn].ref_counts = 0;
 }
 
 void
 {
     pm_table[ppn].ref_counts = 0;
 }
 
 void
-pmm_mark_page_occupied(pid_t owner, uintptr_t ppn, pp_attr_t attr)
+pmm_mark_page_occupied(ptr_t ppn, pp_attr_t attr)
 {
     pm_table[ppn] =
 {
     pm_table[ppn] =
-      (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr };
+      (struct pp_struct){ .ref_counts = 1, .attr = attr };
 }
 
 void
 }
 
 void
-pmm_mark_chunk_free(uintptr_t start_ppn, size_t page_count)
+pmm_mark_chunk_free(ptr_t start_ppn, size_t page_count)
 {
     for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
         pm_table[i].ref_counts = 0;
 {
     for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
         pm_table[i].ref_counts = 0;
@@ -29,24 +31,23 @@ pmm_mark_chunk_free(uintptr_t start_ppn, size_t page_count)
 }
 
 void
 }
 
 void
-pmm_mark_chunk_occupied(pid_t owner,
-                        uint32_t start_ppn,
+pmm_mark_chunk_occupied(u32_t start_ppn,
                         size_t page_count,
                         pp_attr_t attr)
 {
     for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
         pm_table[i] =
                         size_t page_count,
                         pp_attr_t attr)
 {
     for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
         pm_table[i] =
-          (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr };
+          (struct pp_struct){ .ref_counts = 1, .attr = attr };
     }
 }
 
 // 我们跳过位于0x0的页。我们不希望空指针是指向一个有效的内存空间。
 #define LOOKUP_START 1
 
     }
 }
 
 // 我们跳过位于0x0的页。我们不希望空指针是指向一个有效的内存空间。
 #define LOOKUP_START 1
 
-size_t pg_lookup_ptr;
+volatile size_t pg_lookup_ptr;
 
 void
 
 void
-pmm_init(uintptr_t mem_upper_lim)
+pmm_init(ptr_t mem_upper_lim)
 {
     max_pg = (PG_ALIGN(mem_upper_lim) >> 12);
 
 {
     max_pg = (PG_ALIGN(mem_upper_lim) >> 12);
 
@@ -55,34 +56,34 @@ pmm_init(uintptr_t mem_upper_lim)
     // mark all as occupied
     for (size_t i = 0; i < PM_BMP_MAX_SIZE; i++) {
         pm_table[i] =
     // mark all as occupied
     for (size_t i = 0; i < PM_BMP_MAX_SIZE; i++) {
         pm_table[i] =
-          (struct pp_struct){ .owner = 0, .attr = 0, .ref_counts = 1 };
+          (struct pp_struct){ .attr = 0, .ref_counts = 1 };
     }
 }
 
     }
 }
 
-void*
-pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr)
+ptr_t
+pmm_alloc_cpage(size_t num_pages, pp_attr_t attr)
 {
     size_t p1 = 0;
     size_t p2 = 0;
 
     while (p2 < max_pg && p2 - p1 < num_pages) {
 {
     size_t p1 = 0;
     size_t p2 = 0;
 
     while (p2 < max_pg && p2 - p1 < num_pages) {
-        (!(&pm_table[p2])->ref_counts) ? (p2++) : (p1 = p2);
+        (!(&pm_table[p2])->ref_counts) ? (p2++) : (p1 = ++p2);
     }
 
     }
 
-    if (p2 < max_pg) {
-        return NULL;
+    if (p2 == max_pg && p2 - p1 < num_pages) {
+        return NULLPTR;
     }
 
     }
 
-    pmm_mark_chunk_occupied(owner, p1, num_pages, attr);
+    pmm_mark_chunk_occupied(p1, num_pages, attr);
 
     return p1 << 12;
 }
 
 
     return p1 << 12;
 }
 
-void*
-pmm_alloc_page(pid_t owner, pp_attr_t attr)
+ptr_t
+pmm_alloc_page(pp_attr_t attr)
 {
     // Next fit approach. Maximize the throughput!
 {
     // Next fit approach. Maximize the throughput!
-    uintptr_t good_page_found = (uintptr_t)NULL;
+    ptr_t good_page_found = (ptr_t)NULL;
     size_t old_pg_ptr = pg_lookup_ptr;
     size_t upper_lim = max_pg;
     struct pp_struct* pm;
     size_t old_pg_ptr = pg_lookup_ptr;
     size_t upper_lim = max_pg;
     struct pp_struct* pm;
@@ -91,7 +92,6 @@ pmm_alloc_page(pid_t owner, pp_attr_t attr)
 
         if (!pm->ref_counts) {
             *pm = (struct pp_struct){ .attr = attr,
 
         if (!pm->ref_counts) {
             *pm = (struct pp_struct){ .attr = attr,
-                                      .owner = owner,
                                       .ref_counts = 1 };
             good_page_found = pg_lookup_ptr << 12;
             break;
                                       .ref_counts = 1 };
             good_page_found = pg_lookup_ptr << 12;
             break;
@@ -108,19 +108,16 @@ pmm_alloc_page(pid_t owner, pp_attr_t attr)
             }
         }
     }
             }
         }
     }
-    if (!good_page_found) {
-        __current->k_status = LXOUTOFMEM;
-    }
-    return (void*)good_page_found;
+    return good_page_found;
 }
 
 int
 }
 
 int
-pmm_free_page(pid_t owner, void* page)
+pmm_free_page(ptr_t page)
 {
 {
-    struct pp_struct* pm = &pm_table[(intptr_t)page >> 12];
+    struct pp_struct* pm = &pm_table[page >> 12];
 
     // Is this a MMIO mapping or double free?
 
     // Is this a MMIO mapping or double free?
-    if (((intptr_t)page >> 12) >= max_pg || !(pm->ref_counts)) {
+    if ((page >> 12) >= max_pg || !(pm->ref_counts)) {
         return 0;
     }
 
         return 0;
     }
 
@@ -136,11 +133,9 @@ pmm_free_page(pid_t owner, void* page)
 }
 
 int
 }
 
 int
-pmm_ref_page(pid_t owner, void* page)
+pmm_ref_page(ptr_t page)
 {
 {
-    (void*)owner; // TODO: do smth with owner
-
-    uint32_t ppn = (uintptr_t)page >> 12;
+    u32_t ppn = page >> 12;
 
     if (ppn >= PM_BMP_MAX_SIZE) {
         return 0;
 
     if (ppn >= PM_BMP_MAX_SIZE) {
         return 0;
@@ -156,9 +151,9 @@ pmm_ref_page(pid_t owner, void* page)
 }
 
 struct pp_struct*
 }
 
 struct pp_struct*
-pmm_query(void* pa)
+pmm_query(ptr_t pa)
 {
 {
-    uint32_t ppn = (uintptr_t)pa >> 12;
+    u32_t ppn = pa >> 12;
 
     if (ppn >= PM_BMP_MAX_SIZE) {
         return NULL;
 
     if (ppn >= PM_BMP_MAX_SIZE) {
         return NULL;