bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] gnumach: kalloc: Zone determining and constants optimization


From: Maksym Planeta
Subject: [PATCH] gnumach: kalloc: Zone determining and constants optimization
Date: Wed, 30 Mar 2011 08:49:01 +0300

Variables, which change their value only once, by the initialization
were defined as macros.

Routine for determining zone for object depends of object size. Since
zone sizes are powers of two this routine was optimized. On x86
proceessors will be used bsr instruction.

Signed-off-by: Maksym Planeta <address@hidden>
---
 kern/kalloc.c |  118 ++++++++++++++++++++------------------------------------
 kern/kalloc.h |    2 -
 2 files changed, 42 insertions(+), 78 deletions(-)

diff --git a/kern/kalloc.c b/kern/kalloc.c
index 4460d59..61d9def 100644
--- a/kern/kalloc.c
+++ b/kern/kalloc.c
@@ -48,8 +48,20 @@
 
 
 vm_map_t kalloc_map;
-vm_size_t kalloc_map_size = 8 * 1024 * 1024;
-vm_size_t kalloc_max;
+#define KALLOC_MAP_SIZE 8 * 1024 * 1024
+#define ZONE_START_ORDER 4
+#define ZONES_COUNT 12
+#define ZONE_MAX_ORDER (ZONES_COUNT + ZONE_START_ORDER - 1)
+#define SIZE_BY_ORDER(x) (1UL << (ZONE_START_ORDER + x))
+#define ZONE_MAX_SIZE SIZE_BY_ORDER(ZONES_COUNT - 1)
+#define MINSIZE (1 << ZONE_START_ORDER)
+#define KALLOC_MAX ((PAGE_SIZE < ZONE_MAX_SIZE) ? KALLOC_MAX = ZONE_MAX_SIZE : 
PAGE_SIZE)
+
+/*
+ * Attention! Undefined result on x < 2
+ */
+#define get_order(x) \
+       ((__builtin_clz(x-1) ^ (sizeof(x)*8 - 1)) + 1 - ZONE_START_ORDER)
 
 /*
  *     All allocations of size less than kalloc_max are rounded to the
@@ -61,11 +73,8 @@ vm_size_t kalloc_max;
  *     thus 16 is a safe array size for k_zone and k_zone_name.
  */
 
-int first_k_zone = -1;
-struct zone *k_zone[16];
-static char *k_zone_name[16] = {
-       "kalloc.1",             "kalloc.2",
-       "kalloc.4",             "kalloc.8",
+struct zone *k_zone[ZONES_COUNT];
+static char *k_zone_name[ZONES_COUNT] = {
        "kalloc.16",            "kalloc.32",
        "kalloc.64",            "kalloc.128",
        "kalloc.256",           "kalloc.512",
@@ -80,23 +89,19 @@ static char *k_zone_name[16] = {
  *  based on need, rather than just guessing; it also
  *  means its patchable in case you're wrong!
  */
-unsigned long k_zone_max[16] = {
-      1024,            /*      1 Byte  */
-      1024,            /*      2 Byte  */
-      1024,            /*      4 Byte  */
-      1024,            /*      8 Byte  */
-      1024,            /*     16 Byte  */
-      4096,            /*     32 Byte  */
-      4096,            /*     64 Byte  */
-      4096,            /*    128 Byte  */
-      4096,            /*    256 Byte  */
-      1024,            /*    512 Byte  */
-      1024,            /*   1024 Byte  */
-      1024,            /*   2048 Byte  */
-      1024,            /*   4096 Byte  */
-      4096,            /*   8192 Byte  */
-      64,              /*  16384 Byte  */
-      64,              /*  32768 Byte  */
+unsigned long k_zone_max[ZONES_COUNT] = {
+       1024,           /*     16 Byte  */
+       4096,           /*     32 Byte  */
+       4096,           /*     64 Byte  */
+       4096,           /*    128 Byte  */
+       4096,           /*    256 Byte  */
+       1024,           /*    512 Byte  */
+       1024,           /*   1024 Byte  */
+       1024,           /*   2048 Byte  */
+       1024,           /*   4096 Byte  */
+       4096,           /*   8192 Byte  */
+       64,             /*  16384 Byte  */
+       64,             /*  32768 Byte  */
 };
 
 /*
@@ -120,7 +125,7 @@ void kalloc_init()
        assert (! kalloc_init_called);
 
        kalloc_map = kmem_suballoc(kernel_map, &min, &max,
-                                  kalloc_map_size, FALSE);
+                       KALLOC_MAP_SIZE, FALSE);
 
        /*
         *      Ensure that zones up to size 8192 bytes exist.
@@ -128,26 +133,14 @@ void kalloc_init()
         *      with kalloc, and messages up through size 8192 are common.
         */
 
-       if (PAGE_SIZE < 16*1024)
-               kalloc_max = 16*1024;
-       else
-               kalloc_max = PAGE_SIZE;
-
        /*
         *      Allocate a zone for each size we are going to handle.
         *      We specify non-paged memory.
         */
-       for (i = 0, size = 1; size < kalloc_max; i++, size <<= 1) {
-               if (size < MINSIZE) {
-                       k_zone[i] = 0;
-                       continue;
-               }
-               if (size == MINSIZE) {
-                       first_k_zone = i;
-               }
+       for (i = 0, size = MINSIZE; i < ZONES_COUNT; i++, size <<= 1) {
                k_zone[i] = zinit(size, 0, k_zone_max[i] * size, size,
-                                 size >= PAGE_SIZE ? ZONE_COLLECTABLE : 0,
-                                 k_zone_name[i]);
+                                                 size >= PAGE_SIZE ? 
ZONE_COLLECTABLE : 0,
+                                                 k_zone_name[i]);
        }
 
 #ifndef NDEBUG
@@ -159,32 +152,23 @@ vm_offset_t kalloc(size)
        vm_size_t size;
 {
        register int zindex;
-       register vm_size_t allocsize;
        vm_offset_t addr;
 
        /* compute the size of the block that we will actually allocate */
 
        assert (kalloc_init_called);
 
-       allocsize = size;
-       if (size < kalloc_max) {
-               allocsize = MINSIZE;
-               zindex = first_k_zone;
-               while (allocsize < size) {
-                       allocsize <<= 1;
-                       zindex++;
-               }
-       }
+       zindex = size <= MINSIZE ? 0 : get_order (size);
 
        /*
         * If our size is still small enough, check the queue for that size
         * and allocate.
         */
 
-       if (allocsize < kalloc_max) {
+       if (zindex < ZONE_MAX_ORDER) {
                addr = zalloc(k_zone[zindex]);
        } else {
-               if (kmem_alloc_wired(kalloc_map, &addr, allocsize)
+               if (kmem_alloc_wired(kalloc_map, &addr, SIZE_BY_ORDER(zindex))
                                                        != KERN_SUCCESS)
                        addr = 0;
        }
@@ -195,29 +179,20 @@ vm_offset_t kget(size)
        vm_size_t size;
 {
        register int zindex;
-       register vm_size_t allocsize;
        vm_offset_t addr;
 
        assert (kalloc_init_called);
 
        /* compute the size of the block that we will actually allocate */
 
-       allocsize = size;
-       if (size < kalloc_max) {
-               allocsize = MINSIZE;
-               zindex = first_k_zone;
-               while (allocsize < size) {
-                       allocsize <<= 1;
-                       zindex++;
-               }
-       }
+       zindex = size <= MINSIZE ? 0 : get_order (size);
 
        /*
         * If our size is still small enough, check the queue for that size
         * and allocate.
         */
 
-       if (allocsize < kalloc_max) {
+       if (zindex < ZONE_MAX_ORDER) {
                addr = zget(k_zone[zindex]);
        } else {
                /* This will never work, so we might as well panic */
@@ -226,29 +201,20 @@ vm_offset_t kget(size)
        return(addr);
 }
 
-void
+       void
 kfree(data, size)
        vm_offset_t data;
        vm_size_t size;
 {
        register int zindex;
-       register vm_size_t freesize;
 
        assert (kalloc_init_called);
 
-       freesize = size;
-       if (size < kalloc_max) {
-               freesize = MINSIZE;
-               zindex = first_k_zone;
-               while (freesize < size) {
-                       freesize <<= 1;
-                       zindex++;
-               }
-       }
+       zindex = size <= MINSIZE ? 0 : get_order (size);
 
-       if (freesize < kalloc_max) {
+       if (zindex < ZONE_MAX_ORDER) {
                zfree(k_zone[zindex], data);
        } else {
-               kmem_free(kalloc_map, data, freesize);
+               kmem_free(kalloc_map, data, SIZE_BY_ORDER(zindex));
        }
 }
diff --git a/kern/kalloc.h b/kern/kalloc.h
index a80f6db..d228963 100644
--- a/kern/kalloc.h
+++ b/kern/kalloc.h
@@ -29,8 +29,6 @@
 
 #include <mach/machine/vm_types.h>
 
-#define MINSIZE 16
-
 extern vm_offset_t kalloc (vm_size_t size);
 extern vm_offset_t kget (vm_size_t size);
 extern void kfree (vm_offset_t data, vm_size_t size);
-- 
1.7.2.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]