lua-users home
lua-l archive

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


In message <199709091844.PAA08845@server02> lua-l@tecgraf.puc-rio.br writes:
 > About the on-going discussion on multiple threads:

Well, it *was* ongoing; sorry, I had to do a bit of paying work.

 > Like Roberto said, multiple threads of execution in Lua would require
 > support on the C part, something that neither ANSI C nor POSIX can give.

Am I right or wrong in thinking that the ANSI C definition of setjmp() and
longjmp() permits home-cooked co-routines? I can certainly do it in Turbo C,
which I have always found to be pretty strict in adhering to the standard.

Basically, I chop up the available stack by recursing down it, planting
a setjmp() at my chosen intervals and filling in an array of jmp_bufs as I
go. I can then longjmp() to any one I choose from my scheduling kernel, but
of course there's no protection to prevent me exceeding my self-imposed
stack size in each co-routine, so recursion within individual co-routines
whould require some caution. Am I exploiting a feature that pure ANSI C does
not necessarily support? Here's a simple function that chops the stack
into equal chunks...

#include <setjmp.h>

extern void reschedule(const int thread_tag);


void prepare_stacks( const int n_stacks,
                     const int stack_depth,
                     const int depth_count,
                     jmp_buf   *jbuf_array  )

/* N.B:  Units of 'stack_depth' are sizeof(this function's stack frame) */

{
    if (depth_count)
    {
        prepare_stacks( n_stacks,
                        stack_depth,          /* continue recursing and */
                        depth_count - 1,       /* decrement frame count */
                        jbuf_array       );
    }
    else
    {
        const int stacks_remaining = n_stacks - 1;

        int thread_tag = setjmp(jbuf_array[stacks_remaining]);

        if (thread_tag)
        {
            reschedule(thread_tag);   /* scheduler called our longjmp() */
        }
        else if (stacks_remaining)
        {
            prepare_stacks( stacks_remaining,
                            stack_depth,         /* head down again but */
                            stack_depth,           /* reset frame count */
                            jbuf_array    );
        }
    }
}


 <snip stuff about multiple interpreters>
 > 
 > Multiple environments are easy to implement in Lua.
 > One way is as Roberto mentioned: use tables to save and restore the global
 > environment.
 > Another way is to use the setglobal/getglobal tag methods.
 > In this solution, these tag methods are used to filter and redirect requests
 > to read and write the global environment, say to tables.
 > To switch environments, simply change the handlers for setglobal/getglobal.

This (latter) method takes care of a fast environment switch; If I
restricted myself to, say, switching context only at specific time-
slice de-scheduling points, maybe even only at function entry/exit
(via the debugger interface) how much else would I need to save?

--  Mark Ian Barlow                Non-Linear Control Consultants Ltd.
    -----------------------------------------------------------------
    Mark@nlcc.demon.co.uk            Voice / Fax: +44 (0)1207 562 154