diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bundler/bundle_v2.zig | 2 | ||||
-rw-r--r-- | src/thread_pool.zig | 30 |
2 files changed, 32 insertions, 0 deletions
diff --git a/src/bundler/bundle_v2.zig b/src/bundler/bundle_v2.zig index 24e6f8b3c..a4ab0b486 100644 --- a/src/bundler/bundle_v2.zig +++ b/src/bundler/bundle_v2.zig @@ -167,6 +167,8 @@ pub const ThreadPool = struct { debug("{d} workers", .{cpu_count}); } + this.pool.warm(8); + this.pool.setThreadContext(this); } diff --git a/src/thread_pool.zig b/src/thread_pool.zig index 02b508673..b6e766cf9 100644 --- a/src/thread_pool.zig +++ b/src/thread_pool.zig @@ -23,6 +23,7 @@ join_event: Event = .{}, run_queue: Node.Queue = .{}, threads: Atomic(?*Thread) = Atomic(?*Thread).init(null), name: []const u8 = "", +spawned_thread_count: Atomic(u32) = Atomic(u32).init(0), const Sync = packed struct { /// Tracks the number of threads not searching for Tasks @@ -439,6 +440,35 @@ inline fn notify(self: *ThreadPool, is_waking: bool) void { return self.notifySlow(is_waking); } +/// Warm the thread pool up to the given number of threads. +/// https://www.youtube.com/watch?v=ys3qcbO5KWw +pub fn warm(self: *ThreadPool, count: u14) void { + var sync = @bitCast(Sync, self.sync.load(.Monotonic)); + if (sync.spawned >= count) + return; + + const to_spawn = @min(count - sync.spawned, @truncate(u14, self.max_threads)); + while (sync.spawned < to_spawn) { + var new_sync = sync; + new_sync.spawned += 1; + sync = @bitCast(Sync, self.sync.tryCompareAndSwap( + @bitCast(u32, sync), + @bitCast(u32, new_sync), + .Release, + .Monotonic, + ) orelse break); + const spawn_config = if (Environment.isMac) + // stack size must be a multiple of page_size + // macOS will fail to spawn a thread if the stack size is not a multiple of page_size + std.Thread.SpawnConfig{ .stack_size = ((std.Thread.SpawnConfig{}).stack_size + (std.mem.page_size / 2) / std.mem.page_size) * std.mem.page_size } + else + std.Thread.SpawnConfig{}; + + const thread = std.Thread.spawn(spawn_config, Thread.run, .{self}) catch return self.unregister(null); + thread.detach(); + } +} + noinline fn notifySlow(self: *ThreadPool, is_waking: bool) void { var sync = @bitCast(Sync, self.sync.load(.Monotonic)); while (sync.state != .shutdown) { |