Browse Source

added new memory management to the most fragile part in this matter...the class system...well, the server test gives me a memory corruption, but all other are running now....anyway most likely this is in an unusable state right now.

release0.1.5
Georg Hopp 12 years ago
parent
commit
fc40342711
  1. 12
      src/class/interface/i_class.c
  2. 19
      src/logger/interface/i_logger.c
  3. 46
      src/utils/memory.c
  4. 2
      tests/Makefile.am

12
src/class/interface/i_class.c

@ -27,6 +27,9 @@
#include "class/class.h" #include "class/class.h"
#include "class/interface/class.h" #include "class/interface/class.h"
#include "utils/memory.h"
const const
struct interface i_Class = { struct interface i_Class = {
"class", "class",
@ -36,7 +39,7 @@ struct interface i_Class = {
void * void *
classNew(class_ptr class, ...) classNew(class_ptr class, ...)
{ {
void * object = calloc(1, class->object_size + sizeof(void*));
void * object = memCalloc(1, class->object_size + sizeof(void*));
va_list params; va_list params;
int ret; int ret;
@ -58,9 +61,12 @@ void
classDelete(void ** object) classDelete(void ** object)
{ {
if (NULL != *object) { if (NULL != *object) {
void * mem;
CALL(*object, Class, dtor); CALL(*object, Class, dtor);
free(*object - sizeof(void*));
mem = *object - sizeof(void*);
MEM_FREE(mem);
*object = NULL; *object = NULL;
} }
} }
@ -69,7 +75,7 @@ void *
classClone(void * _object) classClone(void * _object)
{ {
class_ptr class = GET_CLASS(_object); class_ptr class = GET_CLASS(_object);
void * object = calloc(1, class->object_size + sizeof(void*));
void * object = memCalloc(1, class->object_size + sizeof(void*));
* (class_ptr *)object = class; * (class_ptr *)object = class;
object += sizeof(void*); object += sizeof(void*);

19
src/logger/interface/i_logger.c

@ -53,7 +53,24 @@ loggerLog(void * _object, logger_level level, const char * const fmt, ...) {
vsnprintf(msg, msg_size + 1, fmt, params); vsnprintf(msg, msg_size + 1, fmt, params);
va_end(params); va_end(params);
CALL(_object, Logger, log, level, msg);
// ----- DEBUG ------
do {
struct i_Logger * iface;
do {
class_ptr class = GET_CLASS(_object);
iface = (struct i_Logger *)IFACE_GET(class, &i_Logger);
while ((NULL == iface || NULL == iface->log) && HAS_PARENT(class)) {
class = class->parent;
iface = (struct i_Logger *)IFACE_GET(class, &i_Logger);
}
assert(NULL != iface->log);
} while(0);
iface->log(_object, level, msg);
} while(0);
// ----- DEBUG ------
//CALL(_object, Logger, log, level, msg);
MEM_FREE(msg); MEM_FREE(msg);
} }

46
src/utils/memory.c

@ -42,6 +42,7 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE #define _GNU_SOURCE
#include <search.h> #include <search.h>
@ -108,56 +109,51 @@ segmentFree(void * segment)
void * void *
memMalloc(size_t size) memMalloc(size_t size)
{ {
struct memSegment * seg = tfind(&size, &segments, segmentFindCmp);
struct memSegment ** seg_ptr = tfind(&size, &segments, segmentFindCmp);
struct memSegment * seg;
if (NULL == seg) {
if (NULL == seg_ptr) {
seg = (struct memSegment *)malloc(sizeof(struct memSegment) + size); seg = (struct memSegment *)malloc(sizeof(struct memSegment) + size);
seg->size = size; seg->size = size;
seg->ptr = seg + sizeof(struct memSegment);
seg->ptr = (void *)seg + sizeof(struct memSegment);
} else { } else {
seg = *seg_ptr;
// remove the found one from the tree as we use it now. // remove the found one from the tree as we use it now.
tdelete((void *)seg, &segments, segmentSearchCmp); tdelete((void *)seg, &segments, segmentSearchCmp);
seg = *(struct memSegment **)seg;
} }
return seg->ptr; return seg->ptr;
} }
/** /**
* we do NOT ensure that the memory region is zeroed
* because we want the best performance.
* Most times this is not neccessary at all.
* this is a really memory wasting solution....just to be able to
* use calloc, which might be faster then malloc/memset solution.
*
* Maybe this is a bad idea, as we need to memset the buffer anyway
* if it comes from our tree, which hopefully should be the majority
* of cases.
*/ */
void * void *
memCalloc(size_t nmemb, size_t size) memCalloc(size_t nmemb, size_t size)
{ {
size_t _size = nmemb * size;
size_t _inmemb = (sizeof(struct memSegment) / size) + 1;
struct memSegment * seg = tfind(&_size, &segments, segmentFindCmp);
size_t _size = nmemb * size;
void * mem = memMalloc(_size);
struct memSegment * seg =
(struct memSegment *)(mem - sizeof(struct memSegment));
if (NULL == seg) {
seg = (struct memSegment *)calloc(nmemb + _inmemb, size);
seg->size = size;
seg->ptr = seg + sizeof(struct memSegment);
} else {
// remove the found one from the tree as we use it now.
tdelete((void *)seg, &segments, segmentSearchCmp);
seg = *(struct memSegment **)seg;
}
printf("DEBUG %zu : %zu\n", _size, seg->size);
return seg->ptr;
memset(mem, 0, _size);
return mem;
} }
void void
memFree(void ** mem) memFree(void ** mem)
{ {
if (NULL != *mem) { if (NULL != *mem) {
struct memSegment * seg = *(struct memSegment **)mem;
seg -= sizeof(struct memSegment);
tsearch((void *)seg, &segments, segmentSearchCmp);
void * foo = tsearch(*mem - sizeof(struct memSegment), &segments, segmentSearchCmp);
*mem = NULL; *mem = NULL;
} }
} }

2
tests/Makefile.am

@ -8,6 +8,7 @@ COMMON = runtest.c
CLASS = $(COMMON) \ CLASS = $(COMMON) \
../src/class/interface.c \ ../src/class/interface.c \
../src/class/interface/i_class.c \ ../src/class/interface/i_class.c \
../src/utils/memory.c \
mock/mock_class.c mock/mock_class.c
LOGGER = $(CLASS) \ LOGGER = $(CLASS) \
@ -15,7 +16,6 @@ LOGGER = $(CLASS) \
../src/logger/stderr.c \ ../src/logger/stderr.c \
../src/logger/syslog.c \ ../src/logger/syslog.c \
../src/logger/interface/i_logger.c \ ../src/logger/interface/i_logger.c \
../src/utils/memory.c \
mock/mock_logger.c mock/mock_logger.c
SOCKET = $(LOGGER) \ SOCKET = $(LOGGER) \

Loading…
Cancel
Save