rewrite makefile, and remove luacode cache.

This commit is contained in:
Cloud Wu
2014-03-26 15:13:30 +08:00
parent 103602259a
commit 58aa7556a5
107 changed files with 20585 additions and 1070 deletions

View File

@@ -1,161 +0,0 @@
#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 File

@@ -1,14 +0,0 @@
#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 File

@@ -1,385 +0,0 @@
#include "luacode_cache.h"
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {}
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
struct codecache {
int lock;
lua_State *L;
};
static struct codecache CC = { 0 , NULL };
static void
_clearcache() {
if (CC.L == NULL)
return;
LOCK(&CC)
lua_close(CC.L);
CC.L = luaL_newstate();
UNLOCK(&CC)
}
static void
_init() {
CC.lock = 0;
CC.L = luaL_newstate();
}
static const char *
_load(const char *key, size_t *sz) {
if (CC.L == NULL)
return NULL;
LOCK(&CC)
lua_State *L = CC.L;
lua_getglobal(L, key);
const char * result = NULL;
if (lua_isstring(L,-1)) {
result = lua_tolstring(L, -1, sz);
}
lua_pop(L, 1);
UNLOCK(&CC)
return result;
}
static const char *
_save(const char *key, const char * code, size_t *sz) {
lua_State *L;
const char * result = NULL;
LOCK(&CC)
if (CC.L == NULL) {
_init();
L = CC.L;
} else {
L = CC.L;
lua_getglobal(L, key);
if (lua_isstring(L,-1)) {
size_t code_sz = *sz;
result = lua_tolstring(L, -1, sz);
assert(code_sz == *sz);
lua_pop(L, 1);
goto _ret;
}
lua_pop(L, 1);
}
lua_pushlstring(L, code, *sz);
result = lua_tostring(L, -1);
lua_setglobal(L, key);
_ret:
UNLOCK(&CC)
return result;
}
const char *
luacode_load(const char * key, const char * code, size_t *sz) {
if (code == NULL) {
return _load(key, sz);
}
const char * result = _load(key,sz);
if (result) {
return result;
}
return _save(key, code, sz);
}
// copy from lbaselib.c
static int
load_aux (lua_State *L, int status, int envidx) {
if (status == LUA_OK) {
if (envidx != 0) { /* 'env' parameter? */
lua_pushvalue(L, envidx); /* environment for loaded function */
if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */
lua_pop(L, 1); /* remove 'env' if not used by previous call */
}
return 1;
}
else { /* error (message is on top of the stack) */
lua_pushnil(L);
lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */
}
}
static int
writer (lua_State *L, const void* b, size_t size, void* B) {
(void)L;
luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
return 0;
}
static void
str_dump (lua_State *L) {
luaL_Buffer b;
luaL_buffinit(L,&b);
if (lua_dump(L, writer, &b) != 0)
luaL_error(L, "unable to dump given function");
luaL_pushresult(&b);
}
static int
cache_loadfile(lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
const char *mode = luaL_optstring(L, 2, NULL);
int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */
int status;
if (fname == NULL) {
status = luaL_loadfilex(L, fname, mode);
} else {
// read cache
size_t sz = 0;
const char * bytecode = luacode_load(fname, NULL, &sz);
if (bytecode) {
// load from cache
status = luaL_loadbuffer(L, bytecode, sz, fname);
} else {
status = luaL_loadfilex(L, fname, mode);
if (status == LUA_OK) {
str_dump(L);
const char * bytecode = lua_tolstring(L,-1,&sz);
// update cache
luacode_load(fname, bytecode, &sz);
lua_pop(L,1);
}
}
}
return load_aux(L, status, env);
}
/*
** reserved slot, above all arguments, to hold a copy of the returned
** string to avoid it being collected while parsed. 'load' has four
** optional arguments (chunk, source name, mode, and environment).
*/
#define RESERVEDSLOT 5
/*
** Reader for generic `load' function: `lua_load' uses the
** stack for internal stuff, so the reader cannot change the
** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
(void)(ud); /* not used */
luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* pop result */
*size = 0;
return NULL;
}
else if (!lua_isstring(L, -1))
luaL_error(L, "reader function must return a string");
lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
return lua_tolstring(L, RESERVEDSLOT, size);
}
static int
cache_load(lua_State *L) {
int status;
size_t l;
const char *s = lua_tolstring(L, 1, &l);
const char *mode = luaL_optstring(L, 3, "bt");
int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
const char *cname = lua_tostring(L,2);
if (cname) {
// read cache
size_t sz = 0;
const char * bytecode = luacode_load(cname, NULL, &sz);
if (bytecode) {
// load from cache
status = luaL_loadbuffer(L, bytecode, sz, cname);
return load_aux(L, status, env);
}
}
if (s != NULL) { /* loading a string? */
const char *chunkname = luaL_optstring(L, 2, s);
status = luaL_loadbufferx(L, s, l, chunkname, mode);
}
else { /* loading from a reader function */
const char *chunkname = luaL_optstring(L, 2, "=(load)");
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, RESERVEDSLOT); /* create reserved slot */
status = lua_load(L, generic_reader, NULL, chunkname, mode);
}
if (cname && status == LUA_OK) {
size_t sz = 0;
str_dump(L);
const char * bytecode = lua_tolstring(L,-1,&sz);
// update cache
luacode_load(cname, bytecode, &sz);
lua_pop(L,1);
}
return load_aux(L, status, env);
}
int
luacode_loadfile(lua_State *L, const char *filename) {
size_t sz = 0;
const char * bytecode = luacode_load(filename, NULL, &sz);
int status;
if (bytecode) {
status = luaL_loadbuffer(L, bytecode, sz, filename);
} else {
status = luaL_loadfile(L, filename);
if (status == LUA_OK) {
str_dump(L);
const char * bytecode = lua_tolstring(L,-1,&sz);
// update cache
luacode_load(filename, bytecode, &sz);
lua_pop(L,1);
}
}
return status;
}
// require loader, copy and modify from loadlib.c
#if !defined (LUA_PATH_SEP)
#define LUA_PATH_SEP ";"
#endif
#if !defined (LUA_PATH_MARK)
#define LUA_PATH_MARK "?"
#endif
#if !defined(LUA_LSUBSEP)
#define LUA_LSUBSEP LUA_DIRSEP
#endif
static int
readable (const char *filename) {
size_t sz = 0;
const char * bytecode = luacode_load(filename, NULL, &sz);
if (bytecode) {
return 1;
}
FILE *f = fopen(filename, "r"); /* try to open file */
if (f == NULL) return 0; /* open failed */
fclose(f);
return 1;
}
static const char *
pushnexttemplate (lua_State *L, const char *path) {
const char *l;
while (*path == *LUA_PATH_SEP) path++; /* skip separators */
if (*path == '\0') return NULL; /* no more templates */
l = strchr(path, *LUA_PATH_SEP); /* find next separator */
if (l == NULL) l = path + strlen(path);
lua_pushlstring(L, path, l - path); /* template */
return l;
}
static const char *
searchpath (lua_State *L, const char *name,
const char *path,
const char *sep,
const char *dirsep) {
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
luaL_addvalue(&msg); /* concatenate error msg. entry */
}
luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
static const char *
findfile (lua_State *L, const char *name,
const char *pname,
const char *dirsep) {
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
return searchpath(L, name, path, ".", dirsep);
}
static int
checkload (lua_State *L, int stat, const char *filename) {
if (stat) { /* module loaded successfully? */
lua_pushstring(L, filename); /* will be 2nd argument to module */
return 2; /* return open function and file name */
}
else
return luaL_error(L, "error loading module " LUA_QS
" from file " LUA_QS ":\n\t%s",
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
static int
searcher_cache (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path", LUA_LSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (luacode_loadfile(L, filename) == LUA_OK), filename);
}
static int
replace_searcher_lua(lua_State *L) {
lua_getglobal(L, "package");
if (!lua_istable(L,-1)) {
// luaL_error(L, "Can't find package");
return 1;
}
lua_getfield(L, -1, "searchers");
if (!lua_istable(L,-1)) {
// luaL_error(L, "Can't find package.searchers");
return 1;
}
lua_pushvalue(L,-2);
lua_pushcclosure(L, searcher_cache, 1);
// package.searcher[2] is searcher_lua, replace it.
lua_rawseti(L, -2, 2);
lua_pop(L,2);
return 0;
}
static int
cache_clear(lua_State *L) {
_clearcache();
return 0;
}
//-------------------------
int
luacode_lib(lua_State *L) {
if (replace_searcher_lua(L)) {
// Don't support package.searchers
return 0;
}
luaL_Reg l[] = {
{ "load", cache_load },
{ "clear", cache_clear },
{ "loadfile", cache_loadfile },
{ NULL, NULL },
};
luaL_newlib(L,l);
return 1;
}

View File

@@ -1,10 +0,0 @@
#ifndef lua_code_cache_h
#define lua_code_cache_h
#include <lua.h>
#include <stddef.h>
int luacode_loadfile(lua_State *L, const char *filename);
int luacode_lib(lua_State *);
#endif

View File

@@ -0,0 +1,56 @@
#include "skynet.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
struct logger {
FILE * handle;
int close;
};
struct logger *
logger_create(void) {
struct logger * inst = malloc(sizeof(*inst));
inst->handle = NULL;
inst->close = 0;
return inst;
}
void
logger_release(struct logger * inst) {
if (inst->close) {
fclose(inst->handle);
}
free(inst);
}
static int
_logger(struct skynet_context * context, void *ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
struct logger * inst = ud;
fprintf(inst->handle, "[:%x] ",source);
fwrite(msg, sz , 1, inst->handle);
fprintf(inst->handle, "\n");
fflush(inst->handle);
return 0;
}
int
logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) {
if (parm) {
inst->handle = fopen(parm,"w");
if (inst->handle == NULL) {
return 1;
}
inst->close = 1;
} else {
inst->handle = stdout;
}
if (inst->handle) {
skynet_callback(ctx, inst, _logger);
skynet_command(ctx, "REG", ".logger");
return 0;
}
return 1;
}

View File

@@ -4,33 +4,13 @@
#include <lualib.h>
#include <lauxlib.h>
#include <assert.h>
#include "luacompat52.h"
#include "service_lua.h"
#include "luaalloc.h"
#include "luacode_cache.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// define PREALLOCMEM to enable skynet defined alloc
//#define PREALLOCMEM (1024 * 1024)
// define NOCODECACHE to disable lua code cache
#define NOCODECACHE
#ifdef NOCODECACHE
#define loadfile(L, name) luaL_loadfile(L,name)
#else
// luacode_loadfile is the same with luaL_loadfile except cache.
#define loadfile(L, name) luacode_loadfile(L,name)
#endif
// LUA_CACHELIB may defined in patched lua for shared proto
#ifdef LUA_CACHELIB
@@ -38,7 +18,22 @@
#else
#define codecache luacode_lib
static int
cleardummy(lua_State *L) {
return 0;
}
static int
codecache(lua_State *L) {
luaL_Reg l[] = {
{ "clear", cleardummy },
{ NULL, NULL },
};
luaL_newlib(L,l);
lua_getglobal(L, "loadfile");
lua_setfield(L, -2, "loadfile");
return 1;
}
#endif
@@ -96,7 +91,7 @@ _try_load(lua_State *L, const char * path, int pathlen, const char * name) {
exit(1);
}
tmp[namelen+pathlen-1] = '\0';
int r = loadfile(L,tmp);
int r = luaL_loadfile(L,tmp);
if (r == LUA_OK) {
int i;
for (i=namelen+pathlen-2;i>=0;i--) {
@@ -190,7 +185,6 @@ static int
_init(struct snlua *l, struct skynet_context *ctx, const char * args) {
lua_State *L = l->L;
l->ctx = ctx;
luaL_init(L);
lua_gc(L, LUA_GCSTOP, 0);
luaL_openlibs(L);
lua_pushlightuserdata(L, l);
@@ -273,25 +267,13 @@ 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) {
#ifdef PREALLOCMEM
void * ud = NULL;
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);
}