summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-12-20 16:17:46 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-12-20 16:17:46 -0200
commit737f119187aca3c8f6743ec6e3cfc04e83723180 (patch)
tree4e1bfb4b2bef35dd2acfe2915ab51481cd9ebc16
parent8980c630bf40e05dad71ded377e3d0f0a17b076c (diff)
downloadlua-737f119187aca3c8f6743ec6e3cfc04e83723180.tar.gz
lua-737f119187aca3c8f6743ec6e3cfc04e83723180.tar.bz2
lua-737f119187aca3c8f6743ec6e3cfc04e83723180.zip
better control for GC running or stopped
-rw-r--r--lapi.c14
-rw-r--r--lgc.c21
-rw-r--r--lgc.h6
-rw-r--r--lmem.c13
-rw-r--r--lstate.c5
-rw-r--r--lstate.h3
6 files changed, 31 insertions, 31 deletions
diff --git a/lapi.c b/lapi.c
index a1796db3..b4dbc8ed 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.141 2010/11/18 19:15:00 roberto Exp roberto $ 2** $Id: lapi.c,v 2.141 2010/11/26 14:32:31 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -960,14 +960,16 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
960 g = G(L); 960 g = G(L);
961 switch (what) { 961 switch (what) {
962 case LUA_GCSTOP: { 962 case LUA_GCSTOP: {
963 stopgc(g); 963 g->gcrunning = 0;
964 break; 964 break;
965 } 965 }
966 case LUA_GCRESTART: { 966 case LUA_GCRESTART: {
967 g->GCdebt = 0; 967 g->GCdebt = 0;
968 g->gcrunning = 1;
968 break; 969 break;
969 } 970 }
970 case LUA_GCCOLLECT: { 971 case LUA_GCCOLLECT: {
972 g->gcrunning = 1; /* restart collector if stopped ?? */
971 luaC_fullgc(L, 0); 973 luaC_fullgc(L, 0);
972 break; 974 break;
973 } 975 }
@@ -981,7 +983,8 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
981 break; 983 break;
982 } 984 }
983 case LUA_GCSTEP: { 985 case LUA_GCSTEP: {
984 int stopped = gcstopped(g); 986 int running = g->gcrunning;
987 g->gcrunning = 1; /* allow steps */
985 if (g->gckind == KGC_GEN) { /* generational mode? */ 988 if (g->gckind == KGC_GEN) { /* generational mode? */
986 res = (g->lastmajormem == 0); /* 1 if will do major collection */ 989 res = (g->lastmajormem == 0); /* 1 if will do major collection */
987 luaC_step(L); /* do a single step */ 990 luaC_step(L); /* do a single step */
@@ -995,8 +998,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
995 } 998 }
996 } 999 }
997 } 1000 }
998 if (stopped) /* collector was stopped? */ 1001 g->gcrunning = running; /* restore previous state */
999 stopgc(g); /* keep it that way */
1000 break; 1002 break;
1001 } 1003 }
1002 case LUA_GCSETPAUSE: { 1004 case LUA_GCSETPAUSE: {
@@ -1015,7 +1017,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
1015 break; 1017 break;
1016 } 1018 }
1017 case LUA_GCISRUNNING: { 1019 case LUA_GCISRUNNING: {
1018 res = !gcstopped(g); 1020 res = g->gcrunning;
1019 break; 1021 break;
1020 } 1022 }
1021 case LUA_GCGEN: { /* change collector to generational mode */ 1023 case LUA_GCGEN: { /* change collector to generational mode */
diff --git a/lgc.c b/lgc.c
index 0a59ddc7..bc9f0d4a 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.104 2010/11/26 14:32:31 roberto Exp roberto $ 2** $Id: lgc.c,v 2.105 2010/12/03 11:48:25 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*/
@@ -715,15 +715,15 @@ static void GCTM (lua_State *L, int propagateerrors) {
715 if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ 715 if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */
716 int status; 716 int status;
717 lu_byte oldah = L->allowhook; 717 lu_byte oldah = L->allowhook;
718 lu_mem oldd = g->GCdebt; 718 int running = g->gcrunning;
719 L->allowhook = 0; /* stop debug hooks during GC tag method */ 719 L->allowhook = 0; /* stop debug hooks during GC tag method */
720 stopgc(g); /* avoid GC steps */ 720 g->gcrunning = 0; /* avoid GC steps */
721 setobj2s(L, L->top, tm); /* push finalizer... */ 721 setobj2s(L, L->top, tm); /* push finalizer... */
722 setobj2s(L, L->top + 1, &v); /* ... and its argument */ 722 setobj2s(L, L->top + 1, &v); /* ... and its argument */
723 L->top += 2; /* and (next line) call the finalizer */ 723 L->top += 2; /* and (next line) call the finalizer */
724 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); 724 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
725 L->allowhook = oldah; /* restore hooks */ 725 L->allowhook = oldah; /* restore hooks */
726 g->GCdebt = oldd; /* restore threshold */ 726 g->gcrunning = running; /* restore state */
727 if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ 727 if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
728 if (status == LUA_ERRRUN) { /* is there an error msg.? */ 728 if (status == LUA_ERRRUN) { /* is there an error msg.? */
729 luaO_pushfstring(L, "error in __gc tag method (%s)", 729 luaO_pushfstring(L, "error in __gc tag method (%s)",
@@ -984,11 +984,14 @@ static void step (lua_State *L) {
984 984
985 985
986void luaC_step (lua_State *L) { 986void luaC_step (lua_State *L) {
987 int i; 987 global_State *g = G(L);
988 if (isgenerational(G(L))) generationalcollection(L); 988 if (g->gcrunning) {
989 else step(L); 989 int i;
990 for (i = 0; i < GCFINALIZENUM && G(L)->tobefnz; i++) 990 if (isgenerational(g)) generationalcollection(L);
991 GCTM(L, 1); /* Call a few pending finalizers */ 991 else step(L);
992 for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++)
993 GCTM(L, 1); /* Call a few pending finalizers */
994 }
992} 995}
993 996
994 997
diff --git a/lgc.h b/lgc.h
index 49ca6bf5..8a430294 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.46 2010/12/02 19:51:15 roberto Exp roberto $ 2** $Id: lgc.h,v 2.47 2010/12/17 12:02:29 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*/
@@ -52,10 +52,6 @@
52#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) 52#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic)
53 53
54 54
55#define gcstopped(g) ((g)->GCdebt == MIN_LMEM)
56#define stopgc(g) ((g)->GCdebt = MIN_LMEM)
57
58
59/* 55/*
60** some useful bit tricks 56** some useful bit tricks
61*/ 57*/
diff --git a/lmem.c b/lmem.c
index fd49a789..31c03364 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.78 2010/05/04 18:10:02 roberto Exp roberto $ 2** $Id: lmem.c,v 1.79 2010/05/05 18:49:56 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -79,14 +79,14 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
79 size_t realosize = (block) ? osize : 0; 79 size_t realosize = (block) ? osize : 0;
80 lua_assert((realosize == 0) == (block == NULL)); 80 lua_assert((realosize == 0) == (block == NULL));
81#if defined(HARDMEMTESTS) 81#if defined(HARDMEMTESTS)
82 if (nsize > realosize && !gcstopped(g)) 82 if (nsize > realosize && g->gcrunning)
83 luaC_fullgc(L, 1); /* force a GC whenever possible */ 83 luaC_fullgc(L, 1); /* force a GC whenever possible */
84#endif 84#endif
85 newblock = (*g->frealloc)(g->ud, block, osize, nsize); 85 newblock = (*g->frealloc)(g->ud, block, osize, nsize);
86 if (newblock == NULL && nsize > 0) { 86 if (newblock == NULL && nsize > 0) {
87 api_check(L, nsize > realosize, 87 api_check(L, nsize > realosize,
88 "realloc cannot fail when shrinking a block"); 88 "realloc cannot fail when shrinking a block");
89 if (!gcstopped(g)) { 89 if (g->gcrunning) {
90 luaC_fullgc(L, 1); /* try to free some memory... */ 90 luaC_fullgc(L, 1); /* try to free some memory... */
91 newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 91 newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
92 } 92 }
@@ -95,8 +95,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
95 } 95 }
96 lua_assert((nsize == 0) == (newblock == NULL)); 96 lua_assert((nsize == 0) == (newblock == NULL));
97 g->totalbytes = (g->totalbytes - realosize) + nsize; 97 g->totalbytes = (g->totalbytes - realosize) + nsize;
98 if (!gcstopped(g)) 98 g->GCdebt += nsize; /* give some credit to garbage collector */
99 g->GCdebt += nsize; /* give some credit to garbage collector */
100#if defined(TRACEMEM) 99#if defined(TRACEMEM)
101 { /* auxiliary patch to monitor garbage collection. 100 { /* auxiliary patch to monitor garbage collection.
102 ** To plot, gnuplot with following command: 101 ** To plot, gnuplot with following command:
@@ -108,9 +107,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
108 if ((total % 200) == 0) { 107 if ((total % 200) == 0) {
109 if (f == NULL) f = fopen(TRACEMEM, "w"); 108 if (f == NULL) f = fopen(TRACEMEM, "w");
110 fprintf(f, "%lu %u %d %d\n", total, 109 fprintf(f, "%lu %u %d %d\n", total,
111 g->totalbytes, 110 g->totalbytes, g->GCdebt, g->gcstate * 1000);
112 gcstopped(g) ? 0 : g->GCdebt,
113 g->gcstate * 1000);
114 } 111 }
115 } 112 }
116#endif 113#endif
diff --git a/lstate.c b/lstate.c
index fee415b6..d13a3ad5 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.86 2010/09/03 14:14:01 roberto Exp roberto $ 2** $Id: lstate.c,v 2.87 2010/11/26 14:32:31 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -155,6 +155,7 @@ static void f_luaopen (lua_State *L, void *ud) {
155 g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 155 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
156 luaS_fix(g->memerrmsg); /* it should never be collected */ 156 luaS_fix(g->memerrmsg); /* it should never be collected */
157 g->GCdebt = 0; 157 g->GCdebt = 0;
158 g->gcrunning = 1; /* allow gc */
158} 159}
159 160
160 161
@@ -241,7 +242,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
241 g->mainthread = L; 242 g->mainthread = L;
242 g->uvhead.u.l.prev = &g->uvhead; 243 g->uvhead.u.l.prev = &g->uvhead;
243 g->uvhead.u.l.next = &g->uvhead; 244 g->uvhead.u.l.next = &g->uvhead;
244 stopgc(g); /* no GC while building state */ 245 g->gcrunning = 0; /* no GC while building state */
245 g->lastmajormem = 0; 246 g->lastmajormem = 0;
246 g->strt.size = 0; 247 g->strt.size = 0;
247 g->strt.nuse = 0; 248 g->strt.nuse = 0;
diff --git a/lstate.h b/lstate.h
index 40c3ac16..fd1b2d66 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.68 2010/10/29 17:52:46 roberto Exp roberto $ 2** $Id: lstate.h,v 2.69 2010/11/26 14:32:31 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -123,6 +123,7 @@ typedef struct global_State {
123 lu_byte currentwhite; 123 lu_byte currentwhite;
124 lu_byte gcstate; /* state of garbage collector */ 124 lu_byte gcstate; /* state of garbage collector */
125 lu_byte gckind; /* kind of GC running */ 125 lu_byte gckind; /* kind of GC running */
126 lu_byte gcrunning; /* true if GC is running */
126 int sweepstrgc; /* position of sweep in `strt' */ 127 int sweepstrgc; /* position of sweep in `strt' */
127 GCObject *allgc; /* list of all collectable objects */ 128 GCObject *allgc; /* list of all collectable objects */
128 GCObject *finobj; /* list of collectable objects with finalizers */ 129 GCObject *finobj; /* list of collectable objects with finalizers */