Преглед на файлове

new macro `lua_threadyield' + lock stuff in `luaconf.h' + details

Roberto Ierusalimschy преди 21 години
родител
ревизия
e8d4fe7236
променени са 6 файла, в които са добавени 84 реда и са изтрити 90 реда
  1. 7 6
      ldebug.c
  2. 2 2
      ldebug.h
  3. 6 6
      ldo.c
  4. 3 34
      lstate.h
  5. 27 1
      luaconf.h
  6. 39 41
      lvm.c

+ 7 - 6
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $
+** $Id: ldebug.c,v 2.5 2004/05/31 18:51:50 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -35,7 +35,7 @@ static const char *getfuncname (CallInfo *ci, const char **name);
 
 static int currentpc (CallInfo *ci) {
   if (!isLua(ci)) return -1;  /* function is not a Lua function? */
-  return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p);
+  return pcRel(ci->savedpc, ci_func(ci)->l.p);
 }
 
 
@@ -86,7 +86,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
   for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
     level--;
     if (f_isLua(ci))  /* Lua function? */
-      level -= ci->u.l.tailcalls;  /* skip lost tail calls */
+      level -= ci->tailcalls;  /* skip lost tail calls */
   }
   if (level > 0 || ci == L->base_ci) status = 0;  /* there is no such level */
   else if (level < 0) {  /* level is of a lost tail call */
@@ -255,8 +255,9 @@ static int precheck (const Proto *pt) {
 }
 
 
-static int checkopenop (const Proto *pt, int pc) {
-  Instruction i = pt->code[pc+1];
+#define checkopenop(pt,pc)	luaG_checkopenop((pt)->code[(pc)+1])
+
+int luaG_checkopenop (Instruction i) {
   switch (GET_OPCODE(i)) {
     case OP_CALL:
     case OP_TAILCALL:
@@ -487,7 +488,7 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
 
 static const char *getfuncname (CallInfo *ci, const char **name) {
   Instruction i;
-  if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
+  if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
     return NULL;  /* calling function is not Lua (or is unknown) */
   ci--;  /* calling function */
   i = ci_func(ci)->l.p->code[currentpc(ci)];

+ 2 - 2
ldebug.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.h,v 1.33 2003/07/16 20:49:02 roberto Exp roberto $
+** $Id: ldebug.h,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
 ** Auxiliary functions from Debug Interface module
 ** See Copyright Notice in lua.h
 */
@@ -25,6 +25,6 @@ int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2);
 void luaG_runerror (lua_State *L, const char *fmt, ...);
 void luaG_errormsg (lua_State *L);
 int luaG_checkcode (const Proto *pt);
-
+int luaG_checkopenop (Instruction i);
 
 #endif

+ 6 - 6
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.5 2004/05/14 19:25:09 roberto Exp roberto $
+** $Id: ldo.c,v 2.6 2004/05/31 18:51:50 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -256,8 +256,8 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
     ci->func = func;
     L->base = ci->base = base;
     ci->top = L->base + p->maxstacksize;
-    ci->u.l.savedpc = p->code;  /* starting point */
-    ci->u.l.tailcalls = 0;
+    ci->savedpc = p->code;  /* starting point */
+    ci->tailcalls = 0;
     ci->nresults = nresults;
     for (st = L->top; st < ci->top; st++)
       setnilvalue(st);
@@ -293,7 +293,7 @@ static StkId callrethooks (lua_State *L, StkId firstResult) {
   ptrdiff_t fr = savestack(L, firstResult);  /* next call may change stack */
   luaD_callhook(L, LUA_HOOKRET, -1);
   if (f_isLua(L->ci)) {  /* Lua function? */
-    while (L->ci->u.l.tailcalls--)  /* call hook for eventual tail calls */
+    while (L->ci->tailcalls--)  /* call hook for eventual tail calls */
       luaD_callhook(L, LUA_HOOKTAILRET, -1);
   }
   return restorestack(L, fr);
@@ -352,8 +352,8 @@ static void resume (lua_State *L, void *ud) {
     if (!f_isLua(ci)) {  /* `common' yield? */
       /* finish interrupted execution of `OP_CALL' */
       int nresults = ci->nresults;
-      lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
-                 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
+      lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
+                 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
       luaD_poscall(L, nresults, L->top - nargs);  /* complete it */
       if (nresults >= 0) L->top = L->ci->top;
     }  /* else yielded inside a hook: just continue its execution */

+ 3 - 34
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 2.3 2004/05/14 19:25:09 roberto Exp roberto $
+** $Id: lstate.h,v 2.4 2004/05/31 18:51:50 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -14,30 +14,6 @@
 #include "lzio.h"
 
 
-/*
-** macros for thread synchronization inside Lua core machine:
-** all accesses to the global state and to global objects are synchronized.
-** Because threads can read the stack of other threads
-** (when running garbage collection),
-** a thread must also synchronize any write-access to its own stack.
-** Unsynchronized accesses are allowed only when reading its own stack,
-** or when reading immutable fields from global objects
-** (such as string values and udata values). 
-*/
-#ifndef lua_lock
-#define lua_lock(L)	((void) 0)
-#endif
-
-#ifndef lua_unlock
-#define lua_unlock(L)	((void) 0)
-#endif
-
-
-#ifndef lua_userstateopen
-#define lua_userstateopen(l)
-#endif
-
-
 
 struct lua_longjmp;  /* defined in ldo.c */
 
@@ -74,15 +50,8 @@ typedef struct CallInfo {
   StkId func;  /* function index in the stack */
   StkId	top;  /* top for this function */
   int nresults;  /* expected number of results from this function */
-  union {
-    struct {  /* for Lua functions */
-      const Instruction *savedpc;
-      int tailcalls;  /* number of tail calls lost under this entry */
-    } l;
-    struct {  /* for C functions */
-      int dummy;  /* just to avoid an empty struct */
-    } c;
-  } u;
+  const Instruction *savedpc;
+  int tailcalls;  /* number of tail calls lost under this entry */
 } CallInfo;
 
 

+ 27 - 1
luaconf.h

@@ -1,5 +1,5 @@
 /*
-** $Id: luaconf.h,v 1.4 2004/05/28 18:32:51 roberto Exp roberto $
+** $Id: luaconf.h,v 1.5 2004/06/02 13:24:43 roberto Exp roberto $
 ** Configuration file for Lua
 ** See Copyright Notice in lua.h
 */
@@ -215,6 +215,32 @@
 #endif
 
 
+
+/*
+** macros for thread synchronization inside Lua core machine:
+** all accesses to the global state and to global objects are synchronized.
+** Because threads can read the stack of other threads
+** (when running garbage collection),
+** a thread must also synchronize any write-access to its own stack.
+** Unsynchronized accesses are allowed only when reading its own stack,
+** or when reading immutable fields from global objects
+** (such as string values and udata values).
+*/
+#define lua_lock(L)     ((void) 0)
+#define lua_unlock(L)   ((void) 0)
+
+/*
+** this macro allows a thread switch in appropriate places in the Lua
+** core
+*/
+#define lua_threadyield(L)	{lua_unlock(L); lua_lock(L);}
+
+
+
+/* allows user-specific initialization on new threads */
+#define lua_userstateopen(l)	/* empty */
+
+
 #endif
 
 /* }====================================================== */

+ 39 - 41
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.6 2004/05/14 19:25:09 roberto Exp $
+** $Id: lvm.c,v 2.7 2004/05/31 18:51:50 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -58,8 +58,8 @@ int luaV_tostring (lua_State *L, StkId obj) {
 static void traceexec (lua_State *L, const Instruction *pc) {
   lu_byte mask = L->hookmask;
   CallInfo *ci = L->ci;
-  const Instruction *oldpc = ci->u.l.savedpc;
-  ci->u.l.savedpc = pc;
+  const Instruction *oldpc = ci->savedpc;
+  ci->savedpc = pc;
   if (mask > LUA_MASKLINE) {  /* instruction-hook set? */
     if (L->hookcount == 0) {
       resethookcount(L);
@@ -122,18 +122,18 @@ StkId luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val,
       /* else will try the tag method */
     }
     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) {
-      if (pc) L->ci->u.l.savedpc = pc;
+      L->ci->savedpc = pc;
       luaG_typeerror(L, t, "index");
     }
     if (ttisfunction(tm)) {
-      if (pc) L->ci->u.l.savedpc = pc;
+      L->ci->savedpc = pc;
       prepTMcall(L, tm, t, key);
       callTMres(L, val);
       return L->base;
     }
     t = tm;  /* else repeat with `tm' */ 
   }
-  if (pc) L->ci->u.l.savedpc = pc;
+  L->ci->savedpc = pc;
   luaG_runerror(L, "loop in gettable");
   return NULL;  /* to avoid warnings */
 }
@@ -156,11 +156,11 @@ StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
       /* else will try the tag method */
     }
     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) {
-      if (pc) L->ci->u.l.savedpc = pc;
+      L->ci->savedpc = pc;
       luaG_typeerror(L, t, "index");
     }
     if (ttisfunction(tm)) {
-      if (pc) L->ci->u.l.savedpc = pc;
+      L->ci->savedpc = pc;
       prepTMcall(L, tm, t, key);
       setobj2s(L, L->top+3, val);  /* 3th argument */
       callTM(L);
@@ -168,7 +168,7 @@ StkId luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val,
     }
     t = tm;  /* else repeat with `tm' */ 
   }
-  if (pc) L->ci->u.l.savedpc = pc;
+  L->ci->savedpc = pc;
   luaG_runerror(L, "loop in settable");
   return NULL;  /* to avoid warnings */
 }
@@ -331,7 +331,7 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb,
                     const TValue *rc, TMS op, const Instruction *pc) {
   TValue tempb, tempc;
   const TValue *b, *c;
-  L->ci->u.l.savedpc = pc;
+  L->ci->savedpc = pc;
   if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
       (c = luaV_tonumber(rc, &tempc)) != NULL) {
     switch (op) {
@@ -374,7 +374,7 @@ static StkId Arith (lua_State *L, StkId ra, const TValue *rb,
 #define KBx(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
 
 
-#define dojump(pc, i)	((pc) += (i))
+#define dojump(L,pc,i)	{(pc) += (i); lua_threadyield(L);}
 
 
 StkId luaV_execute (lua_State *L, int nexeccalls) {
@@ -386,7 +386,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
   if (L->hookmask & LUA_MASKCALL)
     luaD_callhook(L, LUA_HOOKCALL, -1);
  retentry:  /* entry point when returning to old functions */
-  pc = L->ci->u.l.savedpc;
+  pc = L->ci->savedpc;
   cl = &clvalue(L->ci->func)->l;
   base = L->base;
   k = cl->p->k;
@@ -398,7 +398,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
       traceexec(L, pc);  /***/
       if (L->isSuspended) {  /* did hook yield? */
-        L->ci->u.l.savedpc = pc - 1;
+        L->ci->savedpc = pc - 1;
         return NULL;
       }
       base = L->base;
@@ -406,10 +406,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
     /* warning!! several calls may realloc the stack and invalidate `ra' */
     ra = RA(i);
     lua_assert(base == L->ci->base && base == L->base);
-    lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);
-    lua_assert(L->top == L->ci->top ||
-         GET_OPCODE(i) == OP_CALL ||   GET_OPCODE(i) == OP_TAILCALL ||
-         GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
+    lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
+    lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
     switch (GET_OPCODE(i)) {
       case OP_MOVE: {
         setobjs2s(L, ra, RB(i));
@@ -465,7 +463,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         int b = GETARG_B(i);
         b = fb2int(b);
         sethvalue(L, ra, luaH_new(L, b, GETARG_C(i)));
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         luaC_checkGC(L);  /***/
         base = L->base;
         break;
@@ -528,7 +526,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         }
         else {
           setnilvalue(&temp);
-          L->ci->u.l.savedpc = pc;
+          L->ci->savedpc = pc;
           if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))  /***/
             luaG_aritherror(L, RB(i), &temp);
           base = L->base;
@@ -543,7 +541,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
       case OP_CONCAT: {
         int b = GETARG_B(i);
         int c = GETARG_C(i);
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         luaV_concat(L, c-b+1, c);  /* may change `base' (and `ra') */  /***/
         luaC_checkGC(L);  /***/
         base = L->base;
@@ -551,27 +549,27 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         break;
       }
       case OP_JMP: {
-        dojump(pc, GETARG_sBx(i));
+        dojump(L, pc, GETARG_sBx(i));
         break;
       }
       case OP_EQ: {
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;  /***/
-        else dojump(pc, GETARG_sBx(*pc) + 1);
+        else dojump(L, pc, GETARG_sBx(*pc) + 1);
         base = L->base;
         break;
       }
       case OP_LT: {
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;  /***/
-        else dojump(pc, GETARG_sBx(*pc) + 1);
+        else dojump(L, pc, GETARG_sBx(*pc) + 1);
         base = L->base;
         break;
       }
       case OP_LE: {
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;  /***/
-        else dojump(pc, GETARG_sBx(*pc) + 1);
+        else dojump(L, pc, GETARG_sBx(*pc) + 1);
         base = L->base;
         break;
       }
@@ -580,7 +578,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         if (l_isfalse(rb) == GETARG_C(i)) pc++;
         else {
           setobjs2s(L, ra, rb);
-          dojump(pc, GETARG_sBx(*pc) + 1);
+          dojump(L, pc, GETARG_sBx(*pc) + 1);
         }
         break;
       }
@@ -589,7 +587,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         int b = GETARG_B(i);
         int nresults = GETARG_C(i) - 1;
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         pcr = luaD_precall(L, ra, nresults);
         if (pcr == PCRLUA) {
           nexeccalls++;
@@ -610,7 +608,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         int pcr;
         int b = GETARG_B(i);
         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
         pcr = luaD_precall(L, ra, LUA_MULTRET);
         if (pcr == PCRLUA) {
@@ -625,8 +623,8 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
           for (aux = 0; pfunc+aux < L->top; aux++)  /* move frame down */
             setobjs2s(L, func+aux, pfunc+aux);
           ci->top = L->top = base+aux;  /* correct top */
-          ci->u.l.savedpc = L->ci->u.l.savedpc;
-          ci->u.l.tailcalls++;  /* one more call lost */
+          ci->savedpc = L->ci->savedpc;
+          ci->tailcalls++;  /* one more call lost */
           L->ci--;  /* remove new frame */
           goto callentry;
         }
@@ -645,13 +643,13 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         int b = GETARG_B(i);
         if (b != 0) L->top = ra+b-1;
         if (L->openupval) luaF_close(L, base);
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         if (--nexeccalls == 0)  /* was previous function running `here'? */
           return ra;  /* no: return */
         else {  /* yes: continue its execution */
           int nresults = (ci+1)->nresults;
           lua_assert(isLua(ci));
-          lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
+          lua_assert(GET_OPCODE(*(ci->savedpc - 1)) == OP_CALL);
           luaD_poscall(L, nresults, ra);
           if (nresults >= 0) L->top = L->ci->top;
           goto retentry;
@@ -662,7 +660,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         lua_Number idx = nvalue(ra) + step;  /* increment index */
         lua_Number limit = nvalue(ra+1);
         if (step > 0 ? idx <= limit : idx >= limit) {
-          dojump(pc, GETARG_sBx(i));  /* jump back */
+          dojump(L, pc, GETARG_sBx(i));  /* jump back */
           setnvalue(ra, idx);  /* update internal index... */
           setnvalue(ra+3, idx);  /* ...and external index */
         }
@@ -672,7 +670,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         const TValue *init = ra;
         const TValue *plimit = ra+1;
         const TValue *pstep = ra+2;
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         if (!tonumber(init, ra))
           luaG_runerror(L, "`for' initial value must be a number");
         else if (!tonumber(plimit, ra+1))
@@ -680,7 +678,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         else if (!tonumber(pstep, ra+2))
           luaG_runerror(L, "`for' step must be a number");
         setnvalue(ra, nvalue(ra) - nvalue(pstep));
-        dojump(pc, GETARG_sBx(i));
+        dojump(L, pc, GETARG_sBx(i));
         break;
       }
       case OP_TFORLOOP: {
@@ -689,7 +687,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         setobjs2s(L, cb+1, ra+1);
         setobjs2s(L, cb, ra);
         L->top = cb+3;  /* func. + 2 args (state and index) */
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         luaD_call(L, cb, GETARG_C(i));  /***/
         L->top = L->ci->top;
         base = L->base;
@@ -698,7 +696,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
           pc++;  /* skip jump (break loop) */
         else {
           setobjs2s(L, cb-1, cb);  /* save control variable */
-          dojump(pc, GETARG_sBx(*pc) + 1);  /* jump back */
+          dojump(L, pc, GETARG_sBx(*pc) + 1);  /* jump back */
         }
         break;
       }
@@ -707,7 +705,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
           setobjs2s(L, ra+1, ra);
           setobj2s(L, ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
         }
-        dojump(pc, GETARG_sBx(i));
+        dojump(L, pc, GETARG_sBx(i));
         break;
       }
       case OP_SETLIST:
@@ -755,7 +753,7 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
           }
         }
         setclvalue(L, ra, ncl);
-        L->ci->u.l.savedpc = pc;
+        L->ci->savedpc = pc;
         luaC_checkGC(L);  /***/
         base = L->base;
         break;