Bläddra i källkod

BiBoP raw block implementation; bibop_free pending

Ioannis Koutras 13 år sedan
förälder
incheckning
2a4d7ce342

+ 3 - 1
DefineOptions.cmake

@@ -1,5 +1,5 @@
 set(WITH_SYSTEM_CALLS "none" CACHE STRING "Choose what system calls can be used, options are: none, sbrk, mmap")
-set(RAW_BLOCKS_TYPE "freelist" CACHE STRING "Choose what raw blocks can be used, options are: freelist")
+set(RAW_BLOCKS_TYPE "bibop" CACHE STRING "Choose what raw blocks can be used, options are: freelist, bibop")
 option(HAVE_LOCKS "Build with POSIX locking mechanisms" ON)
 option(WITH_REALLOC "Build with realloc" OFF)
 option(WITH_EXAMPLES "Build with examples" OFF)
@@ -81,6 +81,8 @@ endif (LINUXTEST)
 
 if(RAW_BLOCKS_TYPE STREQUAL "freelist")
   set(FL_RB_ONLY ON)
+elseif(RAW_BLOCKS_TYPE STREQUAL "bibop")
+  set(BIBOP_RB_ONLY ON)
 endif(RAW_BLOCKS_TYPE STREQUAL "freelist")
 
 if(COALESCE_AFTER_SPLIT)

+ 1 - 0
dmm_config.h.in

@@ -2,6 +2,7 @@
 #define DMM_CONFIG_H
 
 #cmakedefine FL_RB_ONLY
+#cmakedefine BIBOP_RB_ONLY
 #cmakedefine SYS_ALLOC_SIZE @SYS_ALLOC_SIZE@
 #cmakedefine HAVE_LOCKS
 

+ 42 - 0
private-include/bibop/bibop_malloc.h

@@ -0,0 +1,42 @@
+/*
+ *   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   bibop_malloc.h
+ * @author Ioannis Koutras (joko@microlab.ntua.gr)
+ * @brief  Memory allocation for BiBoP-organized raw blocks
+ */
+
+#ifndef BIBOP_MALLOC_H
+#define BIBOP_MALLOC_H
+#include "dmm_config.h"
+
+#include "dmmlib/raw_block.h"
+
+#ifdef BIBOP_RB_ONLY
+#define dmmlib_malloc(raw_block, size) bibop_malloc(raw_block, size)
+#endif /* BIBOP_RB_ONLY */
+
+void * bibop_malloc(raw_block_header_t *raw_block, size_t size);
+
+#ifdef BIBOP_RB_ONLY
+#define dmmlib_free(raw_block, size) bibop_free(raw_block, size)
+#endif /* BIBOP_RB_ONLY */
+
+void bibop_free(raw_block_header_t *raw_block, void *ptr);
+
+#endif /* BIBOP_MALLOC_H */

+ 41 - 0
private-include/bibop/bibop_other.h

@@ -0,0 +1,41 @@
+/*
+ *   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   bibop_other.h
+ * @author Ilias Pliotas, Ioannis Koutras
+ * @date   September, 2012
+ * @brief  Helping functions for BiBoP raw blocks
+ */
+
+#ifndef BIBOP_OTHER_H
+#define BIBOP_OTHER_H
+#include "dmm_config.h"
+
+#include "bibop/bibop_rb.h"
+
+void copy_array(BMAP_EL_TYPE *dest, BMAP_EL_TYPE *src);
+
+void shift_array(BMAP_EL_TYPE *array, size_t n);
+
+void add_arrays(BMAP_EL_TYPE *array1, BMAP_EL_TYPE *array2);
+
+size_t prev_pow2(size_t n);
+
+BMAP_EL_TYPE make_bit_mask(unsigned int start_pos, size_t length);
+
+#endif /* BIBOP_OTHER_H */

+ 49 - 0
private-include/bibop/bibop_rb.h

@@ -0,0 +1,49 @@
+/*
+ *   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   bibop_rb.h
+ * @author Ioannis Koutras (joko@microlab.ntua.gr)
+ * @date   September 2012
+ * @brief  BiBoP raw block structure and creation function.
+ */
+
+#ifndef BIBOP_RB_H
+#define BIBOP_RB_H
+#include "dmm_config.h"
+
+#include <inttypes.h>
+#include <stddef.h> /* for size_t */
+
+#define BMAP_EL_TYPE uint64_t
+#define BMAP_EL_SIZE_BITS (sizeof(BMAP_EL_TYPE) * 8)
+
+#define BMAP_INDEX_NUM 20
+
+typedef struct bibop_rb_s {
+    BMAP_EL_TYPE bmap_array[BMAP_INDEX_NUM];
+    BMAP_EL_TYPE bmap_array2[BMAP_INDEX_NUM];
+    BMAP_EL_TYPE bmap_array3[BMAP_INDEX_NUM];
+    size_t bytes_per_cell; /* FIXME - As long as the bitmap arrays are
+                              fixed-sized, this is also fixed */
+} bibop_rb_t;
+
+typedef struct chunk_header_s {
+    size_t num_of_cells;
+} chunk_header_t;
+
+#endif /* BIBOP_RB_H */

+ 8 - 0
src/CMakeLists.txt

@@ -82,6 +82,14 @@ if(RAW_BLOCKS_TYPE STREQUAL "freelist")
       )
   endif(SPLITTING_FIXED OR SPLITTING_VARIABLE)
 
+elseif(RAW_BLOCKS_TYPE STREQUAL "bibop")
+
+  set(dmmlib_SRCS
+    ${dmmlib_SRCS}
+    bibop/bibop_other.c
+    bibop/bibop_malloc.c
+    )
+
 endif(RAW_BLOCKS_TYPE STREQUAL "freelist")
 
 if(WITH_SYSTEM_CALLS STREQUAL "none")

+ 113 - 0
src/bibop/bibop_malloc.c

@@ -0,0 +1,113 @@
+/*
+ *   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   bibop_malloc.c
+ * @author Ilias Pliotas, Ioannis Koutras
+ * @date   September, 2012
+ * @brief  malloc() implementation for BiBoP raw blocks
+ */
+
+#include "bibop/bibop_malloc.h"
+#include "bibop/bibop_rb.h"
+#include "bibop/bibop_other.h"
+
+#ifdef HAVE_LOCKS
+#include <pthread.h>
+#endif /* HAVE_LOCKS */
+
+/**
+ * Returns a memory block from a BiBoP-organized raw block
+ *
+ * @param  size_t The requested memory size.
+ * @retval        The address to serve the request.
+ * @retval NULL   No available memory space.
+ */
+void * bibop_malloc(raw_block_header_t *raw_block, size_t req_size) { 
+    bibop_rb_t *rb_header;
+    size_t cells, stop, i;
+    void *ret;
+    unsigned int found;
+    BMAP_EL_TYPE mask1, mask2;
+    chunk_header_t *chunk_address;
+
+    rb_header = (bibop_rb_t *)((char *)raw_block + sizeof(raw_block_header_t));
+
+    ret = NULL;
+
+    req_size += sizeof(chunk_header_t);
+
+    if(req_size % rb_header->bytes_per_cell > 0) {
+        cells = req_size / rb_header->bytes_per_cell + 1;
+    } else {
+        cells = req_size / rb_header->bytes_per_cell;
+    }
+
+#ifdef HAVE_LOCKS
+    pthread_mutex_lock(&raw_block->mutex);
+#endif /* HAVE_LOCKS */
+
+    // perform bitwise shift & and operations in the BMAP_EL_TYPE arrays
+    stop = prev_pow2(cells);
+
+    copy_array(rb_header->bmap_array2, rb_header->bmap_array);
+    for(i = 1; i < stop; i <<= 1) {
+        copy_array(rb_header->bmap_array3, rb_header->bmap_array2);
+        shift_array(rb_header->bmap_array3, i);
+        add_arrays(rb_header->bmap_array2, rb_header->bmap_array3);
+    }
+    if(stop < cells) {
+        copy_array(rb_header->bmap_array3, rb_header->bmap_array2);
+        shift_array(rb_header->bmap_array3, cells - stop);
+        add_arrays(rb_header->bmap_array2, rb_header->bmap_array3);
+    }
+
+    found = 0 ;
+    ret = NULL;
+
+    for(i = 0; i < BMAP_INDEX_NUM; ++i) {
+        found = __builtin_ffsl(rb_header->bmap_array2[i]);
+        if(found) {
+            int ext = BMAP_EL_SIZE_BITS - found - (cells - 1);
+            if(ext >= 0) {
+                mask1 = ~make_bit_mask(found, cells);
+                rb_header->bmap_array[i] &= mask1;
+            } else {
+                mask1 = ~make_bit_mask(found, BMAP_EL_SIZE_BITS - found + 1);
+                mask2 = ~make_bit_mask(1, cells - (BMAP_EL_SIZE_BITS - found) - 1);
+                rb_header->bmap_array[i] &= mask1;
+                rb_header->bmap_array[i + 1] &= mask2;
+            }
+
+            // Calculate the pointer to the chunk to be retrieved
+            chunk_address = (chunk_header_t *)((char *)rb_header + (i *
+                        BMAP_EL_SIZE_BITS + found - 1) *
+                    rb_header->bytes_per_cell);
+            chunk_address->num_of_cells = cells;
+
+            ret = (void *)((char *)chunk_address + sizeof(chunk_header_t));
+
+            break;
+        }
+    }
+
+#ifdef HAVE_LOCKS
+    pthread_mutex_unlock(&raw_block->mutex);
+#endif /* HAVE_LOCKS */
+
+    return ret;
+} 

+ 107 - 0
src/bibop/bibop_other.c

@@ -0,0 +1,107 @@
+/*
+ *   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   bibop_other.c
+ * @author Ilias Pliotas, Ioannis Koutras
+ * @date   September, 2012
+ * @brief  Helping functions for BiBoP raw blocks
+ */
+
+#include "bibop/bibop_other.h"
+
+/** Copy the elements of one bitmap array to another.
+ *
+ * @param dest The destination bitmap array.
+ * @param src  The source bitmap array.
+ */
+void copy_array(BMAP_EL_TYPE *dest, BMAP_EL_TYPE *src) {
+    for(int i = 0; i < BMAP_INDEX_NUM; i++) {
+        dest[i] = src[i];
+    }
+}
+
+/** Shift right by n bits all the elements of a BMAP_EL_TYPE array
+ *
+ * @param array The array to be shifted right
+ * @param n The number of bits to be shifted
+ */
+void shift_array(BMAP_EL_TYPE *array, size_t n) {
+    int i;
+    BMAP_EL_TYPE mask1, mask2, guard_mask;
+
+    // Move element-wise at first
+    while(n >= BMAP_EL_SIZE_BITS) {
+        for(i = 1; i < BMAP_INDEX_NUM; i++) {
+            array[i - 1] = array[i];
+        }
+        array[BMAP_INDEX_NUM - 1] = 0;
+        n -= BMAP_EL_SIZE_BITS;
+    }
+
+    // Check if there are still bits to be shifted
+    if(n > 0) {
+        mask1 = (BMAP_EL_TYPE) 0;
+        guard_mask = ((BMAP_EL_TYPE) 1 << n) - 1;
+        for(i = BMAP_INDEX_NUM - 1; i >= 0; --i) {
+            mask2 = array[i] & guard_mask;
+            array[i] >>= n;
+            array[i] |= mask1 << (BMAP_EL_SIZE_BITS - n);
+            mask1 = mask2;
+        }
+    }
+}
+
+/** Perform bitwsie add on every element of a BMAP_EL_TYPE arrays; store the
+ *  result on the first array
+ */
+void add_arrays(BMAP_EL_TYPE *array1, BMAP_EL_TYPE *array2) {
+    for(int i = 0; i < BMAP_INDEX_NUM; i++) {
+        array1[i] &= array2[i];
+    }
+}
+
+size_t prev_pow2(size_t n) {
+	n |= n >> 1;
+	n |= n >> 2;
+	n |= n >> 4;
+	n |= n >> 8;
+	n |= n >> 16;
+	n |= n >> 32;
+	return ((n >> 1) + 1);
+}
+
+/** Makes a bit mask of 1's
+ * @param start_pos The starting position of 1's
+ * @param length    The amount of 1's
+ */
+BMAP_EL_TYPE make_bit_mask(unsigned int start_pos , size_t length) { 
+    BMAP_EL_TYPE init;
+    
+    init = (BMAP_EL_TYPE) 1;	
+
+    // length should be <= BMAP_EL_SIZE_BITS in any case
+    if (length < BMAP_EL_SIZE_BITS) {	
+        init <<= length ;
+        init--;
+        init <<= start_pos - 1;
+        return init;
+    } else {
+        return ~((BMAP_EL_TYPE) 0);
+    }
+
+}

+ 15 - 4
src/dmmlib.c

@@ -26,8 +26,12 @@
 #include "dmmlib/dmmlib.h"
 #ifdef FL_RB_ONLY
 #include "freelist/freelist_malloc.h"
-#include "freelist/block_header.h"
 #endif /* FL_RB_ONLY */
+#ifdef BIBOP_RB_ONLY
+#include "bibop/bibop_malloc.h"
+#include "bibop/bibop_rb.h"
+#endif /* BIBOP_RB_ONLY */
+#include <stdbool.h>
 #include <string.h> /* for memset() */
 
 void * malloc(size_t size) {
@@ -49,7 +53,14 @@ void * malloc(size_t size) {
     }
 
     if(ptr == NULL) {
-        allocation_size = size;
+#ifdef FL_RB_ONLY
+        allocation_size = size + sizeof(raw_block_header_t) +
+            sizeof(freelist_rb_t);
+#endif /* FL_RB_ONLY */
+#ifdef BIBOP_RB_ONLY
+        allocation_size = size + sizeof(raw_block_header_t) +
+            sizeof(bibop_rb_t);
+#endif /* BIBOP_RB_ONLY */
 
         if(allocation_size < SYS_ALLOC_SIZE) {
             allocation_size = SYS_ALLOC_SIZE;
@@ -57,7 +68,7 @@ void * malloc(size_t size) {
             /* If allocation size is more than the default size, then request
              * multiples of it.
              */
-            allocation_size = ((size + HEADER_SIZE) / SYS_ALLOC_SIZE + 1) *
+            allocation_size = (allocation_size / SYS_ALLOC_SIZE + 1) *
                 SYS_ALLOC_SIZE;
         }
 
@@ -67,7 +78,7 @@ void * malloc(size_t size) {
             new_raw_block->next_raw_block = systemallocator.raw_block_head;
             systemallocator.raw_block_head = new_raw_block;
             pthread_mutex_unlock(&systemallocator.creation_mutex);
-            ptr = freelist_malloc(new_raw_block, size);
+            ptr = dmmlib_malloc(new_raw_block, size);
         }
     }
     

+ 17 - 0
src/raw_block.c

@@ -24,6 +24,9 @@
 #ifdef FL_RB_ONLY
 #include "freelist/freelist_rb.h"
 #endif /* FL_RB_ONLY */
+#ifdef BIBOP_RB_ONLY
+#include "bibop/bibop_rb.h"
+#endif /* BIBOP_RB_ONLY */
 
 raw_block_header_t *create_new_raw_block(size_t raw_block_size) {
     void *ptr;
@@ -36,12 +39,26 @@ 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;
+
 #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;
 #endif /* FL_RB_ONLY */
+
+#ifdef BIBOP_RB_ONLY
+    bibop_rb_t *bibop_rb;
+    bibop_rb = (bibop_rb_t *)((char *)ptr + sizeof(raw_block_header_t));
+    bibop_rb->bytes_per_cell = (raw_block_size - sizeof(raw_block_header_t) -
+        sizeof(bibop_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
+        bibop_rb->bmap_array[i] = 0xFFFFFFFF;
+    }
+#endif /* BIBOP_RB_ONLY */
+
 #ifdef HAVE_LOCKS
     pthread_mutex_init(&((raw_block_header_t *)ptr)->mutex, NULL);
 #endif /* HAVE LOCKS */