Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why should it be implemented this way? #95

Open
lachlansneff opened this issue Jun 24, 2018 · 8 comments
Open

Why should it be implemented this way? #95

lachlansneff opened this issue Jun 24, 2018 · 8 comments

Comments

@lachlansneff
Copy link

lachlansneff commented Jun 24, 2018

Looking at the proposal for threading support in wasm, I'm a bit confused. It seems to me like, since it's been decided for some reason to have threads be separate instances of the same module, that much of the proposal is patching over that. For example, conditional initialization is just a fix for something inherently broken in design.

Why not have threads in webassembly be similar to threads in a more familiar setting. Add a few instructions:

  • thread.create which takes a table index, an index into that table, and an i32 argument and returns a thread id (an i32).
  • thread.join which takes a thread id as an argument and blocks until the specified thread finishes.
  • thread.exit which exits the current thread.

An example of using this api would be like this:

(module
  (func $make_thread
    (thread.join
      (thread.create
        (i32.const 0)   // table index
        (i32.const 0)   // index into that table
        (i32.const 42)  // arg to pass to thread
      )
    )
  )
  (func $thread_entry (param $arg i32))
  (table 1 anyfunc)
  (elem (i32.const 0) $thread_entry)
  (start $make_thread)
)

This proposed api would not need conditional initialization or shared memories. It would be easy to understand and simple to implement.

There could be more thread. instructions, these are just examples of the most basic way it could work.

@xtuc
Copy link
Contributor

xtuc commented Jun 24, 2018

That implies that threads share the same module's memory?

@lachlansneff
Copy link
Author

@xtuc Yep!

@binji
Copy link
Member

binji commented Jun 24, 2018

@lachlansneff yes, we discussed doing something similar to what you've described here. However, the current proposal was designed to be as similar as possible to what is currently available in the web platform. We can already use Worker to create a new thread, so rather than adding a new threading primitive we defer thread creation to the embedder.

This was discussed in the May 2017 CG meeting, and some discussion on github issue #8.

edit:
I should add, I think we'd like to add wasm thread creation afterward, but decided that this is a good first step.

@lachlansneff
Copy link
Author

lachlansneff commented Jun 24, 2018

@binji That makes sense to me, but an important part of WebAssembly is support for Non-Web embedding. I'm working on Nebulet, an os that runs wasm natively and attempting to support the way that wasm intends to allow threading is not really feasible. Additionally, I presume that worker creation is quite heavy, at least heavier than creating a raw native thread.

I'd like to bring this up again in the next CG meeting on June 26th, if that's okay. I think that sticking to the currently proposed way will hinder wasm use and development in the future.

Edit: Just saw your edit. I still think that going this way first would be better. You could easy build workers on top of this later by adding shared memories.

@binji
Copy link
Member

binji commented Jun 24, 2018

Yes, as mentioned in that bug, creating a Worker is heavyweight, so we would like to have a lightweight native threading primitive for wasm. That said, the design and implementation on the web platform for this new primitive is not obvious. In the JS embedding and perhaps others, it would be not be possible for a "native wasm" thread to use imports, so a native thread would be have to be computation only. Since memory can be exported, a module that has a wasm thread could modify the contents of the memory without having being active on the shared call stack, which would break assumptions of the embedder as well.

I'd like to bring this up again in the next CG meeting on June 26th, if that's okay.

I've added it to the agenda, but there are few items there already so we may not get to it. Normally we won't discuss a topic again unless there is new information to bring to the CG, but I think that having a perspective from a non-web embedding, and a year passing is enough reason to revisit.

@lachlansneff
Copy link
Author

lachlansneff commented Jun 24, 2018

Imports is definitely an interesting issue. You could just leave that to the embedded. In web environments, when threading was used, imports could get transparently wrapped in mutex. I'm not sure about the memory exporting. It seems to me like if the user wants to use exported memory from a module with multiple threads, they should just deal with the possibility that the data could change. Afterall, presumably the same party wrote the wasm module and the javascript that loads/uses it.

@lachlansneff
Copy link
Author

Has it been decided, in the current threading proposal, that tables are thread-local? How are threads going to share the opaque values that are stored in the tables?

@rossberg
Copy link
Member

The current proposal simply provides no way to transfer and share tables across threads, so the question is avoided altogether. That is, of course, intentional since we don't have a proper answer to the question of sharing references yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants