ソースを参照

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 13 年 前
コミット
2fa5f1a3c3
共有6 個のファイルを変更した128 個の追加23 個の削除を含む
  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);
+}