Module-based parallel JS strawman

Isiah Meadows isiahmeadows at
Sun Nov 6 20:29:19 UTC 2016

Ok. I'll admit my terminology is mostly incorrect (this isn't technically
*cooperative*). I also have a few clarifications inline.

On Sun, Nov 6, 2016, 06:03 Florian Bösch <pyalot at> wrote:

> On Sun, Nov 6, 2016 at 6:57 AM, Isiah Meadows <isiahmeadows at>
> wrote:
> TL;DR: I'm proposing a completely different threading model,
> supporting lightweight and cooperative multitasking while allowing
> synchronous, thread-safe communication and inspection. Apologies for
> the length.
> Cooperative multitasking is a mode of operation where a thread once
> started continues to run until it yields control. What you are describing
> isn't cooperative multitasking since it lacks the ability to yield.
> Therefore your suggestion is preemptive multitasking where tasks timeshare
> CPU time (presumably switching at random/scheduled intervals at the
> interpreter level).

Yeah... This is where I screwed up in my terminology. I'll fix the wording
in my gist. I'll note that technically, it's a mixture of preemptive and
cooperative multitasking, since the task's thread is in control of when it

> It's widely acknowledged that preemptive multitasking (however you
> implement it be that via interpreter level granularity, or as OS native
> threads etc.) is difficult to control and often results in incorrect code,
> race conditions, data corruption, mutex proliferation and deadlocks.

I took special steps to avoid race conditions outside asynchronous code
that's already marked "unsafe" (with the `atomic` keyword). If you look in
the section explaining the timing queue, I intentionally specified it in
terms of waits, not locks (deadlock is not a problem). Instead of locking
for access, you're waiting on a return value after requesting an access.

It also routinely fails to efficiently address I/O scheduling concerns,
> because it is effectively just trying to timeshare a single strand of
> processing across disjoint threads of execution. However, preemptive
> multitasking is an effective strategy to timeshare CPU time if that is the
> bottleneck. It could be argued though that WebWorkers already fill that
> role more effectively.

> Structured coroutines is a concept that allows switching between strands
> of execution by "yielding" control to another strand. This isn't
> necessarily related to multitasking, but it can be. If the coroutines are
> managed by a scheduler, which is trivial to implement and customize in the
> presence of coroutine functionalty, then coroutines can be used to
> implement cooperative multitasking. It's widely acknowledged that
> cooperative multitasking is not an effective strategy to address CPU
> timesharing, however it is an extremely efficient method to address all
> other forms of scheduling problems (such as I/O scheduling).

My main focus on this was CPU scheduling and time sharing. Most runtimes
already shove most outside I/O to another thread, so I wasn't that
concerned about that. (You could use some indirection and deferral to
implement cooperative multitasking.)

> Please note that efficiency in scheduling is always a function of how well
> the scheduler matches the use-case in question. Thus it is important to
> have a low level concept like coroutines upon which user-code can exist
> that implements the scheduling. Examples of scheduling problems may include:
>    - wait for user-input arrives (i.e. wait for input)
>    - wait for network actcivity (download or upload) has finished (i.e.
>    wait for xhr)
>    - wait for a WebWorker has finished processing (i.e. wait for
>    worker.postMessage)
>    - wait for GPU activity (i.e. query results, texImage2D, bufferData,
>    shader compile etc.)
> These could be handled by simply returning a promise. Each thread has its
own event loop which runs within that thread. So just not doing it
synchronously would be the solution.

>    - evaluation of a dependency graph
>    - evaluation finite state machines (without resorting to state
>    transition methods)
>    - etc.
> I believe it would be much better to introduce true coroutines to JS, than
> to try to introduce preemptive threading.

Cooperative multithreading and coroutines can be done with async iterators.
When those get standardized, it'll become easy to use cooperative
multitasking. (I need to make well-known symbols identical cross-realm to
make it work, though.)

export atomic async function *sync(file) {
  while (true) {
    if (await yield) await updateFile(file)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list