#include <assert.h>
#include <stdio.h>
+#ifndef ALLOCATOR_C_
+#define ALLOCATOR_C_
+#endif
+
#include "allocator.h"
#ifdef LEAK_DETECTIVE
};
/**
- * global list of allocations
- *
- * thread-save through mutex
+ * private allocator_t object
*/
-static memory_hdr_t *allocations = NULL;
+typedef struct private_allocator_s private_allocator_t;
+
+struct private_allocator_s
+{
+ /**
+ * public part of an allocator_t object
+ */
+ allocator_t public;
+
+ /**
+ * global list of allocations
+ *
+ * thread-save through mutex
+ */
+ memory_hdr_t *allocations;
+
+ /**
+ * Mutex to ensure, all functions are thread-save
+ */
+ pthread_mutex_t mutex;
+
+};
+
/**
- * Mutex to ensure, all functions are thread-save
+ * implements allocator_t's function allocate
*/
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/*
- * described in header
- */
-void * allocate(size_t bytes, char * file,int line)
+static void * allocate(allocator_t *allocator,size_t bytes, char * file,int line)
{
+ private_allocator_t *this = (private_allocator_t *) allocator;
memory_hdr_t *allocated_memory = malloc(sizeof(memory_hdr_t) + bytes);
if (allocated_memory == NULL)
return allocated_memory;
}
- pthread_mutex_lock( &mutex);
+ pthread_mutex_lock( &(this->mutex));
allocated_memory->info.line = line;
allocated_memory->info.filename = file;
allocated_memory->info.size_of_memory = bytes;
- allocated_memory->info.older = allocations;
- if (allocations != NULL)
+ allocated_memory->info.older = this->allocations;
+ if (this->allocations != NULL)
{
- allocations->info.newer = allocated_memory;
+ this->allocations->info.newer = allocated_memory;
}
- allocations = allocated_memory;
+ this->allocations = allocated_memory;
allocated_memory->info.newer = NULL;
/* fill memory with zero's */
memset(allocated_memory+1, '\0', bytes);
- pthread_mutex_unlock( &mutex);
+ pthread_mutex_unlock(&(this->mutex));
/* real memory starts after header */
return (allocated_memory+1);
}
-/*
- * described in header
- */
-void free_pointer(void * pointer)
+/**
+ * implements allocator_t's function free_pointer
+ */
+static void free_pointer(allocator_t *allocator, void * pointer)
{
+ private_allocator_t *this = (private_allocator_t *) allocator;
memory_hdr_t *allocated_memory;
if (pointer == NULL)
{
return;
}
- pthread_mutex_lock( &mutex);
+ pthread_mutex_lock( &(this->mutex));
allocated_memory = ((memory_hdr_t *)pointer) - 1;
if (allocated_memory->info.older != NULL)
}
if (allocated_memory->info.newer == NULL)
{
- assert(allocated_memory == allocations);
- allocations = allocated_memory->info.older;
+ assert(allocated_memory == this->allocations);
+ this->allocations = allocated_memory->info.older;
}
else
{
assert(allocated_memory->info.newer->info.older == allocated_memory);
allocated_memory->info.newer->info.older = allocated_memory->info.older;
}
- pthread_mutex_unlock( &mutex);
+ pthread_mutex_unlock(&(this->mutex));
free(allocated_memory);
}
-/*
- * described in header
- */
-void * reallocate(void * old, size_t bytes, char * file,int line)
+/**
+ * implements allocator_t's function reallocate
+ */
+static void * reallocate(allocator_t *allocator, void * old, size_t bytes, char * file,int line)
{
+ private_allocator_t *this = (private_allocator_t *) allocator;
memory_hdr_t *allocated_memory;
if (old == NULL)
{
return NULL;
}
- pthread_mutex_lock( &mutex);
+ pthread_mutex_lock( &(this->mutex));
allocated_memory = ((memory_hdr_t *)old) - 1;
- void *new_space = allocate(bytes,file,line);
+ void *new_space = this->public.allocate(&(this->public),bytes,file,line);
if (new_space == NULL)
{
- free_pointer(old);
- pthread_mutex_unlock( &mutex);
+ this->public.free_pointer(&(this->public),old);
+ pthread_mutex_unlock(&(this->mutex));
return NULL;
}
memcpy(new_space,old,allocated_memory->info.size_of_memory);
- pthread_mutex_unlock( &mutex);
+ pthread_mutex_unlock(&(this->mutex));
return new_space;
}
-
-/*
- * described in header
- */
-void report_memory_leaks(void)
+/**
+ * implements allocator_t's function report_memory_leaks
+ */
+static void allocator_report_memory_leaks(allocator_t *allocator)
{
- memory_hdr_t *p = allocations,
- *pprev = NULL;
+ private_allocator_t *this = (private_allocator_t *) allocator;
+ memory_hdr_t *p = this->allocations;
+ memory_hdr_t *pprev = NULL;
unsigned long n = 0;
- pthread_mutex_lock( &mutex);
+
+ pthread_mutex_lock(&(this->mutex));
while (p != NULL)
{
if (p == NULL || pprev->info.filename != p->info.filename)
{
if (n != 1)
- fprintf(stderr,"leak: %lu * File %s, Line %d\n", n, pprev->info.filename,pprev->info.line);
+ fprintf(stderr,"LEAK: \"%lu * File %s, Line %d\"\n", n, pprev->info.filename,pprev->info.line);
else
- fprintf(stderr,"leak: File %s, Line %d\n", pprev->info.filename,pprev->info.line);
+ fprintf(stderr,"LEAK: \"%s, Line %d\"\n", pprev->info.filename,pprev->info.line);
n = 0;
}
}
- pthread_mutex_unlock( &mutex);
+ pthread_mutex_unlock( &(this->mutex));
}
+static private_allocator_t allocator = {
+ public: {allocate: allocate,
+ free_pointer: free_pointer,
+ reallocate: reallocate,
+ report_memory_leaks: allocator_report_memory_leaks},
+ allocations: NULL,
+ mutex: PTHREAD_MUTEX_INITIALIZER
+};
+
+//allocator.public.allocate = (void *) (allocator_t *,size_t, char *,int) allocate;
+
+
+allocator_t *global_allocator = &(allocator.public);
#endif
#define allocator_alloc_thing(thing) (allocator_alloc(sizeof(thing)))
#ifdef LEAK_DETECTIVE
- /**
- * Allocates memory with LEAK_DETECTION and
- * returns an empty data area filled with zeros
- *
- * @warning use this function not directly, only with assigned macros
- * allocator_alloc and allocator_alloc_thing
- *
- * @param bytes number of bytes to allocate
- * @param file filename from which the memory is allocated
- * @param line line number in specific file
- * @return allocated memory area
- */
- void * allocate(size_t bytes, char * file,int line);
- /**
- * Reallocates memory with LEAK_DETECTION and
- * returns an empty data area filled with zeros
- *
- * @warning use this function not directly, only with assigned macro
- * allocator_realloc
- *
- * @param old pointer to the old data area
- * @param bytes number of bytes to allocate
- * @param file filename from which the memory is allocated
- * @param line line number in specific file
- * @return reallocated memory area
- */
- void * reallocate(void * old, size_t bytes, char * file, int line);
- /**
- * Frees memory with LEAK_DETECTION
- *
- * @warning use this function not directly, only with assigned macro
- * allocator_free
- *
- * @param pointer pointer to the data area to free
- */
- void free_pointer(void * pointer);
+ typedef struct allocator_s allocator_t;
+
+ struct allocator_s {
+
+ /**
+ * Allocates memory with LEAK_DETECTION and
+ * returns an empty data area filled with zeros
+ *
+ * @warning use this function not directly, only with assigned macros
+ * allocator_alloc and allocator_alloc_thing
+ *
+ * @param this allocator_t object
+ * @param bytes number of bytes to allocate
+ * @param file filename from which the memory is allocated
+ * @param line line number in specific file
+ * @return allocated memory area
+ */
+ void * (*allocate) (allocator_t *this,size_t bytes, char * file,int line);
+
+ /**
+ * Reallocates memory with LEAK_DETECTION and
+ * returns an empty data area filled with zeros
+ *
+ * @warning use this function not directly, only with assigned macro
+ * allocator_realloc
+ *
+ * @param this allocator_t object
+ * @param old pointer to the old data area
+ * @param bytes number of bytes to allocate
+ * @param file filename from which the memory is allocated
+ * @param line line number in specific file
+ * @return reallocated memory area
+ */
+ void * (*reallocate) (allocator_t *this,void * old, size_t bytes, char * file, int line);
+ /**
+ * Frees memory with LEAK_DETECTION
+ *
+ * @warning use this function not directly, only with assigned macro
+ * allocator_free
+ *
+ * @param this allocator_t object
+ * @param pointer pointer to the data area to free
+ */
+ void (*free_pointer) (allocator_t *this,void * pointer);
+
+ /**
+ * Report memory leaks to stderr
+ *
+ * @warning use this function not directly, only with assigned macro
+ * report_memory_leaks
+ *
+ * @param this allocator_t object
+ */
+ void (*report_memory_leaks) (allocator_t *this);
+ };
- #define allocator_alloc(bytes) (allocate(bytes,__FILE__,__LINE__))
- #define allocator_realloc(old,bytes) (reallocate(old,bytes,__FILE__, __LINE__))
- #define allocator_free(pointer) (free_pointer(pointer))
+ #ifndef ALLOCATOR_C_
+ extern allocator_t *global_allocator;
+ #endif
+
+ #define allocator_alloc(bytes) (global_allocator->allocate(global_allocator,bytes,__FILE__,__LINE__))
+ #define allocator_realloc(old,bytes) (global_allocator->reallocate(global_allocator,old,bytes,__FILE__, __LINE__))
+ #define allocator_free(pointer) (global_allocator->free_pointer(global_allocator,pointer))
#define allocator_free_chunk(chunk){ \
- free_pointer(chunk.ptr); \
+ global_allocator->free_pointer(global_allocator,chunk.ptr); \
chunk.ptr = NULL; \
chunk.len = 0; \
}
- /**
- * Report memory leaks to stderr
- */
- void report_memory_leaks(void);
+ #define report_memory_leaks(void) global_allocator->report_memory_leaks(global_allocator);
#else
#define allocator_alloc(bytes) (malloc(bytes))
#define allocator_realloc(old,bytes) (realloc(old,bytes))