Преглед изворни кода

allocator space for allocator state on the heap

Ioannis Koutras пре 11 година
родитељ
комит
97fbea0bb8

+ 3 - 3
examples/test_for_memory_space_aware.c

@@ -7,10 +7,10 @@
 
 #define ALLOCATOR_SIZE 2*MAX_COAL_SIZE*sizeof(char)
 
-#define cmalloc(size) custom_ahmalloc(&systemallocator, &systemallocator.heaps[0], (size_t) size)
-#define cfree(ptr) custom_ahfree(&systemallocator, &systemallocator.heaps[0], ptr)
+#define cmalloc(size) custom_ahmalloc(&systemallocator, &systemallocator->heaps[0], (size_t) size)
+#define cfree(ptr) custom_ahfree(&systemallocator, &systemallocator->heaps[0], ptr)
 #ifdef WITH_REALLOC
-#define crealloc(ptr, size) custom_ahrealloc(&systemallocator, &systemallocator.heaps[0], ptr, size)
+#define crealloc(ptr, size) custom_ahrealloc(&systemallocator, &systemallocator->heaps[0], ptr, size)
 #endif /* WITH_REALLOC */
 
 int main(void) {

+ 1 - 1
include/dmmlib/dmmlib.h

@@ -33,7 +33,7 @@
 #include <dmmlib/allocator.h>
 
 /** Global variable storing allocator's settings */
-allocator_t systemallocator;
+allocator_t *systemallocator;
 
 #if !defined _STDLIB_H && !defined _STDLIB_H_
 

+ 3 - 3
private-include/dmmlib_trace.h

@@ -48,7 +48,7 @@ FILE* mem_fd;
 
 /** Function for memory trace messages */
 #define MEM_TRACE(...) \
-    if(__builtin_expect (systemallocator.initialized, true)) { \
+    if(__builtin_expect (systemallocator->initialized, true)) { \
         fprintf(MEM_FD, __VA_ARGS__); \
     }
 
@@ -79,7 +79,7 @@ FILE* stats_fd;
 
 /** Function for statistics trace messages */
 #define STATS_TRACE(...) \
-    if(__builtin_expect (systemallocator.initialized, true)) { \
+    if(__builtin_expect (systemallocator->initialized, true)) { \
         fprintf(STATS_FD, __VA_ARGS__); \
     }
 
@@ -110,7 +110,7 @@ FILE* dbg_fd;
 
 /** Function for debug trace messages */
 #define DBG_TRACE(...) \
-    if(__builtin_expect (systemallocator.initialized, true)) { \
+    if(__builtin_expect (systemallocator->initialized, true)) { \
         fprintf(DBG_FD, __VA_ARGS__); \
     }
 

+ 2 - 2
private-include/locks.h

@@ -32,9 +32,9 @@
 #include <pthread.h>
 
 /** Locks the systemallocator object */
-#define LOCK_GLOBAL() pthread_mutex_lock(&systemallocator.creation_mutex)
+#define LOCK_GLOBAL() pthread_mutex_lock(&systemallocator->creation_mutex)
 /** Unlocks the systemallocator object */
-#define UNLOCK_GLOBAL() pthread_mutex_unlock(&systemallocator.creation_mutex)
+#define UNLOCK_GLOBAL() pthread_mutex_unlock(&systemallocator->creation_mutex)
 /** Locks a specific raw block */
 #define LOCK_RAW_BLOCK(rb) pthread_mutex_lock(&rb->mutex)
 /** Tries to lock a specific raw block */

+ 26 - 0
private-include/parse_env.h

@@ -0,0 +1,26 @@
+/*
+ *   Copyright RubberDuck Software P.C.
+ *
+ *   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   parse_env.h
+ * @author Ioannis Koutras (joko@rdsoftware.eu)
+ * @date   February 2014
+ * @brief  Function to parse environment variables
+ */
+
+/** Parses various allocator-related enviroment variables. */
+void parse_env(void);

+ 2 - 2
private-include/statistics.h

@@ -38,13 +38,13 @@
 /** Updates the global statistics for specific dmmlib events */
 #define UPDATE_GLOBAL_STATS(EVENT_TYPE, REQ_SIZE) \
     LOCK_GLOBAL(); \
-    update_stats(&systemallocator.dmm_stats, EVENT_TYPE, REQ_SIZE); \
+    update_stats(&systemallocator->dmm_stats, EVENT_TYPE, REQ_SIZE); \
     UNLOCK_GLOBAL();
 #else /* REQUEST_SIZE_INFO */
 /** Updates the global statistics for specific dmmlib events */
 #define UPDATE_GLOBAL_STATS(EVENT_TYPE) \
     LOCK_GLOBAL(); \
-    update_stats(&systemallocator.dmm_stats, EVENT_TYPE); \
+    update_stats(&systemallocator->dmm_stats, EVENT_TYPE); \
     UNLOCK_GLOBAL();
 #endif /* REQUEST_SIZE_INFO */
 

+ 3 - 3
src/free.c

@@ -42,7 +42,7 @@ void free(void *ptr) {
     }
 
 #if defined PARSE_ENV && defined WITH_MEM_TRACE
-    if(__builtin_expect (systemallocator.initialized, true)) {
+    if(__builtin_expect (systemallocator->initialized, true)) {
 #endif /* PARSE_ENV && WITH_MEM_TRACE */
     MEM_TRACE("dmmlib - f %p\n", ptr);
 #if defined PARSE_ENV && defined WITH_MEM_TRACE
@@ -66,13 +66,13 @@ void free(void *ptr) {
 #ifdef WITH_ALLOCATOR_STATS
         LOCK_GLOBAL();
         update_stats
-            ( &systemallocator.dmm_stats
+            ( &systemallocator->dmm_stats
             , FREE
 #ifdef REQUEST_SIZE_INFO
             , owner_raw_block->requested_size
 #endif /* REQUEST_SIZE_INFO */
             );
-        systemallocator.dmm_stats.total_mem_allocated -= owner_raw_block->size;
+        systemallocator->dmm_stats.total_mem_allocated -= owner_raw_block->size;
         UNLOCK_GLOBAL();
 #endif /* WITH_ALLOCATOR_STATS */
 

+ 1 - 1
src/freelist/coalesce.c

@@ -37,7 +37,7 @@ void coalesce(freelist_rb_t *raw_block, block_header_t *ptr) {
     max_coal_size = MAX_COAL_SIZE;
 #endif /* COALESCING_FIXED */
 #ifdef COALESCING_VARIABLE
-    max_coal_size = (size_t) systemallocator.dmm_knobs.max_coal_size;
+    max_coal_size = (size_t) systemallocator->dmm_knobs.max_coal_size;
 #endif /* COALESCING_VARIABLE */
 
     size = get_size(ptr);

+ 1 - 1
src/freelist/fitting/good.c

@@ -36,7 +36,7 @@ block_header_t * fl_good_fit(freelist_rb_t *raw_block, size_t requested_size) {
     good_size = (size_t) -1; /* SIZE_MAX */
 #ifdef WITH_KNOBS
     ideal_size = (size_t) ((double) requested_size /
-            systemallocator.dmm_knobs.fit_percentage);
+            systemallocator->dmm_knobs.fit_percentage);
 #else /* WITH_KNOBS */
     ideal_size = (size_t) ((double) requested_size / GOOD_FIT_PERCENTAGE);
 #endif /* WITH_KNOBS */

+ 2 - 2
src/freelist/split.c

@@ -58,7 +58,7 @@ void split(freelist_rb_t *raw_block, block_header_t *ptr, size_t req_size) {
     min_split_size = MIN_SPLIT_SIZE;
 #endif /* SPLITTING_FIXED */
 #ifdef SPLITTING_VARIABLE
-    min_split_size = (size_t) systemallocator.dmm_knobs.min_split_size;
+    min_split_size = (size_t) systemallocator->dmm_knobs.min_split_size;
 #endif /* SPLITTING_VARIABLE */
 
     if(new_size < min_split_size) {
@@ -80,7 +80,7 @@ void split(freelist_rb_t *raw_block, block_header_t *ptr, size_t req_size) {
     max_coal_size = MAX_COAL_SIZE;
 #endif /* COALESCING_FIXED */
 #ifdef COALESCING_VARIABLE
-    max_coal_size = systemallocator.dmm_knobs.max_coal_size;
+    max_coal_size = systemallocator->dmm_knobs.max_coal_size;
 #endif /* COALESCING_VARIABLE */
 
     if(next_block != NULL && is_free(next_block) == true) {

+ 42 - 21
src/initialize.c

@@ -22,48 +22,69 @@
  * @brief  System allocator's global object initializer.
  */
 
+#include <fcntl.h> /* for open() */
+#include <sys/mman.h> /* for mmap() */
+
 #include <dmmlib/config.h>
 #include "dmmlib/dmmlib.h"
+#include "parse_env.h"
+
+__attribute__((constructor)) int initialize_allocator(void);
+
+/** Initializes space to store the allocator state in heap. */
+int initialize_allocator(void) {
 
-/** Global variable storing allocator's settings */
-allocator_t systemallocator =
-    { .rb_head = {NULL}
+    int fd = open("/dev/zero", O_RDWR);
+    allocator_t *allocator = mmap(NULL, SYS_PAGESIZE,
+            PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+
+    if(__builtin_expect(!!(allocator == MAP_FAILED), 0)) {
+        return -1;
+    }
+
+    SLIST_INIT(&allocator->rb_head);
 #ifdef HAVE_LOCKS
-    , .creation_mutex = PTHREAD_MUTEX_INITIALIZER
+    pthread_mutex_init(&allocator->creation_mutex, NULL);
 #endif /* HAVE_LOCKS */
 #ifdef WITH_KNOBS
-    , .dmm_knobs =
-            { .sys_alloc_size = SYS_ALLOC_SIZE
+    allocator->dmm_knobs.sys_alloc_size = SYS_ALLOC_SIZE;
 #ifdef GOOD_FIT
-            , .fit_percentage = GOOD_FIT_PERCENTAGE
+    allocator->dmm_knobs.fit_percentage = GOOD_FIT_PERCENTAGE;
 #endif /* GOOD_FIT */
 #ifdef COALESCING_VARIABLE
-            , .max_coal_size = MAX_COAL_SIZE
+    allocator->dmm_knobs.max_coal_size = MAX_COAL_SIZE;
 #endif /* COALESCING_VARIABLE */
 #ifdef SPLITTING_VARIABLE
-            , .min_split_size = MIN_SPLIT_SIZE
+    allocator->dmm_knobs.min_split_size = MIN_SPLIT_SIZE;
 #endif /* SPLITTING_VARIABLE */
-            }
 #endif /* WITH_KNOBS */
 #ifdef WITH_ALLOCATOR_STATS
-    ,   {
 #ifdef REQUEST_SIZE_INFO
-          0,
+    allocator->dmm_stats.total_mem_requested = 0;
 #endif /* REQUEST_SIZE_INFO */
-          0
-        , 0
-        , 0
-        , 0
-        , 0
+    allocator->dmm_stats.total_mem_allocated = 0;
+    allocator->dmm_stats.live_objects = 0;
+    allocator->dmm_stats.num_malloc = 0;
+    allocator->dmm_stats.num_free = 0;
+    allocator->dmm_stats.num_realloc= 0;
 #ifdef WITH_MEMALIGN
-        , 0
+    allocator->dmm_stats.num_memalign = 0;
 #endif /* WITH_MEMALIGN */
-        }
 #endif /* WITH_ALLOCATOR_STATS */
 #ifdef PARSE_ENV
 #if defined  WITH_MEM_TRACE || defined WITH_STATS_TRACE || defined WITH_DEBUG
-    , .initialized = false
+    allocator->initialized = false;
+#endif /* WITH_MEM_TRACE || WITH_STATS_TRACE || WITH_DEBUG */
+#endif /* PARSE_ENV */
+
+    systemallocator = allocator;
+
+#ifdef PARSE_ENV
+    parse_env();
+#if defined  WITH_MEM_TRACE || defined WITH_STATS_TRACE || defined WITH_DEBUG
+    allocator->initialized = true;
 #endif /* WITH_MEM_TRACE || WITH_STATS_TRACE || WITH_DEBUG */
 #endif /* PARSE_ENV */
-};
 
+    return 0;
+}

+ 4 - 4
src/knobs.c

@@ -29,15 +29,15 @@
 
 uint32_t dmm_set_knobs(dmm_knobs_t *conf) {
     LOCK_GLOBAL();
-    systemallocator.dmm_knobs.sys_alloc_size = conf->sys_alloc_size;
+    systemallocator->dmm_knobs.sys_alloc_size = conf->sys_alloc_size;
 #ifdef GOOD_FIT
-    systemallocator.dmm_knobs.fit_percentage = conf->fit_percentage;
+    systemallocator->dmm_knobs.fit_percentage = conf->fit_percentage;
 #endif /* GOOD_FIT_PERCENTAGE */
 #ifdef COALESCING_VARIABLE
-    systemallocator.dmm_knobs.max_coal_size = conf->max_coal_size;
+    systemallocator->dmm_knobs.max_coal_size = conf->max_coal_size;
 #endif /* COALESCING_VARIABLE */
 #ifdef SPLITTING_VARIABLE
-    systemallocator.dmm_knobs.min_split_size = conf->min_split_size;
+    systemallocator->dmm_knobs.min_split_size = conf->min_split_size;
 #endif /* SPLITTING_VARIABLE */
     UNLOCK_GLOBAL();
     return 0;

+ 3 - 3
src/malloc.c

@@ -48,7 +48,7 @@ void * malloc(size_t size) {
     }
 
 #ifdef WITH_KNOBS
-    sys_alloc_size = (size_t) systemallocator.dmm_knobs.sys_alloc_size;
+    sys_alloc_size = (size_t) systemallocator->dmm_knobs.sys_alloc_size;
 #else /* WITH_KNOBS */
     sys_alloc_size = SYS_ALLOC_SIZE;
 #endif /* WITH_KNOBS */
@@ -74,7 +74,7 @@ void * malloc(size_t size) {
         ptr = NULL;
 
         /* Try to find a raw block available for allocation */
-        SLIST_FOREACH(raw_block, &systemallocator.rb_head, pointers) {
+        SLIST_FOREACH(raw_block, &systemallocator->rb_head, pointers) {
 #ifdef TRYLOCK_ON_MALLOC
             if(TRYLOCK_RAW_BLOCK(raw_block) == 0) {
 #else /* TRYLOCK_ON_MALLOC */
@@ -105,7 +105,7 @@ void * malloc(size_t size) {
             if(new_raw_block != NULL) {
                 LOCK_GLOBAL();
                 LOCK_RAW_BLOCK(new_raw_block);
-                SLIST_INSERT_HEAD(&systemallocator.rb_head, new_raw_block,
+                SLIST_INSERT_HEAD(&systemallocator->rb_head, new_raw_block,
                         pointers);
                 UNLOCK_GLOBAL();
 

+ 2 - 2
src/memalign.c

@@ -68,7 +68,7 @@ void *memalign(size_t alignment, size_t size) {
             sizeof(freelist_rb_t)) {
 
         /* Search the available freelist-organized raw blocks */
-        SLIST_FOREACH(raw_block, &systemallocator.rb_head, pointers) {
+        SLIST_FOREACH(raw_block, &systemallocator->rb_head, pointers) {
 #ifdef TRYLOCK_ON_MALLOC
             if(TRYLOCK_RAW_BLOCK(raw_block) == 0) {
 #else /* TRYLOCK_ON_MALLOC */
@@ -93,7 +93,7 @@ void *memalign(size_t alignment, size_t size) {
             if(raw_block != NULL) {
                 LOCK_GLOBAL();
                 LOCK_RAW_BLOCK(raw_block);
-                SLIST_INSERT_HEAD(&systemallocator.rb_head, raw_block, pointers);
+                SLIST_INSERT_HEAD(&systemallocator->rb_head, raw_block, pointers);
                 UNLOCK_GLOBAL();
 
                 encapsulated_rb = (DEFAULT_RB_T *)

+ 3 - 7
src/parse_env.c

@@ -30,10 +30,8 @@
 #include "dmmlib/config.h"
 #include "dmmlib/dmmlib.h"
 #include "dmmlib_trace.h"
+#include "parse_env.h"
 
-__attribute__((constructor)) void parse_env(void);
-
-/** Parses the DMMLIB_OPTS enviroment variable. */
 void parse_env(void) {
     const char* env;
 
@@ -74,7 +72,7 @@ void parse_env(void) {
         char *end;
         double good_fit_perc = strtod(env, &end);
         if(good_fit_perc != 0) {
-            systemallocator.dmm_knobs.fit_percentage = good_fit_perc;
+            systemallocator->dmm_knobs.fit_percentage = good_fit_perc;
         }
     }
 #endif /* WITH_KNOBS && GOOD_FIT */
@@ -86,13 +84,11 @@ void parse_env(void) {
         char *end;
         uintmax_t num = strtoumax(env, &end, 10);
         if(num != UINTMAX_MAX) {
-            systemallocator.dmm_knobs.sys_alloc_size = (double) num;
+            systemallocator->dmm_knobs.sys_alloc_size = (double) num;
         }
     }
 #endif /* WITH_KNOBS */
 
-    systemallocator.initialized = true;
-
     return;
 }
 

+ 2 - 2
src/realloc.c

@@ -118,7 +118,7 @@ void * realloc(void *ptr, size_t size) {
 
 #ifdef WITH_ALLOCATOR_STATS
                 LOCK_GLOBAL();
-                systemallocator.dmm_stats.total_mem_allocated -= remaining_size;
+                systemallocator->dmm_stats.total_mem_allocated -= remaining_size;
                 UNLOCK_GLOBAL();
 #endif /* WITH_ALLOCATOR_STATS */
 
@@ -156,7 +156,7 @@ void * realloc(void *ptr, size_t size) {
 
 #ifdef WITH_ALLOCATOR_STATS
                 LOCK_GLOBAL();
-                systemallocator.dmm_stats.total_mem_allocated += new_block->size
+                systemallocator->dmm_stats.total_mem_allocated += new_block->size
                     - owner_raw_block->size;
                 UNLOCK_GLOBAL();
 #endif /* WITH_ALLOCATOR_STATS */

+ 1 - 1
src/request_memory_mmap_linux.c

@@ -53,7 +53,7 @@ void *request_memory(size_t size) {
     } else {
 #ifdef WITH_ALLOCATOR_STATS
         LOCK_GLOBAL();
-        systemallocator.dmm_stats.total_mem_allocated += size;
+        systemallocator->dmm_stats.total_mem_allocated += size;
         UNLOCK_GLOBAL();
 #endif /* WITH_ALLOCATOR_STATS */
         return zone;

+ 5 - 5
src/statistics.c

@@ -98,13 +98,13 @@ void update_stats
 #ifdef REQUEST_SIZE_INFO
 /** Returns the total memory currently requested by the application. */
 size_t get_total_requested_memory(void) {
-    return systemallocator.dmm_stats.total_mem_requested;
+    return systemallocator->dmm_stats.total_mem_requested;
 }
 
 long double get_utilization_index(void) {
-    if(systemallocator.dmm_stats.total_mem_allocated != 0) {
-        return (long double) systemallocator.dmm_stats.total_mem_requested /
-            systemallocator.dmm_stats.total_mem_allocated;
+    if(systemallocator->dmm_stats.total_mem_allocated != 0) {
+        return (long double) systemallocator->dmm_stats.total_mem_requested /
+            systemallocator->dmm_stats.total_mem_allocated;
     } else {
         return 1.0;
     }
@@ -112,5 +112,5 @@ long double get_utilization_index(void) {
 #endif /* REQUEST_SIZE_INFO */
 
 size_t get_total_allocated_memory(void) {
-    return systemallocator.dmm_stats.total_mem_allocated;
+    return systemallocator->dmm_stats.total_mem_allocated;
 }