[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: co-routines [was Re: Unicode]
- From: Roberto Ierusalimschy <roberto@...>
- Date: Thu, 01 Feb 2001 11:19:09 -0200
> Could you be a little bit more specific? Just some functions to save/set
> L->stack & co and a registration for lock-callbacks on table-set/get?
> Or something more sophisticated? What about the GC?
We broke the lua_State in two structs; the lua_State itself has the
thread-specific data, and it points to the other structure with the
"global" data. There is only one new function (let us call it lua_newstack,
we don't know the final name): the call lua_newstack(L, stacksize) returns
a new lua_State sharing the global state with L. Actually, lua_open is now
a macro lua_newstack(NULL, stacksize).
All stacks sharing the same global part are in a linked list, so the GC
traverse them all.
lua_close destroys a stack. If it is the last stack of the global state,
it also closes the global state.
About the locks: we considered the whole core of Lua as one single critical
region (it is too complicated and too expensive to lock every single
internal operation that can have impact in other threads). So all API
functions have a pair of macros LUA_LOCK/LUA_UNLOCK around them. On the
other side, whenever Lua calls C, in unlocks its core. So, unless you are
in a closed loop completely inside Lua, you have plenty of opportunites to
switch treads. (Notice that the core never blocks; all blocking functions
are C functions outside). If you really want it badly, you can register an
empty line-hook (because line-hooks are outside the core, everytime Lua
calls the line-hook it will unlock and lock again).
The following code shows the critical parts for implementing multi-threads
(with pthreads) in Lua 4.1. An implementation with co-routines could
follow the same structure, but without the macros for lock/unlock.
file p.h (included in lua.h)
#include <pthread.h>
#define LUA_LOCK pthread_mutex_lock(&mutex)
#define LUA_UNLOCK pthread_mutex_unlock(&mutex)
/* mutex for the Lua core */
extern pthread_mutex_t mutex;
...
file p.c
#include <pthread.h>
#include "../lua.h"
#include "../lauxlib.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static void *init_thread (void *arg) {
lua_State *L = (lua_State *)arg;
int n = lua_getn(L, 1); /* number of arguments */
int i;
for (i=1; i<=n; i++) /* push arguments */
lua_rawgeti(L, 1, i);
lua_remove(L, 1); /* table is garbage now */
pthread_detach(pthread_self());
lua_call(L, n, 0);
return NULL;
}
static int newthread (lua_State *L) {
lua_State *NL;
int ref;
pthread_t thread;
luaL_checktype(L, 1, LUA_TFUNCTION);
luaL_checktype(L, 2, LUA_TTABLE);
NL = lua_newstack(L, luaL_opt_int(L, 3, 0));
if (NL == NULL)
lua_error(L, "cannot create new stack");
lua_settop(L, 2); /* remove eventual stacksize */
/* move table and function from L to NL */
ref = lua_ref(L, 1); /* maybe we need a function for that? */
lua_getref(NL, ref);
lua_unref(L, ref);
ref = lua_ref(L, 1);
lua_getref(NL, ref);
lua_unref(L, ref);
if (pthread_create(&thread, NULL, init_thread, NL) != 0)
lua_error(L, "cannot create new thread");
return 0;
}
...
-- Roberto