Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Lua works!
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Tue, 23 Mar 2010 21:49:56 +0000 (21:49 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Tue, 23 Mar 2010 21:49:56 +0000 (21:49 +0000)
I don't even have to write a context mechanism. Lua vm's fine with
having swapcontextes changing the world around it. It's also fine with
threads doing so, as long as they dont do it at the exact same time
(but we're just fine in SimGrid).

Some more cleanups are needed, I guess.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7340 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/bindings/lua/simgrid_lua.c
src/simix/smx_context_lua.c
src/simix/smx_context_private.h
src/simix/smx_context_sysv.c
src/simix/smx_context_sysv_private.h [new file with mode: 0644]

index 7c395d2..67328c6 100644 (file)
@@ -55,7 +55,7 @@ static void stackDump (lua_State *L) {
     }
     p+=sprintf(p,"  ");  /* put a separator */
   }
-  INFO1("%s",buff);
+  DEBUG1("%s",buff);
 }
 
 /** @brief ensures that a userdata on the stack is a task and returns the pointer inside the userdata */
@@ -92,7 +92,7 @@ static int Task_new(lua_State* L) {
   int msg_size = luaL_checkint(L,3);
   // FIXME: data shouldn't be NULL I guess
   pushTask(L,MSG_task_create(name,comp_size,msg_size,NULL));
-  INFO0("Created task");
+  DEBUG0("Created task");
   return 1;
 }
 
@@ -124,21 +124,18 @@ static int Task_destroy(lua_State *L) {
 static int Task_send(lua_State *L)  {
   m_task_t tk = checkTask(L,1);
   const char *mailbox = luaL_checkstring(L,2);
-  stackDump(L);fflush(stdout);fflush(stderr);
   int res = MSG_task_send(tk,mailbox);
   res++;//FIXME: check it instead of avoiding the warning
-  stackDump(L);
   return 0;
 }
 static int Task_recv(lua_State *L)  {
   m_task_t tk = NULL;
-  //stackDump(L);
   const char *mailbox = luaL_checkstring(L,1);
   int res = MSG_task_receive(&tk,mailbox);
+  MSG_task_ref(tk);
   res++;//FIXME: check it instead of avoiding the warning
-  INFO1("Task Name : >>>%s",MSG_task_get_name(tk));
+  DEBUG1("Task Name : >>>%s",MSG_task_get_name(tk));
   pushTask(L,tk);
-  //  stackDump(L);
   return 1;
 }
 
@@ -174,20 +171,55 @@ static const luaL_reg Task_meta[] = {
 /*
  * Environment related
  */
+extern lua_State *simgrid_lua_state;
+
+static int run_lua_code(int argc,char **argv) {
+  DEBUG1("Run lua code %s",argv[0]);
+//  fprintf(stderr,"Run lua code %s\n", (argv ? argv[0] : "(null)"));
+  lua_State *L = lua_newthread(simgrid_lua_state);
+  int ref = luaL_ref(simgrid_lua_state, LUA_REGISTRYINDEX); // protect the thread from being garbage collected
+  int res = 1;
+
+  /* Start the co-routine */
+  lua_getglobal(L,argv[0]);
+  xbt_assert1(lua_isfunction(L,-1),
+      "The lua function %s does not seem to exist",argv[0]);
+
+  // push arguments onto the stack
+  int i;
+  for(i=1;i<argc;i++)
+    lua_pushstring(L,argv[i]);
+
+  // Call the function (in resume)
+  xbt_assert2(lua_pcall(L, argc-1, 1, 0) == 0,
+    "error running function `%s': %s",argv[0], lua_tostring(L, -1));
+
+  /* retrieve result */
+  if (lua_isnumber(L, -1)) {
+    res = lua_tonumber(L, -1);
+    lua_pop(L, 1);  /* pop returned value */
+  }
+
+  // cleanups
+  luaL_unref(simgrid_lua_state,LUA_REGISTRYINDEX,ref );
+  fprintf(stderr,"Execution of lua code %s is over\n", (argv ? argv[0] : "(null)"));
+  return res;
+}
 static int launch_application(lua_State *L) {
   const char * file = luaL_checkstring(L,1);
+  MSG_function_register_default(run_lua_code);
   MSG_launch_application(file);
   return 0;
 }
 #include "simix/simix.h" //FIXME: KILLME when debugging on simix internals become useless
 static int create_environment(lua_State *L) {
   const char *file = luaL_checkstring(L,1);
-  INFO1("Loading environment file %s",file);
+  DEBUG1("Loading environment file %s",file);
   MSG_create_environment(file);
   smx_host_t *hosts = SIMIX_host_get_table();
   int i;
   for (i=0;i<SIMIX_host_get_number();i++) {
-    INFO1("We have an host %s", SIMIX_host_get_name(hosts[i]));
+    DEBUG1("We have an host %s", SIMIX_host_get_name(hosts[i]));
   }
 
   return 0;
@@ -227,14 +259,13 @@ static const luaL_Reg simgrid_funcs[] = {
 /*                       module management functions                                 */
 /* ********************************************************************************* */
 
-void SIMIX_ctx_lua_factory_set_state(void *state);/* Hack: pass the L to our factory */
 extern const char*xbt_ctx_factory_to_use; /*Hack: let msg load directly the right factory */
 
 #define LUA_MAX_ARGS_COUNT 10 /* maximum amount of arguments we can get from lua on command line */
 
 int luaopen_simgrid(lua_State* L); // Fuck gcc: we don't need that prototype
 int luaopen_simgrid(lua_State* L) {
-  xbt_ctx_factory_to_use = "lua";
+  //xbt_ctx_factory_to_use = "lua";
 
   char **argv=malloc(sizeof(char*)*LUA_MAX_ARGS_COUNT);
   int argc=1;
@@ -256,14 +287,14 @@ int luaopen_simgrid(lua_State* L) {
            __FILE__,LUA_MAX_ARGS_COUNT-1);
       argv[argc-1] = (char*)luaL_checkstring(L,-1);
       lua_pop(L,1);
-      INFO1("Got command line argument %s from lua",argv[argc-1]);
+      DEBUG1("Got command line argument %s from lua",argv[argc-1]);
     }
   }
   argv[argc--]=NULL;
 
   /* Initialize the MSG core */
   MSG_global_init(&argc,argv);
-  INFO1("Still %d arguments on command line",argc); // FIXME: update the lua's arg table to reflect the changes from SimGrid
+  DEBUG1("Still %d arguments on command line",argc); // FIXME: update the lua's arg table to reflect the changes from SimGrid
 
   /* register the core C functions to lua */
   luaL_register(L, "simgrid", simgrid_funcs);
@@ -280,7 +311,7 @@ int luaopen_simgrid(lua_State* L) {
   lua_pop(L,1);   //drop metatable
 
   /* Keep the context mechanism informed of our lua world today */
-  SIMIX_ctx_lua_factory_set_state(L);
+  simgrid_lua_state = L;
 
   return 1;
 }
index dc2b441..5d5d376 100644 (file)
@@ -5,25 +5,16 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-#include "smx_context_private.h"
 #include <lua5.1/lauxlib.h>
 #include <lua5.1/lualib.h>
 
-/* lower this if you want to reduce the memory consumption  */
-//#define STACK_SIZE 128*1024
+/* lua can run with ultra tiny stacks since the user code lives in lua stacks, not the main one */
+//#define CONTEXT_STACK_SIZE 4*1024
+#include "smx_context_sysv_private.h"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(lua);
 
-typedef struct s_smx_ctx_lua {
-  s_smx_ctx_sysv_t super;  /* Fields of super implementation */
-
-  /* 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 */
-} s_smx_ctx_lua_t, *smx_ctx_lua_t;
-
-static lua_State *lua_state;
+lua_State *simgrid_lua_state;
 
 static smx_context_t 
 smx_ctx_lua_create_context(xbt_main_func_t code, int argc, char** argv, 
@@ -36,113 +27,57 @@ 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 new_context);
 
-static void smx_ctx_sysv_wrapper(void);
 
-/* 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) {
 
   smx_ctx_base_factory_init(factory);
 
   (*factory)->create_context = smx_ctx_lua_create_context;
-  (*factory)->finalize = smx_ctx_lua_factory_finalize;
-  (*factory)->free = smx_ctx_lua_free;
-  (*factory)->stop = smx_ctx_lua_stop;
-  (*factory)->suspend = smx_ctx_lua_suspend;
-  (*factory)->resume = smx_ctx_lua_resume;
+  /* don't override (*factory)->finalize */;
+  (*factory)->free = smx_ctx_sysv_free;
+  (*factory)->stop = smx_ctx_sysv_stop;
+  (*factory)->suspend = smx_ctx_sysv_suspend;
+  (*factory)->resume = smx_ctx_sysv_resume;
   (*factory)->name = "smx_lua_context_factory";
 
   INFO0("Lua Factory created");
 }
 
-static int smx_ctx_lua_factory_finalize(smx_context_factory_t * factory) {
-  lua_close(lua_state);
-
-  return smx_ctx_base_factory_finalize(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) {
 
-  smx_ctx_lua_t context = (smx_ctx_lua_t)smx_ctx_sysv_create_context_sized
-      (sizeof(s_smx_ctx_lua_t), code,argc,argv,cleanup_func,cleanup_arg);
-
-
-  /* If the user provided a function for the process then use it
-     otherwise is the context for maestro */
-  if (code){
-    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
-
-    /* Start the co-routine */
-    lua_getglobal(context->state,context->super.super.argv[0]);
-    xbt_assert1(lua_isfunction(context->state,-1),
-        "The lua function %s does not seem to exist",context->super.super.argv[0]);
-
-    // push arguments onto the stack
-    int i;
-    for(i=1;i<context->super.super.argc;i++)
-      lua_pushstring(context->state,context->super.super.argv[i]);
-
-    // Call the function (in resume)
-    context->nargs = context->super.super.argc-1;
-
-  } else {
-    INFO0("Created context for maestro");
-  }
-
-  return (smx_context_t)context;
+  return smx_ctx_sysv_create_context_sized(sizeof(s_smx_ctx_sysv_t),
+      code,argc,argv,cleanup_func,cleanup_arg);
 }
-
+#if KILLME
 static void smx_ctx_lua_free(smx_context_t context) {
 
   if (context){
     DEBUG1("smx_ctx_lua_free_context(%p)",context);
 
-    /* let the lua garbage collector reclaim the thread used for the coroutine */
-    luaL_unref(lua_state,LUA_REGISTRYINDEX,((smx_ctx_lua_t)context)->ref );
   }
 
-  smx_ctx_base_free(context);
+  smx_ctx_sysv_free(context);
 }
 
 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->super.super.argv[0]);
-  if (context->super.super.cleanup_func)
-    (*context->super.super.cleanup_func) (context->super.super.cleanup_arg);
-
-//  smx_ctx_lua_suspend(pcontext);
+  DEBUG1("Stopping '%s' (nothing to do)",pcontext->argv[0]);
+  smx_ctx_sysv_stop(pcontext);
 }
 
 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->super.super.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");
+  DEBUG1("Suspending '%s' (using sysv facilities)",context->super.super.argv[0]);
+  smx_ctx_sysv_suspend(pcontext);
+
+  DEBUG0("Back from call yielding");
 }
 
 static void 
 smx_ctx_lua_resume(smx_context_t new_context) {
   smx_ctx_lua_t context = (smx_ctx_lua_t)new_context;
   DEBUG1("Resuming %s",context->super.super.argv[0]);
-  int ret = lua_resume(context->state,context->nargs);
-  INFO3("Function %s yielded back with value %d %s",context->super.super.argv[0],ret,(ret==LUA_YIELD?"(ie, LUA_YIELD)":""));
-  if (lua_isstring(context->state,-1))
-    INFO2("Result of %s seem to be '%s'",context->super.super.argv[0],luaL_checkstring(context->state,-1));
-  context->nargs=0;
+  smx_ctx_sysv_resume(new_context);
 }
+#endif
index 5c561c1..d2e0ef2 100644 (file)
@@ -43,35 +43,6 @@ smx_ctx_base_factory_create_context_sized(size_t size,
 void smx_ctx_base_free(smx_context_t context);
 void smx_ctx_base_stop(smx_context_t context);
 
-/* Functions of sysv context mecanism: lua inherites them */
-#include "portable.h"
-#ifdef CONTEXT_UCONTEXT
-
-/* lower this if you want to reduce the memory consumption  */
-#ifndef CONTEXT_STACK_SIZE /* allow lua to override this */
-#define CONTEXT_STACK_SIZE 128*1024
-#endif /*CONTEXT_STACK_SIZE */
-
-#include "context_sysv_config.h"        /* loads context system definitions */
-#include <ucontext.h>           /* context relative declarations */
-
-typedef struct s_smx_ctx_sysv {
-  s_smx_ctx_base_t super;       /* Fields of super implementation */
-  ucontext_t uc;                /* the thread that execute the code */
-  char stack[CONTEXT_STACK_SIZE];       /* the thread stack size */
-#ifdef HAVE_VALGRIND_VALGRIND_H
-  unsigned int valgrind_stack_id;       /* the valgrind stack id */
-#endif
-} s_smx_ctx_sysv_t, *smx_ctx_sysv_t;smx_context_t
-smx_ctx_sysv_create_context_sized(size_t size,
-    xbt_main_func_t code, int argc, char** argv,
-    void_f_pvoid_t cleanup_func, void* cleanup_arg);
-void smx_ctx_sysv_free(smx_context_t context);
-void smx_ctx_sysv_stop(smx_context_t context);
-void smx_ctx_sysv_suspend(smx_context_t context);
-void smx_ctx_sysv_resume(smx_context_t new_context);
-#endif
-
 SG_END_DECL()
 #endif /* !_XBT_CONTEXT_PRIVATE_H */
 
index b1636d7..844f175 100644 (file)
@@ -1,13 +1,11 @@
-/* $Id$ */
+/* context_sysv - context switching with ucontextes from System V           */
 
-/* context_sysv - implementation of context switching with ucontextes from Sys V */
+/* Copyright (c) 2004-2010 the SimGrid team. All right reserved             */
 
-/* Copyright (c) 2004-2008 the SimGrid team. All right reserved */
+ /* This program is free software; you can redistribute it and/or modify it
+  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include "smx_context_private.h"
+#include "smx_context_sysv_private.h"
 
 #ifdef HAVE_VALGRIND_VALGRIND_H
 #  include <valgrind/valgrind.h>
diff --git a/src/simix/smx_context_sysv_private.h b/src/simix/smx_context_sysv_private.h
new file mode 100644 (file)
index 0000000..47d8096
--- /dev/null
@@ -0,0 +1,46 @@
+/* Functions of sysv context mecanism: lua inherites them                   */
+
+/* Copyright (c) 2004-2010 the SimGrid team. All rights reserved.           */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef _XBT_CONTEXT_SYSV_PRIVATE_H
+#define _XBT_CONTEXT_SYSV_PRIVATE_H
+
+#include "xbt/swag.h"
+#include "simix/smx_context_private.h"
+#include "portable.h"
+
+SG_BEGIN_DECL()
+
+
+
+/* lower this if you want to reduce the memory consumption  */
+#ifndef CONTEXT_STACK_SIZE /* allow lua to override this */
+#define CONTEXT_STACK_SIZE 128*1024
+#endif /*CONTEXT_STACK_SIZE */
+
+#include "context_sysv_config.h"        /* loads context system definitions */
+#include <ucontext.h>           /* context relative declarations */
+
+typedef struct s_smx_ctx_sysv {
+  s_smx_ctx_base_t super;       /* Fields of super implementation */
+  ucontext_t uc;                /* the thread that execute the code */
+#ifdef HAVE_VALGRIND_VALGRIND_H
+  unsigned int valgrind_stack_id;       /* the valgrind stack id */
+#endif
+  char stack[CONTEXT_STACK_SIZE];       /* the thread stack size */
+} s_smx_ctx_sysv_t, *smx_ctx_sysv_t;smx_context_t
+smx_ctx_sysv_create_context_sized(size_t structure_size,
+    xbt_main_func_t code, int argc, char** argv,
+    void_f_pvoid_t cleanup_func, void* cleanup_arg);
+void smx_ctx_sysv_free(smx_context_t context);
+void smx_ctx_sysv_stop(smx_context_t context);
+void smx_ctx_sysv_suspend(smx_context_t context);
+void smx_ctx_sysv_resume(smx_context_t new_context);
+
+SG_END_DECL()
+#endif /* !_XBT_CONTEXT_SYSV_PRIVATE_H */
+
+