Commit 05268bb967

David CARLIER <devnexen@gmail.com>
2023-05-13 22:25:15
std.os: implementing sched_setaffinity wrapper for freebsd
1 parent 87de821
Changed files (2)
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;
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");
     }