mirror of
https://github.com/lua/lua
synced 2025-03-25 07:02:51 +03:00
GC local pause configurable
This commit is contained in:
parent
06156e7575
commit
686e57cf9c
7
lapi.c
7
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;
|
||||
|
@ -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);
|
||||
|
46
lgc.c
46
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 */
|
||||
|
7
lstate.c
7
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) {
|
||||
|
3
lstate.h
3
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;
|
||||
|
5
lua.h
5
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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user