X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/d238ac3722c3a1c530d8142c00e066fe7a5aa245..273f840b0cbfdf3ce198781ad3c7ea195eac7135:/src/simix/smx_context_lua.c?ds=sidebyside diff --git a/src/simix/smx_context_lua.c b/src/simix/smx_context_lua.c index 669ac82f6c..51ac850b00 100644 --- a/src/simix/smx_context_lua.c +++ b/src/simix/smx_context_lua.c @@ -8,18 +8,34 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "private.h" -#include "context_sysv_config.h" /* loads context system definitions */ -#include "portable.h" +//#include "context_sysv_config.h" /* loads context system definitions */ +//#include "portable.h" +//#include /* context relative declarations */ #include #include -// FIXME: better location for that -extern void MSG_register(lua_State *L); +/* lower this if you want to reduce the memory consumption */ +//#define STACK_SIZE 128*1024 -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smx_lua); +//#ifdef HAVE_VALGRIND_VALGRIND_H +//# include +//#endif /* HAVE_VALGRIND_VALGRIND_H */ + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(lua); typedef struct s_smx_ctx_sysv { SMX_CTX_BASE_T; +#ifdef KILLME + /* Ucontext info */ + ucontext_t uc; /* the thread that execute the code */ + char stack[STACK_SIZE]; /* the thread stack size */ + struct s_smx_ctx_sysv *prev; /* the previous process */ +#ifdef HAVE_VALGRIND_VALGRIND_H + unsigned int valgrind_stack_id; /* the valgrind stack id */ +#endif +#endif /* KILLME */ + + /* lua state info */ lua_State *state; int ref; /* to prevent the lua GC from collecting my threads, I ref them explicitely */ int nargs; /* argument to lua_resume. First time: argc-1, afterward: 0 */ @@ -29,27 +45,23 @@ static lua_State *lua_state; static smx_context_t smx_ctx_lua_create_context(xbt_main_func_t code, int argc, char** argv, - void_f_pvoid_t cleanup_func, void* cleanup_arg); + void_f_pvoid_t cleanup_func, void* cleanup_arg); static int smx_ctx_lua_factory_finalize(smx_context_factory_t *factory); - static void smx_ctx_lua_free(smx_context_t context); - static void smx_ctx_lua_start(smx_context_t context); - static void smx_ctx_lua_stop(smx_context_t context); - static void smx_ctx_lua_suspend(smx_context_t context); static void - smx_ctx_lua_resume(smx_context_t old_context, smx_context_t new_context); +smx_ctx_lua_resume(smx_context_t old_context, smx_context_t new_context); static void smx_ctx_sysv_wrapper(void); -void SIMIX_ctx_lua_factory_loadfile(const char *file) { - if (luaL_loadfile(lua_state, file) || lua_pcall(lua_state, 0, 0, 0)) - THROW2(unknown_error,0,"error while parsing %s: %s", file, lua_tostring(lua_state, -1)); - INFO1("File %s loaded",file); +/* Actually, the parameter is a lua_State*, but it got anonymized because that function + * is defined in a global header where lua may not be defined */ +void SIMIX_ctx_lua_factory_set_state(void* state) { + lua_state = state; } void SIMIX_ctx_lua_factory_init(smx_context_factory_t *factory) { @@ -64,14 +76,10 @@ void SIMIX_ctx_lua_factory_init(smx_context_factory_t *factory) { (*factory)->resume = smx_ctx_lua_resume; (*factory)->name = "smx_lua_context_factory"; - lua_state = lua_open(); - luaL_openlibs(lua_state); - MSG_register(lua_state); INFO0("Lua Factory created"); } -static int smx_ctx_lua_factory_finalize(smx_context_factory_t * factory) -{ +static int smx_ctx_lua_factory_finalize(smx_context_factory_t * factory) { lua_close(lua_state); free(*factory); @@ -81,28 +89,30 @@ static int smx_ctx_lua_factory_finalize(smx_context_factory_t * factory) static smx_context_t smx_ctx_lua_create_context(xbt_main_func_t code, int argc, char** argv, - void_f_pvoid_t cleanup_func, void* cleanup_arg) -{ + void_f_pvoid_t cleanup_func, void* cleanup_arg) { + smx_ctx_lua_t context = xbt_new0(s_smx_ctx_lua_t, 1); /* If the user provided a function for the process then use it otherwise is the context for maestro */ - if(code){ + if (code){ context->code = code; - context->state = lua_newthread(lua_state); - - context->ref = luaL_ref(lua_state, LUA_REGISTRYINDEX); - //lua_pop(lua_state,1); context->argc = argc; context->argv = argv; context->cleanup_func = cleanup_func; context->cleanup_arg = cleanup_arg; INFO1("Created context for function %s",argv[0]); + + /* start the coroutine in charge of running that code */ + context->state = lua_newthread(lua_state); + context->ref = luaL_ref(lua_state, LUA_REGISTRYINDEX); // protect the thread from being garbage collected + /* the actual co-routine starting is done in smx_ctx_lua_start */ + context->nargs = argc-1; } else { INFO0("Created context for maestro"); } - + return (smx_context_t)context; } @@ -110,7 +120,9 @@ static void smx_ctx_lua_free(smx_context_t pcontext) { int i; smx_ctx_lua_t context = (smx_ctx_lua_t)pcontext; + if (context){ + DEBUG1("smx_ctx_lua_free_context(%p)",context); /* free argv */ if (context->argv) { @@ -120,22 +132,23 @@ static void smx_ctx_lua_free(smx_context_t pcontext) free(context->argv); } - - /* destroy the context */ + + /* let the lua garbage collector reclaim the thread used for the coroutine */ luaL_unref(lua_state,LUA_REGISTRYINDEX,context->ref ); + free(context); + context = NULL; } } static void smx_ctx_lua_start(smx_context_t pcontext) { smx_ctx_lua_t context = (smx_ctx_lua_t)pcontext; - INFO1("Starting '%s'",context->argv[0]); + + DEBUG1("Starting '%s'",context->argv[0]); lua_getglobal(context->state,context->argv[0]); - if(!lua_isfunction(context->state,-1)) { - lua_pop(context->state,1); - THROW1(arg_error,0,"The lua function %s does not seem to exist",context->argv[0]); - } + xbt_assert1(lua_isfunction(context->state,-1), + "The lua function %s does not seem to exist",context->argv[0]); // push arguments onto the stack int i; @@ -148,30 +161,34 @@ static void smx_ctx_lua_start(smx_context_t pcontext) { static void smx_ctx_lua_stop(smx_context_t pcontext) { smx_ctx_lua_t context = (smx_ctx_lua_t)pcontext; - + + INFO1("Stopping '%s' (nothing to do)",context->argv[0]); if (context->cleanup_func) (*context->cleanup_func) (context->cleanup_arg); - // FIXME: DO it +// smx_ctx_lua_suspend(pcontext); } - -static void smx_ctx_lua_suspend(smx_context_t context) -{ - INFO1("Suspending %s",context->argv[0]); - lua_yield(((smx_ctx_lua_t)context)->state,0); // Should be the last line of the function -// INFO1("Suspended %s",context->argv[0]); +static void smx_ctx_lua_suspend(smx_context_t pcontext) { + smx_ctx_lua_t context = (smx_ctx_lua_t)pcontext; + DEBUG1("Suspending '%s' (calling lua_yield)",context->argv[0]); + //lua_yield(context->state,0); + + lua_getglobal(context->state,"doyield"); + xbt_assert0(lua_isfunction(context->state,-1), + "Cannot find the coroutine.yield function..."); + INFO0("Call coroutine.yield"); + lua_call(context->state,0,0); + INFO0("Back from call to coroutine.yield"); } static void smx_ctx_lua_resume(smx_context_t old_context, smx_context_t new_context) { smx_ctx_lua_t context = (smx_ctx_lua_t)new_context; - - INFO1("Resuming %s",context->argv[0]); - lua_resume(context->state,context->nargs); - context->nargs = 0; - INFO1("Resumed %s",context->argv[0]); - -// INFO1("Process %s done ?",context->argv[0]); -// lua_resume(((smx_ctx_lua_t)new_context)->state,0); + DEBUG1("Resuming %s",context->argv[0]); + int ret = lua_resume(context->state,context->nargs); + INFO3("Function %s yielded back with value %d %s",context->argv[0],ret,(ret==LUA_YIELD?"(ie, LUA_YIELD)":"")); + if (lua_isstring(context->state,-1)) + INFO2("Result of %s seem to be '%s'",context->argv[0],luaL_checkstring(context->state,-1)); + context->nargs=0; }