• Subject: RE: Corotines in Lua
• From: "Stefano Lanzavecchia" <stf@...>
• Date: Thu, 26 Oct 2000 12:57:09 +0200

```> > 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!
> >
>
> Yeah, i didn't think of that myself. Although, i took a look at Lua's
> GC code and it seems simple enough to support multiple threads.
> Basicaly, you'd need to split up the marking and the collecting
> parts. Then simply call mark for all threads and then collect. It

Actually I found a simple way. I only had to modify markstack in lgc.c and
teach it about all the stacks for all the coroutines. Works like a charm :-)
And, while I am at it, I also have implemented passing of arguments on my
cororesume. One argument only (but tables can do wonders). And coronew

So my sample now looks like this:
==========
print "setup"

function hot_potato_1 (n)
while (1) do
print ("co1: n is ".. n)
if (n <= 0) then
return "co1: done!"
else
n = cororesume (co2,n-1)
end
end
end

function hot_potato_2 (n)
while (1) do
print ("co2: n is ".. n)
if (n <= 0) then
return "co2: done!"
else
n = cororesume (co1,n-1)
end
end
end

print "create"
co1 = coronew (hot_potato_1)
co2 = coronew (hot_potato_2)

n=101
print ("start: "..n)
print (cororesume (co1,n))

corokill(co1)
corokill(co2)
==========

> > ========================
> > 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.
> > =========================
>
> Hmm...  Are you sure there's no other problem?  This should work!  The
> global table is shared between all threads and shouldn't be affected.
> And if you really have different L->gt the one of main should
> have been
> freed.  But then even finding 'print' would be pretty difficult ;)

I did not actually try it :-) And you are right, this should work. But I am
sure there could be a way to make variables disappear. Anyway, as I said
earlier, the little change in markstack seems to do the trick. And since I
don't have to copy any more the parent's stack, less memory is wasted and
the creation of the coroutine is marginally faster (that's not a big concern
anyway, at least, not yet).

> Btw, when working on such things a debug malloc that fills
> freed memory
> may be handy to detect references to stale data.

That's how I caught it. VC++ on debug builds fills released memory with 0xdd
... By the way: I tried this on Lua:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/
(which means: replace the only call to realloc to GC_REALLOC, dummy out the
garbage collector and the free).
It works beatifully (no benchmarks done) but dies as expected on coroutines
since it cannot know about the new stacks.
--
WildHeart'2k - mailto:stf@apl.it
Homepage: http://come.to/wildheart/

<<<Kimi wo Kimi wo shinjiteru Samui yoru mo  ---
I'll believe in you Even on a cold night. >>>

```