[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Back to the GC stall in atomic()
- From: Niklas Frykholm <niklas@...>
- Date: Wed, 12 Dec 2007 14:02:49 +0100
Roberto Ierusalimschy wrote:
Even if you promise not to touch other Lua objects, Lua itself needs
the metatable of the userdata in order to call its finalizer. If the
metatable is collected (because the last reference to it came from
the userdata and it was not marked in the atomic phase), you are in
trouble...
I'm holding references to all the metatables on the C side, so I should
be safe from that at least. If there are no other possible issues, it
might work....
I'll try it. I really need to get rid of those stalls.
It seems to work, knock on wood. Here is my patch if someone is
interested (line numbers may be off, because there are some other
patches in there already):
Index: lua/src/lgc.c
===================================================================
--- lua/src/lgc.c (revision 4140)
+++ lua/src/lgc.c (working copy)
@@ -392,6 +392,25 @@
break;
}
case LUA_TUSERDATA: {
+ #ifdef LUA_SIMPLE_FINALIZERS
+ global_State *g = G(L);
+ Udata *udata = rawgco2u(o);
+ const TValue *tm;
+ tm = fasttm(L, udata->uv.metatable, TM_GC);
+ if (tm != NULL) {
+ lu_byte oldah = L->allowhook;
+ lu_mem oldt = g->GCthreshold;
+ L->allowhook = 0; /* stop debug hooks during GC tag method */
+ g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
+ setobj2s(L, L->top, tm);
+ setuvalue(L, L->top+1, udata);
+ L->top += 2;
+ luaD_call(L, L->top - 2, 0);
+ L->allowhook = oldah; /* restore hooks */
+ g->GCthreshold = oldt; /* restore threshold */
+ }
+ #endif
+
luaM_freemem(L, o, sizeudata(gco2u(o)));
break;
}
@@ -543,7 +560,11 @@
g->gray = g->grayagain;
g->grayagain = NULL;
propagateall(g);
- udsize = luaC_separateudata(L, 0); /* separate userdata to be
finalized */
+ #ifdef LUA_SIMPLE_FINALIZERS
+ udsize = 0;
+ #else
+ udsize = luaC_separateudata(L, 0); /* separate userdata to be
finalized */
+ #endif
marktmu(g); /* mark `preserved' userdata */
udsize += propagateall(g); /* remark, to propagate `preserveness' */
cleartable(g->weak); /* remove collected objects from weak tables */
Index: lua/src/lstate.c
===================================================================
--- lua/src/lstate.c (revision 4140)
+++ lua/src/lstate.c (working copy)
@@ -200,7 +200,11 @@
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
+ #ifdef LUA_SIMPLE_FINALIZERS
+ ;
+ #else
+ luaC_separateudata(L, 1); /* separate udata that have GC
metamethods */
+ #endif
L->errfunc = 0; /* no error function during GC metamethods */
do { /* repeat until no more errors */
L->ci = L->base_ci;
Index: lua/src/luaconf.h
===================================================================
--- lua/src/luaconf.h (revision 4140)
+++ lua/src/luaconf.h (working copy)
@@ -34,6 +34,10 @@
#define LUASYSTEM(x) system(x)
#endif
+/* GRIN: Skip luas complicated handling of finalizers and call them
directly when the
+ userdata is destroyed, to get rid of the stall in atomic(). */
+#define LUA_SIMPLE_FINALIZERS
+
/*
@@ LUA_ANSI controls the use of non-ansi features.
** CHANGE it (define it) if you want Lua to avoid the use of any
// Niklas