import { ArrayBufferView } from "./arraybuffer"; import { E_INDEXOUTOFRANGE } from "./util/error"; export namespace Atomics { // @ts-ignore: decorator @inline export function load(array: T, index: i32): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.load>( changetype(array.buffer) + (index << align) + array.byteOffset ); } // @ts-ignore: decorator @inline export function store(array: T, index: i32, value: valueof): void { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); atomic.store>( changetype(array.buffer) + (index << align) + array.byteOffset, value ); } // @ts-ignore: decorator @inline export function add(array: T, index: i32, value: valueof): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.add>( changetype(array.buffer) + (index << align) + array.byteOffset, value ); } // @ts-ignore: decorator @inline export function sub(array: T, index: i32, value: valueof): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.sub>( changetype(array.buffer) + (index << align) + array.byteOffset, value ); } // @ts-ignore: decorator @inline export function and(array: T, index: i32, value: valueof): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.and>( changetype(array.buffer) + (index << align) + array.byteOffset, value ); } // @ts-ignore: decorator @inline export function or(array: T, index: i32, value: valueof): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.or>( changetype(array.buffer) + (index << align) + array.byteOffset, value ); } // @ts-ignore: decorator @inline export function xor(array: T, index: i32, value: valueof): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.xor>( changetype(array.buffer) + (index << align) + array.byteOffset, value ); } // @ts-ignore: decorator @inline export function exchange(array: T, index: i32, value: valueof): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.xchg>( changetype(array.buffer) + (index << align) + array.byteOffset, value ); } // @ts-ignore: decorator @inline export function compareExchange( array: T, index: i32, expectedValue: valueof, replacementValue: valueof ): valueof { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.cmpxchg>( changetype(array.buffer) + (index << align) + array.byteOffset, expectedValue, replacementValue ); } // @ts-ignore: decorator @inline export function wait(array: T, value: valueof, timeout: i64 = -1): AtomicWaitResult { return atomic.wait>(changetype(array.buffer) + array.byteOffset, value, timeout); } // @ts-ignore: decorator @inline export function notify(array: T, index: i32, count: i32 = -1): i32 { const align = alignof>(); if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return atomic.notify(changetype(array.buffer) + (index << align) + array.byteOffset, count); } export function isLockFree(size: usize): bool { return size == 1 || size == 2 || size == 4; } }