diff --git a/src/header/spawn/mod.rs b/src/header/spawn/mod.rs index f44bf2d79a..10942d9a15 100644 --- a/src/header/spawn/mod.rs +++ b/src/header/spawn/mod.rs @@ -15,6 +15,7 @@ use crate::{ c_str::CStr, header::{ errno::EINVAL, + sched, signal, unistd, }, @@ -61,6 +62,8 @@ struct AttrsInner { pgroup: pid_t, sigdefault: c_ulonglong, sigmask: c_ulonglong, + schedpolicy: c_int, + sched_priority: c_int, } const ACTIONS_MAGIC: u32 = 0x53504641; // "SPFA" @@ -467,6 +470,90 @@ pub unsafe extern "C" fn posix_spawnattr_setsigdefault( 0 } +/// See . +#[unsafe(no_mangle)] +pub unsafe extern "C" fn posix_spawnattr_getschedpolicy( + attr: *const posix_spawnattr_t, + schedpolicy: *mut c_int, +) -> c_int { + if attr.is_null() || schedpolicy.is_null() { + platform::ERRNO.set(EINVAL); + return -1; + } + let inner = attrs_as_inner(attr as *mut posix_spawnattr_t); + unsafe { + if (*inner).magic != ATTRS_MAGIC { + platform::ERRNO.set(EINVAL); + return -1; + } + *schedpolicy = (*inner).schedpolicy; + } + 0 +} + +/// See . +#[unsafe(no_mangle)] +pub unsafe extern "C" fn posix_spawnattr_setschedpolicy( + attr: *mut posix_spawnattr_t, + schedpolicy: c_int, +) -> c_int { + if attr.is_null() { + platform::ERRNO.set(EINVAL); + return -1; + } + let inner = attrs_as_inner(attr); + unsafe { + if (*inner).magic != ATTRS_MAGIC { + platform::ERRNO.set(EINVAL); + return -1; + } + (*inner).schedpolicy = schedpolicy; + } + 0 +} + +/// See . +#[unsafe(no_mangle)] +pub unsafe extern "C" fn posix_spawnattr_getschedparam( + attr: *const posix_spawnattr_t, + schedparam: *mut sched::sched_param, +) -> c_int { + if attr.is_null() || schedparam.is_null() { + platform::ERRNO.set(EINVAL); + return -1; + } + let inner = attrs_as_inner(attr as *mut posix_spawnattr_t); + unsafe { + if (*inner).magic != ATTRS_MAGIC { + platform::ERRNO.set(EINVAL); + return -1; + } + (*schedparam).sched_priority = (*inner).sched_priority; + } + 0 +} + +/// See . +#[unsafe(no_mangle)] +pub unsafe extern "C" fn posix_spawnattr_setschedparam( + attr: *mut posix_spawnattr_t, + schedparam: *const sched::sched_param, +) -> c_int { + if attr.is_null() || schedparam.is_null() { + platform::ERRNO.set(EINVAL); + return -1; + } + let inner = attrs_as_inner(attr); + unsafe { + if (*inner).magic != ATTRS_MAGIC { + platform::ERRNO.set(EINVAL); + return -1; + } + (*inner).sched_priority = (*schedparam).sched_priority; + } + 0 +} + // ─── Core spawn implementation ─────────────────────────────────────────────── unsafe fn do_spawn( @@ -541,6 +628,21 @@ unsafe fn do_spawn( } } + if (flags & POSIX_SPAWN_SETSCHEDULER != 0 || flags & POSIX_SPAWN_SETSCHEDPARAM != 0) + && !attr.is_null() + { + let inner = unsafe { &*attrs_as_inner(attr as *mut _) }; + let param = sched::sched_param { + sched_priority: inner.sched_priority, + }; + if flags & POSIX_SPAWN_SETSCHEDULER != 0 { + unsafe { sched::sched_setscheduler(0, inner.schedpolicy, ¶m) }; + } + if flags & POSIX_SPAWN_SETSCHEDPARAM != 0 { + unsafe { sched::sched_setparam(0, ¶m) }; + } + } + if !actions.is_null() { let inner = actions_as_inner(actions as *mut _); let mut node = unsafe { (*inner).head };