Index: src/harmony-atomics.js |
diff --git a/src/harmony-atomics.js b/src/harmony-atomics.js |
index aa81822d1e2f877f4de933f02d269b81775eea11..433d547e223b4cb8858a32d51dfd79d0180a0bcc 100644 |
--- a/src/harmony-atomics.js |
+++ b/src/harmony-atomics.js |
@@ -13,21 +13,34 @@ |
var GlobalObject = global.Object; |
+var MathMax; |
+ |
+utils.Import(function(from) { |
+ MathMax = from.MathMax; |
+}); |
+ |
// ------------------------------------------------------------------- |
function CheckSharedTypedArray(sta) { |
- if (!%_IsSharedTypedArray(sta)) { |
+ if (!%IsSharedTypedArray(sta)) { |
throw MakeTypeError(kNotSharedTypedArray, sta); |
} |
} |
function CheckSharedIntegerTypedArray(ia) { |
- if (!%_IsSharedIntegerTypedArray(ia)) { |
+ if (!%IsSharedIntegerTypedArray(ia)) { |
throw MakeTypeError(kNotIntegerSharedTypedArray, ia); |
} |
} |
+function CheckSharedInteger32TypedArray(ia) { |
+ CheckSharedIntegerTypedArray(ia); |
+ if (%_ClassOf(ia) !== 'Int32Array') { |
+ throw MakeTypeError(kNotInt32SharedTypedArray, ia); |
+ } |
+} |
+ |
//------------------------------------------------------------------- |
function AtomicsCompareExchangeJS(sta, index, oldValue, newValue) { |
@@ -115,6 +128,49 @@ function AtomicsIsLockFreeJS(size) { |
return %_AtomicsIsLockFree(size); |
} |
+// Futexes |
+ |
+function AtomicsFutexWaitJS(ia, index, value, timeout) { |
+ CheckSharedInteger32TypedArray(ia); |
+ index = $toInteger(index); |
+ if (index < 0 || index >= ia.length) { |
Jarin
2015/07/10 12:11:39
I believe you should not rely on the length proper
binji
2015/07/14 19:24:37
Done.
|
+ return UNDEFINED; |
+ } |
+ if (IS_UNDEFINED(timeout)) { |
+ timeout = INFINITY; |
+ } else { |
+ timeout = $toNumber(timeout); |
+ if (NUMBER_IS_NAN(timeout)) { |
+ timeout = INFINITY; |
+ } else { |
+ timeout = MathMax(0, timeout); |
+ } |
+ } |
+ return %AtomicsFutexWait(ia, index, value, timeout); |
+} |
+ |
+function AtomicsFutexWakeJS(ia, index, count) { |
+ CheckSharedInteger32TypedArray(ia); |
+ index = $toInteger(index); |
+ if (index < 0 || index >= ia.length) { |
+ return UNDEFINED; |
+ } |
+ count = MathMax(0, $toInteger(count)); |
+ return %AtomicsFutexWake(ia, index, count); |
+} |
+ |
+function AtomicsFutexWakeOrRequeueJS(ia, index1, count, value, index2) { |
+ CheckSharedInteger32TypedArray(ia); |
+ index1 = $toInteger(index1); |
+ count = MathMax(0, $toInteger(count)); |
+ value = $toInt32(value); |
+ index2 = $toInteger(index2); |
+ if (index1 < 0 || index1 >= ia.length || index2 < 0 || index2 >= ia.length) { |
+ return UNDEFINED; |
+ } |
+ return %AtomicsFutexWakeOrRequeue(ia, index1, count, value, index2); |
+} |
+ |
// ------------------------------------------------------------------- |
function AtomicsConstructor() {} |
@@ -127,6 +183,13 @@ var Atomics = new AtomicsConstructor(); |
%AddNamedProperty(Atomics, symbolToStringTag, "Atomics", READ_ONLY | DONT_ENUM); |
+// These must match the values in src/futex-emulation.h |
+utils.InstallConstants(Atomics, [ |
+ "OK", 0, |
+ "NOTEQUAL", -1, |
+ "TIMEDOUT", -2, |
+]); |
+ |
utils.InstallFunctions(Atomics, DONT_ENUM, [ |
"compareExchange", AtomicsCompareExchangeJS, |
"load", AtomicsLoadJS, |
@@ -138,6 +201,9 @@ utils.InstallFunctions(Atomics, DONT_ENUM, [ |
"xor", AtomicsXorJS, |
"exchange", AtomicsExchangeJS, |
"isLockFree", AtomicsIsLockFreeJS, |
+ "futexWait", AtomicsFutexWaitJS, |
+ "futexWake", AtomicsFutexWakeJS, |
+ "futexWakeOrRequeue", AtomicsFutexWakeOrRequeueJS, |
]); |
}) |