Skip to content

feat: Make timeout and count optional for atomic.wait and atomic.notify #2093

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

Merged
merged 2 commits into from
Oct 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2673,14 +2673,14 @@ function builtin_atomic_cmpxchg(ctx: BuiltinContext): ExpressionRef {
}
builtins.set(BuiltinNames.atomic_cmpxchg, builtin_atomic_cmpxchg);

// atomic.wait<T!>(ptr: usize, expected: T, timeout: i64) -> i32
// atomic.wait<T!>(ptr: usize, expected: T, timeout?: i64) -> i32
function builtin_atomic_wait(ctx: BuiltinContext): ExpressionRef {
var compiler = ctx.compiler;
var module = compiler.module;
if (
checkFeatureEnabled(ctx, Feature.THREADS) |
checkTypeRequired(ctx) |
checkArgsRequired(ctx, 3)
checkArgsOptional(ctx, 2, 3)
) {
compiler.currentType = Type.i32;
return module.unreachable();
Expand All @@ -2690,7 +2690,9 @@ function builtin_atomic_wait(ctx: BuiltinContext): ExpressionRef {
var type = typeArguments![0];
var arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.CONV_IMPLICIT);
var arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT);
var arg2 = compiler.compileExpression(operands[2], Type.i64, Constraints.CONV_IMPLICIT);
var arg2 = operands.length == 3
? compiler.compileExpression(operands[2], Type.i64, Constraints.CONV_IMPLICIT)
: module.i64(-1, -1); // Infinite timeout
compiler.currentType = Type.i32;
switch (type.kind) {
case TypeKind.I32:
Expand All @@ -2708,21 +2710,23 @@ function builtin_atomic_wait(ctx: BuiltinContext): ExpressionRef {
}
builtins.set(BuiltinNames.atomic_wait, builtin_atomic_wait);

// atomic.notify(ptr: usize, count: i32) -> i32
// atomic.notify(ptr: usize, count?: i32) -> i32
function builtin_atomic_notify(ctx: BuiltinContext): ExpressionRef {
var compiler = ctx.compiler;
var module = compiler.module;
if (
checkFeatureEnabled(ctx, Feature.THREADS) |
checkTypeAbsent(ctx) |
checkArgsRequired(ctx, 2)
checkArgsOptional(ctx, 1, 2)
) {
compiler.currentType = Type.i32;
return module.unreachable();
}
var operands = ctx.operands;
var arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.CONV_IMPLICIT);
var arg1 = compiler.compileExpression(operands[1], Type.i32, Constraints.CONV_IMPLICIT);
var arg1 = operands.length == 2
? compiler.compileExpression(operands[1], Type.i32, Constraints.CONV_IMPLICIT)
: module.i32(-1); // Inifinity count of waiters
compiler.currentType = Type.i32;
return module.atomic_notify(arg0, arg1);
}
Expand Down
8 changes: 4 additions & 4 deletions std/assembly/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,9 @@ declare namespace atomic {
/** Atomically compares and exchanges an integer value in memory if the condition is met. */
export function cmpxchg<T>(ptr: usize, expected: T, replacement: T, immOffset?: usize): T;
/** Performs a wait operation on an address in memory suspending this agent if the integer condition is met. */
export function wait<T>(ptr: usize, expected: T, timeout: i64): AtomicWaitResult;
export function wait<T>(ptr: usize, expected: T, timeout?: i64): AtomicWaitResult;
/** Performs a notify operation on an address in memory waking up suspended agents. */
export function notify(ptr: usize, count: i32): i32;
export function notify(ptr: usize, count?: i32): i32;
/** Performs a fence operation, preserving synchronization guarantees of higher level languages. */
export function fence(): void;
}
Expand Down Expand Up @@ -345,7 +345,7 @@ declare namespace i32 {
/** Atomically stores a 32-bit integer value to memory. */
export function store(ptr: usize, value: i32, immOffset?: usize): void;
/** Performs a wait operation on a 32-bit integer value in memory suspending this agent if the condition is met. */
export function wait(ptr: usize, expected: i32, timeout: i64): AtomicWaitResult;
export function wait(ptr: usize, expected: i32, timeout?: i64): AtomicWaitResult;
/** Atomic 32-bit integer read-modify-write operations on 8-bit values. */
export namespace rmw8 {
/** Atomically adds an 8-bit unsigned integer value in memory. */
Expand Down Expand Up @@ -469,7 +469,7 @@ declare namespace i64 {
/** Atomically stores a 64-bit integer value to memory. */
export function store(ptr: usize, value: i64, immOffset?: usize): void;
/** Performs a wait operation on a 64-bit integer value in memory suspending this agent if the condition is met. */
export function wait(ptr: usize, expected: i64, timeout: i64): AtomicWaitResult;
export function wait(ptr: usize, expected: i64, timeout?: i64): AtomicWaitResult;
/** Atomic 64-bit integer read-modify-write operations on 8-bit values. */
export namespace rmw8 {
/** Atomically adds an 8-bit unsigned integer value in memory. */
Expand Down