Skip to content

Commit 6b8f0c3

Browse files
committed
zig build: add a -j<N> option for limiting concurrency
1 parent 96d3953 commit 6b8f0c3

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

lib/build_runner.zig

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ pub fn main() !void {
8787

8888
var targets = ArrayList([]const u8).init(allocator);
8989
var debug_log_scopes = ArrayList([]const u8).init(allocator);
90+
var thread_pool_options: std.Thread.Pool.Options = .{ .allocator = allocator };
9091

9192
const stderr_stream = io.getStdErr().writer();
9293
const stdout_stream = io.getStdOut().writer();
@@ -231,6 +232,19 @@ pub fn main() !void {
231232
};
232233
} else if (mem.eql(u8, arg, "-fno-reference-trace")) {
233234
builder.reference_trace = null;
235+
} else if (mem.startsWith(u8, arg, "-j")) {
236+
const num = arg["-j".len..];
237+
const n_jobs = std.fmt.parseUnsigned(u32, num, 10) catch |err| {
238+
std.debug.print("unable to parse jobs count '{s}': {s}", .{
239+
num, @errorName(err),
240+
});
241+
process.exit(1);
242+
};
243+
if (n_jobs < 1) {
244+
std.debug.print("number of jobs must be at least 1\n", .{});
245+
process.exit(1);
246+
}
247+
thread_pool_options.n_jobs = n_jobs;
234248
} else if (mem.eql(u8, arg, "--")) {
235249
builder.args = argsRest(args, arg_idx);
236250
break;
@@ -258,7 +272,7 @@ pub fn main() !void {
258272
if (builder.validateUserInputDidItFail())
259273
usageAndErr(builder, true, stderr_stream);
260274

261-
runStepNames(builder, targets.items, main_progress_node) catch |err| {
275+
runStepNames(builder, targets.items, main_progress_node, thread_pool_options) catch |err| {
262276
switch (err) {
263277
error.UncleanExit => process.exit(1),
264278
else => return err,
@@ -270,6 +284,7 @@ fn runStepNames(
270284
b: *std.Build,
271285
step_names: []const []const u8,
272286
parent_prog_node: *std.Progress.Node,
287+
thread_pool_options: std.Thread.Pool.Options,
273288
) !void {
274289
var step_stack = ArrayList(*Step).init(b.allocator);
275290
defer step_stack.deinit();
@@ -297,7 +312,7 @@ fn runStepNames(
297312
}
298313

299314
var thread_pool: std.Thread.Pool = undefined;
300-
try thread_pool.init(b.allocator);
315+
try thread_pool.init(thread_pool_options);
301316
defer thread_pool.deinit();
302317

303318
{
@@ -523,6 +538,7 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi
523538
\\ --verbose Print commands before executing them
524539
\\ --color [auto|off|on] Enable or disable colored error messages
525540
\\ --prominent-compile-errors Output compile errors formatted for a human to read
541+
\\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
526542
\\
527543
\\Project-Specific Options:
528544
\\

lib/std/Thread/Pool.zig

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ const Runnable = struct {
1717

1818
const RunProto = *const fn (*Runnable) void;
1919

20-
pub fn init(pool: *Pool, allocator: std.mem.Allocator) !void {
20+
pub const Options = struct {
21+
allocator: std.mem.Allocator,
22+
n_jobs: ?u32 = null,
23+
};
24+
25+
pub fn init(pool: *Pool, options: Options) !void {
26+
const allocator = options.allocator;
27+
2128
pool.* = .{
2229
.allocator = allocator,
2330
.threads = &[_]std.Thread{},
@@ -27,7 +34,7 @@ pub fn init(pool: *Pool, allocator: std.mem.Allocator) !void {
2734
return;
2835
}
2936

30-
const thread_count = std.math.max(1, std.Thread.getCpuCount() catch 1);
37+
const thread_count = options.n_jobs orelse @max(1, std.Thread.getCpuCount() catch 1);
3138
pool.threads = try allocator.alloc(std.Thread, thread_count);
3239
errdefer allocator.free(pool.threads);
3340

src/main.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,7 +2951,7 @@ fn buildOutputType(
29512951
defer zig_lib_directory.handle.close();
29522952

29532953
var thread_pool: ThreadPool = undefined;
2954-
try thread_pool.init(gpa);
2954+
try thread_pool.init(.{ .allocator = gpa });
29552955
defer thread_pool.deinit();
29562956

29572957
var libc_installation: ?LibCInstallation = null;
@@ -4132,7 +4132,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
41324132
.basename = exe_basename,
41334133
};
41344134
var thread_pool: ThreadPool = undefined;
4135-
try thread_pool.init(gpa);
4135+
try thread_pool.init(.{ .allocator = gpa });
41364136
defer thread_pool.deinit();
41374137

41384138
var main_pkg: Package = .{

0 commit comments

Comments
 (0)