Browse Source

fix data alignment issues; freelist/realloc(): wrong size on memcpy

Ioannis Koutras 12 years ago
parent
commit
cdd31f61db
8 changed files with 48 additions and 33 deletions
  1. 2 0
      CMakeLists.txt
  2. 3 0
      config.h.cmake
  3. 4 1
      private-include/other.h
  4. 1 27
      src/freelist/malloc.c
  5. 7 1
      src/freelist/realloc.c
  6. 6 2
      src/freelist/split.c
  7. 24 1
      src/other.c
  8. 1 1
      src/realloc.c

+ 2 - 0
CMakeLists.txt

@@ -109,6 +109,8 @@ if(STATS STREQUAL "global")
   set(WITH_ALLOCATOR_STATS ON)
 endif(STATS STREQUAL "global")
 
+set(DMM_DATA_ALIGNMENT "${CMAKE_SIZEOF_VOID_P}")
+
 configure_file (
 	"${PROJECT_SOURCE_DIR}/config.h.cmake"
 	"${PROJECT_BINARY_DIR}/dmmlib/config.h"

+ 3 - 0
config.h.cmake

@@ -148,5 +148,8 @@
 /** Make raw block requests for sizes that are multiple of the pagesize */
 #cmakedefine PAGESIZE_ALIGN
 
+/** Data alignment */
+#cmakedefine DMM_DATA_ALIGNMENT @DMM_DATA_ALIGNMENT@
+
 #endif /* DMM_CONFIG_H */
 

+ 4 - 1
private-include/other.h

@@ -24,10 +24,13 @@
 
 #ifndef OTHER_H
 #define OTHER_H
-#include <dmmlib/config.h>
+#include <inttypes.h>
 
+#include "dmmlib/config.h"
 #include "dmmlib/raw_block.h"
 
 raw_block_header_t * find_raw_block_owner(struct rb_head_s head, void* ptr);
 
+size_t req_padding(size_t size);
+
 #endif /* OTHER_H */

+ 1 - 27
src/freelist/malloc.c

@@ -29,6 +29,7 @@
 
 #include "dmmlib/freelist/freelist.h"
 
+#include "other.h"
 #include "statistics.h"
 #include "trace.h"
 
@@ -36,33 +37,6 @@
 #include "freelist/fitting_policy.h"
 #include "freelist/split.h"
 
-size_t req_padding(size_t size);
-
-/** Tries to align the input to 32, 64, 128, 256 or to a multiple of 4 if it is
- * larger.
- *
- * @param size The input number.
- */
-size_t req_padding(size_t size) {
-    size_t align;
-
-    if(size <= 32)
-        return 32;
-    if(size <= 64)
-        return 64;
-    if(size <= 128)
-        return 128;
-    if(size <= 256)
-        return 256;
-
-    align = size % 4;
-    if(align != 0) {
-        size += (4 - align);
-    }
-
-    return size;
-}
-
 /** Tries to allocate memory from a specific free-list organized raw block.
  * @param raw_block The pointer of the freelist-organised raw block.
  * @param size      The requested size.

+ 7 - 1
src/freelist/realloc.c

@@ -35,6 +35,7 @@
 #include <inttypes.h>
 #endif /* HAVE_LOCKS */
 #include "locks.h"
+#include "other.h"
 
 /**
  * Re-allocates a memory block from a freelist-organized raw block
@@ -50,6 +51,8 @@ void * freelist_realloc(freelist_rb_t *raw_block, void *ptr,
     block_header_t *block;
     void *ret;
 
+    req_size = req_padding(req_size);
+
     block = get_header(ptr);
 
     if(get_size(block) > req_size) {
@@ -66,6 +69,9 @@ void * freelist_realloc(freelist_rb_t *raw_block, void *ptr,
     /* First try to allocate space from the same raw block.
      * If it fails, try a more generic malloc. */
 
+    /* TODO check if the next memory block is free and try to coalesce if
+     * possible */
+
     LOCK_RAW_BLOCK(rb);
     ret = freelist_malloc(raw_block, req_size);
     UNLOCK_RAW_BLOCK(rb);
@@ -78,7 +84,7 @@ void * freelist_realloc(freelist_rb_t *raw_block, void *ptr,
         return NULL;
     }
 
-    memcpy(ret, ptr, block->size);
+    memcpy(ret, ptr, get_size(block));
 
     LOCK_RAW_BLOCK(rb);
     freelist_free(raw_block, ptr);

+ 6 - 2
src/freelist/split.c

@@ -17,12 +17,13 @@
 
 #include "freelist/split.h"
 
-#include <dmmlib/config.h>
-
+#include "dmmlib/config.h"
 #ifdef WITH_KNOBS
 #include "dmmlib/dmmlib.h"
 #endif /* WITH_KNOBS */
 
+#include "other.h"
+
 #include "freelist/block_header_funcs.h"
 #include "freelist/ordering_policy.h"
 
@@ -38,6 +39,9 @@ void split(freelist_rb_t *raw_block, block_header_t *ptr, size_t req_size) {
     next_block = get_dlnext(raw_block, ptr);
 #endif /* COALESCE_AFTER_SPLIT */
 
+    /* Align the requested size */
+    req_size = req_padding(req_size);
+
     /* Check what would be the size of the new block if we split the current
      * one.
      * Note: new_size is a size_t, so compare first in order to prevent an

+ 24 - 1
src/other.c

@@ -25,7 +25,30 @@
 
 #include "other.h"
 
-#include <inttypes.h>
+/** Tries to align the input to 32, 64, 128, 256 or to a multiple of processor
+ * word width if it is larger.
+ *
+ * @param size The input number.
+ */
+size_t req_padding(size_t size) {
+    size_t align;
+
+    if(size <= 32)
+        return 32;
+    if(size <= 64)
+        return 64;
+    if(size <= 128)
+        return 128;
+    if(size <= 256)
+        return 256;
+
+    align = size % DMM_DATA_ALIGNMENT;
+    if(align != 0) {
+        size += (DMM_DATA_ALIGNMENT - align);
+    }
+
+    return size;
+}
 
 /** Finds the raw block owner of a certain pointer */
 raw_block_header_t * find_raw_block_owner(struct rb_head_s head, void* ptr) {

+ 1 - 1
src/realloc.c

@@ -76,7 +76,7 @@ void * realloc(void *ptr, size_t size) {
         owner_raw_block = (raw_block_header_t *)
             ((uintptr_t) ptr - sizeof(raw_block_header_t));
 
-        size_t full_size = sizeof(raw_block_header_t) + size;
+        size_t full_size = sizeof(raw_block_header_t) + req_padding(size);
 
 #ifdef PAGESIZE_ALIGN
         size_t pagesize = (size_t) sysconf(_SC_PAGESIZE);