From 057b4266a4882e322cd8f581280412555e2f42bf Mon Sep 17 00:00:00 2001 From: Jordan Baczuk Date: Tue, 15 Sep 2026 14:47:42 -0600 Subject: [PATCH 1/2] build: use ucontext coroutines instead of pthreads on Linux and arm fibers ships prebuilt binaries for linux-x64 only, so every arm64 host (production Graviton nodes, the arm64 CI runners, M-series dev containers) compiles from source and lands in the CORO_PTHREAD branch of binding.gyp, where each fiber is an OS thread and each switch is a pthread condvar handoff. On the same node 18.16.1 arm64 host a run()/yield() round trip costs 12.7 us p50 with pthreads and 0.71 us with swapcontext, and the pthread build shows the same ~9x in Meteor's fiber_yield_switch_seconds histogram. glibc implements swapcontext on aarch64; the "problems getting real fibers working on arm" comment predates arm64. Linux now picks CORO_UCONTEXT on glibc and CORO_ASM on musl (upstream's conditions), and the arm/arm64 blocks select CORO_UCONTEXT explicitly. Test suite on node 18.16.1 arm64: 18/19 with ucontext (pool.js and cleanup.js now pass) versus 16/19 with pthreads; future-exception.js fails on both. Co-Authored-By: Claude Fable 5.1 --- binding.gyp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/binding.gyp b/binding.gyp index 824ce58..4709888 100644 --- a/binding.gyp +++ b/binding.gyp @@ -41,7 +41,15 @@ ['OS == "linux"', { 'cflags_c': [ '-std=gnu11' ], - 'defines': ['CORO_PTHREAD'], + 'variables': { + 'USE_MUSL': '&1 | head -n1 | grep "musl" | wc -l)', + }, + 'conditions': [ + ['<(USE_MUSL) == 1', + {'defines': ['CORO_ASM', '__MUSL__']}, + {'defines': ['CORO_UCONTEXT']} + ], + ], }, ], ['OS == "solaris" or OS == "sunos" or OS == "freebsd" or OS == "aix"', {'defines': ['CORO_UCONTEXT']}], @@ -49,16 +57,19 @@ ['OS == "openbsd"', {'defines': ['CORO_ASM']}], ['target_arch == "arm"', { - # There's been problems getting real fibers working on arm - 'defines': ['CORO_PTHREAD'], - 'defines!': ['CORO_UCONTEXT', 'CORO_SJLJ', 'CORO_ASM'], + # ucontext works on 32-bit arm with glibc; the old CORO_PTHREAD fallback made every + # fiber an OS thread and every switch a condvar handoff. + 'defines': ['CORO_UCONTEXT', '_XOPEN_SOURCE'], + 'defines!': ['CORO_PTHREAD', 'CORO_SJLJ', 'CORO_ASM'], }, ], ['target_arch == "arm64"', { - # There's been problems getting real fibers working on arm - 'defines': ['CORO_PTHREAD'], - 'defines!': ['CORO_UCONTEXT', 'CORO_SJLJ', 'CORO_ASM'], + # No prebuilt binaries ship for arm64, so production (Graviton) and arm64 CI/dev + # compile from source. CORO_PTHREAD here cost ~13 us per switch versus ~0.7 us with + # swapcontext, which glibc supports on aarch64. + 'defines': ['CORO_UCONTEXT', '_XOPEN_SOURCE'], + 'defines!': ['CORO_PTHREAD', 'CORO_SJLJ', 'CORO_ASM'], }, ], ], From 5422b70bfabb94e6edd2ffd96fd60c181a2aca70 Mon Sep 17 00:00:00 2001 From: Jordan Baczuk Date: Wed, 16 Sep 2026 11:41:04 -0600 Subject: [PATCH 2/2] chore: bump version to 5.0.6 5.0.5 is already published (@meteor/blaze depends on ^5.0.5), so the ucontext build needs a new version before it can be released. Co-Authored-By: Claude Fable 5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b286705..0139bc7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fibers", - "version": "5.0.5", + "version": "5.0.6", "description": "Cooperative multi-tasking for Javascript", "keywords": [ "fiber",