Объект Atomics:
- является %Atomics%.
- является начальным значением свойства «Atomics» глобального объекта.
- это обычный объект.
- имеет внутренний слот [[Prototype]], значение которого равно %Object.prototype%.
- не имеет внутреннего метода [[Construct]]; его нельзя использовать в качестве конструктора с оператором
new
. - не имеет внутреннего метода [[Call]]; его нельзя вызвать как функцию.
Объект Atomics предоставляет функции, которые неделимо (атомарно) работают с ячейками массива разделяемой памяти, а также функции, которые позволяют агентам ждать и отправлять примитивные события. При дисциплинированном использовании функции Atomics позволяют много-агентным программам, которые обмениваются данными через разделяемую память, выполняться в понятном порядке даже на параллельных процессорах. Правила, управляющие обменом данными с общей памятью, предоставляются моделью памяти, определенной ниже.
Информативные рекомендации по программированию и реализации разделяемой памяти в ECMAScript смотри в примечаниях в конце раздела о модели памяти.
25.4.1 Объекты Список Ожидателей (WaiterList Objects)
WaiterList — это семантический объект, который содержит упорядоченный список тех агентов, которые ожидают в определенном месте (block, i) в общей памяти; block — это Совместно Используемый Блок Данных, а i — байтовое смещение в памяти блока block. Объект WaiterList также необязательно содержит событие Synchronize, обозначающее предыдущий выход из его критического раздела.
Изначально у объекта WaiterList есть пустой список и нет события Synchronize.
Кластер агентов имеет хранилище объектов WaiterList; магазин индексируется (block, i). WaiterList не зависит от агента: поиск в хранилище WaiterLists по (block, i) приведет к тому же объекту WaiterList в любом агенте в кластере агентов.
Каждый WaiterList имеет критическую секцию (critical section), которая контролирует эксклюзивный доступ к этому WaiterList во время оценки. Только один агент может войти в критическую секцию WaiterList одновременно. Вход в критическую секцию WaiterList и выход из нее контролируется абстрактными операциями EnterCriticalSection и LeaveCriticalSection. Операции с WaiterList — добавление и удаление ожидающих агентов, просмотр списка агентов, приостановка и уведомление агентов в списке, установка и получение события Synchronize — могут выполняться только агентами, которые вошли в критическую секцию WaiterList.
25.4.2 Абстрактные операции для Атомик
25.4.2.1 ValidateIntegerTypedArray ( typedArray [ , waitable ] )
Абстрактная операция ValidateIntegerTypedArray (Проверить массив с целочисленным типом) принимает аргумент typedArray и необязательный аргумент waitable (логическое значение Boolean). При вызове она выполняет следующие шаги:
1. Если waitable отсутствует, установите для параметра waitable значение false. 2. Выполнить ? ValidateTypedArray(typedArray). 3. Пусть buffer будет typeedArray.[[ViewedArrayBuffer]]. 4. Пусть typeName будет typedArray.[[TypedArrayName]]. 5. Пусть type будет значением типа элемента в Таблице 72 для typeName. 6. Если waitable является true (истинно), то а. Если typeName не является "Int32Array" или "BigInt64Array", вызовите исключение TypeError. 7. Иначе, а. Если ! IsUnclampedIntegerElementType(type) является false и ! IsBigIntElementType(type) является false, вызовите исключение TypeError. 8. Возвратный buffer.
25.4.2.2 ValidateAtomicAccess ( typedArray, requestIndex )
Абстрактная операция ValidateAtomicAccess (Проверить атомарный доступ) принимает аргументы typedArray (TypedArray) и requestIndex. При вызове она выполняет следующие шаги:
1. Пусть length будет typeedArray.[[ArrayLength]]. 2. Пусть accessIndex будет ? ToIndex(requestIndex). 3. Утверждено: accessIndex ≥ 0. 4. Если accessIndex ≥ length, выбросить исключение RangeError. 5. Пусть arrayTypeName будет typedArray.[[TypedArrayName]]. 6. Пусть elementSize будет значением размера элемента, указанным в Таблице 72 для arrayTypeName. 7. Пусть смещение offset будет typedArray.[[ByteOffset]]. 8. Вернуть (accessIndex × elementSize) + offset.
25.4.2.3 GetWaiterList ( block, i )
Абстрактная операция GetWaiterList (Получить Список Ожидателей) принимает аргумент block (блок общих данных) и i (неотрицательное целое число, которое делится на 4 без остатка). При вызове он выполняет следующие шаги:
1. Утверждено: i и i + 3 - допустимые байтовые смещения в памяти блока block. 2. Верните WaiterList, на который ссылается пара (block, i).
25.4.2.4 EnterCriticalSection (WL)
Абстрактная операция EnterCriticalSection (Войти в критический раздел) принимает аргумент WL (WaiterList). При вызове она выполняет следующие шаги:
1. Утверждено: вызывающий агент не находится в критическом разделе ни для одного списка ожидателей WaiterList. 2. Подождите, пока в критической секции для WL не окажется ни один агент, затем войдите в критическую секцию для WL (не позволяя войти другим агентам). 3. Если в WL есть событие Synchronize, то а. ПРИМЕЧАНИЕ: WL, критическая секция которого была введена хотя бы один раз, имеет событие Synchronize, установленное LeaveCriticalSection. b. Пусть выполнение execution будет полем [[CandidateExecution]] в Записи Агента окружающего агента. c. Пусть eventsRecord будет Записью Событий Агента в процессе execution.[[EventsRecords]], у которой [[AgentSignifier]] является AgentSignifier(). d. Пусть entererEventList будет eventsRecord.[[EventList]]. e. Пусть enterEvent будет новым событием Synchronize. f. Добавьте enterEvent в entererEventList. g. Пусть leaveEvent будет событием Synchronize в WL. h. Добавьте (leaveEvent, enterEvent) к eventsRecord.[[AgentSynchronizesWith]].
EnterCriticalSection имеет конфликт (contention), когда агент, пытающийся войти в критическую секцию, должен ждать, пока другой агент не покинет ее. Когда нет конкуренции, можно наблюдать порядок FIFO вызовов EnterCriticalSection. При возникновении разногласий реализация может выбрать произвольный порядок, но не может заставлять агента ждать бесконечно.
25.4.2.5 LeaveCriticalSection ( WL )
Абстрактная операция LeaveCriticalSection (Покинуть критический раздел) принимает аргумент WL (WaiterList). При вызове она выполняет следующие шаги:
1. Утверждено: вызывающий агент находится в критической секции для WL. 2. Пусть выполнение execution будет полем [[CandidateExecution]] в Записи Агента вызывающего окружения. 3. Пусть eventsRecord будет Записью Событий Агента в процессе execution.[[EventsRecords]], у которой [[AgentSignifier]] есть AgentSignifier(). 4. Пусть leaverEventList будет eventsRecord.[[EventList]]. 5. Пусть leaveEvent будет новым событием Synchronize. 6. Добавьте leaveEvent в leaverEventList. 7. Установите для события Synchronize в WL значение leaveEvent. 8. Оставьте критическую секцию для WL.
25.4.2.6 AddWaiter ( WL, W )
Абстрактная операция AddWaiter (Добавить Ожидателя) принимает аргументы WL (WaiterList) и W (указатель агента). При вызове она выполняет следующие шаги:
1. Утверждено: вызывающий агент находится в критической секции для WL. 2. Утверждено: W нет в списке ожидателей ни в одном WaiterList. 3. Добавьте W в конец списка ожидателей в WL.
25.4.2.7 RemoveWaiter ( WL, W )
Абстрактная операция RemoveWaiter (Удалить Ожидателя) принимает аргументы WL (список ожидания WaiterList) и W (указатель агента). При вызове она выполняет следующие шаги:
1. Утверждено: вызывающий агент находится в критической секции для WL. 2. Утверждено: W находится в списке официантов в WL. 3. Убрать W из списка официантов в WL.
25.4.2.8 RemoveWaiters ( WL, c )
Абстрактная операция RemoveWaiters (Удалить Ожидателей) принимает аргументы WL (WaiterList) и c (неотрицательное целое число или +∞). При вызове он выполняет следующие шаги:
1. Утверждено: вызывающий агент находится в критической секции для WL. 2. Пусть L будет новым пустым Списком. 3. Пусть S будет ссылкой на список ожидателей в WL. 4. Повторите, пока c > 0 и S не является пустым Списком, а. Пусть W будет первым ожидателем в S. b. Добавьте W в конец L. c. Удалите W из S. d. Если c конечно, установите c равным c - 1. 5. Верните L.
25.4.2.9 SuspendAgent ( WL, W, timeout )
Абстрактная операция SuspendAgent (Приостановить агент) принимает аргументы WL (WaiterList), W (обозначающее агент) и timeout (неотрицательное целое число). При вызове она выполняет следующие шаги:
1. Утверждено: вызывающий агент находится в критической секции для WL. 2. Утверждено: W эквивалентно AgentSignifier(). 3. Утверждено: W находится в списке официантов в WL. 4. Утверждено: AgentCanSuspend() является true (истинно). 5. Выполните LeaveCriticalSection(WL) и приостановите W на время timeout в миллисекундах, выполняя комбинированную операцию таким образом, чтобы уведомление, поступившее после выхода из критического раздела, но до того, как приостановка вступила в силу, не потерялось. W может уведомить либо потому, что тайм-аут истек, либо потому, что он был явно уведомлен другим агентом, вызывающим NotifyWaiter(WL, W), а не по каким-либо другим причинам вообще. 6. Выполните EnterCriticalSection(WL). 7. Если W был явно уведомлен другим агентом, вызывающим NotifyWaiter(WL, W), вернуть true. 8. Вернуть false.
25.4.2.10 NotifyWaiter ( WL, W )
Абстрактная операция NotifyWaiter (Уведомить Ожидателя) принимает аргументы WL (WaiterList) и W (обозначение агента). При вызове она выполняет следующие шаги:
1. Утверждено: вызывающий агент находится в критической секции для WL. 2. Сообщите агенту W.
Встраивание может задержать уведомление W, например по причинам управления ресурсами, но W в конечном итоге должен быть уведомлен, чтобы гарантировать продвижение вперед.
25.4.2.11 AtomicReadModifyWrite ( typedArray, index, value, op )
Абстрактная операция AtomicReadModifyWrite (Атомарное чтение Изменить запись) принимает аргументы typedArray, index, value и op (функция модификации чтения-изменения-записи). op принимает два Списка байтовых значений и возвращает Список байтовых значений. Эта операция атомарно загружает значение, объединяет его с другим значением и сохраняет результат комбинации. Возвращает загруженное значение. При вызове она выполняет следующие шаги:
1. Пусть buffer будет ? ValidateIntegerTypedArray(typedArray). 2. Пусть indexedPosition будет ? ValidateAtomicAccess(typedArray, index). 3. Пусть arrayTypeName будет typeedArray.[[TypedArrayName]]. 4. Если typedArray.[[ContentType]] имеет значение BigInt, пусть v будет ? ToBigInt(value). 5. Иначе пусть v будет 𝔽(? ToIntegerOrInfinity(value)). 6. Если IsDetachedBuffer(buffer) имеет значение true, выбросить исключение TypeError. 7. ПРИМЕЧАНИЕ. Вышеупомянутая проверка не является избыточной с проверкой в ValidateIntegerTypedArray, потому что вызов ToBigInt или ToIntegerOrInfinity в предыдущих строках может иметь произвольные побочные эффекты, которые могут привести к отсоединению буфера. 8. Пусть elementType будет значением типа элемента в таблице 72 для arrayTypeName. 9. Верните GetModifySetValueInBuffer(buffer, indexedPosition, elementType, v, op).
25.4.2.12 ByteListBitwiseOp ( op, xBytes, yBytes )
Абстрактная операция ByteListBitwiseOp (Операция Побитовый список байтов) принимает аргументы op (&
, ^
или |
), xBytes (Список байтовых значений) и yBytes (Список байтовых значений). Операция атомарно выполняет побитовую операцию со всеми байтовыми значениями аргументов и возвращает Список байтовых значений. При вызове она выполняет следующие шаги:
1. Утверждено: xBytes и yBytes имеют одинаковое количество элементов. 2. Пусть result будет новым пустым Списком. 3. Пусть i равно 0. 4. Для каждого элемента xByte из xBytes выполните а. Пусть yByte будет yBytes[i]. b. Если op равен &, пусть resultByte будет результатом применения побитовой операции "И" (AND) к xByte и yByte. c. Иначе, если op равно ^, пусть resultByte будет результатом применения операции побитового "исключающего ИЛИ" (XOR) к xByte и yByte. d. Иначе op равен |. Пусть resultByte будет результатом применения побитовой операции включающего ИЛИ к xByte и yByte. e. Установите i в i + 1. f. Добавить resultByte в конец result. 5. Вернуть result.
25.4.2.13 ByteListEqual ( xBytes, yBytes )
Абстрактная операция ByteListEqual (Список байтов равен) принимает аргументы xBytes (список байтовых значений) и yBytes (список байтовых значений). При вызове она выполняет следующие шаги:
1. Если xBytes и yBytes не имеют одинакового количества элементов, вернуть false. 2. Пусть i равно 0. 3. Для каждого элемента xByte из xBytes выполните а. Пусть yByte будет yBytes[i]. b. Если xByte ≠ yByte, вернуть false. c. Установите i в i + 1. 4. Верните true (истину).
25.4.3 Atomics.add ( typedArray, index, value )
Выполняются следующие шаги:
1. Пусть type будет значением типа элемента в Таблице 72 для typedArray.[[TypedArrayName]]. 2. Пусть isLittleEndian будет значением поля [[LittleEndian]] в Записи Агента окружающего агента. 3. Пусть add будет новой функцией модификации чтения-изменения-записи с параметрами (xBytes, yBytes), которая фиксирует type и isLittleEndian и при вызове выполняет следующие шаги атомарно: а. Пусть x будет RawBytesToNumeric(type, xBytes, isLittleEndian). b. Пусть y будет RawBytesToNumeric(type, yBytes, isLittleEndian). c. Пусть T будет Type(x). d. Пусть sum равна T::add(x, y). e. Пусть sumBytes будет NumericToRawBytes(type, sum, isLittleEndian). f. Утверждено: sumBytes, xBytes и yBytes имеют одинаковое количество элементов. g. Вернуть sumBytes. 4. Вернуть ? AtomicReadModifyWrite(typedArray, индекс, значение, добавить).
25.4.4 Atomics.and ( typedArray, index, value )
Выполняются следующие шаги:
1. Пусть и будет новой функцией модификации чтения-изменения-записи с параметрами (xBytes, yBytes), которая ничего не захватывает и при вызове выполняет следующие шаги атомарно: а. Вернуть ByteListBitwiseOp (&, xBytes, yBytes). 2. Вернуть? AtomicReadModifyWrite (typedArray, index, value и).
25.4.5 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue )
Выполняются следующие шаги:
1. Да будет буфер? ValidateIntegerTypedArray (typedArray). 2. Пусть блок будет буфером. [[ArrayBufferData]]. 3. Пусть будет indexedPosition? ValidateAtomicAccess (typedArray, индекс). 4. Пусть arrayTypeName будет typedArray. [[TypedArrayName]]. 5. Если typedArray. [[ContentType]] имеет значение BigInt, то а. Пусть будет? ToBigInt (ожидаемое значение). b. Пусть будет замена? ToBigInt (replaceValue). 6. Иначе, а. Пусть ожидается (? ToIntegerOrInfinity (expectedValue)). b. Пусть замена будет 𝔽 (? ToIntegerOrInfinity (replaceValue)). 7. Если IsDetachedBuffer (buffer) истинно, выбросить исключение TypeError. 8. ПРИМЕЧАНИЕ. Вышеупомянутая проверка не является избыточной с проверкой в ValidateIntegerTypedArray, потому что вызов ToBigInt или ToIntegerOrInfinity в предыдущих строках может иметь произвольные побочные эффекты, которые могут привести к отсоединению буфера. 9. Пусть elementType будет значением типа элемента в таблице 73 для arrayTypeName. 10. Пусть elementSize будет значением размера элемента, указанным в таблице 73 для типа элемента elementType. 11. Пусть isLittleEndian будет значением поля [[LittleEndian]] в записи агента окружающего агента. 12. Пусть expectedBytes будет NumericToRawBytes (elementType, expected, isLittleEndian). 13. Пусть replaceBytes будет NumericToRawBytes (elementType, replacement, isLittleEndian). 14. Если IsSharedArrayBuffer (buffer) истинно, то а. Пусть выполнение будет полем [[CandidateExecution]] в записи агента окружающего агента. b. Пусть eventList будет полем [[EventList]] выполняемого элемента. [[EventsRecords]], у которого [[AgentSignifier]] есть AgentSignifier (). c. Пусть rawBytesRead будет List длины elementSize, элементы которого являются недетерминированно выбранными байтовыми значениями. d. ПРИМЕЧАНИЕ. В реализациях rawBytesRead является результатом ссылки загрузки, исключающей загрузки или операнда инструкции чтения-изменения-записи на базовом оборудовании. Недетерминизм - это семантическое предписание модели памяти для описания наблюдаемого поведения оборудования со слабой согласованностью. e. ПРИМЕЧАНИЕ. Сравнение ожидаемого значения и считанного значения выполняется вне функции модификации «чтение-изменение-запись», чтобы избежать ненужной сильной синхронизации, когда ожидаемое значение не равно считанному значению. f. Если ByteListEqual (rawBytesRead, expectedBytes) истинно, то i. Пусть вторая будет новой функцией модификации чтения-изменения-записи с параметрами (oldBytes, newBytes), которая ничего не захватывает и при вызове выполняет следующие шаги атомарно: 1. Верните newBytes. ii. Пусть событие будет ReadModifyWriteSharedMemory {[[Order]]: SeqCst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: indexedPosition, [[ElementSize]]: elementSize, [[Payload]] " : replaceBytes, [[ModifyOp]]: второй}. грамм. Еще, i. Пусть событие будет ReadSharedMemory {[[Порядок]]: SeqCst, [[NoTear]]: истина, [[Блок]]: блок, [[ByteIndex]]: indexedPosition, [[ElementSize]]: elementSize} ". час Добавить событие в список событий. i. Добавить к выполнению запись выбранного значения {[[Event]]: событие, [[ChosenValue]]: rawBytesRead}. [[ChosenValues]]. 15. Иначе, а. Пусть rawBytesRead будет List длины elementSize, элементы которого представляют собой последовательность байтов elementSize, начинающуюся с блока [indexedPosition]. b. Если ByteListEqual (rawBytesRead, expectedBytes) истинно, то i. Сохраните отдельные байты replaceBytes в блоке, начиная с блока [indexedPosition]. 16. Верните RawBytesToNumeric (elementType, rawBytesRead, isLittleEndian).
25.4.6 Atomics.exchange ( typedArray, index, value )
Выполняются следующие шаги:
1. Пусть вторая будет новой функцией модификации чтения-изменения-записи с параметрами (oldBytes, newBytes), которая ничего не захватывает и при вызове выполняет следующие шаги атомарно: а. Верните newBytes. 2. Вернуть? AtomicReadModifyWrite (typedArray, индекс, значение, секунда).
25.4.7 Atomics.isLockFree ( size )
Выполняются следующие шаги:
1. Пусть n будет? ToIntegerOrInfinity (размер). 2. Пусть AR будет записью агента окружающего агента. 3. Если n = 1, вернуть AR. [[IsLockFree1]]. 4. Если n = 2, вернуть AR. [[IsLockFree2]]. 5. Если n = 4, вернуть истину. 6. Если n = 8, вернуть AR. [[IsLockFree8]]. 7. Вернуть false.
Примечание
Atomics.isLockFree () — это примитив оптимизации. Интуиция заключается в том, что если атомарный шаг атомарного примитива (compareExchange, load, store, add, sub и, or, xor, or exchange) для данных размером n байтов будет выполнен без получения вызывающим агентом блокировки вне n байтов, составляющих данные, тогда Atomics.isLockFree (n) вернет true. Высокопроизводительные алгоритмы будут использовать Atomics.isLockFree, чтобы определить, использовать ли блокировки или атомарные операции в критических секциях. Если атомарный примитив не свободен от блокировок, то для алгоритма часто более эффективно обеспечить собственную блокировку.
Atomics.isLockFree (4) всегда возвращает истину, поскольку это может поддерживаться на всем известном соответствующем оборудовании. Возможность предположить, что это обычно упрощает программы.
Независимо от значения Atomics.isLockFree, все атомарные операции гарантированно будут атомарными. Например, у них никогда не будет видимой операции в середине операции (например, «разрыв»).
25.4.8 Atomics.load ( typedArray, index )
Выполняются следующие шаги:
1. Да будет буфер? ValidateIntegerTypedArray (typedArray). 2. Пусть будет indexedPosition? ValidateAtomicAccess (typedArray, индекс). 3. Если IsDetachedBuffer (buffer) истинно, выбросить исключение TypeError. 4. ПРИМЕЧАНИЕ. Вышеупомянутая проверка не является избыточной с проверкой в ValidateIntegerTypedArray, поскольку вызов ValidateAtomicAccess в предыдущей строке может иметь произвольные побочные эффекты, которые могут привести к отсоединению буфера. 5. Пусть arrayTypeName будет typedArray. [[TypedArrayName]]. 6. Пусть elementType будет значением типа элемента в таблице 73 для arrayTypeName. 7. Верните GetValueFromBuffer (buffer, indexedPosition, elementType, true, SeqCst).
25.4.9 Atomics.or ( typedArray, index, value )
Выполняются следующие шаги:
1. Позвольте или быть новой функцией модификации чтения-изменения-записи с параметрами (xBytes, yBytes), которая ничего не захватывает и при вызове выполняет следующие шаги атомарно: а. Вернуть ByteListBitwiseOp (|, xBytes, yBytes). 2. Вернуть? AtomicReadModifyWrite (typedArray, index, value или).
25.4.10 Atomics.store ( typedArray, index, value )
Выполняются следующие шаги:
1. Да будет буфер? ValidateIntegerTypedArray (typedArray). 2. Пусть будет indexedPosition? ValidateAtomicAccess (typedArray, индекс). 3. Пусть arrayTypeName будет typeedArray. [[TypedArrayName]]. 4. Если arrayTypeName - «BigUint64Array» или «BigInt64Array», пусть v будет? ToBigInt (значение). 5. В противном случае пусть v будет (? ToIntegerOrInfinity (value)). 6. Если IsDetachedBuffer (buffer) имеет значение true, выбросить исключение TypeError. 7. ПРИМЕЧАНИЕ. Вышеупомянутая проверка не является избыточной с проверкой в ValidateIntegerTypedArray, потому что вызов ToBigInt или ToIntegerOrInfinity в предыдущих строках может иметь произвольные побочные эффекты, которые могут привести к отсоединению буфера. 8. Пусть elementType будет значением типа элемента в таблице 73 для arrayTypeName. 9. Выполните SetValueInBuffer (buffer, indexedPosition, elementType, v, true, SeqCst). 10. Возврат v.
25.4.11 Atomics.sub ( typedArray, index, value )
Выполняются следующие шаги:
1. Пусть type будет значением типа элемента в таблице 73 для typedArray. [[TypedArrayName]]. 2. Пусть isLittleEndian будет значением поля [[LittleEndian]] в записи агента окружающего агента. 3. Пусть subtract будет новой функцией модификации чтения-изменения-записи с параметрами (xBytes, yBytes), которая фиксирует тип и isLittleEndian и при вызове выполняет следующие шаги атомарно: а. Пусть x будет RawBytesToNumeric (тип, xBytes, isLittleEndian). b. Пусть y будет RawBytesToNumeric (тип, yBytes, isLittleEndian). c. Пусть T будет Type (x). d. Пусть разница будет T :: subtract (x, y). e. Пусть разницаBytes будет NumericToRawBytes (тип, разница, isLittleEndian). f. Утверждение: differenceBytes, xBytes и yBytes имеют одинаковое количество элементов. g. Разница в возвратеБайты. 4. Вернуться? AtomicReadModifyWrite (typedArray, индекс, значение, вычитание).
25.4.12 Atomics.wait ( typedArray, index, value, timeout )
Atomics.wait помещает вызывающий агент в очередь ожидания и переводит его в спящий режим до тех пор, пока он не получит уведомление или не истечет время ожидания. Выполняются следующие шаги:
1. Да будет буфер? ValidateIntegerTypedArray (typedArray, истина). 2. Если IsSharedArrayBuffer (buffer) имеет значение false, выбросить исключение TypeError. 3. Пусть будет indexedPosition? ValidateAtomicAccess (typedArray, индекс). 4. Пусть arrayTypeName будет typedArray. [[TypedArrayName]]. 5. Если arrayTypeName - «BigInt64Array», пусть v будет? ToBigInt64 (значение). 6. В противном случае пусть будет v? ToInt32 (значение). 7. Пусть q будет? ToNumber (тайм-аут). 8. Если q равно NaN или + ∞𝔽, пусть t равно + ∞; иначе, если q равно -∞𝔽, пусть t равно 0; иначе пусть t будет max (ℝ (q), 0). 9. Пусть B будет AgentCanSuspend (). 10. Если B ложно, выбросить исключение TypeError. 11. Пусть блок будет буфером. [[ArrayBufferData]]. 12. Пусть WL будет GetWaiterList (block, indexedPosition). 13. Выполните EnterCriticalSection (WL). 14. Пусть elementType будет значением типа элемента в таблице 73 для arrayTypeName. 15. Пусть будет w! GetValueFromBuffer (буфер, indexedPosition, elementType, true, SeqCst). 16. Если v ≠ w, то а. Выполните LeaveCriticalSection (WL). b. Вернуть строку «не равно». 17. Пусть W будет AgentSignifier (). 18. Выполните AddWaiter (WL, W). 19. Пусть уведомлен SuspendAgent (WL, W, t). 20. Если уведомление верно, то а. Утверждение: W нет в списке официантов в WL. 21. Иначе, а. Выполните RemoveWaiter (WL, W). 22. Выполните LeaveCriticalSection (WL). 23. Если уведомление истинно, верните строку «ok». 24. Верните строку «истекло время ожидания».
25.4.13 Atomics.notify ( typedArray, index, count )
Atomics.notify уведомляет некоторых агентов, которые спят в очереди ожидания. Выполняются следующие шаги:
1. Да будет буфер? ValidateIntegerTypedArray (typedArray, истина). 2. Пусть будет indexedPosition? ValidateAtomicAccess (typedArray, индекс). 3. Если count не определен, пусть c будет + ∞. 4. Иначе, а. Пусть будет intCount? ToIntegerOrInfinity (количество). b. Пусть c будет max (intCount, 0). 5. Пусть блок будет буфером. [[ArrayBufferData]]. 6. Если IsSharedArrayBuffer (буфер) имеет значение false, вернуть + 0𝔽. 7. Пусть WL будет GetWaiterList (block, indexedPosition). 8. Пусть n равно 0. 9. Выполните EnterCriticalSection (WL). 10. Пусть S будет RemoveWaiters (WL, c). 11. Повторите, пока S не является пустым списком, а. Пусть W - первый агент в S. b. Удалите W с передней части S. c. Выполните NotifyWaiter (WL, W). d. Установите n равным n + 1. 12. Выполните LeaveCriticalSection (WL). 13. Верните 𝔽 (n).
25.4.14 Atomics.xor ( typedArray, index, value )
Выполняются следующие шаги:
1. Пусть xor будет новой функцией модификации чтения-изменения-записи с параметрами (xBytes, yBytes), которая ничего не захватывает и при вызове выполняет следующие шаги атомарно: а. Вернуть ByteListBitwiseOp (^, xBytes, yBytes). 2. Вернуть? AtomicReadModifyWrite (typedArray, индекс, значение, xor).
25.4.15 Atomics [ @@toStringTag ]
Начальным значением свойства @@toStringTag является строковое значение «Atomics».
Это свойство имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}.
Информационные ссылки
Стандарт ECMAScript — Раздел «25.4 The Atomics Object» — https://tc39.es/ecma262/#sec-atomics-object