diff --git a/include/tr/memory.h b/include/tr/memory.h index 127ae86..fe927f7 100644 --- a/include/tr/memory.h +++ b/include/tr/memory.h @@ -25,8 +25,19 @@ #define TR_MEM_FREE(seg) (TR_free((void **)&(seg))) +#include // for NULL definition #include +struct memSegment +{ + size_t ref_count; + size_t size; + int idx; + void * ptr; + + struct memSegment * next; +}; + /** * I found this at stanford.edu: * https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup @@ -36,10 +47,9 @@ * because on a 64bit system size_t is also 64bit and thus it is possible * to allocate that much amount of memory theoretically. */ -static inline int -bitwidth(size_t value) +TR_bitwidth(size_t value) { static const char LogTable256[256] = { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, @@ -52,7 +62,7 @@ bitwidth(size_t value) int r; // r will be lg(v) register size_t t1, t2, t3; // temporaries - if ((t3 = value >> 32)) { + if (sizeof(value) == 8 && (t3 = value >> 32)) { if ((t2 = t3 >> 16)) { r = (t1 = t2 >> 8) ? 56 + LogTable256[t1] : 48 + LogTable256[t2]; } else { @@ -69,11 +79,50 @@ bitwidth(size_t value) return r; } +inline +struct memSegment * +_getMemInfo(void * mem) +{ + if (NULL == mem) { + return 0; + } + + return (struct memSegment *)(mem - sizeof(struct memSegment)); +} + +inline +size_t +TR_getSize(void * mem) +{ + struct memSegment * segment = + (struct memSegment *)(mem - sizeof(struct memSegment)); + + return segment ? segment->size : 0; +} + +inline +size_t +TR_getUsableSize(void * mem) +{ + size_t size = TR_getSize(mem); + + return size ? size - sizeof(struct memSegment) : 0; +} + +inline +int +TR_getIdx(void * mem) +{ + struct memSegment * segment = + (struct memSegment *)(mem - sizeof(struct memSegment)); + + return segment ? segment->idx : -1; +} + void * TR_malloc(size_t); void * TR_calloc(size_t, size_t); void * TR_reference(void *); void TR_free(void **); -size_t TR_getSize(void *); void TR_cleanup(); char * TR_strdup(const char *); diff --git a/src/memory.c b/src/memory.c index 87ff5af..7a27a74 100644 --- a/src/memory.c +++ b/src/memory.c @@ -48,7 +48,6 @@ #include -#include #include #include #include @@ -57,16 +56,24 @@ #include "tr/memory.h" +#ifdef _WIN32 +#define _SC_PAGESIZE 2048L -struct memSegment +long +sysconf(int name) { - size_t ref_count; - size_t size; - int idx; - void * ptr; + switch (name) { + case _SC_PAGESIZE: return 2048L; + } - struct memSegment * next; -}; + return -1; +} +#endif + +extern inline int TR_bitwidth(size_t); +extern inline size_t TR_getSize(void *); +extern inline size_t TR_getUsableSize(void *); +extern inline int TR_getIdx(void *); static struct memSegment * @@ -116,7 +123,6 @@ deleteElement(struct memSegment ** stack) #define TR_MAX_MEM_IDX 1024 struct memSegment * segments[TR_MAX_MEM_IDX] = {}; -pthread_mutex_t TR_memop_lock = PTHREAD_MUTEX_INITIALIZER; static inline @@ -176,19 +182,20 @@ TR_malloc(size_t size) static int psize_width = 0; int idx; - if (psize_width == 0) psize_width = bitwidth(psize); + psize_width = psize_width ? psize_width : TR_bitwidth(psize); size += sizeof(struct memSegment); #define MIN_BITS 8 if (size >= psize) { + // get a multiple of pagesize idx = size / psize; if (0 != (size % psize)) { // size if not a multiple of pagesize so bring it to one. - size = (idx + 1) * psize; idx++; + size = idx * psize; } idx += psize_width - MIN_BITS; @@ -199,7 +206,7 @@ TR_malloc(size_t size) } else { size_t mask; - idx = bitwidth(size); + idx = TR_bitwidth(size); mask = (1 << (idx + 1)) - 1; idx -= (MIN_BITS - 1); @@ -214,9 +221,7 @@ TR_malloc(size_t size) #ifdef MEM_OPT if (idx < TR_MAX_MEM_IDX) { - pthread_mutex_lock(&TR_memop_lock); seg = deleteElement(&(segments[idx])); - pthread_mutex_unlock(&TR_memop_lock); } else #endif { @@ -260,9 +265,7 @@ TR_free(void ** mem) } else { #ifdef MEM_OPT if (-1 != seg->idx) { - pthread_mutex_lock(&TR_memop_lock); insertElement(&(segments[seg->idx]), seg); - pthread_mutex_unlock(&TR_memop_lock); } else #endif { @@ -274,19 +277,6 @@ TR_free(void ** mem) } } -size_t -TR_getSize(void * mem) -{ - struct memSegment * segment; - - if (NULL == mem) { - return 0; - } - - segment = (struct memSegment *)(mem - sizeof(struct memSegment)); - return segment->size; -} - void TR_cleanup() { diff --git a/tests/foo.c b/tests/foo.c new file mode 100644 index 0000000..5fe88da --- /dev/null +++ b/tests/foo.c @@ -0,0 +1,19 @@ +#include +#include + +#include "trbase.h" + +int +main (int argc, char * argv[]) +{ + void * foo = TR_malloc(strtol(argv[1], NULL, 10)); + + printf("idx: %d / size: %zd / usable_size: %zd\n", + TR_getIdx(foo), + TR_getSize(foo), + TR_getUsableSize(foo)); + + return 0; +} + +// vim: set ts=4 sw=4: