|
|
|
@ -14,6 +14,7 @@
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
|
@ -21,9 +22,53 @@
|
|
|
|
|
|
|
|
|
|
#include <sntl/mcache.h>
|
|
|
|
|
|
|
|
|
|
static long __cmp_longs(const void *a, const void *b)
|
|
|
|
|
{
|
|
|
|
|
return (long)(*(unsigned long*)a - *(unsigned long*)b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int sntl_mcache_init(sntl_mcache_t *mc, size_t esize, int flags)
|
|
|
|
|
{
|
|
|
|
|
return EINVAL;
|
|
|
|
|
int r = 0, i;
|
|
|
|
|
usrtc_t *tree;
|
|
|
|
|
void *pt;
|
|
|
|
|
struct _mpg *pg;
|
|
|
|
|
|
|
|
|
|
/* check it */
|
|
|
|
|
if((esize < _MCACHE_EMINSIZE) || (esize > _MCACHE_EMAXSIZE)) return EINVAL;
|
|
|
|
|
|
|
|
|
|
/* yep, nil it */
|
|
|
|
|
memset(mc, 0, sizeof(sntl_mcache_t));
|
|
|
|
|
|
|
|
|
|
mc->magic = _MCACHE_MAGIC; /* let it be */
|
|
|
|
|
|
|
|
|
|
if((r = pthread_rwlock_init(&(mc->lock), NULL))) return -r;
|
|
|
|
|
|
|
|
|
|
/* init trees */
|
|
|
|
|
for(i = 0; i < 3; i ++) {
|
|
|
|
|
switch(i) {
|
|
|
|
|
case 0: tree = &(mc->pg_tree); break;
|
|
|
|
|
case 1: tree = &(mc->allocated); break;
|
|
|
|
|
case 2: tree = &(mc->used); break;
|
|
|
|
|
}
|
|
|
|
|
usrtc_init(tree, USRTC_REDBLACK, 129038, __cmp_longs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* deal with flags */
|
|
|
|
|
mc->flags = flags;
|
|
|
|
|
/* sizes */
|
|
|
|
|
mc->esize = esize + sizeof(unsigned long);
|
|
|
|
|
mc->epc = (_MPG_SIZE - sizeof(struct _mpg)) / mc->esize;
|
|
|
|
|
|
|
|
|
|
if((flags & _MCACHE_PREALLOC)) {
|
|
|
|
|
pt = mmap(NULL, _MPG_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS, -1, 0);
|
|
|
|
|
if(pt == MAP_FAILED) {
|
|
|
|
|
pthread_rwlock_destroy(&(mc->lock));
|
|
|
|
|
return ENOMEM;
|
|
|
|
|
} else pg = (struct _mpg *)pt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* sntl_mcache_alloc(sntl_mcache_t *mc)
|
|
|
|
|