Skip to content

Commit e9c098b

Browse files
authored
Merge pull request #3126 from zetwhite/posix_sched
posix : implement sched_set/getscheduler and sched_set/getparam
2 parents 2bbcf9c + 2d9867d commit e9c098b

File tree

1 file changed

+130
-3
lines changed

1 file changed

+130
-3
lines changed

vm/src/stdlib/posix.rs

Lines changed: 130 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,139 @@ pub mod module {
472472
sched_priority_repr.as_str()
473473
))
474474
}
475+
476+
#[cfg(any(
477+
target_os = "linux",
478+
target_os = "netbsd",
479+
target_os = "freebsd",
480+
target_os = "android"
481+
))]
482+
fn try_to_libc(&self, vm: &VirtualMachine) -> PyResult<libc::sched_param> {
483+
use crate::TypeProtocol;
484+
let priority = self.sched_priority.clone();
485+
let priority_type = priority.class().name();
486+
let value = priority.downcast::<int::PyInt>().map_err(|_| {
487+
vm.new_type_error(format!(
488+
"an integer is required (got type {})",
489+
priority_type
490+
))
491+
})?;
492+
let sched_priority = int::try_to_primitive(value.as_bigint(), vm)?;
493+
Ok(libc::sched_param { sched_priority })
494+
}
475495
}
476496

497+
#[derive(FromArgs)]
498+
pub struct SchedParamArg {
499+
#[pyarg(any)]
500+
sched_priority: PyObjectRef,
501+
}
477502
impl SlotConstructor for SchedParam {
478-
type Args = SchedParam;
479-
fn py_new(cls: PyTypeRef, sched_param: Self::Args, vm: &VirtualMachine) -> PyResult {
480-
sched_param.into_pyresult_with_type(vm, cls)
503+
type Args = SchedParamArg;
504+
fn py_new(cls: PyTypeRef, arg: Self::Args, vm: &VirtualMachine) -> PyResult {
505+
SchedParam {
506+
sched_priority: arg.sched_priority,
507+
}
508+
.into_pyresult_with_type(vm, cls)
509+
}
510+
}
511+
512+
#[cfg(any(
513+
target_os = "linux",
514+
target_os = "netbsd",
515+
target_os = "freebsd",
516+
target_os = "android"
517+
))]
518+
#[pyfunction]
519+
fn sched_getscheduler(pid: libc::pid_t, vm: &VirtualMachine) -> PyResult<i32> {
520+
let policy = unsafe { libc::sched_getscheduler(pid) };
521+
if policy == -1 {
522+
Err(errno_err(vm))
523+
} else {
524+
Ok(policy)
525+
}
526+
}
527+
528+
#[cfg(any(
529+
target_os = "linux",
530+
target_os = "netbsd",
531+
target_os = "freebsd",
532+
target_os = "android"
533+
))]
534+
#[derive(FromArgs)]
535+
struct SchedSetschedulerArgs {
536+
#[pyarg(positional)]
537+
pid: i32,
538+
#[pyarg(positional)]
539+
policy: i32,
540+
#[pyarg(positional)]
541+
sched_param_obj: crate::PyRef<SchedParam>,
542+
}
543+
544+
#[cfg(any(
545+
target_os = "linux",
546+
target_os = "netbsd",
547+
target_os = "freebsd",
548+
target_os = "android"
549+
))]
550+
#[pyfunction]
551+
fn sched_setscheduler(args: SchedSetschedulerArgs, vm: &VirtualMachine) -> PyResult<i32> {
552+
let libc_sched_param = args.sched_param_obj.try_to_libc(vm)?;
553+
let policy = unsafe { libc::sched_setscheduler(args.pid, args.policy, &libc_sched_param) };
554+
if policy == -1 {
555+
Err(errno_err(vm))
556+
} else {
557+
Ok(policy)
558+
}
559+
}
560+
#[cfg(any(
561+
target_os = "linux",
562+
target_os = "netbsd",
563+
target_os = "freebsd",
564+
target_os = "android"
565+
))]
566+
#[pyfunction]
567+
fn sched_getparam(pid: libc::pid_t, vm: &VirtualMachine) -> PyResult<SchedParam> {
568+
let param = unsafe {
569+
let mut param = std::mem::MaybeUninit::uninit();
570+
if -1 == libc::sched_getparam(pid, param.as_mut_ptr()) {
571+
return Err(errno_err(vm));
572+
}
573+
param.assume_init()
574+
};
575+
Ok(SchedParam {
576+
sched_priority: param.sched_priority.into_pyobject(vm),
577+
})
578+
}
579+
580+
#[cfg(any(
581+
target_os = "linux",
582+
target_os = "netbsd",
583+
target_os = "freebsd",
584+
target_os = "android"
585+
))]
586+
#[derive(FromArgs)]
587+
struct SchedSetParamArgs {
588+
#[pyarg(positional)]
589+
pid: i32,
590+
#[pyarg(positional)]
591+
sched_param_obj: crate::PyRef<SchedParam>,
592+
}
593+
594+
#[cfg(any(
595+
target_os = "linux",
596+
target_os = "netbsd",
597+
target_os = "freebsd",
598+
target_os = "android"
599+
))]
600+
#[pyfunction]
601+
fn sched_setparam(args: SchedSetParamArgs, vm: &VirtualMachine) -> PyResult<i32> {
602+
let libc_sched_param = args.sched_param_obj.try_to_libc(vm)?;
603+
let ret = unsafe { libc::sched_setparam(args.pid, &libc_sched_param) };
604+
if ret == -1 {
605+
Err(errno_err(vm))
606+
} else {
607+
Ok(ret)
481608
}
482609
}
483610

0 commit comments

Comments
 (0)