diff --git a/src/bun.js/bindings/WTF.zig b/src/bun.js/bindings/WTF.zig index 17c5661b2a..2804b9d10d 100644 --- a/src/bun.js/bindings/WTF.zig +++ b/src/bun.js/bindings/WTF.zig @@ -1,6 +1,13 @@ pub const WTF = struct { extern fn WTF__parseDouble(bytes: [*]const u8, length: usize, counted: *usize) f64; + extern fn WTF__releaseFastMallocFreeMemoryForThisThread() void; + + pub fn releaseFastMallocFreeMemoryForThisThread() void { + jsc.markBinding(@src()); + WTF__releaseFastMallocFreeMemoryForThisThread(); + } + pub fn parseDouble(buf: []const u8) !f64 { jsc.markBinding(@src()); diff --git a/src/bun.js/bindings/wtf-bindings.cpp b/src/bun.js/bindings/wtf-bindings.cpp index 0e5bfd5cc4..7d9d6fb10d 100644 --- a/src/bun.js/bindings/wtf-bindings.cpp +++ b/src/bun.js/bindings/wtf-bindings.cpp @@ -249,4 +249,10 @@ extern "C" void WTF__DumpStackTrace(void** stack, size_t stack_count) { WTFPrintBacktrace({ stack, stack_count }); } + +extern "C" void WTF__releaseFastMallocFreeMemoryForThisThread() +{ + WTF::releaseFastMallocFreeMemoryForThisThread(); +} + } diff --git a/src/threading/ThreadPool.zig b/src/threading/ThreadPool.zig index 5862ccb281..448f8dfdf3 100644 --- a/src/threading/ThreadPool.zig +++ b/src/threading/ThreadPool.zig @@ -660,6 +660,7 @@ const Event = struct { noinline fn wait(self: *Event) void { var acquire_with: u32 = EMPTY; var state = self.state.load(.monotonic); + var has_shrunk_memory: bool = false; while (true) { // If we're shutdown then exit early. @@ -699,7 +700,11 @@ const Event = struct { // Acquiring to WAITING will make the next notify() or shutdown() wake a sleeping futex thread // who will either exit on SHUTDOWN or acquire with WAITING again, ensuring all threads are awoken. // This unfortunately results in the last notify() or shutdown() doing an extra futex wake but that's fine. - Futex.wait(&self.state, WAITING, null) catch unreachable; + Futex.wait(&self.state, WAITING, if (!has_shrunk_memory) std.time.ns_per_s * 10 else null) catch { + has_shrunk_memory = true; + bun.Global.mimalloc_cleanup(false); + bun.jsc.wtf.releaseFastMallocFreeMemoryForThisThread(); + }; state = self.state.load(.monotonic); acquire_with = WAITING; }