2025-11-14 [16:59:31.0713] i wonder if we might be having too many technical discussions in the delegates channel instead of here ๐Ÿ˜„ 2025-11-18 [17:06:41.0545] Maybe so. I don't envy the work done by delegates. But I am a little jealous of the trip to Japan. It sounds like a lot of fun and I think I saw something about karaoke the other day.. [17:07:03.0065] When less busy I should seek guidance again regarding my proposal. [04:35:19.0254] Question regarding Atomics wait/waitAsync and notify: are these intended to be just fronts for a futex API, possibly backed by the OS, or is the WL locking supposed to give some guarantees on top? There's an atomic read inside the critical section of DoWait that makes sense to me if it is intended to model the OS futex APIs possibly never suspending a thread if the futexword comparison with value fails immediately. But is that the intention, or am I completely lost? [06:40:56.0970] In effect what I guess I am asking is: is the critical section supposed to protect the buffer value / reading somehow as well? Looking at normal futex APIs it seems reasonable to implement the APIs using a native futex with the exception of the "fail-fast" path for waitAsync: using just futexes, the fail-fast read has to either be a separate atomic load before calling into a futex syscall, in which case it isn't done within the futex's critical section of course, or the main thread needs to spawn a separate thread for calling the syscall and then that thread needs to ... No, I guess it's just not really possible at all. [06:42:36.0101] Nevermind: it's possible with a parking lot futex but as far as I can tell, the futex still needs to be locked on a separate thread and the main thread would need to block until the futex thread confirms that it is going to sleep. That hardly seems like a "fail-fast" path. 2025-11-19 [22:16:09.0476] Anyone have any idea regarding the wait(Async)/notify thing above? I'm planning on just writing my implementation as a Futex syscall wrapper, and thus doing the "fail-fast" path outside of the critical section. Of course, the syscall will also perform the same read inside its critical section (presumably) so rather than moving anything, I'm just adding an extra read of the SAB to check if a syscall should be made or not. [12:54:43.0528] Uhh, am I crazy or is the `DoWait`'s timeout handling text just plain wrong? This is the text: > 8. Let q be ? ToNumber(timeout). > 9. If q is either NaN or +โˆž๐”ฝ, let t be +โˆž; else if q is -โˆž๐”ฝ, let t be 0; else let t be max(โ„(q), 0). But then there's a bunch of tests testing that passing `undefined` as `timeout` coerces to 0. `ToNumber(undefined)` returns `NaN` so we should go into the first branch and set t as +โˆž. [12:55:06.0625] But presumably the tests are the correct source here. [12:59:01.0599] https://github.com/tc39/test262/blob/main/test/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout.js https://github.com/tc39/test262/blob/main/test/built-ins/Atomics/waitAsync/undefined-for-timeout.js https://github.com/tc39/test262/blob/main/test/built-ins/Atomics/wait/undefined-for-timeout.js [13:00:05.0396] I guess it's just the few tests that are wrong after all. [14:31:30.0508] shu is the atomics person [15:19:22.0021] Aapo Alasuutari: It looks to me like the tests are correct except for the description comment. Note that the text you quote is also summarized in the tests (eg [here](https://github.com/tc39/test262/blob/main/test/built-ins/Atomics/wait/undefined-for-timeout.js#L11-L14)). If the last argument is undefined, the intended behaviour is to not set a timeout; that's what's being tested. [15:20:08.0348] So basically I think the only problem is that [this line](https://github.com/tc39/test262/blob/main/test/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout.js#L6) should say "Undefined timeout arg coerced to +โˆž", or maybe "Undefined timeout arg should not set timeout" 2025-11-20 [18:18:08.0875] @snek Do you mean 3600Wsยฏยนs? [18:18:16.0270] * snek: Do you mean 3600Wsยฏยนs? [18:18:37.0081] * snek: Do you mean 3600Jsยฏยนs? [18:18:43.0772] :> [23:02:02.0684] Mmyup, I indeed just had a bug in my code and got quite confused about the incorrect description comment. [23:12:58.0689] On a related note, the `INTERPRETING.md` is a little out of date, eg. broadcast doesn't take or pass two parameters but instead just takes and passes a single SharedArrayBuffer between agents. Also the document is seemingly missing a note about `setTimeout` which seems to be a requirement for a whopping three `waitAsync` tests. `atomicsHelper.js` does set up a custom `setTimeout` function if none exist in the global but that function is based on just `Promise.resolve().then(cb)`'ing recursively. That exercises the microtask queue until timeout, which means that the `Atomics.waitAsync` timeouts that the test is exercising do not get a chance to run (best as I can tell anyway). eg. Running the test in Node with the custom `setTimeout` function used unconditionally fails from a timeout. [23:43:08.0530] https://github.com/tc39/test262/pull/4692 https://github.com/tc39/test262/pull/4693 [07:15:13.0942] > <@aapo.alasuutari:matrix.org> On a related note, the `INTERPRETING.md` is a little out of date, eg. broadcast doesn't take or pass two parameters but instead just takes and passes a single SharedArrayBuffer between agents. > > Also the document is seemingly missing a note about `setTimeout` which seems to be a requirement for a whopping three `waitAsync` tests. `atomicsHelper.js` does set up a custom `setTimeout` function if none exist in the global but that function is based on just `Promise.resolve().then(cb)`'ing recursively. That exercises the microtask queue until timeout, which means that the `Atomics.waitAsync` timeouts that the test is exercising do not get a chance to run (best as I can tell anyway). eg. Running the test in Node with the custom `setTimeout` function used unconditionally fails from a timeout. > That exercises the microtask queue until timeout, which means that the Atomics.waitAsync timeouts that the test is exercising do not get a chance to run (best as I can tell anyway). Is that the correct behaviour? I would expect the event loop to interweave promise jobs with timeout jobs instead of trying to execute all pending promise jobs first [09:42:19.0985] That does sound like yes, those 3 tests do seem to rely on the host providing a event loop with a timeout event [09:50:26.0689] trying to emulate such an environment purely within 262 is naturally quite a challenge as the language does not have an event loop [09:59:15.0533] Maybe there is a way to avoid the setTimeout dependency, or mock it using a subagent + broadcast - but that might mean the test uses the API under test to test that API ๐ŸŒ€ [09:59:47.0180] * Maybe there is a way to avoid the setTimeout dependency, or mock it more faithfully using a subagent + broadcast - but that might mean the test uses the API under test to test that API ๐ŸŒ€ [13:32:11.0159] it's true that the JS spec doesn't specify anything about the ordering of promise jobs vs other kinds of jobs, but HTML does run all of the "microtasks" (which do include promise jobs) before any other kind of task [13:32:30.0511] * it's true that the JS spec doesn't specify anything about the ordering of promise jobs vs other kinds of jobs, but the HTML spec does say to run all of the "microtasks" (which include promise jobs) before any other kind of task [13:54:01.0433] Which is of itself rather difficult for anything outside of browsers to follow. It's going to be nearly impossible to get consistency with that for stuff that needs to run across multiple runtimes :-/ [13:54:30.0011] node.js, for instance, of course drains next ticks before microtasks and runs immediates and timers on an entirely separate mechanism [13:57:30.0579] leaving next ticks aside, I don't think node.js is inconsistent with the HTML spec here, because in HTML tasks are not a single queue, they're multiple task queues and it's up to the browser to decide which queue the next task comes from [13:58:58.0974] Yeah, not inconsistent, just difficult at time to ensure the timing lines up [13:59:59.0429] it's an unfortunte sad reality that there's so much code out there... particularly in tests... that rely on assuming strict ordering of timers and other tasks [14:57:33.0572] am i still needed for atomics or no, seems like confusion was resolved 2025-11-21 [08:36:34.0054] and it's actually important for some applications that microtasks _are_ higher priority than everything else (e.g., that `while (true) await null;` starves out all timers) 2025-11-23 [05:23:22.0404] > <@shuyuguo:matrix.org> am i still needed for atomics or no, seems like confusion was resolved If you have any context knowledge about what sort of abstraction level was the target of the Atomics.wait/waitAsync/notify APIs, I'd be interested in hearing: was it intended that they're a pretty high-level abstraction above OS futexes, emulating the Linux futex APIs on all platforms with built-in performance optimisations and so on? Or was it intended to rather be a low-level API, providing more of a direct access to OS futexes that just ended up defined in a way that didn't actually really make that possible?