...
 
......@@ -26,6 +26,7 @@ doctest = false
default = ["aot"]
aot = []
jit = []
realtime = []
[build-dependencies]
cc = "*"
......@@ -34,7 +35,7 @@ built = "*"
[dependencies]
mu_ast = {path = "src/ast"}
mu_utils = {path = "src/utils"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version = "^0.4.0" }
libc="*"
field-offset = "*"
......
......@@ -26,5 +26,5 @@ lazy_static = "0.2.11"
log = "*"
simple_logger = "*"
regex = "0.2.2"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
#rodal = { path = "../../rodal", version = "*" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version = "^0.4.0" }
libc = "*"
\ No newline at end of file
// Copyright 2019 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#[cfg(target_os = "linux")]
pub use ir_rt_linux::*;
pub type RTMuThreadID = SysThreadID;
pub type RTMuThreadAttr = SysThreadAttr;
pub type RTMuPriority = SysPriority;
pub type RTMuTime = SysTime;
pub type RTMuAffinityMask = SysAffinityMask;
pub type RTMuAffinitySize = SysAffinitySize;
// Copyright 2019 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate libc;
pub type SysThreadID = libc::pthread_t;
pub type SysThreadAttr = libc::pthread_attr_t;
pub type SysPriority = libc::c_int;
pub type SysTime = libc::timespec;
pub type SysAffinityMask = libc::cpu_set_t;
pub type SysAffinitySize = libc::size_t;
......@@ -78,3 +78,9 @@ pub mod inst;
pub mod op;
pub mod ptr;
pub mod types;
#[cfg(feature="realtime")]
pub mod ir_rt;
#[cfg(all(feature="realtime", target_os = "linux"))]
pub mod ir_rt_linux;
\ No newline at end of file
......@@ -36,4 +36,4 @@ stderrlog = "*"
aligned_alloc = "*"
crossbeam = "0.3.0"
field-offset = "*"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version = "^0.4.0" }
......@@ -33,6 +33,9 @@ use std::sync::Arc;
use std::thread;
use std::thread::JoinHandle;
#[cfg(feature = "realtime")]
use ast::ir_rt::*;
/// a 4mb Mu stack
pub const STACK_SIZE: ByteSize = (4 << 20); // 4mb
......@@ -289,6 +292,9 @@ pub enum MuStackState {
Unknown,
}
// RTMU - add rt thread metadata to MuThread
// this includes priority, affinity, ...
/// MuThread represents metadata for a Mu thread.
/// A Mu thread in Zebu is basically an OS thread (pthread). However, we need to maintain our own
/// thread local info, such as allocator, stack, user-level thread local pointer, exception object,
......@@ -296,6 +302,7 @@ pub enum MuStackState {
/// We keep the pointer to MuThread for each thread, so that we can query our MuThread metadata.
/// The user-level thread local pointer can be found within MuThread.
/// The compiler emits code that uses offsets to some fields in this struct.
#[cfg(not(feature = "realtime"))]
#[repr(C)]
pub struct MuThread {
pub hdr: MuEntityHeader,
......@@ -313,7 +320,32 @@ pub struct MuThread {
/// a pointer to the virtual machine
pub vm: Arc<VM>,
}
#[cfg(feature = "realtime")]
#[repr(C)]
pub struct MuThread {
pub hdr: MuEntityHeader,
// the next 3 attributes are specific to realtime
pub priority: MuPriority,
pub affinity: MuAffinityMask,
pub deadline: MuTime,
/// the allocator from memory manager
pub allocator: mm::Mutator,
/// current stack (a thread can execute different stacks, but one stack at a time)
pub stack: *mut MuStack,
/// native stack pointer before we switch to this mu stack
/// (when the thread exits, we restore to native stack, and allow proper destruction)
pub native_sp_loc: Address,
/// user supplied thread local address, can be zero
pub user_tls: Address,
/// exception object being thrown by the thread
pub exception_obj: Address,
/// a pointer to the virtual machine
pub vm: Arc<VM>,
}
unsafe impl Sync for MuThread {}
unsafe impl Send for MuThread {}
// a few field offsets the compiler uses
......@@ -327,6 +359,15 @@ lazy_static! {
offset_of!(MuThread=>exception_obj).get_byte_offset();
}
#[cfg(feature = "realtime")]
macro_rules! write_rt_spec {
() => (
write!(f, "- priority @{:?}\n", &self.priority as *const MuPriority).unwrap();
write!(f, "- affinity @{:?}\n", &self.affinity as *const MuAffinityMask).unwrap();
write!(f, "- deadline @{:?}\n", &self.deadline as *const MuTime).unwrap();
)
}
impl fmt::Display for MuThread {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
......@@ -334,33 +375,37 @@ impl fmt::Display for MuThread {
"MuThread @{:?}: {}\n",
self as *const MuThread, self.hdr
)
.unwrap();
.unwrap();
write!(f, "- header @{:?}\n", &self.hdr as *const MuEntityHeader).unwrap();
#[cfg(feature = "realtime")]
write_rt_spec!();
write!(
f,
"- allocator @{:?}\n",
&self.allocator as *const mm::Mutator
)
.unwrap();
.unwrap();
write!(f, "- stack @{:?}\n", &self.stack as *const *mut MuStack).unwrap();
write!(
f,
"- native sp @{:?}: {}\n",
&self.native_sp_loc as *const Address, self.native_sp_loc
)
.unwrap();
.unwrap();
write!(
f,
"- user_tls @{:?}: {}\n",
&self.user_tls as *const Address, self.user_tls
)
.unwrap();
.unwrap();
write!(
f,
"- exc obj @{:?}: {}\n",
&self.exception_obj as *const Address, self.exception_obj
)
.unwrap();
.unwrap();
Ok(())
}
......@@ -419,6 +464,8 @@ pub fn check_result() -> c_int {
}
impl MuThread {
// RTMU - add another new_thread_normal or e.g. add new_thread_rt
/// creates a new Mu thread with normal execution
pub fn new_thread_normal(
mut stack: Box<MuStack>,
......@@ -433,6 +480,11 @@ impl MuThread {
vm.push_join_handle(join_handle);
}
// RTMU - lunching a thread needs more customizations
// instead of using the safe thread::Builder thing,
// we'll have to use libc::pthread for linux
// we'll add another mu_thread_launch for cfg rtmu feature
/// creates and launches a mu thread, returns a JoinHandle and address to its MuThread structure
fn mu_thread_launch(
id: MuID,
......@@ -483,6 +535,8 @@ impl MuThread {
)
}
// RTMU - add rt thread metadata
/// creates metadata for a Mu thread
fn new(
id: MuID,
......@@ -609,6 +663,8 @@ impl MuThread {
}
}
// RTMU - we will need to keep more info, e.g. pthread_t * & ...
/// PrimordialThreadInfo stores information about primordial thread/entry function for a boot image
#[derive(Debug)]
pub struct PrimordialThreadInfo {
......@@ -659,7 +715,29 @@ pub unsafe extern "C" fn muentry_new_thread_exceptional(
muthread
}
// RTMU - this function is emitted in machine code for NEWTHREAD,
// so it should be changed accordingly
// Creates a new thread
#[cfg(not(feature="realtime"))]
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_normal(
stack: *mut MuStack,
thread_local: Address,
) -> *mut MuThread {
let vm = MuThread::current_mut().vm.clone();
let (join_handle, muthread) = MuThread::mu_thread_launch(
vm.next_id(),
Box::from_raw(stack),
thread_local,
None,
vm.clone(),
);
vm.push_join_handle(join_handle);
muthread
}
#[cfg(feature="realtime")]
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_normal(
stack: *mut MuStack,
......@@ -676,3 +754,4 @@ pub unsafe extern "C" fn muentry_new_thread_normal(
vm.push_join_handle(join_handle);
muthread
}
......@@ -43,7 +43,7 @@ impl RuntimeEntrypoint {
}
}
// decl: thread.rs
// decl: _thread.rs
lazy_static! {
// impl: runtime_ARCH_OS.c
pub static ref GET_THREAD_LOCAL : RuntimeEntrypoint = RuntimeEntrypoint::new(
......@@ -59,7 +59,7 @@ lazy_static! {
vec![ADDRESS_TYPE.clone()],
vec![]);
// impl: thread.rs
// impl: _thread.rs
pub static ref NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_stack",
vec![ADDRESS_TYPE.clone(), ADDRESS_TYPE.clone()],
......
......@@ -125,7 +125,7 @@ pub fn resolve_symbol(symbol: MuName) -> Address {
// result
// }
// *************************************************
// This code has been moved to thread.rs \
// This code has been moved to _thread.rs \
// due to the linkage with libruntime.a happenning there once
/// ValueLocation represents the runtime location for a value.
......@@ -237,6 +237,8 @@ pub extern "C" fn mu_trace_level_log() {
#[no_mangle]
pub static mut LAST_TIME: c_ulong = 0;
// RTMU mu_main needs changes
/// the main function for executable boot image, this function will be called from C
#[no_mangle]
pub extern "C" fn mu_main(
......
This diff is collapsed.
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// MU (non-real-time) specific threading stuff goes to this module
/// Currently it's empty
use super::*;
impl MuThread {
/// creates a new Mu thread with normal execution
pub fn new_thread_normal(
mut stack: Box<MuStack>,
threadlocal: Address,
vals: Vec<ValueLocation>,
vm: Arc<VM>,
) {
// set up arguments on stack
stack.setup_args(vals);
let (join_handle, _) =
MuThread::mu_thread_launch(vm.next_id(), stack, threadlocal, None, vm.clone());
vm.push_join_handle(join_handle);
}
/// creates and launches a mu thread, returns a JoinHandle and address to its MuThread structure
fn mu_thread_launch(
id: MuID,
stack: Box<MuStack>,
user_tls: Address,
exception: Option<Address>,
vm: Arc<VM>,
) -> (JoinHandle<()>, *mut MuThread) {
let new_sp = stack.sp;
let mut thread = Box::new(MuThread::new(id, mm::new_mutator(), stack, user_tls, vm));
{
// set mutator for each allocator
let mutator_ptr = &mut thread.allocator as *mut mm::Mutator;
thread.allocator.update_mutator_ptr(mutator_ptr);
}
// we need to return the pointer, but we cannot send it to other thread
let muthread_ptr = Box::into_raw(thread);
let muthread = unsafe { Box::from_raw(muthread_ptr) };
(
match thread::Builder::new()
.name(format!("Mu Thread #{}", id))
.spawn(move || {
let muthread = Box::into_raw(muthread);
// set thread local
unsafe { set_thread_local(muthread) };
let addr = unsafe { muentry_get_thread_local() };
let sp_threadlocal_loc = addr + *NATIVE_SP_LOC_OFFSET;
debug!("new sp: 0x{:x}", new_sp);
debug!("sp_store: 0x{:x}", sp_threadlocal_loc);
unsafe {
match exception {
Some(e) => muthread_start_exceptional(e, new_sp, sp_threadlocal_loc),
None => muthread_start_normal(new_sp, sp_threadlocal_loc),
}
// Thread finished, delete it's data
Box::from_raw(muthread);
}
}) {
Ok(handle) => handle,
Err(_) => panic!("failed to create a thread"),
},
muthread_ptr,
)
}
/// creates metadata for a Mu thread
fn new(
id: MuID,
allocator: mm::Mutator,
stack: Box<MuStack>,
user_tls: Address,
vm: Arc<VM>,
) -> MuThread {
MuThread {
hdr: MuEntityHeader::unnamed(id),
allocator,
stack: Box::into_raw(stack),
native_sp_loc: unsafe { Address::zero() },
user_tls,
vm,
exception_obj: unsafe { Address::zero() },
}
}
}
// Creates a new thread
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_exceptional(
stack: *mut MuStack,
thread_local: Address,
exception: Address,
) -> *mut MuThread {
let vm = MuThread::current_mut().vm.clone();
let (join_handle, muthread) = MuThread::mu_thread_launch(
vm.next_id(),
Box::from_raw(stack),
thread_local,
Some(exception),
vm.clone(),
);
vm.push_join_handle(join_handle);
muthread
}
// Creates a new thread
#[cfg(not(feature = "realtime"))]
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_normal(
stack: *mut MuStack,
thread_local: Address,
) -> *mut MuThread {
let vm = MuThread::current_mut().vm.clone();
let (join_handle, muthread) = MuThread::mu_thread_launch(
vm.next_id(),
Box::from_raw(stack),
thread_local,
None,
vm.clone(),
);
vm.push_join_handle(join_handle);
muthread
}
// Copyright 2019 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// RTMU specific threading stuff goes here
use super::*;
pub use ast::ir_rt::*;
#[cfg(target_os = "linux")]
use super::thread_rtmu_linux::*;
pub struct RTAttr {
pub priority: RTMuPriority,
pub affinity: RTMuAffinityMask,
pub affinity_size: RTMuAffinitySize,
// pub deadline: RTMuTime, TODO add the logic and uncomment
}
impl RTAttr {
/// returns a `RTAttr` object with default attributes
pub fn new() -> RTAttr {
let mut attr = RTAttr {
priority: RTMU_DEFAULT_PRIORITY,
affinity: (),
affinity_size: RTMU_DEFAULT_AFF_SIZE,
};
sys_affinity_init(&mut attr.affinity);
attr
}
// pub fn to_rtmu_thread_attr(&self) -> RTMuThreadAttr {
// let mut attr: RTMuThreadAttr = unsafe { mem::zeroed() };
//
// let res = sys_thread_attr_init(&attr as *mut RTMuThreadAttr);
// // TODO - add error codes and error to string function
// assert_eq!(res, RTMU_SUCCESS, "Failed to initialize sys thread attr with error#{}", res);
//
// let res = sys_thread_attr_set_affinity(
// &attr as *mut RTMuThreadAttr,
// self.affinity_size,
// &self.affinity as *const RTMuAffinityMask,
// );
// assert_eq!(res, RTMU_SUCCESS, "Failed to set sys thread attr->affinity with error#{}", res);
//
// let res = sys_thread_attr_set_priority(
// attr,
// self.priority,
// );
// assert_eq!(res, RTMU_SUCCESS, "Failed to set sys thread attr->priority with error#{}", res);
//
// attr
// }
}
struct LibcThreadArg {
pub muthread: Box<T>,
pub exception: Option<Address>,
pub new_sp: Address,
}
impl MuThread {
pub fn new_thread_normal(
attr: &RTAttr,
mut stack: Box<MuStack>,
threadlocal: Address,
vals: Vec<ValueLocation>,
vm: Arc<VM>,
) {
// set up arguments on stack
stack.setup_args(vals);
let (join_handle, _) =
MuThread::mu_thread_launch(attr, vm.next_id(), stack, threadlocal, None, vm.clone());
vm.push_join_handle(join_handle);
}
/// creates and launches a mu thread, returns a JoinHandle and address to its MuThread structure
fn mu_thread_launch(
attr: &RTAttr,
id: MuID,
stack: Box<MuStack>,
user_tls: Address,
exception: Option<Address>,
vm: Arc<VM>,
) -> (JoinHandle<()>, *mut MuThread) {
let new_sp = stack.sp;
let mut thread: Box<MuThread> = Box::new(MuThread::new(attr, id, stack, user_tls, vm));
// we need to return the pointer, but we cannot send it to other thread
let muthread_ptr = Box::into_raw(thread);
let muthread = unsafe { Box::from_raw(muthread_ptr) };
(
match thread::Builder::new()
.name(format!("Mu Thread #{}", id))
.spawn(move || {
// Save the sys thread ID before starting
thread.sys_thread_id = sys_thread_self();
// apply the initial rt attributes to the sys thread
let res = sys_thread_apply_rtattr(thread.sys_thread_id, &attr);
assert_eq!(res, RTMU_SUCCESS, "Failed to apply new thread attributes with error #{}", res);
let muthread = Box::into_raw(muthread);
// set thread local
unsafe { set_thread_local(muthread) };
let addr = unsafe { muentry_get_thread_local() };
let sp_threadlocal_loc = addr + *NATIVE_SP_LOC_OFFSET;
debug!("new sp: 0x{:x}", new_sp);
debug!("sp_store: 0x{:x}", sp_threadlocal_loc);
unsafe {
match exception {
Some(e) => muthread_start_exceptional(e, new_sp, sp_threadlocal_loc),
None => muthread_start_normal(new_sp, sp_threadlocal_loc),
}
// Thread finished, delete it's data
Box::from_raw(muthread);
}
}) {
Ok(handle) => handle,
Err(_) => panic!("failed to create a thread"),
},
muthread_ptr,
)
}
/// creates metadata for a RTMu thread
/// which is Mu thread:
/// + rt_attr
/// - allocator by-default
///
fn new(
attr: RTAttr,
id: MuID,
stack: Box<MuStack>,
user_tls: Address,
vm: Arc<VM>,
) -> MuThread {
MuThread {
hdr: MuEntityHeader::unnamed(id),
allocator: None,
stack: Box::into_raw(stack),
native_sp_loc: unsafe { Address::zero() },
user_tls,
vm,
exception_obj: unsafe { Address::zero() },
rt_attr: attr,
}
}
// extern "C" fn lunch_libc_thread(
// libc_thread_args: *mut c_void,
// ) {
// let libc_thread_args = (libc_thread_args as *const c_void as *mut c_void as * mut LibcThreadArg as &mut LibcThreadArg);
// let muthread = libc_thread_args.muthread.clone();
// let exception = libc_thread_args.exception;
// let new_sp = libc_thread_args.new_sp;
//
// let muthread = Box::into_raw(muthread);
// // set thread local
// unsafe { set_thread_local(muthread) };
//
// let addr = unsafe { muentry_get_thread_local() };
// let sp_threadlocal_loc = addr + *NATIVE_SP_LOC_OFFSET;
// debug!("new sp: 0x{:x}", new_sp);
// debug!("sp_store: 0x{:x}", sp_threadlocal_loc);
//
// unsafe {
// match exception {
// Some(e) => muthread_start_exceptional(e, new_sp, sp_threadlocal_loc),
// None => muthread_start_normal(new_sp, sp_threadlocal_loc),
// }
//
// // Thread finished, delete it's data
// Box::from_raw(muthread);
// }
// }
}
// Creates a new thread
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_exceptional(
attr: &RTAttr,
stack: *mut MuStack,
thread_local: Address,
exception: Address,
) -> *mut MuThread {
let vm = MuThread::current_mut().vm.clone();
let (join_handle, muthread) = MuThread::mu_thread_launch(
attr,
vm.next_id(),
Box::from_raw(stack),
thread_local,
Some(exception),
vm.clone(),
);
vm.push_join_handle(join_handle);
muthread
}
// Creates a new thread
#[cfg(not(feature = "realtime"))]
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_normal(
attr: &RTAttr,
stack: *mut MuStack,
thread_local: Address,
) -> *mut MuThread {
let vm = MuThread::current_mut().vm.clone();
let (join_handle, muthread) = MuThread::mu_thread_launch(
attr,
vm.next_id(),
Box::from_raw(stack),
thread_local,
None,
vm.clone(),
);
vm.push_join_handle(join_handle);
muthread
}
// -
#[macro_export]
macro_rules! write_rt_attr {
() => (
write!(f, "- priority @{:?}\n", &self.rt_attr.priority as *const MuPriority).unwrap();
write!(f, "- affinity @{:?}\n", &self.rt_attr.affinity as *const MuAffinityMask).unwrap();
write!(f, "- affinity size @{:?}\n", &selfrt_attr.affinity_size as *const MuAffinitySize).unwrap();
// write!(f, "- deadline @{:?}\n", &self.deadline as *const MuTime).unwrap();
)
}
\ No newline at end of file
// Copyright 2019 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate libc;
pub use ast::ir::*;
pub use ast::ir_rt::*;
pub use ast::ir_rt_linux::*;
pub use std::os::raw::c_void;
pub use std::mem;
use runtime::thread::thread_rtmu::RTAttr;
pub type RTMuResult = libc::c_int;
pub type RTMuSchedPolicy = libc::c_int;
pub const RTMU_SUCCESS: RTMuResult = 0;
pub const RTMU_SCHED_FIFO: RTMuSchedPolicy = libc::SCHED_FIFO;
pub const RTMU_DEFAULT_PRIORITY: RTMuPriority = 50;
pub const RTMU_DEFAULT_AFF_SIZE: RTMuAffinitySize = libc::CPU_SETSIZE;
pub fn sys_thread_attr_init(
attr: *mut RTMuThreadAttr,
) -> RTMuResult {
unsafe {
libc::pthread_attr_init(attr)
}
}
pub fn sys_thread_attr_set_affinity(
attr: *mut RTMuThreadAttr,
mask_size: RTMuAffinitySize,
mask: *const RTMuAffinityMask,
) -> RTMuResult {
unsafe {
libc::pthread_attr_setaffinity_np(
attr,
mask_size,
mask,
)
}
}
pub fn sys_thread_attr_set_priority(
attr: *mut RTMuThreadAttr,
priority: RTMuPriority,
) -> RTMuResult {
let sch_param = libc::sched_param {
sched_priority: priority,
};
unsafe {
libc::pthread_attr_setschedparam(
&attr,
&sch_param as *const libc::sched_param,
)
}
}
pub fn sys_thread_apply_rtattr(
native: RTMuThreadID,
attr: *const RTAttr,
) -> RTMuResult {
let sch_param = libc::sched_param {
sched_priority: attr.priority,
};
let res: RTMuResult = unsafe { libc::pthread_setschedparam(native, RTMU_SCHED_FIFO, sch_param as *const libc::sched_param) };
if res != RTMU_SUCCESS {
res
}
let res: RTMuResult = unsafe { libc::pthread_setaffinity_np(native, attr.affinity_size, attr.affinity as *const libc::cpu_set_t) };
if res != RTMU_SUCCESS {
res
}
RTMU_SUCCESS
}
pub fn sys_thread_set_priority(
native: RTMuThreadID,
priority: RTMuPriority,
) -> RTMuResult {
let sch_param = libc::sched_param {
sched_priority: priority,
};
unsafe { libc::pthread_setschedparam(native, RTMU_SCHED_FIFO, sch_param as *const libc::sched_param) }
}
pub fn sys_thread_set_affinity(
native: RTMuThreadID,
affinity_size: RTMuAffinitySize,
affinity: RTMuAffinityMask,
) -> RTMuResult {
unsafe { libc::pthread_setaffinity_np(native, affinity_size, affinity as *const libc::cpu_set_t) }
}
pub fn sys_thread_self() -> RTMuThreadID {
unsafe { libc::pthread_self() }
}
pub fn sys_affinity_init(affinity: &mut RTMuAffinityMask) {
libc::CPU_ZERO(affinity);
}
pub fn sys_affinity_set(cpu: usize, affinity: &mut RTMuAffinityMask) {
libc::CPU_SET(cpu, affinity);
}
pub fn sys_affinity_clear(cpu: usize, affinity: &mut RTMuAffinityMask) {
libc::CPU_CLR(cpu, affinity);
}
pub fn sys_affinity_isset(cpu: usize, affinity: &mut RTMuAffinityMask) -> bool {
libc::CPU_ISSET(cpu, affinity)
}
pub fn sys_affinity_equal(affinity1: &mut RTMuAffinityMask, affinity2: &mut RTMuAffinityMask) -> bool {
libc::CPU_EQUAL(affinity1, affinity2)
}
\ No newline at end of file
......@@ -27,5 +27,4 @@ memsec = "0.1.9"
byteorder = "*"
log = "*"
doubly = "1.1.3"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
#rodal = { path = "../../rodal", version = "*" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master" , version = "^0.4.0" }