WebAssembly/Threads
From Lazarus wiki
Revision as of 00:35, 28 May 2022 by Nickysn (talk | contribs) (→Atomic instructions: - atomic functions are available in the WebAssembly unit)
Thread support
This page contains some collected informations on the features needed for thread support in WebAssembly (in the browser).
Thread support consists of 2 parts:
- Atomic instructions.
- Actually starting a thread.
Atomic instructions
When the Free Pascal RTL is compiled with -CTwasmthreads, the following RTL functions will use the new atomic instructions and thus should be thread safe in a multithreaded environment:
InterlockedDecrement InterlockedIncrement InterlockedExchange InterlockedCompareExchange InterlockedExchangeAdd
Note that these require proper alignment (4 bytes) of the target, otherwise they trap (i.e. terminate the program with a stack trace).
In addition to that, there are many more atomic functions available in the WebAssembly unit:
const { Special values for the TimeoutNanoseconds parameter of AtomicWait } awtInfiniteTimeout = -1; { AtomicWait result values } awrOk = 0; { woken by another agent in the cluster } awrNotEqual = 1; { the loaded value did not match the expected value } awrTimedOut = 2; { not woken before timeout expired } procedure AtomicFence; inline; function AtomicLoad(constref Mem: Int8): Int8; inline; function AtomicLoad(constref Mem: UInt8): UInt8; inline; function AtomicLoad(constref Mem: Int16): Int16; inline; function AtomicLoad(constref Mem: UInt16): UInt16; inline; function AtomicLoad(constref Mem: Int32): Int32; inline; function AtomicLoad(constref Mem: UInt32): UInt32; inline; function AtomicLoad(constref Mem: Int64): Int64; inline; function AtomicLoad(constref Mem: UInt64): UInt64; inline; procedure AtomicStore(out Mem: Int8; Data: Int8); inline; procedure AtomicStore(out Mem: UInt8; Data: UInt8); inline; procedure AtomicStore(out Mem: Int16; Data: Int16); inline; procedure AtomicStore(out Mem: UInt16; Data: UInt16); inline; procedure AtomicStore(out Mem: Int32; Data: Int32); inline; procedure AtomicStore(out Mem: UInt32; Data: UInt32); inline; procedure AtomicStore(out Mem: Int64; Data: Int64); inline; procedure AtomicStore(out Mem: UInt64; Data: UInt64); inline; function AtomicAdd(var Mem: Int8; Data: Int8): Int8; inline; function AtomicAdd(var Mem: UInt8; Data: UInt8): UInt8; inline; function AtomicAdd(var Mem: Int16; Data: Int16): Int16; inline; function AtomicAdd(var Mem: UInt16; Data: UInt16): UInt16; inline; function AtomicAdd(var Mem: Int32; Data: Int32): Int32; inline; function AtomicAdd(var Mem: UInt32; Data: UInt32): UInt32; inline; function AtomicAdd(var Mem: Int64; Data: Int64): Int64; inline; function AtomicAdd(var Mem: UInt64; Data: UInt64): UInt64; inline; function AtomicSub(var Mem: Int8; Data: Int8): Int8; inline; function AtomicSub(var Mem: UInt8; Data: UInt8): UInt8; inline; function AtomicSub(var Mem: Int16; Data: Int16): Int16; inline; function AtomicSub(var Mem: UInt16; Data: UInt16): UInt16; inline; function AtomicSub(var Mem: Int32; Data: Int32): Int32; inline; function AtomicSub(var Mem: UInt32; Data: UInt32): UInt32; inline; function AtomicSub(var Mem: Int64; Data: Int64): Int64; inline; function AtomicSub(var Mem: UInt64; Data: UInt64): UInt64; inline; function AtomicAnd(var Mem: Int8; Data: Int8): Int8; inline; function AtomicAnd(var Mem: UInt8; Data: UInt8): UInt8; inline; function AtomicAnd(var Mem: Int16; Data: Int16): Int16; inline; function AtomicAnd(var Mem: UInt16; Data: UInt16): UInt16; inline; function AtomicAnd(var Mem: Int32; Data: Int32): Int32; inline; function AtomicAnd(var Mem: UInt32; Data: UInt32): UInt32; inline; function AtomicAnd(var Mem: Int64; Data: Int64): Int64; inline; function AtomicAnd(var Mem: UInt64; Data: UInt64): UInt64; inline; function AtomicOr(var Mem: Int8; Data: Int8): Int8; inline; function AtomicOr(var Mem: UInt8; Data: UInt8): UInt8; inline; function AtomicOr(var Mem: Int16; Data: Int16): Int16; inline; function AtomicOr(var Mem: UInt16; Data: UInt16): UInt16; inline; function AtomicOr(var Mem: Int32; Data: Int32): Int32; inline; function AtomicOr(var Mem: UInt32; Data: UInt32): UInt32; inline; function AtomicOr(var Mem: Int64; Data: Int64): Int64; inline; function AtomicOr(var Mem: UInt64; Data: UInt64): UInt64; inline; function AtomicXor(var Mem: Int8; Data: Int8): Int8; inline; function AtomicXor(var Mem: UInt8; Data: UInt8): UInt8; inline; function AtomicXor(var Mem: Int16; Data: Int16): Int16; inline; function AtomicXor(var Mem: UInt16; Data: UInt16): UInt16; inline; function AtomicXor(var Mem: Int32; Data: Int32): Int32; inline; function AtomicXor(var Mem: UInt32; Data: UInt32): UInt32; inline; function AtomicXor(var Mem: Int64; Data: Int64): Int64; inline; function AtomicXor(var Mem: UInt64; Data: UInt64): UInt64; inline; function AtomicExchange(var Mem: Int8; Data: Int8): Int8; inline; function AtomicExchange(var Mem: UInt8; Data: UInt8): UInt8; inline; function AtomicExchange(var Mem: Int16; Data: Int16): Int16; inline; function AtomicExchange(var Mem: UInt16; Data: UInt16): UInt16; inline; function AtomicExchange(var Mem: Int32; Data: Int32): Int32; inline; function AtomicExchange(var Mem: UInt32; Data: UInt32): UInt32; inline; function AtomicExchange(var Mem: Int64; Data: Int64): Int64; inline; function AtomicExchange(var Mem: UInt64; Data: UInt64): UInt64; inline; function AtomicCompareExchange(var Mem: Int8; Compare, Data: Int8): Int8; inline; function AtomicCompareExchange(var Mem: UInt8; Compare, Data: UInt8): UInt8; inline; function AtomicCompareExchange(var Mem: Int16; Compare, Data: Int16): Int16; inline; function AtomicCompareExchange(var Mem: UInt16; Compare, Data: UInt16): UInt16; inline; function AtomicCompareExchange(var Mem: Int32; Compare, Data: Int32): Int32; inline; function AtomicCompareExchange(var Mem: UInt32; Compare, Data: UInt32): UInt32; inline; function AtomicCompareExchange(var Mem: Int64; Compare, Data: Int64): Int64; inline; function AtomicCompareExchange(var Mem: UInt64; Compare, Data: UInt64): UInt64; inline; function AtomicWait(constref Mem: Int32; Compare: Int32; TimeoutNanoseconds: Int64): Int32; inline; function AtomicWait(constref Mem: UInt32; Compare: UInt32; TimeoutNanoseconds: Int64): Int32; inline; function AtomicWait(constref Mem: Int64; Compare: Int64; TimeoutNanoseconds: Int64): Int32; inline; function AtomicWait(constref Mem: UInt64; Compare: UInt64; TimeoutNanoseconds: Int64): Int32; inline; function AtomicNotify(constref Mem: Int32; Count: UInt32): UInt32; inline; function AtomicNotify(constref Mem: UInt32; Count: UInt32): UInt32; inline; function AtomicNotify(constref Mem: Int64; Count: UInt32): UInt32; inline; function AtomicNotify(constref Mem: UInt64; Count: UInt32): UInt32; inline;
Thread support
Webassembly relies on the hosting environment to actually start threads.
Some extra info: