From 686e57cf9c61070ff961407e3304071e171542f4 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 13 Sep 2013 13:21:52 -0300 Subject: GC local pause configurable --- lapi.c | 7 ++++++- lbaselib.c | 8 +++++--- lgc.c | 46 +++++++++++++++++++--------------------------- lstate.c | 7 ++++++- lstate.h | 3 ++- lua.h | 5 +++-- 6 files changed, 41 insertions(+), 35 deletions(-) diff --git a/lapi.c b/lapi.c index 1dacf222..46af4ce0 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.188 2013/08/27 18:53:35 roberto Exp roberto $ +** $Id: lapi.c,v 2.189 2013/09/11 20:15:31 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -1086,6 +1086,11 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g->gcpause = data; break; } + case LUA_GCSETLOCALPAUSE: { + res = g->gclocalpause; + g->gclocalpause = data; + break; + } case LUA_GCSETSTEPMUL: { res = g->gcstepmul; g->gcstepmul = data; diff --git a/lbaselib.c b/lbaselib.c index 63e9820b..9e3c5c87 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.280 2013/07/10 17:15:12 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.281 2013/08/05 16:58:28 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -174,9 +174,11 @@ static int luaB_rawset (lua_State *L) { static int luaB_collectgarbage (lua_State *L) { static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpause", "setstepmul", "isrunning", NULL}; + "count", "step", "setpause", "setstepmul", + "setlocalpause", "isrunning", NULL}; static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, - LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCISRUNNING}; + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCSETLOCALPAUSE, LUA_GCISRUNNING}; int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; int ex = luaL_optint(L, 2, 0); int res = lua_gc(L, o, ex); diff --git a/lgc.c b/lgc.c index 62e3777f..1f620345 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.163 2013/09/11 14:47:08 roberto Exp roberto $ +** $Id: lgc.c,v 2.164 2013/09/11 14:56:15 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -24,12 +24,6 @@ -/* -** How much memory to allocate before a new local collection -*/ -#define GCLOCALPAUSE 8000 - - /* ** cost of sweeping one element (the size of a small object divided ** by some adjust for the sweep speed) @@ -149,7 +143,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { global_State *g = G(L); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); lua_assert(g->gcstate != GCSpause); - lua_assert(gch(o)->tt != LUA_TTABLE); + lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */ if (keepinvariant(g)) /* must keep invariant? */ reallymarkobject(g, v); /* restore invariant */ else { /* sweep phase */ @@ -888,19 +882,18 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { return; /* nothing to be done */ else { /* move 'o' to 'finobj' list */ GCObject **p; - GCheader *ho = gch(o); - if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ + if (g->sweepgc == &o->gch.next) { /* avoid removing current sweep object */ lua_assert(issweepphase(g)); g->sweepgc = sweeptolive(L, g->sweepgc, NULL); } /* search for pointer pointing to 'o' */ - p = (testbit(ho->marked, LOCALMARK)) ? &g->allgc : &g->localgc; + p = (testbit(o->gch.marked, LOCALMARK)) ? &g->allgc : &g->localgc; for (; *p != o; p = &gch(*p)->next) { /* empty */ } - *p = ho->next; /* remove 'o' from its list */ - p = (testbit(ho->marked, LOCALMARK)) ? &g->finobj : &g->localfin; - ho->next = *p; /* link it in a "fin" list */ + *p = o->gch.next; /* remove 'o' from its list */ + p = (testbit(o->gch.marked, LOCALMARK)) ? &g->finobj : &g->localfin; + o->gch.next = *p; /* link it in a "fin" list */ *p = o; - l_setbit(ho->marked, FINALIZEDBIT); /* mark it as such */ + l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */ if (issweepphase(g)) makewhite(g, o); /* "sweep" object */ } @@ -1032,7 +1025,7 @@ static void setpause (global_State *g, l_mem estimate) { ? estimate * g->gcpause /* no overflow */ : MAX_LMEM; /* overflow; truncate to maximum */ g->GCthreshold = threshold; - luaE_setdebt(g, -GCLOCALPAUSE); + luaE_setdebt(g, -g->gclocalpause); } @@ -1050,8 +1043,6 @@ static int entersweep (lua_State *L) { g->gcstate = GCSswplocalgc; lua_assert(g->sweepgc == NULL); g->sweepgc = sweeptolive(L, &g->localgc, &n); - if (g->sweepgc == NULL) /* no live objects in local list? */ - g->sweepgc = &g->localgc; /* 'sweepgc' cannot be NULL here */ return n; } @@ -1099,7 +1090,7 @@ static l_mem atomic (lua_State *L) { work += g->GCmemtrav; /* stop counting (objects being finalized) */ separatetobefnz(g, 0); /* separate objects to be finalized */ markbeingfnz(g); /* mark objects that will be finalized */ - propagateall(g); /* remark, to propagate `preserveness' */ + propagateall(g); /* remark, to propagate 'resurrection' */ work -= g->GCmemtrav; /* restart counting */ convergeephemerons(g); /* at this point, all resurrected objects are marked. */ @@ -1117,14 +1108,15 @@ static l_mem atomic (lua_State *L) { static lu_mem sweepstep (lua_State *L, global_State *g, int nextstate, GCObject **nextlist) { - g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); - if (g->sweepgc) /* is there still something to sweep? */ - return (GCSWEEPMAX * GCSWEEPCOST); - else { /* enter next state */ - g->gcstate = nextstate; - g->sweepgc = nextlist; - return 0; + if (g->sweepgc) { + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + if (g->sweepgc) /* is there still something to sweep? */ + return (GCSWEEPMAX * GCSWEEPCOST); } + /* else enter next state */ + g->gcstate = nextstate; + g->sweepgc = nextlist; + return 0; } @@ -1245,7 +1237,7 @@ void luaC_step (lua_State *L) { luaC_forcestep(L); /* restart collection */ } else - luaE_setdebt(g, -GCLOCALPAUSE); + luaE_setdebt(g, -g->gclocalpause); } } else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ diff --git a/lstate.c b/lstate.c index f9d857fb..0c3eb8f1 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.112 2013/09/11 12:26:14 roberto Exp roberto $ +** $Id: lstate.c,v 2.113 2013/09/11 14:09:55 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -30,6 +30,10 @@ #define LUAI_GCPAUSE 200 /* 200% */ #endif +#if !defined(LUAI_GCLOCALPAUSE) +#define LUAI_GCLOCALPAUSE (1000 * sizeof(TString)) +#endif + #if !defined(LUAI_GCMUL) #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ #endif @@ -301,6 +305,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->totalbytes = sizeof(LG); g->GCdebt = 0; g->gcpause = LUAI_GCPAUSE; + g->gclocalpause = LUAI_GCLOCALPAUSE; g->gcstepmul = LUAI_GCMUL; for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { diff --git a/lstate.h b/lstate.h index fc8f775d..f886f3e3 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.94 2013/09/05 19:31:49 roberto Exp roberto $ +** $Id: lstate.h,v 2.95 2013/09/11 14:09:55 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -131,6 +131,7 @@ typedef struct global_State { GCObject *fixedgc; /* list of objects not to be collected */ Mbuffer buff; /* temporary buffer for string concatenation */ int gcpause; /* size of pause between successive GCs */ + int gclocalpause; /* size of pause between local collections */ int gcstepmul; /* GC `granularity' */ lua_CFunction panic; /* to be called in unprotected errors */ struct lua_State *mainthread; diff --git a/lua.h b/lua.h index b316d11b..93ba9b0b 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.292 2013/07/05 14:29:51 roberto Exp roberto $ +** $Id: lua.h,v 1.293 2013/08/05 16:58:28 roberto Exp roberto $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -288,7 +288,8 @@ LUA_API int (lua_status) (lua_State *L); #define LUA_GCSTEP 5 #define LUA_GCSETPAUSE 6 #define LUA_GCSETSTEPMUL 7 -#define LUA_GCISRUNNING 8 +#define LUA_GCSETLOCALPAUSE 8 +#define LUA_GCISRUNNING 9 LUA_API int (lua_gc) (lua_State *L, int what, int data); -- cgit v1.2.3-55-g6feb