Going to make huge changes to the RPython annotation and rtyper

parent 6572fe39
......@@ -8,3 +8,4 @@ export RUST_TEST_THREADS=1
export RUST_BACKTRACE=1
export MU_LOG_LEVEL=trace
export LD_LIBRARY_PATH=$MU_ZEBU/target/$ZEBU_BUILD/deps/:$LD_LIBRARY_PATH
# export PYTHONPATH=mu-client-pypy
......@@ -109,7 +109,7 @@ impl Instruction {
| GetTime
| SetTime(_)
| NewTimer
| SetTimer(_,_,_,_,_)
| SetTimer { .. }
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
......@@ -213,7 +213,7 @@ impl Instruction {
// | AffinityZero(_)
| SetTime(_)
| NewTimer
| SetTimer(_,_,_,_,_)
| SetTimer { .. }
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
......@@ -343,7 +343,7 @@ impl Instruction {
| GetTime
| SetTime(_)
| NewTimer
| SetTimer(_, _, _, _, _)
| SetTimer { .. }
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
......@@ -469,7 +469,7 @@ impl Instruction {
| SetTime(_)
| GetTime
| NewTimer
| SetTimer(_,_,_,_,_)
| SetTimer { .. }
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
......@@ -861,9 +861,9 @@ impl Instruction {
format!("COMMINST @uvm.settime({})", ops[time])
}
&Instruction_::NewTimer => format!("COMMINST @uvm.newtimer"),
&Instruction_::SetTimer(tmr, tm, prd, func, args) => format!(
"COMMINST @uvm.settimer({}, {}, {}, {}, {})",
ops[tmr], ops[tm], ops[prd], ops[func], ops[args]
&Instruction_::SetTimer { tmr, tm, prd, ref data } => format!(
"COMMINST @uvm.settimer({}, {}, {}) ",
ops[tmr], ops[tm], ops[prd]
),
&Instruction_::CancelTimer(tmr) => {
format!("COMMINST @uvm.canceltimer({})", ops[tmr])
......@@ -1481,7 +1481,12 @@ pub enum Instruction_ {
SetTime(OpIndex),
NewTimer,
SetTimer(OpIndex, OpIndex, OpIndex, OpIndex, OpIndex),
SetTimer{
tmr: OpIndex,
tm: OpIndex,
prd: OpIndex,
data: CallData,
},
CancelTimer(OpIndex),
DeleteTimer(OpIndex),
Sleep(OpIndex),
......
......@@ -186,6 +186,44 @@ impl MuType {
}
}
pub fn is_threadref(&self) -> bool {
match self.v {
MuType_::ThreadRef => true,
_ => false
}
}
#[cfg(feature = "realtime")]
pub fn is_attrref(&self) -> bool {
match self.v {
MuType_::AttrRef => true,
_ => false
}
}
pub fn is_futexref(&self) -> bool {
match self.v {
MuType_::FutexRef => true,
_ => false
}
}
#[cfg(feature = "realtime")]
pub fn is_timerref(&self) -> bool {
match self.v {
MuType_::TimerRef => true,
_ => false
}
}
#[cfg(feature = "realtime")]
pub fn is_regionref(&self) -> bool {
match self.v {
MuType_::RegionRef => true,
_ => false
}
}
pub fn is_funcref(&self) -> bool {
match self.v {
MuType_::FuncRef(_) => true,
......@@ -255,14 +293,6 @@ impl MuType {
}
}
#[cfg(feature = "realtime")]
pub fn is_attrref(&self) -> bool {
match self.v {
// #[cfg(realtime)]
MuType_::AttrRef => true,
_ => false
}
}
pub fn is_eq_comparable(&self) -> bool {
self.is_int()
......
......@@ -3133,15 +3133,23 @@ impl<'a> InstructionSelection {
}
#[cfg(feature = "realtime")]
Instruction_::SetTimer(tmr, tm, prd, func, args) => {
Instruction_::SetTimer { tmr, tm, prd, ref data } => {
trace!("instsel on SetTimer");
let ref ops = inst.ops;
let ref tmr = ops[tmr];
let ref tm = ops[tm];
let ref prd = ops[prd];
let ref func = ops[func];
let ref args = ops[args];
let ref func = ops[data.func];
let ref func_sig = match func.v {
TreeNode_::Value(ref pv) => pv.ty.get_func_sig().unwrap(),
TreeNode_::Instruction(ref inst) => {
let ref funcref_val = inst.value.as_ref().unwrap()[0];
funcref_val.ty.get_func_sig().unwrap()
}
};
let tmp_tmr =
self.emit_ireg(tmr, f_content, f_context, vm);
......@@ -3151,12 +3159,29 @@ impl<'a> InstructionSelection {
self.emit_ireg(prd, f_content, f_context, vm);
let tmp_func =
self.emit_ireg(func, f_content, f_context, vm);
let tmp_args =
self.emit_ireg(args, f_content, f_context, vm);
// arguments should match the signature
assert_eq!(func_sig.arg_tys.len(), data.args.len());
let arg_values = self
.process_call_arguments(data, ops, f_content, f_context, vm);
let (stack_arg_size, arg_regs) = self.emit_precall_convention(
func_sig,
&arg_values,
data.convention,
f_context,
vm
);
assert_eq!(stack_arg_size, 0, "SetTimer args do not fit in registers");
let mut args = vec![tmp_tmr, tmp_tm, tmp_prd, tmp_func];
args.extend(arg_regs);
self.emit_runtime_entry(
&entrypoints::SETTIMER,
vec![tmp_tmr, tmp_tm, tmp_prd, tmp_func, tmp_args],
args,
None,
Some(node),
f_content,
......
......@@ -726,7 +726,7 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
| GetTime
| SetTime(_)
| NewTimer
| SetTimer(_, _, _, _, _)
| SetTimer { .. }
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
......
......@@ -104,7 +104,7 @@ fn is_suitable_child(inst: &Instruction) -> bool {
| GetTime
| SetTime(_)
| NewTimer
| SetTimer(_, _, _, _, _)
| SetTimer{ .. }
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
......
......@@ -183,6 +183,7 @@ fn link_executable_internal(
cc.arg("-ldl");
cc.arg("-lm");
cc.arg("-lrt");
cc.arg("-lz");
} else if cfg!(target_os = "macos") {
// TODO macos args need to be updated
cc.arg("-liconv");
......
// 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.
pub mod posix;
pub mod rust_std;
\ 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.
pub mod thread;
// 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 super::*;
pub use ast::ir::*;
pub use std::mem;
pub use std::os::raw::c_void;
pub use std::ptr;
pub type SysThreadID = libc::pthread_t;
pub type SysThreadAttr = libc::pthread_attr_t;
pub type SysResult = libc::c_int;
pub type SysVoid = libc::c_void;
pub const MU_SUCCESS: SysResult = 0;
pub const SYSNULL: *const i32 = ptr::null();
#[derive(Debug)]
#[repr(C)]
pub(super) struct MuThreadContext {
pub muthread: Address,
// attr: Option<AttrRef>,
pub new_sp: Address,
pub exception: Address
}
pub(super) extern "C" fn _pthread_entry_point(
_arg: *mut SysVoid
) -> *mut SysVoid {
// let muthread_ptr = _arg as *mut MuThread;
let muthread_boxed: Box<MuThread> =
unsafe { Box::from_raw(_arg as *mut MuThread) };
debug!("PTHREAD_ENTRY THREAD: {}", muthread_boxed);
// let muthread_ptr = Box::into_raw(context);
// let context = unsafe { Box::from_raw(context) };
let context = unsafe {
Box::from_raw(muthread_boxed.sys_thread_context as *mut MuThreadContext)
};
debug!("PTHREAD_ENTRY input context:{:#?}", context);
let _muthread = Box::into_raw(muthread_boxed);
let muthread_ptr: *mut MuThread = context.muthread.to_ptr_mut();
let new_sp = context.new_sp;
let exception = context.exception;
let _context = Box::into_raw(context);
let exception = {
if exception == Address::from_ptr(std::ptr::null() as *const Address) {
None
} else {
Some(exception)
}
};
// let muth_ptr = Box::into_raw(muthread);
//
// let muthread = unsafe { Box::from_raw(muth_ptr) };
// let muthread = Box::into_raw(muthread);
// let muthread = muthread as *const MuThread as *mut MuThread;
// set thread local
unsafe { set_thread_local(muthread_ptr) };
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_ptr);
}
std::ptr::null() as *const SysVoid as *mut SysVoid
}
pub(super) unsafe fn sys_thread_join(thread: SysThreadID) -> SysResult {
libc::pthread_join(
thread,
std::ptr::null() as *const c_void as *mut c_void as *mut *mut c_void
)
}
pub(super) fn sys_thread_self() -> SysThreadID {
unsafe { libc::pthread_self() }
}
// 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.
// 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.
use super::*;
use std::alloc::{alloc, dealloc, Layout};
pub type SysMemBackStore = *mut u8;
pub fn sys_get_base_addr(ptr: SysMemBackStore) -> Address {
Address::from_mut_ptr(ptr)
}
pub fn sys_new_raw_mem(size: usize) -> SysMemBackStore {
sys_allocate_by_size(size)
}
pub fn sys_delete_raw_mem(backstore: SysMemBackStore, size: usize) {
sys_delete_mem(backstore, size)
}
pub fn sys_ealloc(size: usize) -> Address {
sys_get_base_addr(sys_allocate_by_size(size))
}
pub fn sys_edelete(backstore: Address, size: usize) {
sys_delete_mem(backstore.to_ptr_mut() as *const u8 as *mut u8, size)
}
pub fn sys_get_aligned_size(size: usize, align: usize) -> usize {
if size % align == 0 {
size
} else {
size + (align - (size % align))
}
}
fn sys_allocate_by_size(size: usize) -> SysMemBackStore {
let mem_layout =
Box::new(match Layout::from_size_align(size, POINTER_SIZE) {
Ok(LO) => LO,
Err(ERR) => panic!("Allocating region failed with err: {}", ERR)
});
unsafe { alloc(*mem_layout) }
}
fn sys_delete_mem(backstore: SysMemBackStore, size: usize) {
let bbbox = unsafe { Box::from_raw(backstore) };
let mem_layout =
Box::new(match Layout::from_size_align(size, POINTER_SIZE) {
Ok(LO) => LO,
Err(ERR) => panic!("Allocating region failed with err: {}", ERR)
});
unsafe { dealloc(backstore, *mem_layout) };
let backstore = Box::into_raw(bbbox);
}
// 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.
pub mod mm;
pub mod clock;
......@@ -272,7 +272,7 @@ lazy_static! {
"muentry_set_timer",
vec![ADDRESS_TYPE.clone(), UINT64_TYPE.clone(), UINT64_TYPE.clone(), ADDRESS_TYPE.clone(), ADDRESS_TYPE.clone()],
// (timerref, timeval, ufuncptr, uptr<void>)
vec![] // returns timerref
vec![] // returns nothing
);
pub static ref CANCELTIMER: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_cancel_timer",
......
......@@ -293,7 +293,9 @@ pub extern "C" fn muentry_ralloc(regionref: Address, size: usize) -> Address {
trace!("- size: -{}", size);
let mut emmregion = unsafe { regionref.to_ptr_mut() as *mut EMMRegion };
trace!("- from region: {:?}", unsafe { &(*emmregion) });
unsafe { (*emmregion).ralloc(size) }
let res = unsafe { (*emmregion).ralloc(size) };
trace!("=== DONE RALLOC ===");
res
}
#[no_mangle]
......@@ -367,13 +369,14 @@ pub extern "C" fn muentry_ralloc_hybrid_traced(
#[no_mangle]
pub extern "C" fn muentry_ealloc(size: usize) -> Address {
trace!("=== EALLOC({}) ===", size);
let emm_backstore = Box::new(EMMBackStore::new(size, None));
let raw_ptr = Address::from_mut_ptr(emm_backstore.sysbackstore);
let bs_ptr = Address::from_mut_ptr(Box::into_raw(emm_backstore));
let mut map = EMM_MAP.write().unwrap();
map.insert(raw_ptr.as_usize(), bs_ptr.as_usize());
trace!("=== DONE EALLOC ===");
raw_ptr
}
......
......@@ -270,7 +270,8 @@ 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 For RTMu, we start the primordial thread with the default system attr
/// from C
/// For RTMu, we start the primordial thread with the default system attr
/// The client can modify this afterwards
#[no_mangle]
pub extern "C" fn mu_main(
......
......@@ -322,7 +322,7 @@ pub enum MuStackState {
/// MuThread. The compiler emits code that uses offsets to some fields in this
/// struct.
#[repr(C)]
pub struct MuThread {
pub struct MuThread {
pub hdr: MuEntityHeader,
/// the allocator from memory manager
/// Fixme, not all threads need mutator
......@@ -349,7 +349,7 @@ pub struct MuThread {
pub rt_attr: Box<RTAttr>,
// #[cfg(feature = "realtime")]
pub sys_thread_id: SysThreadID,
pub sys_thread_context: *mut SysVoid /* #[cfg(feature = "realtime")]
pub sys_thread_context: *mut MuThreadContext /* #[cfg(feature = "realtime")]
* pub runnable:
* Arc<(Mutex<bool>, Condvar)>, */
}
......@@ -438,9 +438,10 @@ pub fn check_result() -> c_int {
impl MuThread {
pub fn join(&self) {
unsafe {
sys_thread_join(self.sys_thread_id);
let res = unsafe {
sys_thread_join(self.sys_thread_id)
};
trace!("pthread_join returned: {}", res);
}
// pub fn wait_for_run(muthread: *const MuThread) {
......@@ -529,7 +530,8 @@ impl MuThread {
rt_attr: Box::new(RTAttr::new()),
// #[cfg(feature = "realtime")]
sys_thread_id: 0 as SysThreadID,
sys_thread_context: (0 as *mut SysVoid) /*
sys_thread_context: std::ptr::null_mut() as *mut MuThreadContext
/*
* #[cfg(feature =
* "realtime")]
* runnable:
......@@ -546,6 +548,7 @@ impl MuThread {
vals: Vec<ValueLocation>,
vm: Arc<VM>
) -> *mut MuThread {
trace!("new_thread_normal");
// set up arguments on stack
stack.setup_args(vals);
#[cfg(not(feature = "realtime"))]
......@@ -692,7 +695,8 @@ impl MuThread {
rt_attr: Box::new(RTAttr::new()),
// #[cfg(feature = "realtime")]
sys_thread_id: muthread_self(),
sys_thread_context: (0 as *mut SysVoid) /*
sys_thread_context: std::ptr::null_mut() as *mut MuThreadContext
/*
* #[cfg(feature =
* "realtime")]
* runnable:
......@@ -709,12 +713,11 @@ impl MuThread {
let ptr_fake_mu_thread: *mut MuThread = Box::into_raw(fake_mu_thread);
(*ptr_fake_mu_thread).sys_thread_context =
&mut MuThreadContext {
muthread: Address::from_mut_ptr(ptr_fake_mu_thread),
Box::into_raw(Box::new(MuThreadContext {
// muthread: Address::from_mut_ptr(ptr_fake_mu_thread),
new_sp: Address::from_mut_ptr((*ptr_fake_mu_thread).stack),
exception: Address::zero()
} as *const MuThreadContext as *mut MuThreadContext
as *mut SysVoid;
}));
set_thread_local(ptr_fake_mu_thread);
......@@ -744,7 +747,7 @@ impl fmt::Display for MuThread {
write!(
f,
"- affinity @{:?}\n",
&self.rt_attr.affinity as *const SysAffinityMask
self.rt_attr.affinity as *const SysAffinityMask
)
.unwrap();
#[cfg(feature = "realtime")]
......@@ -783,10 +786,12 @@ impl fmt::Display for MuThread {
.unwrap();
writeln!(f, "sys_thread_id @{}", self.sys_thread_id).unwrap();
let context: *mut MuThreadContext =
self.sys_thread_context as *mut MuThreadContext;
writeln!(f, "sys_thread_context @{:#?}", unsafe { &(*context) })
.unwrap();
let context = self.sys_thread_context;
if !context.is_null() {
writeln!(f, "sys_thread_context @{:#?}", unsafe { &(*context) })
.unwrap();
}
Ok(())
}
......
......@@ -39,8 +39,7 @@ pub unsafe fn sys_thread_launch(
exception
});
let context = Box::into_raw(context);
muthread_box.sys_thread_context =
context as *const MuThreadContext as *const SysVoid as *mut SysVoid;
muthread_box.sys_thread_context = context;
let muthread_ptr = Box::into_raw(muthread_box);
......
......@@ -34,8 +34,8 @@ pub const SYSNULL: *const i32 = ptr::null();
#[derive(Debug)]
#[repr(C)]
pub(super) struct MuThreadContext {
pub muthread: Address,
pub struct MuThreadContext {
// pub muthread: Address,
// attr: Option<RTAttr>,
pub new_sp: Address,
pub exception: Address
......@@ -45,21 +45,24 @@ pub(super) extern "C" fn _pthread_entry_point(
_arg: *mut SysVoid
) -> *mut SysVoid {
// let muthread_ptr = _arg as *mut MuThread;
let muthread_boxed: Box<MuThread> =
let mut muthread_boxed: Box<MuThread> =
unsafe { Box::from_raw(_arg as *mut MuThread) };
muthread_boxed.sys_thread_id = muthread_self();
debug!("PTHREAD_ENTRY THREAD: {}", muthread_boxed);
// let muthread_ptr = Box::into_raw(context);
// let context = unsafe { Box::from_raw(context) };
let context = unsafe {
Box::from_raw(muthread_boxed.sys_thread_context as *mut MuThreadContext)
Box::from_raw(muthread_boxed.sys_thread_context)
};
debug!("PTHREAD_ENTRY input context:{:#?}", context);
let _muthread = Box::into_raw(muthread_boxed);
let muthread_ptr = Box::into_raw(muthread_boxed);
let muthread_ptr: *mut MuThread = context.muthread.to_ptr_mut();
let new_sp = context.new_sp;
// let muthread_ptr: *mut MuThread = context.muthread.to_ptr_mut();
let new_sp = unsafe { (*(*muthread_ptr).stack).sp.clone() };
let exception = context.exception;
let _context = Box::into_raw(context);
......@@ -95,7 +98,7 @@ pub(super) extern "C" fn _pthread_entry_point(
}
// Thread finished, delete it's data
Box::from_raw(muthread_ptr);
// Box::from_raw(muthread_ptr);
}
std::ptr::null() as *const SysVoid as *mut SysVoid
......@@ -111,3 +114,21 @@ pub(super) unsafe fn sys_thread_join(thread: SysThreadID) -> SysResult {
pub(super) fn sys_thread_self() -> SysThreadID {
unsafe { libc::pthread_self() }
}
pub(super) fn sys_new_default_affinity_mask() -> SysAffinityMask {
// let def_attr: SysThreadAttr = unsafe { std::mem::zeroed() };
let mut def_aff: SysAffinityMask = unsafe { std::mem::zeroed() };
// let res = unsafe { libc::pthread_attr_init(
// &def_attr as *const SysThreadAttr as *mut SysThreadAttr
// ) };
// assert_eq!(res, MU_SUCCESS);
//
// let res = unsafe { libc::pthread_attr_getaffinity_np(&def_attr as *const libc::pthread_attr_t, libc::CPU_SETSIZE as usize, &def_aff as *const libc::cpu_set_t as *mut libc::cpu_set_t) };
// assert_eq!(res, MU_SUCCESS);
for i in 0..MAX_CPU_COUNT {
unsafe { libc::CPU_SET(i, &mut def_aff); };
}
def_aff
}
......@@ -23,10 +23,12 @@ pub type MuTime = SysTime;
#[cfg(target_os = "linux")]
pub use super::thread_rtmu_linux::*;
pub const MAX_CPU_COUNT: usize = 32;
#[repr(C)]
pub struct RTAttr {
pub priority: SysPriority,
pub affinity: SysAffinityMask,
pub affinity: *mut SysAffinityMask,
pub affinity_size: SysAffinitySize /* pub deadline: MuTime, TODO add