From d238ac3722c3a1c530d8142c00e066fe7a5aa245 Mon Sep 17 00:00:00 2001 From: mquinson Date: Fri, 15 Jan 2010 21:57:54 +0000 Subject: [PATCH] Betterly integrated lua bindings (detected by configure, added to lib, simix interacts with lua coroutines). Cannot yield any process yet, but almost there git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7011 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- configure.ac | 20 ++ src/Makefile.am | 6 + src/bindings/lua/Msglua.c | 622 +++++++++++++++++------------------- src/bindings/lua/doit | 6 +- src/bindings/lua/tasktest.c | 40 +-- src/simix/private.h | 3 + src/simix/smx_context.c | 20 +- src/simix/smx_context_lua.c | 177 ++++++++++ 8 files changed, 527 insertions(+), 367 deletions(-) create mode 100644 src/simix/smx_context_lua.c diff --git a/configure.ac b/configure.ac index 2ecf7eca95..2a3d527028 100644 --- a/configure.ac +++ b/configure.ac @@ -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} diff --git a/src/Makefile.am b/src/Makefile.am index f12fdfda81..ed9474a827 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/bindings/lua/Msglua.c b/src/bindings/lua/Msglua.c index 3b4dd08bef..29cf399ae1 100644 --- a/src/bindings/lua/Msglua.c +++ b/src/bindings/lua/Msglua.c @@ -1,6 +1,6 @@ #include -#include "lauxlib.h" -#include "lualib.h" +#include +#include // Msg Includes #include @@ -19,9 +19,11 @@ 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; +} diff --git a/src/bindings/lua/doit b/src/bindings/lua/doit index a504a989cf..e17115715a 100755 --- a/src/bindings/lua/doit +++ b/src/bindings/lua/doit @@ -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 diff --git a/src/bindings/lua/tasktest.c b/src/bindings/lua/tasktest.c index c774842245..9a57dae2ab 100644 --- a/src/bindings/lua/tasktest.c +++ b/src/bindings/lua/tasktest.c @@ -13,35 +13,18 @@ // *** 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) diff --git a/src/simix/private.h b/src/simix/private.h index af192de721..08a7fe0d50 100644 --- a/src/simix/private.h +++ b/src/simix/private.h @@ -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); diff --git a/src/simix/smx_context.c b/src/simix/smx_context.c index 006c478fb8..0c1387418b 100644 --- a/src/simix/smx_context.c +++ b/src/simix/smx_context.c @@ -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 index 0000000000..669ac82f6c --- /dev/null +++ b/src/simix/smx_context_lua.c @@ -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 +#include + +// 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;iargc;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); +} -- 2.20.1