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

Define thread local storage conventions #116

Merged
merged 4 commits into from Jul 19, 2019
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions Linking.md
Expand Up @@ -528,3 +528,42 @@ threads needs to support both of these proposals.

[passive_segments]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md#design
[datacount_section]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md#datacount-section

Thread Local Storage
--------------------

Currently, thread-local storage is only supported in the main WASM module
and cannot be accessed outside of it. This corresponds to the ELF local
executable TLS model.
quantum5 marked this conversation as resolved.
Show resolved Hide resolved

Additionally, thread local storage depends on bulk memory instructions, and
therefore support depends on the bulk memory proposal.

All thread local variables will be merged into one passive segment called
`.tdata`. This section contains the starting values for all TLS variables.
The thread local block of every thread will be initialized with this segment.

In a threaded build, the module will contain:

* an immutable global variable of type `i32` called `__tls_size`.
Its value is the total size of the thread local block for the module,
i.e. the sum of the sizes of all thread local variables plus padding.
This value will be `0` if there are no thread-local variables.
* a mutable global `i32` called `__tls_base`. This will be initialized to
`0` by default. When a thread is created (including the main thread), memory
will be allocated and this global will be initialized with the help of the
function `__wasm_init_tls`.
quantum5 marked this conversation as resolved.
Show resolved Hide resolved
* a linker-synthesized global function called `__wasm_init_tls`. This function
takes a pointer argument containing the memory address to use as the thread
local storage block of the current thread. If there are no thread-local
variables, this function will do nothing. Otherwise, the memory block will be
initialized with the passive segment `.tdata` via the `memory.init` instruction.
Additionally, `__tls_base` will be set to the value of the pointer argument.

To use thread-local storage properly, a thread should do the equivalent of the
following pseudo-code upon startup:

```
(if (global.get __tls_size) (then
(call __wasm_init_tls (call malloc (global.get __tls_size)))))
quantum5 marked this conversation as resolved.
Show resolved Hide resolved
```