Module-based parallel JS strawman

Isiah Meadows isiahmeadows at gmail.com
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 gmail.com> wrote:

> On Sun, Nov 6, 2016 at 6:57 AM, Isiah Meadows <isiahmeadows at gmail.com>
> 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
returns.


> 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.)

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

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20161106/7320ebfe/attachment.html>


More information about the es-discuss mailing list