[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: gc confusion: now resolved
- From: Juergen Fuhrmann <fuhrmann@...>
- Date: Thu, 20 Feb 2003 15:37:45 +0100 (MET)
Hi, there,
I found the 32bit vs. 64 bit bug. It was a little bit of PITA to find
it, but finally it was not in the core of the gc code but in the API.
The problem was: in lua-4.0.1, on 64 bit machines, forced garbage
collection via lua_setgcthreshold(L,0) does not run, while on 32 bit
it runs. Eg. on SGI, cc -32 and cc -64 result in different behaviour.
The reason is that in the API, amounts of memory are specified in
kbytes. As soon as they are passed to Lua, they are scaled to bytes,
and stored in an unsigned long variable. But before, a comparison is
made:
if (newthreshold > GCscale(ULONG_MAX)) (lapi.c l.430)
where GCscale is defined as
#define GCscale(x) ((int)((x)>>10)) (lapi.c, l.391)
and newthreshold is an int.
On typical 64 bit machines, sizeof(int)==4, sizeof(unsigned long)==8
(sgi 64, alpha Tru64). Thus, the result of GCscale(ULONG_MAX) does not
fit into an int. It is casted to -1 and correspondingly, the test
fails.
We need to change the specification of memory amounts in kbytes from
int to long (in lua.h. lapi.c), and to modify the definition of
GCscale to
#define GCscale(x) ((long)((x)>>10))
I tested this on Tru64 alpha, Linux intel32, sgi32, sgi64, and it
works. I appended a patch to this message.
Roberto, Luiz, do you make a bugfix release to 4.0.1 out of it ?
If not, I will publish the patch on the wiki, but I will do that only
after knowing your decision.
Juergen
diff -urN lua-4.0.1/include/lua.h lua-4.0.1-long/include/lua.h
--- lua-4.0.1/include/lua.h Thu Jun 20 03:51:24 2002
+++ lua-4.0.1-long/include/lua.h Thu Feb 20 14:47:05 2003
@@ -163,9 +163,9 @@
/*
** Garbage-collection functions
*/
-LUA_API int lua_getgcthreshold (lua_State *L);
+LUA_API long lua_getgcthreshold (lua_State *L);
LUA_API int lua_getgccount (lua_State *L);
-LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
+LUA_API void lua_setgcthreshold (lua_State *L, long newthreshold);
/*
** miscellaneous functions
diff -urN lua-4.0.1/src/lapi.c lua-4.0.1-long/src/lapi.c
--- lua-4.0.1/src/lapi.c Tue Jun 11 20:34:32 2002
+++ lua-4.0.1-long/src/lapi.c Thu Feb 20 14:43:27 2003
@@ -388,10 +388,10 @@
*/
/* GC values are expressed in Kbytes: #bytes/2^10 */
-#define GCscale(x) ((int)((x)>>10))
+#define GCscale(x) ((long)((x)>>10))
#define GCunscale(x) ((unsigned long)(x)<<10)
-LUA_API int lua_getgcthreshold (lua_State *L) {
+LUA_API long lua_getgcthreshold (lua_State *L) {
return GCscale(L->GCthreshold);
}
@@ -399,7 +399,7 @@
return GCscale(L->nblocks);
}
-LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
+LUA_API void lua_setgcthreshold (lua_State *L, long newthreshold) {
if (newthreshold > GCscale(ULONG_MAX))
L->GCthreshold = ULONG_MAX;
else