Browse Source

creared some inline functions to access the meminfo structure.

1.0.2
Georg Hopp 11 years ago
parent
commit
3f28478d32
  1. 57
      include/tr/memory.h
  2. 48
      src/memory.c
  3. 19
      tests/foo.c

57
include/tr/memory.h

@ -25,8 +25,19 @@
#define TR_MEM_FREE(seg) (TR_free((void **)&(seg))) #define TR_MEM_FREE(seg) (TR_free((void **)&(seg)))
#include <stdlib.h> // for NULL definition
#include <sys/types.h> #include <sys/types.h>
struct memSegment
{
size_t ref_count;
size_t size;
int idx;
void * ptr;
struct memSegment * next;
};
/** /**
* I found this at stanford.edu: * I found this at stanford.edu:
* https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup * 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 * because on a 64bit system size_t is also 64bit and thus it is possible
* to allocate that much amount of memory theoretically. * to allocate that much amount of memory theoretically.
*/ */
static
inline inline
int int
bitwidth(size_t value)
TR_bitwidth(size_t value)
{ {
static const char LogTable256[256] = { static const char LogTable256[256] = {
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, -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) int r; // r will be lg(v)
register size_t t1, t2, t3; // temporaries register size_t t1, t2, t3; // temporaries
if ((t3 = value >> 32)) {
if (sizeof(value) == 8 && (t3 = value >> 32)) {
if ((t2 = t3 >> 16)) { if ((t2 = t3 >> 16)) {
r = (t1 = t2 >> 8) ? 56 + LogTable256[t1] : 48 + LogTable256[t2]; r = (t1 = t2 >> 8) ? 56 + LogTable256[t1] : 48 + LogTable256[t2];
} else { } else {
@ -69,11 +79,50 @@ bitwidth(size_t value)
return r; 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_malloc(size_t);
void * TR_calloc(size_t, size_t); void * TR_calloc(size_t, size_t);
void * TR_reference(void *); void * TR_reference(void *);
void TR_free(void **); void TR_free(void **);
size_t TR_getSize(void *);
void TR_cleanup(); void TR_cleanup();
char * TR_strdup(const char *); char * TR_strdup(const char *);

48
src/memory.c

@ -48,7 +48,6 @@
#include <stdio.h> #include <stdio.h>
#include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <search.h> #include <search.h>
@ -57,16 +56,24 @@
#include "tr/memory.h" #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 static
struct memSegment * struct memSegment *
@ -116,7 +123,6 @@ deleteElement(struct memSegment ** stack)
#define TR_MAX_MEM_IDX 1024 #define TR_MAX_MEM_IDX 1024
struct memSegment * segments[TR_MAX_MEM_IDX] = {}; struct memSegment * segments[TR_MAX_MEM_IDX] = {};
pthread_mutex_t TR_memop_lock = PTHREAD_MUTEX_INITIALIZER;
static static
inline inline
@ -176,19 +182,20 @@ TR_malloc(size_t size)
static int psize_width = 0; static int psize_width = 0;
int idx; int idx;
if (psize_width == 0) psize_width = bitwidth(psize);
psize_width = psize_width ? psize_width : TR_bitwidth(psize);
size += sizeof(struct memSegment); size += sizeof(struct memSegment);
#define MIN_BITS 8 #define MIN_BITS 8
if (size >= psize) { if (size >= psize) {
// get a multiple of pagesize
idx = size / psize; idx = size / psize;
if (0 != (size % psize)) { if (0 != (size % psize)) {
// size if not a multiple of pagesize so bring it to one. // size if not a multiple of pagesize so bring it to one.
size = (idx + 1) * psize;
idx++; idx++;
size = idx * psize;
} }
idx += psize_width - MIN_BITS; idx += psize_width - MIN_BITS;
@ -199,7 +206,7 @@ TR_malloc(size_t size)
} else { } else {
size_t mask; size_t mask;
idx = bitwidth(size);
idx = TR_bitwidth(size);
mask = (1 << (idx + 1)) - 1; mask = (1 << (idx + 1)) - 1;
idx -= (MIN_BITS - 1); idx -= (MIN_BITS - 1);
@ -214,9 +221,7 @@ TR_malloc(size_t size)
#ifdef MEM_OPT #ifdef MEM_OPT
if (idx < TR_MAX_MEM_IDX) { if (idx < TR_MAX_MEM_IDX) {
pthread_mutex_lock(&TR_memop_lock);
seg = deleteElement(&(segments[idx])); seg = deleteElement(&(segments[idx]));
pthread_mutex_unlock(&TR_memop_lock);
} else } else
#endif #endif
{ {
@ -260,9 +265,7 @@ TR_free(void ** mem)
} else { } else {
#ifdef MEM_OPT #ifdef MEM_OPT
if (-1 != seg->idx) { if (-1 != seg->idx) {
pthread_mutex_lock(&TR_memop_lock);
insertElement(&(segments[seg->idx]), seg); insertElement(&(segments[seg->idx]), seg);
pthread_mutex_unlock(&TR_memop_lock);
} else } else
#endif #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 void
TR_cleanup() TR_cleanup()
{ {

19
tests/foo.c

@ -0,0 +1,19 @@
#include <stdio.h>
#include <stdlib.h>
#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:
Loading…
Cancel
Save