From 20d600a51884e28a4e966a12492a16502529115c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christophe=20Thi=C3=A9ry?= Date: Thu, 12 Jan 2012 16:51:40 +0100 Subject: [PATCH] Lua: only keep tracks of tables coming from maestro --- src/bindings/lua/lua_state_cloner.c | 65 +++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/src/bindings/lua/lua_state_cloner.c b/src/bindings/lua/lua_state_cloner.c index 27a79d64c8..e33aebb3ba 100644 --- a/src/bindings/lua/lua_state_cloner.c +++ b/src/bindings/lua/lua_state_cloner.c @@ -16,6 +16,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(lua_state_cloner, bindings, "Lua state management"); static void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr); +static void sglua_remove_maestro_table(lua_State* L, int index, void* maestro_table_ptr); static void* sglua_get_maestro_table_ptr(lua_State* L, int index); static void sglua_get_table_by_ptr(lua_State* L, void* table_ptr); static int l_get_from_maestro(lua_State* L); @@ -41,7 +42,7 @@ static void sglua_copy_thread(lua_State* src, lua_State* dst); * @param index index of the copy of the maestro table in the stack of L * @param maestro_table_ptr pointer to the original table in maestro's world */ -void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr) { +static void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr) { /* we will set both [ptr] -> table and [table] -> ptr */ @@ -68,6 +69,41 @@ void sglua_add_maestro_table(lua_State* L, int index, void* maestro_table_ptr) { /* ... */ } +/** + * @brief Removes a reference to a maestro table to the list of known maestro + * tables of a state. + * + * @param L a state (can be maestro itself) + * @param index index of the copy of the maestro table in the stack of L + * @param maestro_table_ptr pointer to the original table in maestro's world + */ +static void sglua_remove_maestro_table(lua_State* L, int index, void* maestro_table_ptr) { + + /* we will unset both [ptr] -> table and [table] -> ptr */ + + /* ... */ + lua_pushvalue(L, index); + /* ... table */ + lua_pushstring(L, "simgrid.maestro_tables"); + /* ... table "simgrid.maestro_tables" */ + lua_rawget(L, LUA_REGISTRYINDEX); + /* ... table maestrotbs */ + lua_pushvalue(L, -2); + /* ... table maestrotbs table */ + lua_pushnil(L); + /* ... table maestrotbs table nil */ + lua_pushlightuserdata(L, maestro_table_ptr); + /* ... table maestrotbs table nil tableptr */ + lua_pushnil(L); + /* ... table maestrotbs table nil tableptr nil*/ + lua_settable(L, -5); + /* ... table maestrotbs table nil */ + lua_settable(L, -3); + /* ... table maestrotbs */ + lua_pop(L, 2); + /* ... */ +} + /** * @brief For a table in the stack of L, returns a pointer that identifies the * same table in in maestro's world. @@ -244,12 +280,12 @@ static void sglua_copy_string(lua_State* src, lua_State* dst) { } /** - * @brief Copies the table value on the top of src to the top of dst. + * @brief Copies the table value on top of src to the top of dst. * * A deep copy of the table is made. If the table has a metatable, the * metatable is also copied. - * If the table is already known by the destination state, it is not copied - * again. + * If the table comes from maestro and is already known by the destination + * state, it is not copied again. * * @param src source state * @param dst destination state @@ -262,14 +298,13 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) { /* get from maestro the pointer that identifies this table */ void* table_ptr = sglua_get_maestro_table_ptr(src, -1); - if (table_ptr == NULL) { + int known_by_maestro = (table_ptr != NULL); + + if (!known_by_maestro) { /* the table didn't come from maestro: nevermind, use the pointer of src */ table_ptr = (void*) lua_topointer(src, -1); - - if (!sglua_is_maestro(src)) { - XBT_DEBUG("%sMaestro does not know this table", - sglua_get_spaces(indent)); - } + XBT_DEBUG("%sMaestro does not know this table", + sglua_get_spaces(indent)); } if (sglua_is_maestro(src)) { @@ -277,6 +312,7 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) { XBT_DEBUG("%sKeeping track of this table in maestro itself", sglua_get_spaces(indent)); sglua_add_maestro_table(src, -1, table_ptr); + known_by_maestro = 1; xbt_assert(sglua_get_maestro_table_ptr(src, -1) == table_ptr); } @@ -301,8 +337,8 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) { /* mark the table as known right now to avoid infinite recursion */ sglua_add_maestro_table(dst, -1, table_ptr); - /* FIXME: we may have added a table with a non-maestro pointer, is this a - problem? */ + /* we may have added a table with a non-maestro pointer, but if it was the + * case, we will remove it later */ XBT_DEBUG("%sTable marked as known", sglua_get_spaces(indent)); xbt_assert(sglua_get_maestro_table_ptr(dst, -1) == table_ptr); @@ -375,6 +411,11 @@ static void sglua_copy_table(lua_State* src, lua_State* dst) { } XBT_DEBUG("%sFinished traversing the table", sglua_get_spaces(indent)); } + + if (!known_by_maestro) { + /* actually,it was not a maestro table: forget the pointer */ + sglua_remove_maestro_table(dst, -1, table_ptr); + } } /** -- 2.20.1