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;...@@ -13,6 +13,10 @@ pub const ARCH = linux.ARCH;
13pub const AT = linux.AT;13pub const AT = linux.AT;
14pub const CLOCK = linux.CLOCK;14pub const CLOCK = linux.CLOCK;
15pub const CPU_COUNT = linux.CPU_COUNT;15pub 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;
16pub const E = linux.E;20pub const E = linux.E;
17pub const Elf_Symndx = linux.Elf_Symndx;21pub const Elf_Symndx = linux.Elf_Symndx;
18pub const F = linux.F;22pub const F = linux.F;
...@@ -245,6 +249,7 @@ pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_...@@ -245,6 +249,7 @@ pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_
245249
246pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;250pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
247pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;251pub 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;
248pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;253pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
249pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int;254pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int;
250pub extern "c" fn epoll_create1(flags: c_uint) c_int;255pub 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 {...@@ -5530,6 +5530,7 @@ pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
5530}5530}
55315531
5532pub const SchedGetAffinityError = error{PermissionDenied} || UnexpectedError;5532pub const SchedGetAffinityError = error{PermissionDenied} || UnexpectedError;
5533pub const SchedSetAffinityError = error{ InvalidCpu, PermissionDenied } || UnexpectedError;
55335534
5534pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {5535pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
5535 var set: cpu_set_t = undefined;5536 var set: cpu_set_t = undefined;
...@@ -5557,6 +5558,26 @@ pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {...@@ -5557,6 +5558,26 @@ pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
5557 }5558 }
5558}5559}
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
5560/// Used to convert a slice to a null terminated slice on the stack.5581/// Used to convert a slice to a null terminated slice on the stack.
5561/// TODO https://github.com/ziglang/zig/issues/2875582/// TODO https://github.com/ziglang/zig/issues/287
5562pub fn toPosixPath(file_path: []const u8) ![MAX_PATH_BYTES - 1:0]u8 {5583pub 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...@@ -1535,6 +1535,12 @@ pub fn mbind(addr: ?*anyopaque, len: u32, mode: i32, nodemask: *const u32, maxno
1535 return syscall6(.mbind, addr, len, mode, nodemask, maxnode, flags);1535 return syscall6(.mbind, addr, len, mode, nodemask, maxnode, flags);
1536}1536}
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
1538pub fn epoll_create() usize {1544pub fn epoll_create() usize {
1539 return epoll_create1(0);1545 return epoll_create1(0);
1540}1546}
...@@ -3553,6 +3559,11 @@ pub const CPU_SETSIZE = 128;...@@ -3553,6 +3559,11 @@ pub const CPU_SETSIZE = 128;
3553pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;3559pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
3554pub const cpu_count_t = std.meta.Int(.unsigned, std.math.log2(CPU_SETSIZE * 8));3560pub 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
3556pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {3567pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
3557 var sum: cpu_count_t = 0;3568 var sum: cpu_count_t = 0;
3558 for (set) |x| {3569 for (set) |x| {
...@@ -3561,6 +3572,32 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {...@@ -3561,6 +3572,32 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
3561 return sum;3572 return sum;
3562}3573}
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
3564pub const MINSIGSTKSZ = switch (native_arch) {3601pub const MINSIGSTKSZ = switch (native_arch) {
3565 .x86, .x86_64, .arm, .mipsel => 2048,3602 .x86, .x86_64, .arm, .mipsel => 2048,
3566 .aarch64 => 5120,3603 .aarch64 => 5120,