From ce7fc8b7a8a23fabcb30bb3846043442927eb013 Mon Sep 17 00:00:00 2001 From: mquinson Date: Fri, 15 Jan 2010 15:31:10 +0000 Subject: [PATCH] first draft of lua bindings git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7009 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/bindings/lua/Msglua.h | 498 +++++++++++++++++++++++++++++++++++ src/bindings/lua/deploy.xml | 27 ++ src/bindings/lua/tasklua.lua | 95 +++++++ src/bindings/lua/tasktest.c | 113 ++++++++ 4 files changed, 733 insertions(+) create mode 100644 src/bindings/lua/Msglua.h create mode 100644 src/bindings/lua/deploy.xml create mode 100644 src/bindings/lua/tasklua.lua create mode 100644 src/bindings/lua/tasktest.c diff --git a/src/bindings/lua/Msglua.h b/src/bindings/lua/Msglua.h new file mode 100644 index 0000000000..1c484dd909 --- /dev/null +++ b/src/bindings/lua/Msglua.h @@ -0,0 +1,498 @@ +#include +#include "lauxlib.h" +#include "lualib.h" + +// Msg Includes +#include +#include "msg/msg.h" +#include "xbt/sysdep.h" +#include "xbt/log.h" +#include "xbt/asserts.h" + + + + +/* +============================================= + + Example Lua Bindings for Msg + +============================================= +*/ + + + + +#define TASK "Task" +#define HOST "Host" +#define PROCESS "Process" + +typedef m_task_t Task; +typedef m_host_t Host; +typedef m_process_t Process; + +//**********************************************************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; + } +/** +*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; + } + +/** +*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.new is a constructor that returns a userdata containing a pointer the Task to be manipulated +*/ + + +static int Task_new(lua_State* L) + { + 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; + + } + +/** +* 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; + } + + +/** +* 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; + } + + +/** +*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; + } + +/** +*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; + } + + + + + + +//*************************************************************** HOST SECTION *************************************************************************** + + + +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; + } + + + +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; + } + + + +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; + + } + + +static int Host_new(lua_State* L) + { + 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; + } + + +//******************************************************* 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; + } + + + +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; + } + + + +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; + + } + +/* +m_process_t MSG_process_create ( const char * name, + xbt_main_func_t code, + void * data, + m_host_t host + ) +*/ + + + +static int Process_new(lua_State* L) + { + 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; + } + + + +//**********************************************************MSG Operating System Functions****************************************************************** +/** +* Function to Send a Task +*/ +static void Task_send(lua_State *L) { + Task tk = checkTask(L,1); + char *mailbox = luaL_checkstring(L,2); + + int res = MSG_task_send(tk,mailbox); +} +/** +* Function to Get ( Recieve !! ) a Task +*/ +static int Task_recv(lua_State *L) { + m_task_t tk = NULL; + + char *mailbox = luaL_checkstring(L,1); + int res = MSG_task_receive(&tk,mailbox); + pushTask(L,tk); + return 1; +} + + +//******************************************************* PLATFORM & APPLICATION SECTION **************************************************************** + + + //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WE WONT NEED IT (!!??) +/** +* Launch Application Function +*/ + +static int launch_application(lua_State *L) + { + + const char * file = luaL_checkstring(L,1); + MSG_launch_application(file); + return 0; + + } + +/** +* 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() + { + + //Code ??!!! + + } + +//****************************************************************** REGISTERING ************************************************************ +/** +*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}, +{0,0} +}; + + +static const luaL_reg Host_methods[] = { +{"new", Host_new}, +{"name", Host_name}, +{0,0} +}; + + +static const luaL_reg Process_methods[] = { +{"new", Process_new}, +{"kill", Process_kill}, +{0,0} +}; + + + + +/** +* 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; + } + +static int Task_tostring(lua_State *L) + { + 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} +}; + + + + +/** +* 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; + } + +static int Host_tostring(lua_State *L) + { + 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} +}; + + +/** +* 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; + } + +static int Process_tostring(lua_State *L) + { + 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} +}; + + +/** +*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; + } + +/** +* 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; + } + diff --git a/src/bindings/lua/deploy.xml b/src/bindings/lua/deploy.xml new file mode 100644 index 0000000000..5fab3dc440 --- /dev/null +++ b/src/bindings/lua/deploy.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/bindings/lua/tasklua.lua b/src/bindings/lua/tasklua.lua new file mode 100644 index 0000000000..ece8bb31f6 --- /dev/null +++ b/src/bindings/lua/tasklua.lua @@ -0,0 +1,95 @@ +function getn(t) + if type(t.n) == "number" then return t.n end + local max=0 + for i,_ in to do + if type(i) == "number" and i>max then max=i end + end + t.n = max + return max +end + +--Master Function +function master(...) + +print("Hello from lua, I'm the master") +for i,v in ipairs(arg) do + print("Got "..v) +end +t_tasks={} --tasks table +t_slaves={} --slaves table + +nb_task = arg[1]; +comp_size = arg[2]; +comm_size = arg[3]; + +-- Let's Create the tasks to dispatch +for i=1,nb_task do + t_tasks[i] = Task.new("Task "..i,comp_size,comm_size); --data set to NULL +end + + +-- Process Organisation + +argc=getn(arg) +print("Argc="..argc.." (should be 8)") + +slave_count = getn(arg) -3; + +for i=4,argc do +slv_name = arg[i]; +t_slaves[i - 3] = Host.new(slv_name); +-- do not do directly that : t_slaves[i - 4] = Host.new(argv[i]); +end + + + + +-- Print List Of Tasks / Slaves +--[[ +for i=1,nb_task do +todo = Task.name(t_tasks[i]); +print(i % slave_count+1); +slv = Host.name(t_slaves[i % slave_count+1]); +print ( "Sending : " .. todo .. " To : " .. slv); +end +]]-- + + + +for i=1,nb_task do +tk_name = Task.name(t_tasks[i]); +ht_name = Host.name(t_slaves[i]); +print("Sending " .. tk_name .." To " .. ht_name); +Task.send(t_task[i],"slave "..(i%slave_count)); +print("Sent"); +end + +end + +--Slave Function --------------------------------------------------------- +function slave(...) + +my_mailbox="slave "..arg[1] +print("Hello from lua, I'm a poor slave with mbox: "..my_mailbox) + +while true do + tk = Task.recv(my_mailbox); + print("Got something"); + --testing res !!!! + tk_name = Task.name(tk) + + if (tk_name == "finalize") then + Task.destroy(tk); + end + + print("Processing "..Task.name(tk)) + Task.execute(tk); + + print(Task.name(tk) .. "Done") + Task.destroy(tk); +end -- while + +print("I'm Done . See You !!"); + +end -- function ---------------------------------------------------------- +--]] diff --git a/src/bindings/lua/tasktest.c b/src/bindings/lua/tasktest.c new file mode 100644 index 0000000000..2d90301af8 --- /dev/null +++ b/src/bindings/lua/tasktest.c @@ -0,0 +1,113 @@ +#include "Msglua.h" + + + +// *** 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; + +lua_State *L; + +//***************************** LOAD LUA ************************************************* +int load_lua(char * luaFile) { + L = lua_open(); + + 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; + } + + return 0; + +} + +int lua_wrapper(int argc, char *argv[]) { + // Table that Lua will read to read Arguments + lua_newtable(L); + + // Seek the right lua function + lua_getglobal(L,argv[0]); + if(!lua_isfunction(L,-1)) { + lua_pop(L,1); + ERROR1("The lua function %s does not seem to exist",argv[0]); + return -1; + } + + // push arguments onto the stack + int i; + for(i=1;i