Permalink
Browse files

skynet defined lua alloc

  • Loading branch information...
cloudwu committed Dec 19, 2013
1 parent 331c800 commit 40281a8853a885428f3c2420ee6fc78718868d83
Showing with 191 additions and 1 deletion.
  1. +1 −1 Makefile
  2. +161 −0 service-src/luaalloc.c
  3. +14 −0 service-src/luaalloc.h
  4. +15 −0 service-src/service_lua.c
View
@@ -71,7 +71,7 @@ service/harbor.so : service-src/service_harbor.c
service/logger.so : skynet-src/skynet_logger.c
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
service/snlua.so : service-src/service_lua.c service-src/luacode_cache.c
service/snlua.so : service-src/service_lua.c service-src/luacode_cache.c service-src/luaalloc.c
gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src
service/gate.so : service-src/service_gate.c
View
@@ -0,0 +1,161 @@
#include "luaalloc.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define ALLOCCHUNK (16 * 1024 + sizeof(struct memchunk))
struct freenode {
struct freenode * next;
};
struct memchunk {
struct memchunk * next;
};
struct skynet_lalloc {
// small memory list : 8,16,32,64,128,256,512
struct freenode * freelist[7];
struct memchunk * chunklist;
char * ptr;
char * end;
};
static void
new_chunk(struct skynet_lalloc *lalloc) {
struct memchunk * mc = malloc(ALLOCCHUNK);
mc->next = lalloc->chunklist;
lalloc->ptr = (char *)(mc+1);
lalloc->end = ((char *)mc) + ALLOCCHUNK;
lalloc->chunklist = mc;
}
inline static int
size_index(size_t sz) {
if (sz > 32) {
if (sz > 128) {
if (sz > 256)
return 6;
else
return 5;
} else {
if (sz > 64)
return 4;
else
return 3;
}
} else {
if (sz > 16)
return 2;
else if (sz > 8)
return 1;
else
return 0;
}
}
#define REALSIZE(idx) (1<<((idx)+3))
static void *
new_small_block(struct skynet_lalloc *lalloc, int idx) {
struct freenode * fn = lalloc->freelist[idx];
if (fn) {
lalloc->freelist[idx] = fn->next;
return fn;
} else {
int rsz = REALSIZE(idx);
if ((lalloc->end - lalloc->ptr) < rsz) {
new_chunk(lalloc);
}
void * ret = lalloc->ptr;
lalloc->ptr += rsz;
return ret;
}
}
static void
delete_small_block(struct skynet_lalloc *lalloc, void * ptr, int idx) {
struct freenode * fn = lalloc->freelist[idx];
struct freenode * node = (struct freenode *)ptr;
node->next = fn;
lalloc->freelist[idx] = node;
}
static void *
extend_small_block(struct skynet_lalloc *lalloc, void * ptr, size_t osize, size_t nsize) {
int oidx = size_index(osize);
int nidx = size_index(nsize);
if (oidx == nidx) {
return ptr;
}
void * ret = new_small_block(lalloc,nidx);
memcpy(ret, ptr, osize < nsize ? osize : nsize);
delete_small_block(lalloc, ptr, oidx);
return ret;
}
void *
skynet_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
struct skynet_lalloc *lalloc = ud;
if (ptr == NULL) {
if (nsize > 512) {
return malloc(nsize);
}
int idx = size_index(nsize);
return new_small_block(lalloc, idx);
} else if (nsize == 0) {
if (osize > 512) {
free(ptr);
return NULL;
}
int idx = size_index(osize);
delete_small_block(lalloc, ptr, idx);
return NULL;
} else {
if (osize > 512) {
if (nsize > 512) {
return realloc(ptr, nsize);
} else {
int idx = size_index(nsize);
void * ret = new_small_block(lalloc, idx);
memcpy(ret, ptr, nsize);
free(ptr);
return ret;
}
}
if (nsize > 512) {
void * buffer = malloc(nsize);
memcpy(buffer, ptr, osize);
int idx = size_index(osize);
delete_small_block(lalloc, ptr, idx);
return buffer;
} else {
return extend_small_block(lalloc, ptr, osize, nsize);
}
}
}
struct skynet_lalloc *
skynet_lalloc_new(size_t prealloc) {
assert(prealloc > sizeof(struct skynet_lalloc));
struct skynet_lalloc * lalloc = malloc(prealloc);
int i;
for (i=0;i<sizeof(lalloc->freelist)/sizeof(lalloc->freelist[0]);i++) {
lalloc->freelist[i] = NULL;
}
lalloc->chunklist = NULL;
lalloc->ptr = (char *)(lalloc+1);
lalloc->end = ((char *)lalloc) + prealloc;
return lalloc;
}
void
skynet_lalloc_delete(struct skynet_lalloc *lalloc) {
struct memchunk * mc = lalloc->chunklist;
while(mc) {
struct memchunk * tmp = mc;
mc = mc->next;
free(tmp);
}
free(lalloc);
}
View
@@ -0,0 +1,14 @@
#ifndef skynet_lua_alloc_h
#define skynet_lua_alloc_h
#include <lua.h>
#include <stddef.h>
struct skynet_lalloc;
struct skynet_lalloc * skynet_lalloc_new(size_t prealloc);
void skynet_lalloc_delete(struct skynet_lalloc *);
void * skynet_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize);
#endif
View
@@ -7,12 +7,15 @@
#include "luacompat52.h"
#include "service_lua.h"
#include "luacode_cache.h"
#include "luaalloc.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define PREALLOCMEM (1024 * 1024)
// time
#include <time.h>
@@ -245,13 +248,25 @@ struct snlua *
snlua_create(void) {
struct snlua * l = malloc(sizeof(*l));
memset(l,0,sizeof(*l));
#ifdef PREALLOCMEM
l->L = lua_newstate(skynet_lua_alloc, skynet_lalloc_new(PREALLOCMEM));
#else
l->L = luaL_newstate();
#endif
l->init = _init;
return l;
}
void
snlua_release(struct snlua *l) {
void * ud = NULL;
#ifdef PREALLOCMEM
lua_Alloc lalloc = lua_getallocf(l->L, &ud);
assert(lalloc == skynet_lua_alloc);
lua_close(l->L);
skynet_lalloc_delete(ud);
#else
lua_close(l->L);
#endif
free(l);
}

0 comments on commit 40281a8

Please sign in to comment.