Explorar el Código

Suppport for direct mmap() use for large memory requests

In case a memory request is larger than half of the typical allocation size of
raw blocks, then use directly a whole raw block for it.

Should this raw block gets free'd, the memory space is released back to the
system via munmap().
Ioannis Koutras hace 13 años
padre
commit
2fa5f1a3c3
Se han modificado 6 ficheros con 128 adiciones y 23 borrados
  1. 12 1
      include/dmmlib/raw_block.h
  2. 35 0
      private-include/release_memory.h
  3. 1 0
      src/CMakeLists.txt
  4. 12 8
      src/dmmlib.c
  5. 30 14
      src/raw_block.c
  6. 38 0
      src/release_memory.c

+ 12 - 1
include/dmmlib/raw_block.h

@@ -33,8 +33,19 @@
 #include <pthread.h> /* FIXME To be removed once mutex is removed. */
 #endif /* HAVE_LOCKS */
 
+typedef enum rb_type_en {
+#ifdef FL_RB_ONLY
+    FREELIST,
+#endif /* FL_RB_ONLY */
+#ifdef BITMAP_RB_ONLY
+    BITMAP,
+#endif /* BITMAP_RB_ONLY */
+    BIGBLOCK
+} rb_type;
+
 /** The header structure of every raw block inside a heap. */
 typedef struct raw_block_header_s {
+    rb_type type;
     size_t size; /**< Total available size of the raw block. */
     struct raw_block_header_s *next_raw_block; /**< Pointer to the next raw
                                                  block. */
@@ -47,6 +58,6 @@ typedef struct raw_block_header_s {
 } raw_block_header_t;
 
 /** Create a new raw block. */
-raw_block_header_t *create_new_raw_block(size_t raw_block_size);
+raw_block_header_t *create_new_raw_block(size_t raw_block_size, rb_type type);
 
 #endif /* RAW_BLOCK_H */

+ 35 - 0
private-include/release_memory.h

@@ -0,0 +1,35 @@
+/*
+ *   Copyright 2012 Institute of Communication and Computer Systems (ICCS) 
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * @file   release_memory.h
+ * @author Ioannis Koutras
+ * @date   September 2012
+ * @brief  Function prototype to release memory space to the system.
+ */
+
+#ifndef RELEASE_MEMORY_H
+#define RELEASE_MEMORY_H
+
+/**
+ * Releases memory address space to the OS.
+ *
+ * @param address The address of the memory space to be released.
+ */
+void release_memory(void *address);
+
+#endif /* RELEASE_MEMORY_H */

+ 1 - 0
src/CMakeLists.txt

@@ -31,6 +31,7 @@ endif (WITH_STATIC_LIB)
 set(dmmlib_SRCS
   dmmlib.c
   raw_block.c
+  release_memory.c
   #debug.c FIXME
 )
 

+ 12 - 8
src/dmmlib.c

@@ -31,6 +31,7 @@
 #include "bitmap/bitmap.h"
 #include "bitmap/bitmap_rb.h"
 #endif /* BITMAP_RB_ONLY */
+#include "release_memory.h"
 #include <stdbool.h>
 #include <string.h> /* for memset() */
 
@@ -62,18 +63,19 @@ void * malloc(size_t size) {
             sizeof(bitmap_rb_t);
 #endif /* BITMAP_RB_ONLY */
 
-        if(allocation_size < SYS_ALLOC_SIZE) {
-            allocation_size = SYS_ALLOC_SIZE;
+        if(allocation_size < SYS_ALLOC_SIZE / 2) {
+            allocation_size = SYS_ALLOC_SIZE / 2;
         } else {
-            /* If allocation size is more than the default size, then request
-             * multiples of it.
-             */
-            allocation_size = (allocation_size / SYS_ALLOC_SIZE + 1) *
-                SYS_ALLOC_SIZE;
+            return (void *)create_new_raw_block(allocation_size, BIGBLOCK);
         }
 
         pthread_mutex_lock(&systemallocator.creation_mutex);
-        new_raw_block = create_new_raw_block(allocation_size);
+#ifdef FL_RB_ONLY
+        new_raw_block = create_new_raw_block(allocation_size, FREELIST);
+#endif /* FL_RB_ONLY */
+#ifdef BITMAP_RB_ONLY
+        new_raw_block = create_new_raw_block(allocation_size, BITMAP);
+#endif /* BITMAP_RB_ONLY */
         if(new_raw_block != NULL) {
             new_raw_block->next_raw_block = systemallocator.raw_block_head;
             systemallocator.raw_block_head = new_raw_block;
@@ -107,6 +109,8 @@ void free(void *ptr) {
 
     if(found == true) {
         dmmlib_free(current_raw_block, ptr);
+    } else { // It has to be a BIGBLOCK, just munmap it
+        release_memory(ptr);
     }
 }
 

+ 30 - 14
src/raw_block.c

@@ -28,8 +28,14 @@
 #include "bitmap/bitmap_rb.h"
 #endif /* BITMAP_RB_ONLY */
 
-raw_block_header_t *create_new_raw_block(size_t raw_block_size) {
+raw_block_header_t *create_new_raw_block(size_t raw_block_size, rb_type type) {
     void *ptr;
+#ifdef FL_RB_ONLY
+    freelist_rb_t *fl_rb;
+#endif /* FL_RB_ONLY */
+#ifdef BITMAP_RB_ONLY
+    bitmap_rb_t *bitmap_rb;
+#endif /* BITMAP_RB_ONLY */
 
     ptr = request_memory(raw_block_size);
 
@@ -40,24 +46,34 @@ raw_block_header_t *create_new_raw_block(size_t raw_block_size) {
     ((raw_block_header_t *)ptr)->size = raw_block_size;
     ((raw_block_header_t *)ptr)->next_raw_block = NULL;
 
+    switch(type) {
+
 #ifdef FL_RB_ONLY
-    freelist_rb_t *fl_rb;
-    fl_rb = (freelist_rb_t *)((char *)ptr + sizeof(raw_block_header_t));
-    fl_rb->border_ptr = (block_header_t *)((char *)fl_rb + sizeof(freelist_rb_t));
-    fl_rb->free_list_head = NULL;
+        case FREELIST:
+            fl_rb = (freelist_rb_t *)((char *)ptr +
+                    sizeof(raw_block_header_t));
+            fl_rb->border_ptr = (block_header_t *)((char *)fl_rb +
+                    sizeof(freelist_rb_t));
+            fl_rb->free_list_head = NULL;
+            break;
 #endif /* FL_RB_ONLY */
 
 #ifdef BITMAP_RB_ONLY
-    bitmap_rb_t *bitmap_rb;
-    bitmap_rb = (bitmap_rb_t *)((char *)ptr + sizeof(raw_block_header_t));
-    bitmap_rb->bytes_per_cell = (raw_block_size - sizeof(raw_block_header_t) -
-        sizeof(bitmap_rb_t)) / (BMAP_INDEX_NUM * BMAP_EL_SIZE_BITS);
-    for(int i = 0; i < BMAP_INDEX_NUM; i++) {
-        // initialize for 32 bit bmap elements,
-        // should be 0xFFFFFFFFFFFFFFFF for 64 bit bmap elements
-        bitmap_rb->bmap_array[i] = 0xFFFFFFFF;
-    }
+        case BITMAP:
+            bitmap_rb = (bitmap_rb_t *)((char *)ptr +
+                    sizeof(raw_block_header_t));
+            bitmap_rb->bytes_per_cell = (raw_block_size -
+                    sizeof(raw_block_header_t) - sizeof(bitmap_rb_t)) /
+                (BMAP_INDEX_NUM * BMAP_EL_SIZE_BITS);
+            for(int i = 0; i < BMAP_INDEX_NUM; i++) {
+                bitmap_rb->bmap_array[i] = 0xFFFFFFFFFFFFFFFF;
+                // This is due to the data type of the element (64-bit)
+            }
+            break;
 #endif /* BITMAP_RB_ONLY */
+        case BIGBLOCK:
+            break;
+    }
 
 #ifdef HAVE_LOCKS
     pthread_mutex_init(&((raw_block_header_t *)ptr)->mutex, NULL);

+ 38 - 0
src/release_memory.c

@@ -0,0 +1,38 @@
+/*
+ *   Copyright 2012 Institute of Communication and Computer Systems (ICCS) 
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * @file   release_memory.c
+ * @author Ioannis Koutras (joko@microlab.ntua.gr)
+ * @date   September 2012
+ * @brief  Implementation of the function to release memory space back to the
+ * system.
+ */
+
+#include "release_memory.h"
+
+#include <sys/mman.h>
+#include "dmmlib/raw_block.h"
+
+void release_memory(void *address) {
+    raw_block_header_t *rb_header;
+
+    rb_header = (raw_block_header_t *)((char *)address -
+            sizeof(raw_block_header_t));
+
+    munmap((void *)rb_header, rb_header->size);
+}