Zig Version
0.16.0
Steps to Reproduce and Observed Behavior
const std = @import("std");
fn params_to_args(params: []const std.builtin.Type.Fn.Param) type {
var args: [params.len]type = undefined;
inline for (params, 0..) |param, i| {
args[i] = param.type.?;
}
return @Tuple(&args);
}
pub fn args_type(func: anytype) type {
return params_to_args(@typeInfo(@TypeOf(func)).@"fn".params);
}
pub fn ThreadPool(comptime func: anytype) type {
return struct {
threads: []std.Thread,
args: []args_type(func),
cursor: std.atomic.Value(usize) = .init(0),
count: std.atomic.Value(u64) = .init(0),
pub fn run(self: *@This()) !u64 {
for (0..self.threads.len) |i| {
std.debug.print("spawn: {d}\n", .{i});
self.threads[i] = try std.Thread.spawn(.{}, worker, .{self});
}
for (self.threads) |thread| {
thread.join();
}
return self.count.fetchAdd(0, .monotonic);
}
fn worker(self: *@This()) void {
while (true) {
const i = self.cursor.fetchAdd(1, .acq_rel);
if (i >= self.args.len) {
break;
}
const arg = self.args[i];
const local_count = @call(.auto, func, arg);
_ = self.count.fetchAdd(local_count, .monotonic);
}
}
};
}
test "simple_pool" {
const func = comptime struct {
fn run(n: usize, comptime even: bool) u64 {
if (even) {
if (n % 2 == 0) {
std.debug.print("hello {d}\n", .{n});
}
} else {
std.debug.print("hello {d}\n", .{n});
}
return 1;
}
}.run;
const PoolType = ThreadPool(func);
var threads: [32]std.Thread = undefined;
var args: [100]@Tuple(&.{ usize, bool }) = undefined;
for (0..100) |i| {
args[i] = .{ i, true };
}
std.debug.print("{any}\n", .{args});
var pool: PoolType = .{
.threads = &threads,
.args = &args,
};
const count = try pool.run();
std.debug.print("count: {d}\n", .{count});
}
run the test gives error:
thread_pool.zig:48:17: error: expected type 'bool', found 'type'
if (even) {
remove the comptime qualifier in fn run(n: usize, comptime even: bool) u64 and the problem resolved.
Expected Behavior
no error and print even numbers in 0..100
### Zig Version
0.16.0
### Steps to Reproduce and Observed Behavior
```
const std = @import("std");
fn params_to_args(params: []const std.builtin.Type.Fn.Param) type {
var args: [params.len]type = undefined;
inline for (params, 0..) |param, i| {
args[i] = param.type.?;
}
return @Tuple(&args);
}
pub fn args_type(func: anytype) type {
return params_to_args(@typeInfo(@TypeOf(func)).@"fn".params);
}
pub fn ThreadPool(comptime func: anytype) type {
return struct {
threads: []std.Thread,
args: []args_type(func),
cursor: std.atomic.Value(usize) = .init(0),
count: std.atomic.Value(u64) = .init(0),
pub fn run(self: *@This()) !u64 {
for (0..self.threads.len) |i| {
std.debug.print("spawn: {d}\n", .{i});
self.threads[i] = try std.Thread.spawn(.{}, worker, .{self});
}
for (self.threads) |thread| {
thread.join();
}
return self.count.fetchAdd(0, .monotonic);
}
fn worker(self: *@This()) void {
while (true) {
const i = self.cursor.fetchAdd(1, .acq_rel);
if (i >= self.args.len) {
break;
}
const arg = self.args[i];
const local_count = @call(.auto, func, arg);
_ = self.count.fetchAdd(local_count, .monotonic);
}
}
};
}
test "simple_pool" {
const func = comptime struct {
fn run(n: usize, comptime even: bool) u64 {
if (even) {
if (n % 2 == 0) {
std.debug.print("hello {d}\n", .{n});
}
} else {
std.debug.print("hello {d}\n", .{n});
}
return 1;
}
}.run;
const PoolType = ThreadPool(func);
var threads: [32]std.Thread = undefined;
var args: [100]@Tuple(&.{ usize, bool }) = undefined;
for (0..100) |i| {
args[i] = .{ i, true };
}
std.debug.print("{any}\n", .{args});
var pool: PoolType = .{
.threads = &threads,
.args = &args,
};
const count = try pool.run();
std.debug.print("count: {d}\n", .{count});
}
```
run the test gives error:
```
thread_pool.zig:48:17: error: expected type 'bool', found 'type'
if (even) {
```
remove the comptime qualifier in `fn run(n: usize, comptime even: bool) u64` and the problem resolved.
### Expected Behavior
no error and print even numbers in 0..100