Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Betterly integrated lua bindings (detected by configure, added to lib, simix interact...
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Fri, 15 Jan 2010 21:57:54 +0000 (21:57 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Fri, 15 Jan 2010 21:57:54 +0000 (21:57 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7011 48e7efb5-ca39-0410-a469-dd3cf9ba447f

configure.ac
src/Makefile.am
src/bindings/lua/Msglua.c
src/bindings/lua/doit
src/bindings/lua/tasktest.c
src/simix/private.h
src/simix/smx_context.c
src/simix/smx_context_lua.c [new file with mode: 0644]

index 2ecf7ec..2a3d527 100644 (file)
@@ -430,6 +430,25 @@ AC_MSG_RESULT(decide whether to compile java bindings... $use_java)
 AM_CONDITIONAL(HAVE_JAVA,test "x$use_java" = "xyes")
 
 
+SG_CONFIGURE_PART(Checking Lua bindings...)
+AC_ARG_ENABLE(lua,
+             AS_HELP_STRING([--disable-lua], [To not compile the Lua bindings even if the tools are found]),
+             disable_lua=$enableval,disable_lua=yes)
+if test "x$disable_lua" != "xyes" ; then
+   use_lua="disabled by user"
+else
+  AC_CHECK_HEADERS(lua5.1/lualib.h)
+  if test "x$ac_cv_header_lua5_1_lualib_h" = "xyes" ; then
+     use_lua="yes"
+     AC_DEFINE(HAVE_LUA,1, [defines whether Lua bindings must be compiled or not])
+     SIMGRID_DEP="${SIMGRID_DEP} -ldl -llua5.1"
+  else   
+     use_lua="no"
+  fi
+fi
+AC_MSG_RESULT(decide whether to compile lua bindings... $use_lua)
+AM_CONDITIONAL(HAVE_LUA,test "x$use_lua" = "xyes")
+
 #####################
 ## Check for programs
 ##
@@ -629,6 +648,7 @@ Configuration of package \`${PACKAGE}' (version ${VERSION}) on $gras_arch_name (
 
        Context backend: ${with_context}
        Compile Java:    ${use_java}
+       Compile Lua:     ${use_lua}
        
        Maintainer mode: ${USE_MAINTAINER_MODE}
        Supernovae mode: ${supernovae}
index f12fdfd..ed9474a 100644 (file)
@@ -380,6 +380,12 @@ else
 EXTRA_DIST+=$(JMSG_C_SRC) $(JMSG_JAVA_SRC) $(MSG_SRC)
 endif
 
+LUA_SRC= simix/smx_context_lua.c bindings/lua/Msglua.c
+if HAVE_LUA
+  simgrid_sources += $(LUA_SRC)
+else
+  EXTRA_DIST += $(LUA_SRC)
+endif
 ##
 ## Compile the libs
 CLEANFILES=supernovae_sg.c supernovae_gras.c supernovae_smpi.c
index 3b4dd08..29cf399 100644 (file)
@@ -1,6 +1,6 @@
 #include <stdio.h>
-#include "lauxlib.h"
-#include "lualib.h"
+#include <lua5.1/lauxlib.h>
+#include <lua5.1/lualib.h>
 
 // Msg Includes
 #include <stdio.h>
        Example Lua Bindings for Msg
 
 =============================================
-*/
+ */
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(lua,"Lua bindings");
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smx_lua,simix,
+    "Messages specific for this lua example");
 
 
 #define TASK "Msg.Task"
@@ -34,146 +36,146 @@ typedef m_process_t Process;
 
 
 static void stackDump (lua_State *L) {
+  char buff[2048];
+  char *p=buff;
   int i;
   int top = lua_gettop(L);
-  void *p;
+  void *ptr;
   fflush(stdout);
-  return;
-  INFO0("That's me");
-  printf("STACK(top=%d): ",top);
+  p+=sprintf(p,"STACK(top=%d): ",top);
   for (i = 1; i <= top; i++) {  /* repeat for each level */
     int t = lua_type(L, i);
     switch (t) {
 
-      case LUA_TSTRING:  /* strings */
-        printf("`%s'", lua_tostring(L, i));
-        break;
+    case LUA_TSTRING:  /* strings */
+      p+=sprintf(p,"`%s'", lua_tostring(L, i));
+      break;
 
-      case LUA_TBOOLEAN:  /* booleans */
-        printf(lua_toboolean(L, i) ? "true" : "false");
-        break;
+    case LUA_TBOOLEAN:  /* booleans */
+      p+=sprintf(p,lua_toboolean(L, i) ? "true" : "false");
+      break;
 
-      case LUA_TNUMBER:  /* numbers */
-        printf("%g", lua_tonumber(L, i));
-        break;
+    case LUA_TNUMBER:  /* numbers */
+      p+=sprintf(p,"%g", lua_tonumber(L, i));
+      break;
 
-      default:  /* other values */
-        if ((p = luaL_checkudata(L,i,TASK))) {
-          printf("task");
-        } else {
-          printf("%s", lua_typename(L, t));
-        }
-        break;
+    default:  /* other values */
+      if ((ptr = luaL_checkudata(L,i,TASK))) {
+        p+=sprintf(p,"task");
+      } else {
+        p+=printf(p,"%s", lua_typename(L, t));
+      }
+      break;
 
     }
-    printf("  ");  /* put a separator */
+    p+=sprintf(p,"  ");  /* put a separator */
   }
-  printf("\n");  /* end the listing */
-  fflush(stdout);
+  INFO1("%s",buff);
 }
 
 //**********************************************************TASK SECTION***************************************************
 
 
 static Task toTask(lua_State *L,int index)
-       {
-       Task *pi = (Task*) lua_touserdata(L,index);
-       if(pi == NULL) luaL_typerror(L,index,TASK);
-       return *pi;
-       }
+{
+  Task *pi = (Task*) lua_touserdata(L,index);
+  if(pi == NULL) luaL_typerror(L,index,TASK);
+  return *pi;
+}
 /**
-*checkTask ensures that a userdata on the stack is the correct type, and returns the Task pointer inside the userdata
-*/
+ *checkTask ensures that a userdata on the stack is the correct type, and returns the Task pointer inside the userdata
+ */
 
 static Task checkTask (lua_State *L,int index)
-       {
-       Task *pi,tk;
-       luaL_checktype(L,index,LUA_TUSERDATA);
-       pi = (Task*)luaL_checkudata(L,index,TASK);
-       if(pi == NULL ) luaL_typerror(L,index,TASK);
-       tk = *pi;
-       if(!tk)
-               luaL_error(L,"null Task");
-       return  tk;
-       }
+{
+  Task *pi,tk;
+  luaL_checktype(L,index,LUA_TUSERDATA);
+  pi = (Task*)luaL_checkudata(L,index,TASK);
+  if(pi == NULL ) luaL_typerror(L,index,TASK);
+  tk = *pi;
+  if(!tk)
+    luaL_error(L,"null Task");
+  return  tk;
+}
 
 /**
-*pushTask leaves a new userdata on top of the stack, sets its metatable, and sets the Task pointer inside the userdata.
-*/
+ *pushTask leaves a new userdata on top of the stack, sets its metatable, and sets the Task pointer inside the userdata.
+ */
 
 static Task *pushTask (lua_State *L,Task tk)
-       {
-       Task *pi = (Task*)lua_newuserdata(L,sizeof(Task));
-       *pi=tk;
-       luaL_getmetatable(L,TASK);
-       lua_setmetatable(L,-2);
-       return pi;
+{
+  Task *pi = (Task*)lua_newuserdata(L,sizeof(Task));
+  *pi=tk;
+  luaL_getmetatable(L,TASK);
+  lua_setmetatable(L,-2);
+  return pi;
 
-       }
+}
 
 /**
-*Task.new is a constructor that returns a userdata containing a pointer the Task to be manipulated
-*/
+ *Task.new is a constructor that returns a userdata containing a pointer the Task to be manipulated
+ */
 
 
 static int Task_new(lua_State* L)
-       {
-       const char *name=luaL_checkstring(L,1);
-       int comp_size = luaL_checkint(L,2);
-       int msg_size = luaL_checkint(L,3);
-       // We Will Set The Data as a Null for The Moment
-       pushTask(L,MSG_task_create(name,comp_size,msg_size,NULL));
-       return 1;               
+{
+  const char *name=luaL_checkstring(L,1);
+  int comp_size = luaL_checkint(L,2);
+  int msg_size = luaL_checkint(L,3);
+  // We Will Set The Data as a Null for The Moment
+  pushTask(L,MSG_task_create(name,comp_size,msg_size,NULL));
+  INFO0("Created task");fflush(stdout);fflush(stderr);
+  return 1;
 
-       }
+}
 
 /**
-* Function to return the Task Name
-*/
+ * Function to return the Task Name
+ */
 
 
 static int Task_name(lua_State *L)
-       {
-       Task tk = checkTask(L,1);
-       lua_pushstring(L,MSG_task_get_name(tk));
-       return 1;
-       }
+{
+  Task tk = checkTask(L,1);
+  lua_pushstring(L,MSG_task_get_name(tk));
+  return 1;
+}
 
 
 /**
-* Function to return the Computing Size of a Task
-*/
+ * Function to return the Computing Size of a Task
+ */
 
 static int Task_comp(lua_State *L)
-       {
-       Task tk = checkTask(L,1);
-       lua_pushnumber(L,MSG_task_get_compute_duration (tk));
-       return 1;
-       }
+{
+  Task tk = checkTask(L,1);
+  lua_pushnumber(L,MSG_task_get_compute_duration (tk));
+  return 1;
+}
 
 
 /**
-*Function to Excute a Task
-*/
+ *Function to Excute a Task
+ */
 
 static int Task_execute(lua_State *L)
-       {
-       Task tk = checkTask(L,1);
-       int res = MSG_task_execute(tk);
-       lua_pushnumber(L,res);
-       return 1;
-       }
+{
+  Task tk = checkTask(L,1);
+  int res = MSG_task_execute(tk);
+  lua_pushnumber(L,res);
+  return 1;
+}
 
 /**
-*Function ro Desroy a Task
-*/
+ *Function ro Desroy a Task
+ */
 static int Task_destroy(lua_State *L)
-       {       
-       Task tk = checkTask(L,1);
-       int res = MSG_task_destroy(tk);
-       lua_pushnumber(L,res);
-       return 1;
-       }
+{
+  Task tk = checkTask(L,1);
+  int res = MSG_task_destroy(tk);
+  lua_pushnumber(L,res);
+  return 1;
+}
 
 
 
@@ -185,89 +187,89 @@ static int Task_destroy(lua_State *L)
 
 
 static Host toHost(lua_State *L,int index)
-       {
-       Host *pi = (Host*) lua_touserdata(L,index);
-       if(pi == NULL) luaL_typerror(L,index,HOST);
-       return *pi;
-       }
+{
+  Host *pi = (Host*) lua_touserdata(L,index);
+  if(pi == NULL) luaL_typerror(L,index,HOST);
+  return *pi;
+}
 
 
 
 static Host checkHost (lua_State *L,int index)
-       {
-       Host *pi,ht;
-       luaL_checktype(L,index,LUA_TUSERDATA);
-       pi = (Host*)luaL_checkudata(L,index,HOST);
-       if(pi == NULL ) luaL_typerror(L,index,HOST);
-       ht = *pi;
-       if(!ht)
-               luaL_error(L,"null Host");
-       return  ht;
-       }
+{
+  Host *pi,ht;
+  luaL_checktype(L,index,LUA_TUSERDATA);
+  pi = (Host*)luaL_checkudata(L,index,HOST);
+  if(pi == NULL ) luaL_typerror(L,index,HOST);
+  ht = *pi;
+  if(!ht)
+    luaL_error(L,"null Host");
+  return  ht;
+}
 
 
 
 static Host *pushHost (lua_State *L,Host ht)
-       {
-       Host *pi = (Host*)lua_newuserdata(L,sizeof(Host));
-       *pi=ht;
-       luaL_getmetatable(L,HOST);
-       lua_setmetatable(L,-2);
-       return pi;
+{
+  Host *pi = (Host*)lua_newuserdata(L,sizeof(Host));
+  *pi=ht;
+  luaL_getmetatable(L,HOST);
+  lua_setmetatable(L,-2);
+  return pi;
 
-       }
+}
 
 
 static int Host_new(lua_State* L)
-       {
-       const char *host_name=luaL_checkstring(L,1);
-       pushHost(L,MSG_get_host_by_name(host_name));
-       return 1;               
-       }
+{
+  const char *host_name=luaL_checkstring(L,1);
+  pushHost(L,MSG_get_host_by_name(host_name));
+  return 1;
+}
 
 
 
 static int Host_name(lua_State* L)
-       {
-       Host ht = checkHost(L,1);
-       lua_pushstring(L,MSG_host_get_name(ht));        
-       return 1;
-       }
+{
+  Host ht = checkHost(L,1);
+  lua_pushstring(L,MSG_host_get_name(ht));
+  return 1;
+}
 
 
 //*******************************************************   PROCESS SECTION      ***************************************************************************
 static Process toProcess(lua_State *L,int index)
-       {
-       Process *pi = (Process*) lua_touserdata(L,index);
-       if(pi == NULL) luaL_typerror(L,index,PROCESS);
-       return *pi;
-       }
+{
+  Process *pi = (Process*) lua_touserdata(L,index);
+  if(pi == NULL) luaL_typerror(L,index,PROCESS);
+  return *pi;
+}
 
 
 
 static Process checkProcess (lua_State *L,int index)
-       {
-       Process *pi,ps;
-       luaL_checktype(L,index,LUA_TUSERDATA);
-       pi = (Process*)luaL_checkudata(L,index,PROCESS);
-       if(pi == NULL ) luaL_typerror(L,index,PROCESS);
-       ps = *pi;
-       if(!ps)
-               luaL_error(L,"null Process");
-       return  ps;
-       }
+{
+  Process *pi,ps;
+  luaL_checktype(L,index,LUA_TUSERDATA);
+  pi = (Process*)luaL_checkudata(L,index,PROCESS);
+  if(pi == NULL ) luaL_typerror(L,index,PROCESS);
+  ps = *pi;
+  if(!ps)
+    luaL_error(L,"null Process");
+  return  ps;
+}
 
 
 
 static Process *pushProcess (lua_State *L,Process ps)
-       {
-       Process *pi = (Process*)lua_newuserdata(L,sizeof(Process));
-       *pi=ps;
-       luaL_getmetatable(L,PROCESS);
-       lua_setmetatable(L,-2);
-       return pi;
+{
+  Process *pi = (Process*)lua_newuserdata(L,sizeof(Process));
+  *pi=ps;
+  luaL_getmetatable(L,PROCESS);
+  lua_setmetatable(L,-2);
+  return pi;
 
-       }
+}
 
 /*
 m_process_t MSG_process_create         (       const char *     name,
@@ -275,280 +277,244 @@ m_process_t MSG_process_create          (       const char *     name,
                void *          data,
                m_host_t        host     
        )       
-*/
+ */
 
 
 
 static int Process_new(lua_State* L)
-       {
-       const char *name=luaL_checkstring(L,1);
-       //int code = luaL_checkint(L,2);
-       //xbt_main_func_t << code  
-       // We Will Set The Data as a Null for The Moment
-       Host ht = checkHost(L,4); 
-       pushProcess(L,MSG_process_create(name,NULL,NULL,ht));
-       return 1;               
+{
+  const char *name=luaL_checkstring(L,1);
+  //int code = luaL_checkint(L,2);
+  //xbt_main_func_t << code
+  // We Will Set The Data as a Null for The Moment
+  Host ht = checkHost(L,4);
+  pushProcess(L,MSG_process_create(name,NULL,NULL,ht));
+  return 1;
 
-       }
+}
 
 
 static int Process_kill(lua_State *L)
-       {
-       Process ps = checkProcess (L,1);
-       MSG_process_kill(ps);
-       return 0;
-       }
+{
+  Process ps = checkProcess (L,1);
+  MSG_process_kill(ps);
+  return 0;
+}
 
 
 
 //**********************************************************MSG Operating System Functions******************************************************************
 /**
-* Function to Send a Task
-*/
+ * Function to Send a Task
+ */
 static int Task_send(lua_State *L)     {
   Task tk = checkTask(L,1);
   const char *mailbox = luaL_checkstring(L,2);
-  stackDump(L);
+  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;
 }
 /**
-* Function Recieve a Task
-*/
-static int Task_recv2(lua_State *L)    {
-
-       Task *tk = (Task *)checkTask(L,1);
-       const char *mailbox = luaL_checkstring(L,2);
-       MSG_task_receive(tk,mailbox);
-       printf("Task Name Within Receive Fct: >>>%s\n",MSG_task_get_name(*tk));
-       
-       return 0;
-}
-
-
+ * Function Recieve a Task
+ */
 static int Task_recv(lua_State *L)     {
   Task tk = NULL;
   //stackDump(L);
-       const char *mailbox = luaL_checkstring(L,1);
-       int res = MSG_task_receive(&tk,mailbox);
-       INFO1("Task Name : >>>%s",MSG_task_get_name(tk));
-       pushTask(L,tk);
-//     stackDump(L);
-       return 1;
+  const char *mailbox = luaL_checkstring(L,1);
+  int res = MSG_task_receive(&tk,mailbox);
+  res++;//FIXME: check it instead of avoiding the warning
+  INFO1("Task Name : >>>%s",MSG_task_get_name(tk));
+  pushTask(L,tk);
+  //   stackDump(L);
+  return 1;
 }
 
 //*******************************************************   PLATFORM & APPLICATION SECTION  ****************************************************************
 
 
- //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WE WONT NEED IT (!!??) 
+//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WE WONT NEED IT (!!??)
 /**
-* Launch Application Function
-*/
+ * Launch Application Function
+ */
 
 static int launch_application(lua_State *L)
-       {
+{
 
-       const char * file = luaL_checkstring(L,1);
-       MSG_launch_application(file);
-       return 0;
+  const char * file = luaL_checkstring(L,1);
+  MSG_launch_application(file);
+  return 0;
 
-       }
+}
 
 /**
-* Create Environment Function
-*/
+ * Create Environment Function
+ */
 
 static int create_environment(lua_State *L)
-       {
-
-       const char *file = luaL_checkstring(L,1);
-       MSG_create_environment(file);
-       return 0;
+{
 
-       }
-
-/**
-* Function Register
-*/
-
-static int function_register()
-       {
+  const char *file = luaL_checkstring(L,1);
+  MSG_create_environment(file);
+  return 0;
 
-       //Code ??!!!
+}
 
-       }
 
 //******************************************************************       REGISTERING          ************************************************************
 /**
-*Registering Into Lua
-*/
+ *Registering Into Lua
+ */
 
 
 static const luaL_reg Task_methods[] = {
-{"new",                Task_new},
-{"name",       Task_name},
-{"comp",       Task_comp},
-{"execute",    Task_execute},
-{"destroy",    Task_destroy},
-{"send",               Task_send},
-{"recv",               Task_recv},
-{"recv2",              Task_recv2},
-{0,0}
+    {"new",            Task_new},
+    {"name",   Task_name},
+    {"comp",   Task_comp},
+    {"execute",        Task_execute},
+    {"destroy",        Task_destroy},
+    {"send",           Task_send},
+    {"recv",           Task_recv},
+    {0,0}
 };
 
 
 static const luaL_reg Host_methods[] = {
-{"new",                Host_new},
-{"name",       Host_name},
-{0,0}
+    {"new",            Host_new},
+    {"name",   Host_name},
+    {0,0}
 };
 
 
 static const luaL_reg Process_methods[] = {
-{"new",                Process_new},
-{"kill",       Process_kill},
-{0,0}
+    {"new",            Process_new},
+    {"kill",   Process_kill},
+    {0,0}
 };
 
 
 
 
 /**
-* Task_meta
-*/
+ * Task_meta
+ */
 static int Task_gc(lua_State *L)
-       {
-       Task tk=toTask(L,1);
-       //if (tk) MSG_task_destroy(tk);
-       //printf("GoodBye Task(%p)\n",lua_touserdata(L,1));
-       return 0; 
-       }
+{
+  Task tk=toTask(L,1);
+  if (tk) MSG_task_destroy(tk);
+  //printf("GoodBye Task(%p)\n",lua_touserdata(L,1));
+  return 0;
+}
 
 static int Task_tostring(lua_State *L)
-       {
-       lua_pushfstring(L,"Task :%p",lua_touserdata(L,1));
-       return 1;       
-       }
+{
+  lua_pushfstring(L,"Task :%p",lua_touserdata(L,1));
+  return 1;
+}
 
 
 static const luaL_reg Task_meta[] = {
-       {"__gc",        Task_gc},
-       {"__tostring",  Task_tostring},
-       {0,0}
+    {"__gc",   Task_gc},
+    {"__tostring",     Task_tostring},
+    {0,0}
 };
 
 
 
 
 /**
-* Host_meta
-*/
+ * Host_meta
+ */
 static int Host_gc(lua_State *L)
-       {
-       Host ht=toHost(L,1);
-       if (ht) ht=NULL;
-       printf("GoodBye Host(%p)\n",lua_touserdata(L,1));
-       return 0; 
-       }
+{
+  Host ht=toHost(L,1);
+  if (ht) ht=NULL;
+  printf("GoodBye Host(%p)\n",lua_touserdata(L,1));
+  return 0;
+}
 
 static int Host_tostring(lua_State *L)
-       {
-       lua_pushfstring(L,"Host :%p",lua_touserdata(L,1));
-       return 1;       
-       }
+{
+  lua_pushfstring(L,"Host :%p",lua_touserdata(L,1));
+  return 1;
+}
 
 
 static const luaL_reg Host_meta[] = {
-       {"__gc",        Host_gc},
-       {"__tostring",  Host_tostring},
-       {0,0}
+    {"__gc",   Host_gc},
+    {"__tostring",     Host_tostring},
+    {0,0}
 };
 
 
 /**
-* Process_meta
-*/
+ * Process_meta
+ */
 static int Process_gc(lua_State *L)
-       {
-       Process ps=toProcess(L,1);
-       if (ps) MSG_process_kill(ps) ;
-       printf("GoodBye Process(%p)\n",lua_touserdata(L,1));
-       return 0; 
-       }
+{
+  Process ps=toProcess(L,1);
+  if (ps) MSG_process_kill(ps) ;
+  printf("GoodBye Process(%p)\n",lua_touserdata(L,1));
+  return 0;
+}
 
 static int Process_tostring(lua_State *L)
-       {
-       lua_pushfstring(L,"Process :%p",lua_touserdata(L,1));
-       return 1;       
-       }
+{
+  lua_pushfstring(L,"Process :%p",lua_touserdata(L,1));
+  return 1;
+}
 
 
 static const luaL_reg Process_meta[] = {
-       {"__gc",        Process_gc},
-       {"__tostring",  Process_tostring},
-       {0,0}
+    {"__gc",   Process_gc},
+    {"__tostring",     Process_tostring},
+    {0,0}
 };
 
 
 /**
-*The metatable for the userdata is put in the registry, and the __index field points to the table of methods so that the object:method() syntax will work. The methods table is stored in the table of globals so that scripts can add methods written in Lua. 
-*/
-
-/**
-* Task Register
-*/
-
-int Task_register(lua_State *L)
-       {       
-       luaL_openlib(L,TASK,Task_methods,0); //create methods table,add it to the globals
-       luaL_newmetatable(L,TASK); //create metatable for Task,add it to the Lua registry
-       luaL_openlib(L,0,Task_meta,0);// fill metatable
-       lua_pushliteral(L,"__index");
-       lua_pushvalue(L,-3);    //dup methods table
-       lua_rawset(L,-3);       //matatable.__index = methods
-       lua_pushliteral(L,"__metatable");
-       lua_pushvalue(L,-3);    //dup methods table
-       lua_rawset(L,-3);       //hide metatable:metatable.__metatable = methods 
-       lua_pop(L,1);           //drop metatable
-       return 1;
-       }
-         
-/**
-* Host Register
-*/
-
-int Host_register(lua_State *L)
-       {       
-       luaL_openlib(L,HOST,Host_methods,0); 
-       luaL_newmetatable(L,HOST); 
-       luaL_openlib(L,0,Host_meta,0);
-       lua_pushliteral(L,"__index");
-       lua_pushvalue(L,-3);    
-       lua_rawset(L,-3);       
-       lua_pushliteral(L,"__metatable");
-       lua_pushvalue(L,-3);    
-       lua_rawset(L,-3);       
-       lua_pop(L,1);           
-       return 1;
-       }
+ *The metatable for the userdata is put in the registry, and the __index field points to the table of methods so that the object:method() syntax will work. The methods table is stored in the table of globals so that scripts can add methods written in Lua.
+ */
 
 /**
-*  Process Register
-*/
-
-int Process_register(lua_State *L)
-       {       
-       luaL_openlib(L,PROCESS,Process_methods,0); 
-       luaL_newmetatable(L,PROCESS); 
-       luaL_openlib(L,0,Host_meta,0);
-       lua_pushliteral(L,"__index");
-       lua_pushvalue(L,-3);    
-       lua_rawset(L,-3);       
-       lua_pushliteral(L,"__metatable");
-       lua_pushvalue(L,-3);    
-       lua_rawset(L,-3);       
-       lua_pop(L,1);           
-       return 1;
-       }
+ * Register Task, Host, and Process
+ */
+
+int MSG_register(lua_State *L);// FIXME: better location
+int MSG_register(lua_State *L) {
+  luaL_openlib(L,TASK,Task_methods,0); //create methods table,add it to the globals
+  luaL_newmetatable(L,TASK); //create metatable for Task,add it to the Lua registry
+  luaL_openlib(L,0,Task_meta,0);// fill metatable
+  lua_pushliteral(L,"__index");
+  lua_pushvalue(L,-3); //dup methods table
+  lua_rawset(L,-3);    //matatable.__index = methods
+  lua_pushliteral(L,"__metatable");
+  lua_pushvalue(L,-3); //dup methods table
+  lua_rawset(L,-3);    //hide metatable:metatable.__metatable = methods
+  lua_pop(L,1);                //drop metatable
+  /* HOST */
+  luaL_openlib(L,HOST,Host_methods,0);
+  luaL_newmetatable(L,HOST);
+  luaL_openlib(L,0,Host_meta,0);
+  lua_pushliteral(L,"__index");
+  lua_pushvalue(L,-3);
+  lua_rawset(L,-3);
+  lua_pushliteral(L,"__metatable");
+  lua_pushvalue(L,-3);
+  lua_rawset(L,-3);
+  lua_pop(L,1);
+  /* Process */
+  luaL_openlib(L,PROCESS,Process_methods,0);
+  luaL_newmetatable(L,PROCESS);
+  luaL_openlib(L,0,Host_meta,0);
+  lua_pushliteral(L,"__index");
+  lua_pushvalue(L,-3);
+  lua_rawset(L,-3);
+  lua_pushliteral(L,"__metatable");
+  lua_pushvalue(L,-3);
+  lua_rawset(L,-3);
+  lua_pop(L,1);
+  return 1;
+}
 
index a504a98..e171157 100755 (executable)
@@ -1,4 +1,4 @@
-set -e
+set -ex
 make -C ../../
-gcc -g3 -o runner tasktest.c Msglua.c -I ../../../include/ -I /usr/include/lua5.1/ -I . -L../../.libs  -ldl -llua5.1 -lsimgrid
-valgrind -q ./runner ../../../examples/msg/small_platform.xml deploy.xml tasklua.lua
+gcc -g3 -o runner tasktest.c Msglua.c -I ../../../include/ -I /usr/include/lua5.1/ -I . ../../.libs/libsimgrid.a  -ldl -llua5.1
+valgrind -q ./runner ../../../examples/msg/small_platform.xml deploy.xml tasklua.lua --log=simix.thres:debug
index c774842..9a57dae 100644 (file)
 
 
 // *** Testing Stuff !!
-XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
-    "Messages specific for this msg example");
 
-int master_lua(int argc, char *argv[]); 
-int slave_lua(int argc, char *argv[]); 
-//int load_lua(char * file);
-//int forwarder(int argc, char *argv[]); LUA
-MSG_error_t test_all(const char *platform_file, const char *application_file);
-
-typedef enum {
-
-  PORT_22 = 0,
-      MAX_CHANNEL
-
-} channel_t;
+XBT_LOG_NEW_DEFAULT_CATEGORY(lua,"Lua bindings");
 
 char *lua_file;
 //***************************** LOAD LUA *************************************************
 static int load_lua(char * luaFile, lua_State *L) {
   luaL_openlibs(L);
 
-  // Lua Stuff
-  Task_register(L);
-  Host_register(L);
-  Process_register(L);
 
   if (luaL_loadfile(L, luaFile) || lua_pcall(L, 0, 0, 0)) {
     printf("error while parsing %s: %s", luaFile, lua_tostring(L, -1));
-    return -1;
+    exit(1);
   }
 
   return 0;
@@ -78,34 +61,33 @@ int lua_wrapper(int argc, char *argv[]) {
 
 //*****************************************************************************
 
-int main(int argc,char * argv[])
-{
-
+extern const char*xbt_ctx_factory_to_use; /*Hack: let msg load directly the right factory */
 
+int main(int argc,char * argv[]) {
   MSG_error_t res = MSG_OK;
+  void *lua_factory;
 
+  xbt_ctx_factory_to_use = "lua";
   MSG_global_init(&argc, argv);
 
-  if(argc < 4)
-  {
+
+  if(argc < 4) {
     printf("Usage: %s platform_file deployment_file lua_script\n", argv[0]);
     printf("example: %s msg_platform.xml msg_deployment.xml script_lua.lua\n", argv[0]);
     exit(1);
 
   }
 
-  lua_file=argv[3];
-//  load_lua(argv[3]);
-
   /* MSG_config("surf_workstation_model","KCCFLN05"); */
+  SIMIX_ctx_lua_factory_loadfile(argv[3]);
+
   MSG_create_environment(argv[1]);
-  MSG_function_register_default(&lua_wrapper);
   MSG_launch_application(argv[2]);
+
   res = MSG_main();
 
   fflush(stdout);
   INFO1("Simulation time %g", MSG_get_clock());
-
   MSG_clean();
 
   if (res == MSG_OK)
index af192de..08a7fe0 100644 (file)
@@ -292,6 +292,9 @@ void SIMIX_context_init_factory_by_name(smx_context_factory_t * factory, const c
 void SIMIX_ctx_thread_factory_init(smx_context_factory_t * factory);
 
 void SIMIX_ctx_sysv_factory_init(smx_context_factory_t * factory);
+void SIMIX_ctx_lua_factory_init(smx_context_factory_t * factory);
+void SIMIX_ctx_lua_factory_loadfile(const char *file);
+
 
 void SIMIX_ctx_java_factory_init(smx_context_factory_t * factory);
 
index 006c478..0c13874 100644 (file)
@@ -13,6 +13,7 @@
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_context, simix, "Context switching mecanism");
 
+const char *xbt_ctx_factory_to_use = NULL;
 
 /**
  * This function is call by SIMIX_global_init() to initialize the context module.
@@ -21,7 +22,9 @@ void SIMIX_context_mod_init(void)
 {
   if (!simix_global->context_factory) {
   /* select context factory to use to create the context(depends of the macro definitions) */
-
+    if (xbt_ctx_factory_to_use) {
+      SIMIX_context_select_factory(xbt_ctx_factory_to_use);
+    } else {
 #ifdef CONTEXT_THREADS
     /* context switch based os thread */
     SIMIX_ctx_thread_factory_init(&simix_global->context_factory);
@@ -32,6 +35,7 @@ void SIMIX_context_mod_init(void)
     /* context switch is not allowed on Windows */
 #error ERROR [__FILE__, line __LINE__]: no context based implementation specified.
 #endif
+    }
   }
 }
 
@@ -105,12 +109,14 @@ void SIMIX_context_init_factory_by_name(smx_context_factory_t * factory,
     THROW0(not_found_error, 0, "Factory 'thread' does not exist: thread support was not compiled in the SimGrid library");
 #endif /* CONTEXT_THREADS */
    
-  else if (!strcmp(name, "sysv"))
-#if !defined(WIN32) && !defined(CONTEXT_THREADS)
-    SIMIX_ctx_sysv_factory_init(factory);
-#else
-    THROW0(not_found_error, 0, "Factory 'sysv' does not exist: no System V thread support under Windows");
-#endif   
+    else if (!strcmp(name, "sysv"))
+  #if !defined(WIN32) && !defined(CONTEXT_THREADS)
+      SIMIX_ctx_sysv_factory_init(factory);
+  #else
+      THROW0(not_found_error, 0, "Factory 'sysv' does not exist: no System V thread support under Windows");
+  #endif
+    else if (!strcmp(name, "lua"))
+      SIMIX_ctx_lua_factory_init(factory);
   else
     THROW1(not_found_error, 0, "Factory '%s' does not exist", name);
 }
diff --git a/src/simix/smx_context_lua.c b/src/simix/smx_context_lua.c
new file mode 100644 (file)
index 0000000..669ac82
--- /dev/null
@@ -0,0 +1,177 @@
+/* $Id$ */
+
+/* context_lua - implementation of context switching with lua coroutines */
+
+/* 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. */
+
+#include "private.h"
+#include "context_sysv_config.h"        /* loads context system definitions */
+#include "portable.h"
+#include <lua5.1/lauxlib.h>
+#include <lua5.1/lualib.h>
+
+// FIXME: better location for that
+extern void MSG_register(lua_State *L);
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smx_lua);
+
+typedef struct s_smx_ctx_sysv {
+  SMX_CTX_BASE_T;
+  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;
+
+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);
+
+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);
+
+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);
+}
+void SIMIX_ctx_lua_factory_init(smx_context_factory_t *factory) {
+
+  *factory = xbt_new0(s_smx_context_factory_t, 1);
+
+  (*factory)->create_context = smx_ctx_lua_create_context;
+  (*factory)->finalize = smx_ctx_lua_factory_finalize;
+  (*factory)->free = smx_ctx_lua_free;
+  (*factory)->start = smx_ctx_lua_start;
+  (*factory)->stop = smx_ctx_lua_stop;
+  (*factory)->suspend = smx_ctx_lua_suspend;
+  (*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)
+{
+  lua_close(lua_state);
+
+  free(*factory);
+  *factory = NULL;
+  return 0;
+}
+
+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 = 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){
+    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]);
+  } else {
+    INFO0("Created context for maestro");
+  }
+  
+  return (smx_context_t)context;
+}
+
+static void smx_ctx_lua_free(smx_context_t pcontext)
+{
+  int i;
+  smx_ctx_lua_t context = (smx_ctx_lua_t)pcontext;
+  if (context){
+
+    /* free argv */
+    if (context->argv) {
+      for (i = 0; i < context->argc; i++)
+        if (context->argv[i])
+          free(context->argv[i]);
+
+      free(context->argv);
+    }
+    
+    /* destroy the context */
+    luaL_unref(lua_state,LUA_REGISTRYINDEX,context->ref );
+    free(context);
+  }
+}
+
+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]);
+
+  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]);
+  }
+
+  // push arguments onto the stack
+  int i;
+  for(i=1;i<context->argc;i++)
+    lua_pushstring(context->state,context->argv[i]);
+
+  // Call the function
+  context->nargs = context->argc-1;
+}
+
+static void smx_ctx_lua_stop(smx_context_t pcontext) {
+  smx_ctx_lua_t context = (smx_ctx_lua_t)pcontext;
+  
+  if (context->cleanup_func)
+    (*context->cleanup_func) (context->cleanup_arg);
+
+  // FIXME: DO it
+}
+
+
+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_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);
+}