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

✂[Moving to Small PRs] Shared Memory and Atomic Memory Accesses support #278

Closed

Conversation

nidin
Copy link
Contributor

@nidin nidin commented Sep 21, 2018

This PR will add Shared Memory and Atomic Memory Accesses support to AssemblyScript.
PR is not yet ready to merge.

Closes #241

Syntax

Atomic.{OPERATION}<TYPE>(...OPERANDS);

Changes

1. Declare memory as shared
new compiler argument --sharedMemory=MAXIMUM_SHARED_MEMORY

2. Load/Store
i32.atomic.load8_u: atomically load 1 byte and zero-extend i8 to i32
i32.atomic.load16_u: atomically load 2 bytes and zero-extend i16 to i32
i32.atomic.load: atomically load 4 bytes as i32
i64.atomic.load8_u: atomically load 1 byte and zero-extend i8 to i64
i64.atomic.load16_u: atomically load 2 bytes and zero-extend i16 to i64
i64.atomic.load32_u: atomically load 4 bytes and zero-extend i32 to i64
i64.atomic.load: atomically load 8 bytes as i64
i32.atomic.store8: wrap i32 to i8 and atomically store 1 byte
i32.atomic.store16: wrap i32 to i16 and atomically store 2 bytes
i32.atomic.store: (no conversion) atomically store 4 bytes
i64.atomic.store8: wrap i64 to i8 and atomically store 1 byte
i64.atomic.store16: wrap i64 to i16 and atomically store 2 bytes
i64.atomic.store32: wrap i64 to i32 and atomically store 4 bytes
i64.atomic.store: (no conversion) atomically store 8 bytes

3. Read-Modify-Write

Name Read (as read) Modify Write Return read
i32.atomic.rmw8_u.add 1 byte 8-bit sign-agnostic addition 1 byte zero-extended i8 to i32
i32.atomic.rmw16_u.add 2 bytes 16-bit sign-agnostic addition 2 bytes zero-extended i16 to i32
i32.atomic.rmw.add 4 bytes 32-bit sign-agnostic addition 4 bytes as i32
i64.atomic.rmw8_u.add 1 byte 8-bit sign-agnostic addition 1 byte zero-extended i8 to i64
i64.atomic.rmw16_u.add 2 bytes 16-bit sign-agnostic addition 2 bytes zero-extended i16 to i64
i64.atomic.rmw32_u.add 4 bytes 32-bit sign-agnostic addition 4 bytes zero-extended i32 to i64
i64.atomic.rmw.add 8 bytes 64-bit sign-agnostic addition 8 bytes as i64
i32.atomic.rmw8_u.sub 1 byte 8-bit sign-agnostic subtraction 1 byte zero-extended i8 to i32
i32.atomic.rmw16_u.sub 2 bytes 16-bit sign-agnostic subtraction 2 bytes zero-extended i16 to i32
i32.atomic.rmw.sub 4 bytes 32-bit sign-agnostic subtraction 4 bytes as i32
i64.atomic.rmw8_u.sub 1 byte 8-bit sign-agnostic subtraction 1 byte zero-extended i8 to i64
i64.atomic.rmw16_u.sub 2 bytes 16-bit sign-agnostic subtraction 2 bytes zero-extended i16 to i64
i64.atomic.rmw32_u.sub 4 bytes 32-bit sign-agnostic subtraction 4 bytes zero-extended i32 to i64
i64.atomic.rmw.sub 8 bytes 64-bit sign-agnostic subtraction 8 bytes as i64
i32.atomic.rmw8_u.and 1 byte 8-bit sign-agnostic bitwise and 1 byte zero-extended i8 to i32
i32.atomic.rmw16_u.and 2 bytes 16-bit sign-agnostic bitwise and 2 bytes zero-extended i16 to i32
i32.atomic.rmw.and 4 bytes 32-bit sign-agnostic bitwise and 4 bytes as i32
i64.atomic.rmw8_u.and 1 byte 8-bit sign-agnostic bitwise and 1 byte zero-extended i8 to i64
i64.atomic.rmw16_u.and 2 bytes 16-bit sign-agnostic bitwise and 2 bytes zero-extended i16 to i64
i64.atomic.rmw32_u.and 4 bytes 32-bit sign-agnostic bitwise and 4 bytes zero-extended i32 to i64
i64.atomic.rmw.and 8 bytes 64-bit sign-agnostic bitwise and 8 bytes as i64
i32.atomic.rmw8_u.or 1 byte 8-bit sign-agnostic bitwise inclusive or 1 byte zero-extended i8 to i32
i32.atomic.rmw16_u.or 2 bytes 16-bit sign-agnostic bitwise inclusive or 2 bytes zero-extended i16 to i32
i32.atomic.rmw.or 4 bytes 32-bit sign-agnostic bitwise inclusive or 4 bytes as i32
i64.atomic.rmw8_u.or 1 byte 8-bit sign-agnostic bitwise inclusive or 1 byte zero-extended i8 to i64
i64.atomic.rmw16_u.or 2 bytes 16-bit sign-agnostic bitwise inclusive or 2 bytes zero-extended i16 to i64
i64.atomic.rmw32_u.or 4 bytes 32-bit sign-agnostic bitwise inclusive or 4 bytes zero-extended i32 to i64
i64.atomic.rmw.or 8 bytes 64-bit sign-agnostic bitwise inclusive or 8 bytes as i64
i32.atomic.rmw8_u.xor 1 byte 8-bit sign-agnostic bitwise exclusive or 1 byte zero-extended i8 to i32
i32.atomic.rmw16_u.xor 2 bytes 16-bit sign-agnostic bitwise exclusive or 2 bytes zero-extended i16 to i32
i32.atomic.rmw.xor 4 bytes 32-bit sign-agnostic bitwise exclusive or 4 bytes as i32
i64.atomic.rmw8_u.xor 1 byte 8-bit sign-agnostic bitwise exclusive or 1 byte zero-extended i8 to i64
i64.atomic.rmw16_u.xor 2 bytes 16-bit sign-agnostic bitwise exclusive or 2 bytes zero-extended i16 to i64
i64.atomic.rmw32_u.xor 4 bytes 32-bit sign-agnostic bitwise exclusive or 4 bytes zero-extended i32 to i64
i64.atomic.rmw.xor 8 bytes 64-bit sign-agnostic bitwise exclusive or 8 bytes as i64
i32.atomic.rmw8_u.xchg 1 byte nop 1 byte zero-extended i8 to i32
i32.atomic.rmw16_u.xchg 2 bytes nop 2 bytes zero-extended i16 to i32
i32.atomic.rmw.xchg 4 bytes nop 4 bytes as i32
i64.atomic.rmw8_u.xchg 1 byte nop 1 byte zero-extended i8 to i64
i64.atomic.rmw16_u.xchg 2 bytes nop 2 bytes zero-extended i16 to i64
i64.atomic.rmw32_u.xchg 4 bytes nop 4 bytes zero-extended i32 to i64
i64.atomic.rmw.xchg 8 bytes nop 8 bytes as i64

4. Compare Exchange

Name Load (as loaded) Compare expected with loaded Conditionally Store replacement Return loaded
i32.atomic.rmw8_u.cmpxchg 1 byte expected wrapped from i32 to i8, 8-bit compare equal wrapped from i32 to i8, store 1 byte zero-extended from i8 to i32
i32.atomic.rmw16_u.cmpxchg 2 bytes expected wrapped from i32 to i16, 16-bit compare equal wrapped from i32 to i16, store 2 bytes zero-extended from i8 to i32
i32.atomic.rmw.cmpxchg 4 bytes 32-bit compare equal store 4 bytes as i32
i64.atomic.rmw8_u.cmpxchg 1 byte expected wrapped from i64 to i8, 8-bit compare equal wrapped from i64 to i8, store 1 byte zero-extended from i8 to i64
i64.atomic.rmw16_u.cmpxchg 2 bytes expected wrapped from i64 to i16, 16-bit compare equal wrapped from i64 to i16, store 2 bytes zero-extended from i16 to i64
i64.atomic.rmw32_u.cmpxchg 4 bytes expected wrapped from i64 to i32, 32-bit compare equal wrapped from i64 to i32, store 4 bytes zero-extended from i32 to i64
i64.atomic.rmw.cmpxchg 8 bytes 64-bit compare equal 8 bytes as i64

5. Wait / Wake
The wait operator take three operands: an address operand, an expected value,
and a relative timeout in nanoseconds as an i64. The return value is 0,
1, or 2, returned as an i32.

timeout value Behavior
timeout < 0 Never expires
0 <= timeout <= maximum signed i64 value Expires after timeout nanoseconds
Return value Description
0 "ok", woken by another agent in the cluster
1 "not-equal", the loaded value did not match the expected value
2 "timed-out", not woken before timeout expired
Atomic.wait<i32>(mutexAddr, value, -1);
var count = Atomic.wake<i32>(mutexAddr, numAgents);

Note : i64.wait/wake is not implemented in chrome.

}
if (!(typeArguments && typeArguments.length == 1)) {
if (typeArguments && typeArguments.length) compiler.currentType = typeArguments[0];
compiler.error(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could move on top and unify checking count of type arguments and print error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will prevent catching further errors. typeArguments and operands can be empty.

Copy link
Contributor Author

@nidin nidin Sep 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can definitely improve it. I kept the error checking in same style as load, store implementation.

Copy link
Member

@MaxGraey MaxGraey Sep 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will prevent catching further errors. typeArguments and operands can be empty.

I mean, you check this twice inside branches but may be better move out of branches and do this one level upper only once at first place?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw it. There was a small issue below that error check. Typescript was complaining about typeArguments may be undefined, so I left it like that. I will check other possibility to remove duplicate code.

@@ -149,6 +149,27 @@ declare function fmod(x: f64, y: f64): f64;
/** Returns the 32-bit floating-point remainder of `x/y`. */
declare function fmodf(x: f32, y: f32): f32;

declare namespace Atomic {
Copy link
Member

@MaxGraey MaxGraey Sep 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about use Atomics instead Atomic but only for namespace with generic methods? The same as provided Web API? This also takes effect to Atomics.exchange and Atomics.compareExchange.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's better to align with WebAssembly Spec to avoid confusions. If required we could make alias functions for WebAPI but again WebAPI spec is not compatible with WASM spec. I would also skip Atomics.exchange and Atomics.compareExchange for now in favor of Atomic.xchg and Atomic.cmpxchg

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, aliases sounds great for that

@nidin nidin force-pushed the feature/worker-based-threads branch from e15665b to 0ce39e4 Compare November 12, 2018 14:59
@nidin nidin changed the title [REVIEW-ONLY] Shared Memory and Atomic Memory Accesses support Shared Memory and Atomic Memory Accesses support Nov 12, 2018
@nidin
Copy link
Contributor Author

nidin commented Nov 14, 2018

@dcodeIO @MaxGraey If it's OK, we can merge it.

@MaxGraey
Copy link
Member

As I understand atomic.wait and atomic.wake is not yet implemented?

@nidin
Copy link
Contributor Author

nidin commented Nov 16, 2018

Yes, That's correct.

@nidin
Copy link
Contributor Author

nidin commented Nov 16, 2018

May be it's better idea to implement wait & wake to complete the thread support.

@willemneal
Copy link
Contributor

willemneal commented Nov 29, 2018

@nidin I tried playing around with your branch and tried using wait and wake in chrome since it now supports threads, however, it seems to only support the other atomic instructions. I looked at the example from that article and it uses an imported wait and wake, which I think we'll have to do until their added.

@nidin
Copy link
Contributor Author

nidin commented Nov 29, 2018

@willemneal Wait wake is in this branch
i64 wait/wake is not implemented in chrome. I discussed this issue with v8 team here in Munich. It's a known issue. v8 now has JavaScript equivalent atomic wait wake. I will do some more tests and merge it to PR branch.

…ait-wake-integration

Feature/worker based threads wait wake integration
@nidin
Copy link
Contributor Author

nidin commented Nov 29, 2018

Atomic wait/wake feature added

@nidin
Copy link
Contributor Author

nidin commented Dec 3, 2018

@MaxGraey @dcodeIO PR is ready to review and merge.

This follows the recent JavaScript name change, and was decided in the
Nov 13 CG meeting.
@dcodeIO
Copy link
Member

dcodeIO commented Jan 9, 2019

Thank you so much for looking into this! Could we maybe split this into multiple parts to make it a little easier to grasp? For example, a first part could be to add the respective binaryen defintitions and internal module methods, a second could be the necessary changes to the compiler plus tests and a third could be adding an example?

@nidin
Copy link
Contributor Author

nidin commented Jan 9, 2019 via email

@nidin nidin changed the title Shared Memory and Atomic Memory Accesses support [Moving to Small PRs] Shared Memory and Atomic Memory Accesses support Jan 29, 2019
@nidin nidin changed the title [Moving to Small PRs] Shared Memory and Atomic Memory Accesses support ✂[Moving to Small PRs] Shared Memory and Atomic Memory Accesses support Jan 29, 2019
@nidin nidin closed this Feb 26, 2019
@nidin
Copy link
Contributor Author

nidin commented Feb 26, 2019

Features from this PR already merged to master from another PRs

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

Successfully merging this pull request may close these issues.

None yet

4 participants