Running multiple threads in a lua state

classic Classic list List threaded Threaded
55 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Running multiple threads in a lua state

aryajur
Hi,
     Currently I am creating a Lua state for each lua thread I create and run. I think that it would be more memory efficient if I create just 1 lua state and run all the threads in that, each with its own environment. Is that true?
    I see in 5.2 we cannot set the environment of a thread and the lua_setfenv function is not there. So how can I isolate the environments to the threads?

Thanks,
Milind


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Javier Guerra Giraldez
On Fri, Apr 4, 2014 at 9:49 AM, Milind Gupta <[hidden email]> wrote:
> I think that it would be more memory efficient if I create just 1 lua state
> and run all the threads in that, each with its own environment. Is that
> true?


no

the issue is not about the environment, but about sharing the whole
state.  it's a complex memory data structure fairly optimized for
single-threaded access.  it's definitely _not_ threadsafe as is.

it's not too hard to wrap every access to the state with mutex locks,
but then i amount to a GIL (global interpreter lock), which makes all
Lua code serialized and with a heavy lock/unlock overhead.

long time ago, I dabbled on lock-free datastructures and managed to
create a few that could be used from Lua, but they're much harder to
get right than 'traditional' lock-based threadsafe programming.  In
the end, it's better to have several Lua states that communicate by
message passing.

just my 2¢

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

aryajur
Thank you for your response, it is very helpful. Do you think that having many lua states has memory overhead that may be optimized in some way?

Thanks,
Milind




On Fri, Apr 4, 2014 at 7:59 AM, Javier Guerra Giraldez <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 9:49 AM, Milind Gupta <[hidden email]> wrote:
> I think that it would be more memory efficient if I create just 1 lua state
> and run all the threads in that, each with its own environment. Is that
> true?


no

the issue is not about the environment, but about sharing the whole
state.  it's a complex memory data structure fairly optimized for
single-threaded access.  it's definitely _not_ threadsafe as is.

it's not too hard to wrap every access to the state with mutex locks,
but then i amount to a GIL (global interpreter lock), which makes all
Lua code serialized and with a heavy lock/unlock overhead.

long time ago, I dabbled on lock-free datastructures and managed to
create a few that could be used from Lua, but they're much harder to
get right than 'traditional' lock-based threadsafe programming.  In
the end, it's better to have several Lua states that communicate by
message passing.

just my 2¢

--
Javier


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Coroutines
In reply to this post by Javier Guerra Giraldez
On Fri, Apr 4, 2014 at 7:59 AM, Javier Guerra Giraldez <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 9:49 AM, Milind Gupta <[hidden email]> wrote:
> I think that it would be more memory efficient if I create just 1 lua state
> and run all the threads in that, each with its own environment. Is that
> true?


no

the issue is not about the environment, but about sharing the whole
state.  it's a complex memory data structure fairly optimized for
single-threaded access.  it's definitely _not_ threadsafe as is.

it's not too hard to wrap every access to the state with mutex locks,
but then i amount to a GIL (global interpreter lock), which makes all
Lua code serialized and with a heavy lock/unlock overhead.

long time ago, I dabbled on lock-free datastructures and managed to
create a few that could be used from Lua, but they're much harder to
get right than 'traditional' lock-based threadsafe programming.  In
the end, it's better to have several Lua states that communicate by
message passing.

just my 2¢

--
Javier


You'd think that read-only access to the a shared global_State from different lua_State's (coroutines.create()) would be possible without a global interpreter lock.
Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

aryajur
Yes, I was hoping for the same. A read only for the global environment and individual environments for each thread, if that is possible anymore.

Thanks,
Milind


On Fri, Apr 4, 2014 at 8:05 AM, Coroutines <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 7:59 AM, Javier Guerra Giraldez <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 9:49 AM, Milind Gupta <[hidden email]> wrote:
> I think that it would be more memory efficient if I create just 1 lua state
> and run all the threads in that, each with its own environment. Is that
> true?


no

the issue is not about the environment, but about sharing the whole
state.  it's a complex memory data structure fairly optimized for
single-threaded access.  it's definitely _not_ threadsafe as is.

it's not too hard to wrap every access to the state with mutex locks,
but then i amount to a GIL (global interpreter lock), which makes all
Lua code serialized and with a heavy lock/unlock overhead.

long time ago, I dabbled on lock-free datastructures and managed to
create a few that could be used from Lua, but they're much harder to
get right than 'traditional' lock-based threadsafe programming.  In
the end, it's better to have several Lua states that communicate by
message passing.

just my 2¢

--
Javier


You'd think that read-only access to the a shared global_State from different lua_State's (coroutines.create()) would be possible without a global interpreter lock.

Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

aryajur
After looking a bit deeper I think I can set the _ENV for the script I load into the thread using luaL_loadstring by lua_setupvalue to the environment table I want. That way the script running in that thread will have its own environment.
       Is there a problem with this approach?

Thanks,
Milind



On Fri, Apr 4, 2014 at 8:07 AM, Milind Gupta <[hidden email]> wrote:
Yes, I was hoping for the same. A read only for the global environment and individual environments for each thread, if that is possible anymore.

Thanks,
Milind


On Fri, Apr 4, 2014 at 8:05 AM, Coroutines <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 7:59 AM, Javier Guerra Giraldez <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 9:49 AM, Milind Gupta <[hidden email]> wrote:
> I think that it would be more memory efficient if I create just 1 lua state
> and run all the threads in that, each with its own environment. Is that
> true?


no

the issue is not about the environment, but about sharing the whole
state.  it's a complex memory data structure fairly optimized for
single-threaded access.  it's definitely _not_ threadsafe as is.

it's not too hard to wrap every access to the state with mutex locks,
but then i amount to a GIL (global interpreter lock), which makes all
Lua code serialized and with a heavy lock/unlock overhead.

long time ago, I dabbled on lock-free datastructures and managed to
create a few that could be used from Lua, but they're much harder to
get right than 'traditional' lock-based threadsafe programming.  In
the end, it's better to have several Lua states that communicate by
message passing.

just my 2¢

--
Javier


You'd think that read-only access to the a shared global_State from different lua_State's (coroutines.create()) would be possible without a global interpreter lock.


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Luiz Henrique de Figueiredo
In reply to this post by Coroutines
> You'd think that read-only access to the a shared global_State from
> different lua_State's (coroutines.create()) would be possible without a
> global interpreter lock.

You'd think that, yes, but as soon as you try it you'll see there are
problems. Consider
        lua_getglobal(L,"myvar")
Is that a read-only access to L? It seems so but it may not be if "myvar"
is not in the string table. The implementation of lua_getglobal finds
"myvar" in the string table by actually adding it to the string table.
(In the current version of Lua this only ends up actually adding the var
name to the string table if the var name is longer than 40, but that is
an implementation detail.)

Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Owen Shepherd
In reply to this post by aryajur

Yes. The Lua state is not thread safe in the slightest. It will break the first time something causes a garbage collection, for example

On 4 Apr 2014 16:42, "Milind Gupta" <[hidden email]> wrote:
After looking a bit deeper I think I can set the _ENV for the script I load into the thread using luaL_loadstring by lua_setupvalue to the environment table I want. That way the script running in that thread will have its own environment.
       Is there a problem with this approach?

Thanks,
Milind



On Fri, Apr 4, 2014 at 8:07 AM, Milind Gupta <[hidden email]> wrote:
Yes, I was hoping for the same. A read only for the global environment and individual environments for each thread, if that is possible anymore.

Thanks,
Milind


On Fri, Apr 4, 2014 at 8:05 AM, Coroutines <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 7:59 AM, Javier Guerra Giraldez <[hidden email]> wrote:
On Fri, Apr 4, 2014 at 9:49 AM, Milind Gupta <[hidden email]> wrote:
> I think that it would be more memory efficient if I create just 1 lua state
> and run all the threads in that, each with its own environment. Is that
> true?


no

the issue is not about the environment, but about sharing the whole
state.  it's a complex memory data structure fairly optimized for
single-threaded access.  it's definitely _not_ threadsafe as is.

it's not too hard to wrap every access to the state with mutex locks,
but then i amount to a GIL (global interpreter lock), which makes all
Lua code serialized and with a heavy lock/unlock overhead.

long time ago, I dabbled on lock-free datastructures and managed to
create a few that could be used from Lua, but they're much harder to
get right than 'traditional' lock-based threadsafe programming.  In
the end, it's better to have several Lua states that communicate by
message passing.

just my 2¢

--
Javier


You'd think that read-only access to the a shared global_State from different lua_State's (coroutines.create()) would be possible without a global interpreter lock.


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Coroutines
In reply to this post by Luiz Henrique de Figueiredo
On Fri, Apr 4, 2014 at 8:44 AM, Luiz Henrique de Figueiredo <[hidden email]> wrote:
> You'd think that read-only access to the a shared global_State from
> different lua_State's (coroutines.create()) would be possible without a
> global interpreter lock.

You'd think that, yes, but as soon as you try it you'll see there are
problems. Consider
        lua_getglobal(L,"myvar")
Is that a read-only access to L? It seems so but it may not be if "myvar"
is not in the string table. The implementation of lua_getglobal finds
"myvar" in the string table by actually adding it to the string table.
(In the current version of Lua this only ends up actually adding the var
name to the string table if the var name is longer than 40, but that is
an implementation detail.)


That is a subtle "gotcha"... I still wonder what you can get away with if you're making sure you modify unrelated areas of the global_State without locks.
Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

aryajur
In reply to this post by Luiz Henrique de Figueiredo
Thanks for explaining with an example. But is there any example of it breaking when it is running only a Lua script and no C code is allowed?

Thanks,
Milind




On Fri, Apr 4, 2014 at 8:44 AM, Luiz Henrique de Figueiredo <[hidden email]> wrote:
> You'd think that read-only access to the a shared global_State from
> different lua_State's (coroutines.create()) would be possible without a
> global interpreter lock.

You'd think that, yes, but as soon as you try it you'll see there are
problems. Consider
        lua_getglobal(L,"myvar")
Is that a read-only access to L? It seems so but it may not be if "myvar"
is not in the string table. The implementation of lua_getglobal finds
"myvar" in the string table by actually adding it to the string table.
(In the current version of Lua this only ends up actually adding the var
name to the string table if the var name is longer than 40, but that is
an implementation detail.)


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Javier Guerra Giraldez
In reply to this post by aryajur
On Fri, Apr 4, 2014 at 10:03 AM, Milind Gupta <[hidden email]> wrote:
> Thank you for your response, it is very helpful. Do you think that having
> many lua states has memory overhead that may be optimized in some way?


I haven't analyzed the relative overheads, but my gut feeling is that
if you have significant corpus of read-only shared state, it would be
better managed as external data.

the obvious example is a database, which can be shared not only
between threads but also processes, machines, or around the world.  Of
course, that's possible only because of the ACID guarantees.

but in a much less extreme case, an in-memory key/value database in C
could be perfect.  maybe just a wrapper on top of a C++ std:map.

a nice midpoint could be LMDB, a memory-mapped btree key/value
database with nice MVCC, ACID and very high performance. (there's a
simple Lua binding here: https://github.com/shmul/lightningdbm).

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Luiz Henrique de Figueiredo
In reply to this post by aryajur
> Thanks for explaining with an example. But is there any example of it
> breaking when it is running only a Lua script and no C code is allowed?

Any Lua script that creates new strings writes to the global string table.

Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

aryajur
Thanks,

Milind


On Fri, Apr 4, 2014 at 9:29 AM, Luiz Henrique de Figueiredo <[hidden email]> wrote:
> Thanks for explaining with an example. But is there any example of it
> breaking when it is running only a Lua script and no C code is allowed?

Any Lua script that creates new strings writes to the global string table.


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Sean Conner
In reply to this post by Coroutines
It was thus said that the Great Coroutines once stated:

> On Fri, Apr 4, 2014 at 8:44 AM, Luiz Henrique de Figueiredo <
> [hidden email]> wrote:
>
> > > You'd think that read-only access to the a shared global_State from
> > > different lua_State's (coroutines.create()) would be possible without a
> > > global interpreter lock.
> >
> > You'd think that, yes, but as soon as you try it you'll see there are
> > problems. Consider
> >         lua_getglobal(L,"myvar")
> > Is that a read-only access to L? It seems so but it may not be if "myvar"
> > is not in the string table. The implementation of lua_getglobal finds
> > "myvar" in the string table by actually adding it to the string table.
> > (In the current version of Lua this only ends up actually adding the var
> > name to the string table if the var name is longer than 40, but that is
> > an implementation detail.)
> >
> >
> That is a subtle "gotcha"... I still wonder what you can get away with if
> you're making sure you modify unrelated areas of the global_State without
> locks.

  How can you be sure that two threads aren't mucking with the same area of
the global state?  Even if there's a one-in-a-billion chance of that
happening, that will take what?  All of a few seconds for that to happen
with today's machines?

  I agree with Javier Giraldez, keep the lua states separate and share data
via message passing.  It's the only way to keep sane [1].

  -spc

[1] And oddly enough, performance.  Back in the mid-90s, some friends of
        mine worked at a company that produced commercial X servers.  Their
        fastest version ran on QNX [2], a purely message passing based
        operating system.  Even the X servers that used shared memory were
        slower than their QNX version.

[2] A message-based real-time microkernel.  At the user level, it looked
        like Unix, but underneath, it was incredible.  A very small kernel
        (about 8K on a Pentium) and everything else (file systems, device
        drivers, hell, even some standard libraries) were implenented as
        user processes.  Nothing quit like running a program on machine A,
        redirecting input from a file on machine B, piping the output to
        another program on machine C while the command was typed on machine
        D.  [3]

[3] I worked briefly at a company that did QNX related work.  My boss
        would regularly use the modem on my machine from his machine across
        the hall.  It was invisible to the program that the modem was not
        local.


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Sean Conner
In reply to this post by aryajur
It was thus said that the Great Milind Gupta once stated:
> Thank you for your response, it is very helpful. Do you think that having
> many lua states has memory overhead that may be optimized in some way?

  Compared to the default stack size of pthreads (at least on Linux, which
tends to be megabytes in size) the overhead is probably lost in the noise.

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Coroutines
In reply to this post by Sean Conner
On Fri, Apr 4, 2014 at 4:56 PM, Sean Conner <[hidden email]> wrote:
It was thus said that the Great Coroutines once stated:
> On Fri, Apr 4, 2014 at 8:44 AM, Luiz Henrique de Figueiredo <
> [hidden email]> wrote:
>
> > > You'd think that read-only access to the a shared global_State from
> > > different lua_State's (coroutines.create()) would be possible without a
> > > global interpreter lock.
> >
> > You'd think that, yes, but as soon as you try it you'll see there are
> > problems. Consider
> >         lua_getglobal(L,"myvar")
> > Is that a read-only access to L? It seems so but it may not be if "myvar"
> > is not in the string table. The implementation of lua_getglobal finds
> > "myvar" in the string table by actually adding it to the string table.
> > (In the current version of Lua this only ends up actually adding the var
> > name to the string table if the var name is longer than 40, but that is
> > an implementation detail.)
> >
> >
> That is a subtle "gotcha"... I still wonder what you can get away with if
> you're making sure you modify unrelated areas of the global_State without
> locks.

  How can you be sure that two threads aren't mucking with the same area of
the global state?  Even if there's a one-in-a-billion chance of that
happening, that will take what?  All of a few seconds for that to happen
with today's machines?

  I agree with Javier Giraldez, keep the lua states separate and share data
via message passing.  It's the only way to keep sane [1].

  -spc

[1]     And oddly enough, performance.  Back in the mid-90s, some friends of
        mine worked at a company that produced commercial X servers.  Their
        fastest version ran on QNX [2], a purely message passing based
        operating system.  Even the X servers that used shared memory were
        slower than their QNX version.

[2]     A message-based real-time microkernel.  At the user level, it looked
        like Unix, but underneath, it was incredible.  A very small kernel
        (about 8K on a Pentium) and everything else (file systems, device
        drivers, hell, even some standard libraries) were implenented as
        user processes.  Nothing quit like running a program on machine A,
        redirecting input from a file on machine B, piping the output to
        another program on machine C while the command was typed on machine
        D.  [3]

[3]     I worked briefly at a company that did QNX related work.  My boss
        would regularly use the modem on my machine from his machine across
        the hall.  It was invisible to the program that the modem was not
        local.



I do agree that separate global_States in separate threads is the safer/saner way to go.  The issue I have with that is swallowing the cost of marshalling/serialization.  I wish there were a lua_xmove() for moving objects between global_States, so you could make all "Lua instances" visible within a shared memory space, and swap objects directly between them.
Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Sean Conner
It was thus said that the Great Coroutines once stated:
>
> I do agree that separate global_States in separate threads is the
> safer/saner way to go.  The issue I have with that is swallowing the cost
> of marshalling/serialization.  I wish there were a lua_xmove() for moving
> objects between global_States, so you could make all "Lua instances"
> visible within a shared memory space, and swap objects directly between
> them.

  I don't know.  I want to say that if you want to move an arbitrary object
between threads you are doing it wrong, but I'm not sure what you are trying
to do, so I won't say that 8-P

  In general, it's a difficult, if not outright, impossible task.  Tables
are difficult, and I suspect userdata is all but impossible to handle
correctly with a "lua_gsxmove()" function.  

  And as for the cost of marshalling/serialization, remember, the QNX X
server I'm talking about did all that, and *still* was faster than a shared
memory version of the server.  

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Coroutines



On Fri, Apr 4, 2014 at 5:19 PM, Sean Conner <[hidden email]> wrote:
It was thus said that the Great Coroutines once stated:
>
> I do agree that separate global_States in separate threads is the
> safer/saner way to go.  The issue I have with that is swallowing the cost
> of marshalling/serialization.  I wish there were a lua_xmove() for moving
> objects between global_States, so you could make all "Lua instances"
> visible within a shared memory space, and swap objects directly between
> them.

  I don't know.  I want to say that if you want to move an arbitrary object
between threads you are doing it wrong, but I'm not sure what you are trying
to do, so I won't say that 8-P

  In general, it's a difficult, if not outright, impossible task.  Tables
are difficult, and I suspect userdata is all but impossible to handle
correctly with a "lua_gsxmove()" function.

  And as for the cost of marshalling/serialization, remember, the QNX X
server I'm talking about did all that, and *still* was faster than a shared
memory version of the server.

  -spc


You could make lua_States from separate processes visible to each other with shared memory, but what's on the stack is most likely a reference if the object isn't something like a number.  You could move these references between lua_States of different processes but the data wouldn't be moved from one global_State to the other.  This is why marshalling is the safest/slowest way right now :( 
Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Sean Conner
It was thus said that the Great Coroutines once stated:

> On Fri, Apr 4, 2014 at 5:19 PM, Sean Conner <[hidden email]> wrote:
>
> > It was thus said that the Great Coroutines once stated:
> > >
> > > I do agree that separate global_States in separate threads is the
> > > safer/saner way to go.  The issue I have with that is swallowing the cost
> > > of marshalling/serialization.  I wish there were a lua_xmove() for moving
> > > objects between global_States, so you could make all "Lua instances"
> > > visible within a shared memory space, and swap objects directly between
> > > them.
> >
> >   I don't know.  I want to say that if you want to move an arbitrary object
> > between threads you are doing it wrong, but I'm not sure what you are
> > trying
> > to do, so I won't say that 8-P
> >
> >   In general, it's a difficult, if not outright, impossible task.  Tables
> > are difficult, and I suspect userdata is all but impossible to handle
> > correctly with a "lua_gsxmove()" function.
> >
> >   And as for the cost of marshalling/serialization, remember, the QNX X
> > server I'm talking about did all that, and *still* was faster than a shared
> > memory version of the server.
> >
> >   -spc
> >
> >
> You could make lua_States from separate processes visible to each other
> with shared memory, but what's on the stack is most likely a reference if
> the object isn't something like a number.  You could move these references
> between lua_States of different processes but the data wouldn't be moved
> from one global_State to the other.  This is why marshalling is the
> safest/slowest way right now :(

  How do you know that marshalling is the slowest way?  You are making that
assumption (QNX X server marshalls, and it's faster than using shared
memory).  It may also be that you are trying to share too much thus causing
cache contention [1].  

  -spc (The only way to be sure is to measure ... )

[1] A novel new approach to spinlocks:

                http://lwn.net/Articles/590243/

        It uses way more memory than a traditional spinlock (something like
        2*number-cpus) but in practical real-world tests [2] it was 100%
        faster, *because* it reduced cache contention.

[2] A particular type of benchmark *cough cough*.


Reply | Threaded
Open this post in threaded view
|

Re: Running multiple threads in a lua state

Coroutines
On Fri, Apr 4, 2014 at 5:34 PM, Sean Conner <[hidden email]> wrote:
It was thus said that the Great Coroutines once stated:
> On Fri, Apr 4, 2014 at 5:19 PM, Sean Conner <[hidden email]> wrote:
>
> > It was thus said that the Great Coroutines once stated:
> > >
> > > I do agree that separate global_States in separate threads is the
> > > safer/saner way to go.  The issue I have with that is swallowing the cost
> > > of marshalling/serialization.  I wish there were a lua_xmove() for moving
> > > objects between global_States, so you could make all "Lua instances"
> > > visible within a shared memory space, and swap objects directly between
> > > them.
> >
> >   I don't know.  I want to say that if you want to move an arbitrary object
> > between threads you are doing it wrong, but I'm not sure what you are
> > trying
> > to do, so I won't say that 8-P
> >
> >   In general, it's a difficult, if not outright, impossible task.  Tables
> > are difficult, and I suspect userdata is all but impossible to handle
> > correctly with a "lua_gsxmove()" function.
> >
> >   And as for the cost of marshalling/serialization, remember, the QNX X
> > server I'm talking about did all that, and *still* was faster than a shared
> > memory version of the server.
> >
> >   -spc
> >
> >
> You could make lua_States from separate processes visible to each other
> with shared memory, but what's on the stack is most likely a reference if
> the object isn't something like a number.  You could move these references
> between lua_States of different processes but the data wouldn't be moved
> from one global_State to the other.  This is why marshalling is the
> safest/slowest way right now :(

  How do you know that marshalling is the slowest way?  You are making that
assumption (QNX X server marshalls, and it's faster than using shared
memory).  It may also be that you are trying to share too much thus causing
cache contention [1].

  -spc (The only way to be sure is to measure ... )

[1]     A novel new approach to spinlocks:

                http://lwn.net/Articles/590243/

        It uses way more memory than a traditional spinlock (something like
        2*number-cpus) but in practical real-world tests [2] it was 100%
        faster, *because* it reduced cache contention.

[2]     A particular type of benchmark *cough cough*.



Hmm, well you were right to question my assumptions, I have not done benchmarks -- I just imagined marshalling usually to be converting a table of lua values to a string, which would always seem slower than if I could memcpy a set of Lua objects to load in to this separate global_State (theoretically).  Is there a better way (than object -> string marshalling) ?
123