aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-10-19 16:00:33 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-10-19 16:00:33 -0300
commita799ed5af91c642d12952586ca6ad5ad92bf7f44 (patch)
tree36f88294dc671e51e65390391ef6b614e1cb99c9
parent4082c77ff2fd09aef6131587a8e2537e86fc7d68 (diff)
downloadlua-a799ed5af91c642d12952586ca6ad5ad92bf7f44.tar.gz
lua-a799ed5af91c642d12952586ca6ad5ad92bf7f44.tar.bz2
lua-a799ed5af91c642d12952586ca6ad5ad92bf7f44.zip
more precise control for GC pause (based on threshold)
-rw-r--r--lgc.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/lgc.c b/lgc.c
index 1388c00b..8705ebaf 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.136 2012/09/11 12:53:08 roberto Exp roberto $ 2** $Id: lgc.c,v 2.137 2012/10/03 12:36:17 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -43,21 +43,12 @@
43*/ 43*/
44#define STEPMULADJ 200 44#define STEPMULADJ 200
45 45
46
46/* 47/*
47** macro to adjust 'pause': 'pause' is actually used like 48** macro to adjust 'pause': 'pause' is actually used like
48** 'pause / PAUSEADJ' (value chosen by tests) 49** 'pause / PAUSEADJ' (value chosen by tests)
49*/ 50*/
50#define PAUSEADJ 200 51#define PAUSEADJ 100
51
52
53
54
55/*
56** standard negative debt for GC; a reasonable "time" to wait before
57** starting a new cycle
58*/
59#define stddebtest(g,e) (-cast(l_mem, (e)/PAUSEADJ) * g->gcpause)
60#define stddebt(g) stddebtest(g, gettotalbytes(g))
61 52
62 53
63/* 54/*
@@ -908,6 +899,21 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
908*/ 899*/
909 900
910 901
902/*
903** set a reasonable "time" to wait before starting a new GC cycle;
904** cycle will start when memory use hits threshold
905*/
906static void setpause (global_State *g, l_mem estimate) {
907 l_mem debt, threshold;
908 estimate = estimate / PAUSEADJ; /* adjust 'estimate' */
909 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
910 ? estimate * g->gcpause /* no overflow */
911 : MAX_LMEM; /* overflow; truncate to maximum */
912 debt = -cast(l_mem, threshold - gettotalbytes(g));
913 luaE_setdebt(g, debt);
914}
915
916
911#define sweepphases \ 917#define sweepphases \
912 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) 918 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
913 919
@@ -1028,7 +1034,8 @@ static lu_mem singlestep (lua_State *L) {
1028 global_State *g = G(L); 1034 global_State *g = G(L);
1029 switch (g->gcstate) { 1035 switch (g->gcstate) {
1030 case GCSpause: { 1036 case GCSpause: {
1031 g->GCmemtrav = 0; /* start to count memory traversed */ 1037 /* start to count memory traversed */
1038 g->GCmemtrav = g->strt.size * sizeof(GCObject*);
1032 lua_assert(!isgenerational(g)); 1039 lua_assert(!isgenerational(g));
1033 restartcollection(g); 1040 restartcollection(g);
1034 g->gcstate = GCSpropagate; 1041 g->gcstate = GCSpropagate;
@@ -1117,7 +1124,7 @@ static void generationalcollection (lua_State *L) {
1117 g->GCestimate = estimate; /* keep estimate from last major coll. */ 1124 g->GCestimate = estimate; /* keep estimate from last major coll. */
1118 1125
1119 } 1126 }
1120 luaE_setdebt(g, stddebt(g)); 1127 setpause(g, gettotalbytes(g));
1121 lua_assert(g->gcstate == GCSpropagate); 1128 lua_assert(g->gcstate == GCSpropagate);
1122} 1129}
1123 1130
@@ -1126,7 +1133,7 @@ static void incstep (lua_State *L) {
1126 global_State *g = G(L); 1133 global_State *g = G(L);
1127 l_mem debt = g->GCdebt; 1134 l_mem debt = g->GCdebt;
1128 int stepmul = g->gcstepmul; 1135 int stepmul = g->gcstepmul;
1129 if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values */ 1136 if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */
1130 /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ 1137 /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
1131 debt = (debt / STEPMULADJ) + 1; 1138 debt = (debt / STEPMULADJ) + 1;
1132 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; 1139 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
@@ -1135,10 +1142,11 @@ static void incstep (lua_State *L) {
1135 debt -= work; 1142 debt -= work;
1136 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); 1143 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1137 if (g->gcstate == GCSpause) 1144 if (g->gcstate == GCSpause)
1138 debt = stddebtest(g, g->GCestimate); /* pause until next cycle */ 1145 setpause(g, g->GCestimate); /* pause until next cycle */
1139 else 1146 else {
1140 debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ 1147 debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1141 luaE_setdebt(g, debt); 1148 luaE_setdebt(g, debt);
1149 }
1142} 1150}
1143 1151
1144 1152
@@ -1195,7 +1203,7 @@ void luaC_fullgc (lua_State *L, int isemergency) {
1195 luaC_runtilstate(L, bitmask(GCSpropagate)); 1203 luaC_runtilstate(L, bitmask(GCSpropagate));
1196 } 1204 }
1197 g->gckind = origkind; 1205 g->gckind = origkind;
1198 luaE_setdebt(g, stddebt(g)); 1206 setpause(g, gettotalbytes(g));
1199 if (!isemergency) /* do not run finalizers during emergency GC */ 1207 if (!isemergency) /* do not run finalizers during emergency GC */
1200 callallpendingfinalizers(L, 1); 1208 callallpendingfinalizers(L, 1);
1201} 1209}