Skip to content

Commit a6d934a

Browse files
authored
feat: Make timeout and count optional for atomic.wait and atomic.notify (#2093)
1 parent 88336dd commit a6d934a

File tree

2 files changed

+14
-10
lines changed

2 files changed

+14
-10
lines changed

src/builtins.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,14 +2673,14 @@ function builtin_atomic_cmpxchg(ctx: BuiltinContext): ExpressionRef {
26732673
}
26742674
builtins.set(BuiltinNames.atomic_cmpxchg, builtin_atomic_cmpxchg);
26752675

2676-
// atomic.wait<T!>(ptr: usize, expected: T, timeout: i64) -> i32
2676+
// atomic.wait<T!>(ptr: usize, expected: T, timeout?: i64) -> i32
26772677
function builtin_atomic_wait(ctx: BuiltinContext): ExpressionRef {
26782678
var compiler = ctx.compiler;
26792679
var module = compiler.module;
26802680
if (
26812681
checkFeatureEnabled(ctx, Feature.THREADS) |
26822682
checkTypeRequired(ctx) |
2683-
checkArgsRequired(ctx, 3)
2683+
checkArgsOptional(ctx, 2, 3)
26842684
) {
26852685
compiler.currentType = Type.i32;
26862686
return module.unreachable();
@@ -2690,7 +2690,9 @@ function builtin_atomic_wait(ctx: BuiltinContext): ExpressionRef {
26902690
var type = typeArguments![0];
26912691
var arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.CONV_IMPLICIT);
26922692
var arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT);
2693-
var arg2 = compiler.compileExpression(operands[2], Type.i64, Constraints.CONV_IMPLICIT);
2693+
var arg2 = operands.length == 3
2694+
? compiler.compileExpression(operands[2], Type.i64, Constraints.CONV_IMPLICIT)
2695+
: module.i64(-1, -1); // Infinite timeout
26942696
compiler.currentType = Type.i32;
26952697
switch (type.kind) {
26962698
case TypeKind.I32:
@@ -2708,21 +2710,23 @@ function builtin_atomic_wait(ctx: BuiltinContext): ExpressionRef {
27082710
}
27092711
builtins.set(BuiltinNames.atomic_wait, builtin_atomic_wait);
27102712

2711-
// atomic.notify(ptr: usize, count: i32) -> i32
2713+
// atomic.notify(ptr: usize, count?: i32) -> i32
27122714
function builtin_atomic_notify(ctx: BuiltinContext): ExpressionRef {
27132715
var compiler = ctx.compiler;
27142716
var module = compiler.module;
27152717
if (
27162718
checkFeatureEnabled(ctx, Feature.THREADS) |
27172719
checkTypeAbsent(ctx) |
2718-
checkArgsRequired(ctx, 2)
2720+
checkArgsOptional(ctx, 1, 2)
27192721
) {
27202722
compiler.currentType = Type.i32;
27212723
return module.unreachable();
27222724
}
27232725
var operands = ctx.operands;
27242726
var arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.CONV_IMPLICIT);
2725-
var arg1 = compiler.compileExpression(operands[1], Type.i32, Constraints.CONV_IMPLICIT);
2727+
var arg1 = operands.length == 2
2728+
? compiler.compileExpression(operands[1], Type.i32, Constraints.CONV_IMPLICIT)
2729+
: module.i32(-1); // Inifinity count of waiters
27262730
compiler.currentType = Type.i32;
27272731
return module.atomic_notify(arg0, arg1);
27282732
}

std/assembly/index.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,9 @@ declare namespace atomic {
252252
/** Atomically compares and exchanges an integer value in memory if the condition is met. */
253253
export function cmpxchg<T>(ptr: usize, expected: T, replacement: T, immOffset?: usize): T;
254254
/** Performs a wait operation on an address in memory suspending this agent if the integer condition is met. */
255-
export function wait<T>(ptr: usize, expected: T, timeout: i64): AtomicWaitResult;
255+
export function wait<T>(ptr: usize, expected: T, timeout?: i64): AtomicWaitResult;
256256
/** Performs a notify operation on an address in memory waking up suspended agents. */
257-
export function notify(ptr: usize, count: i32): i32;
257+
export function notify(ptr: usize, count?: i32): i32;
258258
/** Performs a fence operation, preserving synchronization guarantees of higher level languages. */
259259
export function fence(): void;
260260
}
@@ -345,7 +345,7 @@ declare namespace i32 {
345345
/** Atomically stores a 32-bit integer value to memory. */
346346
export function store(ptr: usize, value: i32, immOffset?: usize): void;
347347
/** Performs a wait operation on a 32-bit integer value in memory suspending this agent if the condition is met. */
348-
export function wait(ptr: usize, expected: i32, timeout: i64): AtomicWaitResult;
348+
export function wait(ptr: usize, expected: i32, timeout?: i64): AtomicWaitResult;
349349
/** Atomic 32-bit integer read-modify-write operations on 8-bit values. */
350350
export namespace rmw8 {
351351
/** Atomically adds an 8-bit unsigned integer value in memory. */
@@ -469,7 +469,7 @@ declare namespace i64 {
469469
/** Atomically stores a 64-bit integer value to memory. */
470470
export function store(ptr: usize, value: i64, immOffset?: usize): void;
471471
/** Performs a wait operation on a 64-bit integer value in memory suspending this agent if the condition is met. */
472-
export function wait(ptr: usize, expected: i64, timeout: i64): AtomicWaitResult;
472+
export function wait(ptr: usize, expected: i64, timeout?: i64): AtomicWaitResult;
473473
/** Atomic 64-bit integer read-modify-write operations on 8-bit values. */
474474
export namespace rmw8 {
475475
/** Atomically adds an 8-bit unsigned integer value in memory. */

0 commit comments

Comments
 (0)