Implement objcache free
authorJack Miller <jack@codezen.org>
Mon, 28 Mar 2016 22:15:52 +0000 (17:15 -0500)
committerJack Miller <jack@codezen.org>
Mon, 28 Mar 2016 22:15:52 +0000 (17:15 -0500)
include/objcache.h
kernel/main.c
mm/objcache.c

index aef5535..fcb7ecf 100644 (file)
@@ -9,7 +9,7 @@
 struct objcache {
     u32 obj_size;
 
-       void *current_page;
+       void *start_page;
 
        DEFINE_SPINLOCK(lock);  
 };
@@ -32,3 +32,5 @@ struct objcache {
 #define DEFINE_OBJCACHE(n, t) struct objcache (n) = OBJCACHE(t)
 
 void *objcache_get(struct objcache *objcache);
+void objcache_free(struct objcache *objcache, void *obj);
+void objcache_init(struct objcache *objcache, u32 obj_size);
index f57fffe..1551c9c 100644 (file)
@@ -49,12 +49,8 @@ void main (void *info_phys, unsigned long end_structures)
         * which means 128 allocs should get us to roll over into another page
         */
 
-       for (i = 0; i < 128; i++) {
-               tb = ta;
-               ta = objcache_get(&test_cache);
-               if (PAGE_ALIGN((u64) tb) != PAGE_ALIGN((u64) ta))
-                       printk("[%d]\n", i);
-       }
+       ta = objcache_get(&test_cache);
+       objcache_free(&test_cache, ta);
 
        asm ("sti" : : );
 
index 5b9c7b1..c2576c1 100644 (file)
@@ -53,7 +53,7 @@ static int __bitmap_overall_first_zero(struct objcache *objcache, void **retptr)
        int ret;
        void *cur;
 
-       cur = objcache->current_page;
+       cur = objcache->start_page;
 
        while(cur) {
                ret = __bitmap_first_zero_in_page(bitmap_longs, cur);
@@ -87,12 +87,12 @@ static int __oc_bump_allocation(struct objcache *objcache, void **page)
 
        *page = new_page;
 
-       if (!objcache->current_page) {
-               objcache->current_page = new_page;
+       if (!objcache->start_page) {
+               objcache->start_page = new_page;
                return 0;
        }
 
-       cur = objcache->current_page;
+       cur = objcache->start_page;
        while (cur) {
                if (cur[bitmap_longs] == 0) {
                        cur[bitmap_longs] = (u64) new_page;
@@ -105,6 +105,22 @@ static int __oc_bump_allocation(struct objcache *objcache, void **page)
        return 0;
 }
 
+static int __oc_page_empty(struct objcache *objcache, u64 *page)
+{
+       int bitmap_longs = OVERHEAD_LONGS(objcache) - 1;
+       int i;
+
+       if (page[0] != INITIAL_MASK(objcache))
+               return 0;
+
+       for (i = 1; i < bitmap_longs; i++) {
+               if (page[i] != 0)
+                       return 0;
+       }
+
+       return 1;
+}
+
 void *objcache_get(struct objcache *objcache)
 {
        u64 *page;
@@ -125,6 +141,29 @@ void *objcache_get(struct objcache *objcache)
 
 void objcache_free(struct objcache *objcache, void *obj)
 {
+       u64 bitmap_longs = OVERHEAD_LONGS(objcache) - 1;
+       u64 *page = objcache->start_page;
+       u64 *prev = NULL;
+       int idx;
+
+       while(page) {
+               if (PAGE_ALIGN((u64) obj) == (u64) page) {
+                       idx = ((u64) obj - (u64) page) / objcache->obj_size;
+                       page[idx / 64] &= ~(1UL << (idx % 64));
+
+                       if (__oc_page_empty(objcache, page)) {
+                               if(prev)
+                                       prev[bitmap_longs] = page[bitmap_longs];
+                               else
+                                       objcache->start_page = (void *) page[bitmap_longs];
+                               page_alloc_free(page);
+                       }
+                       break;
+               }
+
+               prev = page;
+               page = (void *) page[bitmap_longs];
+       }
 }
 
 void objcache_init(struct objcache *objcache, u32 obj_size)