authorgravatar for devnexen@gmail.comDavid Carlier <devnexen@gmail.com> 2023-05-13 10:39:10+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-05-13 21:18:18+03:00
logc7bf8bab38f8b89c1371eedb9229e00a29b5ca5b
tree69ab6b3e9fb23e65432aa580e053237d49c67465
parent46527292178d64daa9f81be3eef378d78d254b5d

std.os: adding linux's sched_setaffinity and its wrapper


3 files changed, 63 insertions(+), 0 deletions(-)

lib/std/c/linux.zig+5
......@@ -13,6 +13,10 @@ pub const ARCH = linux.ARCH;
1313pub const AT = linux.AT;
1414pub const CLOCK = linux.CLOCK;
1515pub const CPU_COUNT = linux.CPU_COUNT;
16pub const CPU_SET = linux.CPU_SET;
17pub const CPU_ISSET = linux.CPU_ISSET;
18pub const CPU_CLR = linux.CPU_CLR;
19pub const CPU_ZERO = linux.CPU_ZERO;
1620pub const E = linux.E;
1721pub const Elf_Symndx = linux.Elf_Symndx;
1822pub const F = linux.F;
......@@ -245,6 +249,7 @@ pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_
245249
246250pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
247251pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
252pub extern "c" fn sched_setaffinity(pid: c_int, size: usize, set: *const cpu_set_t) c_int;
248253pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
249254pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int;
250255pub extern "c" fn epoll_create1(flags: c_uint) c_int;
lib/std/os.zig+21
......@@ -5530,6 +5530,7 @@ pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
55305530}
55315531
55325532pub const SchedGetAffinityError = error{PermissionDenied} || UnexpectedError;
5533pub const SchedSetAffinityError = error{ InvalidCpu, PermissionDenied } || UnexpectedError;
55335534
55345535pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
55355536 var set: cpu_set_t = undefined;
......@@ -5557,6 +5558,26 @@ pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
55575558 }
55585559}
55595560
5561pub fn sched_setaffinity(pid: pid_t, cpus: []usize) SchedSetAffinityError!cpu_set_t {
5562 var set: cpu_set_t = undefined;
5563 if (builtin.os.tag == .linux) {
5564 system.CPU_ZERO(&set);
5565 for (cpus) |cpu| {
5566 system.CPU_SET(cpu, &set);
5567 }
5568 switch (errno(system.sched_setaffinity(pid, @sizeOf(cpu_set_t), &set))) {
5569 .SUCCESS => return set,
5570 .FAULT => unreachable,
5571 .SRCH => unreachable,
5572 .INVAL => return error.InvalidCpu,
5573 .PERM => return error.PermissionDenied,
5574 else => |err| return unexpectedErrno(err),
5575 }
5576 } else {
5577 @compileError("unsupported platform");
5578 }
5579}
5580
55605581/// Used to convert a slice to a null terminated slice on the stack.
55615582/// TODO https://github.com/ziglang/zig/issues/287
55625583pub fn toPosixPath(file_path: []const u8) ![MAX_PATH_BYTES - 1:0]u8 {
lib/std/os/linux.zig+37
......@@ -1535,6 +1535,12 @@ pub fn mbind(addr: ?*anyopaque, len: u32, mode: i32, nodemask: *const u32, maxno
15351535 return syscall6(.mbind, addr, len, mode, nodemask, maxnode, flags);
15361536}
15371537
1538pub fn sched_setaffinity(pid: pid_t, size: usize, set: *const cpu_set_t) usize {
1539 const rc = syscall3(.sched_setaffinity, @bitCast(usize, @as(isize, pid)), size, @ptrToInt(set));
1540 if (@bitCast(isize, rc) < 0) return rc;
1541 return 0;
1542}
1543
15381544pub fn epoll_create() usize {
15391545 return epoll_create1(0);
15401546}
......@@ -3553,6 +3559,11 @@ pub const CPU_SETSIZE = 128;
35533559pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
35543560pub const cpu_count_t = std.meta.Int(.unsigned, std.math.log2(CPU_SETSIZE * 8));
35553561
3562fn cpu_mask(s: usize) cpu_count_t {
3563 var x = s & (CPU_SETSIZE * 8);
3564 return @intCast(cpu_count_t, 1) << @intCast(u4, x);
3565}
3566
35563567pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
35573568 var sum: cpu_count_t = 0;
35583569 for (set) |x| {
......@@ -3561,6 +3572,32 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
35613572 return sum;
35623573}
35633574
3575pub fn CPU_ZERO(set: *cpu_set_t) void {
3576 @memset(set, 0);
3577}
3578
3579pub fn CPU_SET(cpu: usize, set: *cpu_set_t) void {
3580 const x = cpu / @sizeOf(usize);
3581 if (x < @sizeOf(cpu_set_t)) {
3582 (set.*)[x] |= cpu_mask(x);
3583 }
3584}
3585
3586pub fn CPU_ISSET(cpu: usize, set: cpu_set_t) bool {
3587 const x = cpu / @sizeOf(usize);
3588 if (x < @sizeOf(cpu_set_t)) {
3589 return set[x] & cpu_mask(x);
3590 }
3591 return false;
3592}
3593
3594pub fn CPU_CLR(cpu: usize, set: *cpu_set_t) void {
3595 const x = cpu / @sizeOf(usize);
3596 if (x < @sizeOf(cpu_set_t)) {
3597 (set.*)[x] &= !cpu_mask(x);
3598 }
3599}
3600
35643601pub const MINSIGSTKSZ = switch (native_arch) {
35653602 .x86, .x86_64, .arm, .mipsel => 2048,
35663603 .aarch64 => 5120,