Uses kref for struct page
[akaros.git] / kern / arch / sparc / page_alloc.c
index a5f9aca..843a782 100644 (file)
@@ -5,6 +5,10 @@
  * Kevin Klues <klueska@cs.berkeley.edu>    
  */
  
+#ifdef __SHARC__
+#pragma nosharc
+#endif
+
 #ifdef __DEPUTY__
 #pragma nodeputy
 #endif
 #include <pmap.h>
 #include <kmalloc.h>
 #include <multiboot.h>
+#include <colored_caches.h>
 
-page_list_t page_free_list;    // Free list of physical pages
-DECLARE_CACHE_COLORED_PAGE_FREE_LISTS(); // Free list of pages filed by color
+page_list_t *COUNT(llc_cache->num_colors) colored_page_free_list = NULL;
+spinlock_t colored_page_free_list_lock;
+
+void page_alloc_bootstrap() {
+        // Allocate space for the array required to manage the free lists
+        size_t list_size = llc_cache->num_colors*sizeof(page_list_t);
+        colored_page_free_list = (page_list_t*) boot_alloc(list_size, PGSIZE);
+}
 
 /*
  * Initialize the memory free lists.
@@ -26,9 +37,18 @@ DECLARE_CACHE_COLORED_PAGE_FREE_LISTS(); // Free list of pages filed by color
  */
 void page_alloc_init() 
 {
-       // Now, initialize the lists required to manage the page free lists
-       LIST_INIT(&page_free_list);
-       INIT_CACHE_COLORED_PAGE_FREE_LISTS();
+        // First Bootstrap the page alloc process
+        static bool bootstrapped = FALSE;
+        if(!bootstrapped) {
+                bootstrapped = TRUE;
+                page_alloc_bootstrap();
+        }
+
+        // Then, initialize the array required to manage the 
+               // colored page free list
+        for(int i=0; i<llc_cache->num_colors; i++) {
+                LIST_INIT(&(colored_page_free_list[i]));
+        }
        
        //  Finally, mark the pages already in use by the kernel. 
        //  1) Mark page 0 as in use.
@@ -43,18 +63,21 @@ void page_alloc_init()
        physaddr_t physaddr_after_kernel = PADDR(ROUNDUP(boot_freemem, PGSIZE));
 
        // mark [0, physaddr_after_kernel) as in-use
-       for(i = 0; i < PPN(physaddr_after_kernel); i++)
-               pages[i].page_ref = 1;
+       for(i = 0; i < LA2PPN(physaddr_after_kernel); i++)
+               page_setref(&pages[i], 1);
 
        // mark [physaddr_after_kernel, maxaddrpa) as free
-       for(i = PPN(physaddr_after_kernel); i < PPN(maxaddrpa); i++)
+       for(i = LA2PPN(physaddr_after_kernel); i < LA2PPN(maxaddrpa); i++)
        {
-               pages[i].page_ref = 0;
-               LIST_INSERT_HEAD(&page_free_list,&pages[i],global_link);
-               INSERT_CACHE_COLORING_PAGE_ONTO_FREE_LISTS(&pages[i]);
+               page_setref(&pages[i], 0);
+                LIST_INSERT_HEAD(
+                   &(colored_page_free_list[get_page_color(i,llc_cache)]),
+                   &pages[i],
+                   pg_link
+                );
        }
 
        // mark [maxaddrpa, ...) as in-use (as they are invalid)
-       for(i = PPN(maxaddrpa); i < npages; i++)
-               pages[i].page_ref = 1;
+       for(i = LA2PPN(maxaddrpa); i < npages; i++)
+               page_setref(&pages[i], 1);
 }