lua-users home
lua-l archive

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


Hi Sean, thanks for your reply.

On Sat, Jan 25, 2020 at 6:15 PM Sean Conner <sean@conman.org> wrote:
> > The most profound restriction is the limitation to a single C call
> > stack (you can't assume pthreads), and so Lua must longjmp() every
> > time there is a coroutine context switch.
>
>   The Lua call stack and C call stack are two separate things.

Sorry if I wasn't being clear. Still learning all this stuff.

I was referring to this section 29.2 of "Programming in Lua" (4th ed):

    It is easy for the interpreter to have multiple soft stacks,
    but the runtime of ISO C has only one internal stack.
    Therefore, coroutines in Lua cannot suspend the execution
    of a C function: if there is a C function in the call path from
    a resume to its respective yield, Lua cannot save the state
    of that C function to restore it in the next resume....

    Lua 5.2 and later versions ameliorated that difficulty with
    continuations. Lua 5.2 implements yields using long jumps,
    in the same way that it implements errors....

Put another way, the problem I'm getting at boils down to this: a C
Lua function A can invoke a normal Lua function B via lua_pcall(). But
lua_pcall() is a synchronous call, and therefore the C stack frame for
A cannot be discarded until B completes or yields.

Now suppose B invokes a blocking system call. Then the entire VM is
frozen. And even if it wasn't, we couldn't unwind the current C stack
(because A's stack frame is still needed), and there is no other C
stack we can use do meaningful work.

Again, I'm talking about "plain" Lua here.

> > For "plain" Lua, restriction to ANSI C creates these problems:
> >
> >     Problem #1. Lua is single-threaded and can't take advantage of
> > multi-core machines
>
>   Yes it can.  Not out of the box certainly...

Yes, but "out of the box" is what I'm talking here...

Let's take a step back.

The Lua developers have been very careful not to bloat "plain" Lua
with extra dependencies and I totally respect that.

However, a large chunk of the Lua user base is using Lua on more
capable (e.g., POSIX) systems, so it makes sense to try to define a
coherent, standard way to take advantage of those capabilities.

But that's a vague and open-ended statement. So I'm trying to take a
conservative, incremental approach to the idea.

So I'd first ask: What is the single most important problem that is
inherent and inescapable with "plain" Lua that we'd like to solve with
additional capabilities? And what is the minimum additional capability
that could be required in order to solve it?

In other words, what's the lowest hanging fruit here?

To me the most important such problem is the non-composability of modules.

Moreover, there is a solution to this problem which relies on a very
minimal set of "extra capabilities". Ref:
https://www.gnu.org/software/pth/pth-manual.html#implementation_notes

> > Problem #1 speaks for itself and is easy to understand. You can
> > address this by creating multiple Lua contexts, but then you have to
> > handle the resulting isolation: there are no shared globals or
> > upvalues, and so all communication between contexts requires
> > serialization of some kind.
>
>   Or implement lua_lock()/lua_unlock() as mentioned.

Yes, that's a neat idea, but doesn't it represent a much more
aggressive change to the semantics of the language, because
invalidates Advantage #2 (atomic execution between yield()s)?

> > As for Problem #3, it's more of an inconvenience than a major problem.
> >
> > Let's talk about Problem #2!
> >
> > In my view, Problem #2 is the most serious problem. It eliminates a
> > huge class of applications, namely, any application supporting
> > simultaneous blocking operations. For example, a web server!
>
>   It does not.  At work, I have a program written in Lua that is handling
> over 200,000,000 calls per day [a].

But surely you're using luv or cqueues or some equivalent, right?

Or do your Lua VM's still block completely when you read from the network?

> > OK so far so good...  BUT - there's still a larger problem with "luv"
> > or any other solution to Problem #2 I've run across so far: none of
> > them are COMPOSABLE with other, unrelated Lua modules.
>
>   True, but you have that issue in any language.

Not really, at least as it relates to Problem #2.

Take POSIX C for example. I can write a C shared library with a
function F() that invokes a blocking system call, and my library can
be linked into some random program, and F() can be invoked without
freezing the entire program. POSIX C provides a standard way to handle
this (pthreads).

An even more interesting example in this debate is Node.js. They solve
this problem simply by making it impossible to invoke a blocking
system call directly!

But look how composable Node.js is, and how its adoption exploded. I'd
argue composability was an essential enabler of that growth.

> > Since we can't do it with pthreads, what about GNU pth? It is
> > specifically designed for non-preemptive multitasking and gives you
> > 3(a), 3(b), and 3(c) by design. Moreover, pth is very portable and
> > stable (I used it back in the 90's).
>
>   At least it's LGPL, but how well does it work with pthreads?  Because I
> have this module over here that uses pthreads ...

You can safely link to the pth and pthreads libraries at the same time.

> > Instead, this addition to the Lua API would define a Lua wrapper
> > funtion for each blocking function.
>
>   What functions would those be?  Because there's this other thread trying
> to define a minimal set of "batteries" for Lua ...

Here are the POSIX functions that pth provides wrappers for:

pth_nanosleep, pth_usleep, pth_sleep, pth_waitpid, pth_system, pth_sigmask,
pth_sigwait, pth_accept, pth_connect, pth_select, pth_pselect,
pth_poll, pth_read,
pth_readv, pth_write, pth_writev, pth_pread, pth_pwrite, pth_recv, pth_recvfrom,
pth_send, pth_sendto.

Ref: https://www.gnu.org/software/pth/pth-manual.html#item_standard_posix_replacement_api

-Archie

--
Archie L. Cobbs