lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


>From Roberto:

> Coroutines is in our wish-list for Lua 4.1. Because there is
> no ANSI way to
> implement them, we will not put them inside Lua, but we want
> to make very
> easy to implement them outside Lua. We are planning to add
> built-in support
> for multiple Lua stacks, so you will not have to worry about the GC
> collecting things from suspended threads.

Great! Thank you guys :-)

>From ET:

> > function hot_potato_1 ()
> >         while (1) do
> >                 print ("co1: n is ".. n)
> >                 if (n <= 0) then
> >                         return
> > ...
>
> Huh.  A coroutine that returns?  To where?

To the guy who did coronew() at his last cororesume(). That is, in my
sample, to main right after the first cororesume(co1). I am not saying this
is the right way to do it. I just thought it was convenient for the time
being.

> > To make sure the
> > garbage collector does not collect stuff from suspended coroutines
> > (including the one implicitly associated with main!) I have
> to copy on
> > coronew the entire content of the stack into the new stack.
>
> The stack is dynamic.  It will surely change after coronew.  So the
> snapshot copied will not be valid very long.  And, the stacks of _all_
> coroutines have to be marked by the gc.  Not only that of the current
> coroutine and a snapshot of it's creator's stack.

Oh man... I did not think of that. And of course you are right. This is
going to cause me a big headache. And changes in the Lua core, of course!

> But I guess, 4.1 will take a while.  So you'll see my
> implementation *g*

I'd love to :-)

> PS: What do you mean with "real mutli-thread"?  Real concurrent pre-
> emptive threads?  That would be hell...

What I have in mind is Python's microthreads. They are based on a small
addition to the core (a timeslice parameter) which returns control to the
registered coroutine handling the task switching (the coroutine is written
in Python, Lua in our case) once the timeslice is expired (more or less).
This is almost real pre-emptive...

> And here's your problem.  The Lua stack of inactive threads has
> references to objects.  But the gc has no knowledge of these
> inactive threads and will not mark the objects referenced by their
> stacks.  So the objects will be freed.  And when a thread later
> becomes active he has references to freed objects.  Boom.

I spent all the afternoon on this yesterday, because I could not see what
was going wrong. And apparently my solution only works because my sample was
to simplistic to catch more complex cases.
Here's an example:

========================
co1 = coronew("some_function")

newvariable = 42 -- a very important constant!

cororesume(co1) -- this causes GC to activate and eventually resume main

print (newvariable) -- this will print NIL since when the stack for
-- coroutine 1 was created, newvariable did not exist, therefore when GC
-- started in coroutine 1 newvariable wasn't linked from any useful place.
=========================


Otherwise, maybe, I should handle the global state explicitly. But that
would be a hell... It would mean that I cannot preload all my utility
functions but I would have to load them inside every coroutine. Otherwise I
would have to write the coroutines so that they access this explicit global
table. I know I could instrument the access to globals so that it could try
my table if a value was not found, but that would slow down things a bit...
how much? That remains to be seen...

Thanks everyone. I am learning a lot of things from these discussions.
--
WildHeart'2k - mailto:stf@apl.it
Homepage: http://come.to/wildheart/

<<<In the beginning the Universe was created.  ---
   This has made a lot of people very angry and been widely regarded as a
bad move. >>>