lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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