diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index 5fcb247af3..be0090cf66 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -18,10 +18,41 @@ fn __BIT_COUNT(bits: []const c_long) c_long { return count; } +fn __BIT_MASK(s: usize) c_long { + var x = s % CPU_SETSIZE; + return @bitCast(c_long, @intCast(c_ulong, 1) << @intCast(u6, x)); +} + pub fn CPU_COUNT(set: cpuset_t) c_int { return @intCast(c_int, __BIT_COUNT(set.__bits[0..])); } +pub fn CPU_ZERO(set: *cpuset_t) void { + @memset((set.*).__bits[0..], 0); +} + +pub fn CPU_SET(cpu: usize, set: *cpuset_t) void { + const x = cpu / @sizeOf(c_long); + if (x < @sizeOf(cpuset_t)) { + (set.*).__bits[x] |= __BIT_MASK(x); + } +} + +pub fn CPU_ISSET(cpu: usize, set: cpuset_t) void { + const x = cpu / @sizeOf(c_long); + if (x < @sizeOf(cpuset_t)) { + return set.__bits[x] & __BIT_MASK(x); + } + return false; +} + +pub fn CPU_CLR(cpu: usize, set: *cpuset_t) void { + const x = cpu / @sizeOf(c_long); + if (x < @sizeOf(cpuset_t)) { + (set.*).__bits[x] &= !__BIT_MASK(x); + } +} + pub const cpulevel_t = c_int; pub const cpuwhich_t = c_int; pub const id_t = i64; diff --git a/lib/std/os.zig b/lib/std/os.zig index 779e913230..5554e6e31a 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -5573,6 +5573,19 @@ pub fn sched_setaffinity(pid: pid_t, cpus: []usize) SchedSetAffinityError!cpu_se .PERM => return error.PermissionDenied, else => |err| return unexpectedErrno(err), } + } else if (builtin.os.tag == .freebsd) { + freebsd.CPU_ZERO(&set); + for (cpus) |cpu| { + freebsd.CPU_SET(cpu, &set); + } + switch (errno(freebsd.cpuset_setaffinity(freebsd.CPU_LEVEL_WHICH, freebsd.CPU_WHICH_PID, pid, @sizeOf(cpu_set_t), &set))) { + .SUCCESS => return set, + .FAULT => unreachable, + .SRCH => unreachable, + .INVAL => return error.InvalidCpu, + .PERM => return error.PermissionDenied, + else => |err| return unexpectedErrno(err), + } } else { @compileError("unsupported platform"); }