WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] minios: Add align support to _xmalloc().

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] minios: Add align support to _xmalloc().
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Jan 2008 01:10:08 -0800
Delivery-date: Wed, 23 Jan 2008 01:10:08 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1200995154 0
# Node ID 5f3c236d1711aa86143c82e6b8df7c23f04db382
# Parent  6ba04ec03decc9af427e1a15ba97da8e9f73e9b9
minios: Add align support to _xmalloc().

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
 extras/mini-os/include/xmalloc.h |    3 
 extras/mini-os/lib/xmalloc.c     |  145 ++++++++++++++++++++++++++-------------
 2 files changed, 100 insertions(+), 48 deletions(-)

diff -r 6ba04ec03dec -r 5f3c236d1711 extras/mini-os/include/xmalloc.h
--- a/extras/mini-os/include/xmalloc.h  Tue Jan 22 09:44:17 2008 +0000
+++ b/extras/mini-os/include/xmalloc.h  Tue Jan 22 09:45:54 2008 +0000
@@ -7,7 +7,8 @@
 /* Allocate space for array of typed objects. */
 #define xmalloc_array(_type, _num) ((_type *)_xmalloc_array(sizeof(_type), 
__alignof__(_type), _num))
 
-#define malloc(size) _xmalloc(size, 4)
+#define DEFAULT_ALIGN (sizeof(unsigned long))
+#define malloc(size) _xmalloc(size, DEFAULT_ALIGN)
 #define free(ptr) xfree(ptr)
 #define realloc(ptr, size) _realloc(ptr, size)
 
diff -r 6ba04ec03dec -r 5f3c236d1711 extras/mini-os/lib/xmalloc.c
--- a/extras/mini-os/lib/xmalloc.c      Tue Jan 22 09:44:17 2008 +0000
+++ b/extras/mini-os/lib/xmalloc.c      Tue Jan 22 09:45:54 2008 +0000
@@ -5,9 +5,11 @@
  *
  *        File: xmaloc.c
  *      Author: Grzegorz Milos (gm281@xxxxxxxxx)
+ *              Samuel Thibault (samuel.thibault@xxxxxxxxxxxxx)
  *     Changes: 
  *              
  *        Date: Aug 2005
+ *              Jan 2008
  * 
  * Environment: Xen Minimal OS
  * Description: simple memory allocator
@@ -39,22 +41,25 @@
 #include <types.h>
 #include <lib.h>
 #include <list.h>
+#include <xmalloc.h>
 
 static LIST_HEAD(freelist);
 /* static spinlock_t freelist_lock = SPIN_LOCK_UNLOCKED; */
 
 struct xmalloc_hdr
 {
-    /* Total including this hdr. */
+    /* Total including this hdr, unused padding and second hdr. */
     size_t size;
     struct list_head freelist;
-#if defined(__ia64__)
-               // Needed for ia64 as long as the align parameter in _xmalloc()
-               // is not supported.
-    uint64_t pad;
-#endif
-
 } __cacheline_aligned;
+
+/* Unused padding data between the two hdrs. */
+
+struct xmalloc_pad
+{
+    /* Size including both hdrs. */
+    size_t hdr_size;
+};
 
 static void maybe_split(struct xmalloc_hdr *hdr, size_t size, size_t block)
 {
@@ -62,11 +67,13 @@ static void maybe_split(struct xmalloc_h
     size_t leftover = block - size;
 
     /* If enough is left to make a block, put it on free list. */
-    if ( leftover >= (2 * sizeof(struct xmalloc_hdr)) )
+    if ( leftover >= (2 * (sizeof(struct xmalloc_hdr) + sizeof(struct 
xmalloc_pad))) )
     {
         extra = (struct xmalloc_hdr *)((unsigned long)hdr + size);
         extra->size = leftover;
+        /* spin_lock_irqsave(&freelist_lock, flags); */
         list_add(&extra->freelist, &freelist);
+        /* spin_unlock_irqrestore(&freelist_lock, flags); */
     }
     else
     {
@@ -78,7 +85,7 @@ static void maybe_split(struct xmalloc_h
     hdr->freelist.next = hdr->freelist.prev = NULL;
 }
 
-static void *xmalloc_new_page(size_t size)
+static struct xmalloc_hdr *xmalloc_new_page(size_t size)
 {
     struct xmalloc_hdr *hdr;
     /* unsigned long flags; */
@@ -87,18 +94,30 @@ static void *xmalloc_new_page(size_t siz
     if ( hdr == NULL )
         return NULL;
 
-    /* spin_lock_irqsave(&freelist_lock, flags); */
     maybe_split(hdr, size, PAGE_SIZE);
-    /* spin_unlock_irqrestore(&freelist_lock, flags); */
-
-    return hdr+1;
+
+    return hdr;
+}
+
+/* Return size, increased to alignment with align. */
+static inline size_t align_up(size_t size, size_t align)
+{
+    return (size + align - 1) & ~(align - 1);
 }
 
 /* Big object?  Just use the page allocator. */
-static void *xmalloc_whole_pages(size_t size)
-{
-    struct xmalloc_hdr *hdr;
-    unsigned int pageorder = get_order(size);
+static void *xmalloc_whole_pages(size_t size, size_t align)
+{
+    struct xmalloc_hdr *hdr;
+    struct xmalloc_pad *pad;
+    unsigned int pageorder;
+    void *ret;
+    /* Room for headers */
+    size_t hdr_size = sizeof(struct xmalloc_hdr) + sizeof(struct xmalloc_pad);
+    /* Align for actual beginning of data */
+    hdr_size = align_up(hdr_size, align);
+
+    pageorder = get_order(hdr_size + size);
 
     hdr = (struct xmalloc_hdr *)alloc_pages(pageorder);
     if ( hdr == NULL )
@@ -108,54 +127,82 @@ static void *xmalloc_whole_pages(size_t 
     /* Debugging aid. */
     hdr->freelist.next = hdr->freelist.prev = NULL;
 
-    return hdr+1;
-}
-
-/* Return size, increased to alignment with align. */
-static inline size_t align_up(size_t size, size_t align)
-{
-    return (size + align - 1) & ~(align - 1);
+    ret = (char*)hdr + hdr_size;
+    pad = (struct xmalloc_pad *) ret - 1;
+    pad->hdr_size = hdr_size;
+    return ret;
 }
 
 void *_xmalloc(size_t size, size_t align)
 {
-    struct xmalloc_hdr *i;
-    /* unsigned long flags; */
-
-    /* Add room for header, pad to align next header. */
-    size += sizeof(struct xmalloc_hdr);
-    size = align_up(size, __alignof__(struct xmalloc_hdr));
+    struct xmalloc_hdr *i, *hdr = NULL;
+    uintptr_t data_begin;
+    size_t hdr_size;
+    /* unsigned long flags; */
+
+    hdr_size = sizeof(struct xmalloc_hdr) + sizeof(struct xmalloc_pad);
+    /* Align on headers requirements. */
+    align = align_up(align, __alignof__(struct xmalloc_hdr));
+    align = align_up(align, __alignof__(struct xmalloc_pad));
 
     /* For big allocs, give them whole pages. */
-    if ( size >= PAGE_SIZE )
-        return xmalloc_whole_pages(size);
+    if ( size + align_up(hdr_size, align) >= PAGE_SIZE )
+        return xmalloc_whole_pages(size, align);
 
     /* Search free list. */
     /* spin_lock_irqsave(&freelist_lock, flags); */
     list_for_each_entry( i, &freelist, freelist )
     {
-        if ( i->size < size )
+        data_begin = align_up((uintptr_t)i + hdr_size, align);
+
+        if ( data_begin + size > (uintptr_t)i + i->size )
             continue;
+
         list_del(&i->freelist);
-        maybe_split(i, size, i->size);
-        /* spin_unlock_irqrestore(&freelist_lock, flags); */
-        return i+1;
-    }
-    /* spin_unlock_irqrestore(&freelist_lock, flags); */
-
-    /* Alloc a new page and return from that. */
-    return xmalloc_new_page(size);
+        /* spin_unlock_irqrestore(&freelist_lock, flags); */
+
+        uintptr_t size_before = (data_begin - hdr_size) - (uintptr_t)i;
+
+        if (size_before >= 2 * hdr_size) {
+            /* Worth splitting the beginning */
+            struct xmalloc_hdr *new_i = (void*)(data_begin - hdr_size);
+            new_i->size = i->size - size_before;
+            i->size = size_before;
+            /* spin_lock_irqsave(&freelist_lock, flags); */
+            list_add(&i->freelist, &freelist);
+            /* spin_unlock_irqrestore(&freelist_lock, flags); */
+            i = new_i;
+        }
+        maybe_split(i, (data_begin + size) - (uintptr_t)i, i->size);
+        hdr = i;
+        break;
+    }
+
+    if (!hdr) {
+        /* spin_unlock_irqrestore(&freelist_lock, flags); */
+
+        /* Alloc a new page and return from that. */
+        hdr = xmalloc_new_page(align_up(hdr_size, align) + size);
+        data_begin = (uintptr_t)hdr + align_up(hdr_size, align);
+    }
+
+    struct xmalloc_pad *pad = (struct xmalloc_pad *) data_begin - 1;
+    pad->hdr_size = data_begin - (uintptr_t)hdr;
+    BUG_ON(data_begin % align);
+    return (void*)data_begin;
 }
 
 void xfree(const void *p)
 {
     /* unsigned long flags; */
     struct xmalloc_hdr *i, *tmp, *hdr;
+    struct xmalloc_pad *pad;
 
     if ( p == NULL )
         return;
 
-    hdr = (struct xmalloc_hdr *)p - 1;
+    pad = (struct xmalloc_pad *)p - 1;
+    hdr = (struct xmalloc_hdr *)((char *)p - pad->hdr_size);
 
     /* We know hdr will be on same page. */
     if(((long)p & PAGE_MASK) != ((long)hdr & PAGE_MASK))
@@ -227,15 +274,19 @@ void *_realloc(void *ptr, size_t size)
 {
     void *new;
     struct xmalloc_hdr *hdr;
+    struct xmalloc_pad *pad;
 
     if (ptr == NULL)
-        return _xmalloc(size, 4);
-
-    hdr = (struct xmalloc_hdr *)ptr - 1;
-    if (hdr->size >= size) 
+        return _xmalloc(size, DEFAULT_ALIGN);
+
+    pad = (struct xmalloc_pad *)ptr - 1;
+    hdr = (struct xmalloc_hdr *)((char*)ptr - pad->hdr_size);
+    if (hdr->size >= size) {
+        maybe_split(hdr, size, hdr->size);
         return ptr;
+    }
     
-    new = _xmalloc(size, 4);
+    new = _xmalloc(size, DEFAULT_ALIGN);
     if (new == NULL) 
         return NULL;
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] minios: Add align support to _xmalloc()., Xen patchbot-unstable <=