To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit b8e09a51 authored by Javad Ebrahimian Amiri's avatar Javad Ebrahimian Amiri
Browse files

less redundant code

parent edc0795b
......@@ -1989,160 +1989,6 @@ impl<'a> InstructionSelection {
}
}
/// This instruction is the same as NewThread, with one change:
/// - the `NEW_THREAD_NORMAL` entrypoint function for realtime threads (RTMu),
/// gets an additional `attr: RTAttr` argument
Instruction_::NewThreadRT {
attr,
stack,
thread_local,
is_exception,
ref args,
} => {
trace!("instsel on NEWTHREADRT");
let ref ops = inst.ops;
let res = self.get_result_value(node);
let attr = self.emit_ireg(&ops[attr], f_content, f_context, vm);
let stack = self.emit_ireg(&ops[stack], f_content, f_context, vm);
let tl = match thread_local {
Some(tl) => self.emit_ireg(&ops[tl], f_content, f_context, vm),
None => self.make_nullref(vm),
};
if is_exception {
let exc = self.emit_ireg(&ops[args[0]], f_content, f_context, vm);
self.emit_runtime_entry(
&entrypoints::NEW_THREAD_EXCEPTIONAL,
vec![attr, stack, tl, exc],
Some(vec![res]),
Some(node),
f_content,
f_context,
vm,
);
} else {
let new_sp = self.make_temporary(f_context, ADDRESS_TYPE.clone(), vm);
self.emit_load_base_offset(
&new_sp,
&stack,
*thread::MUSTACK_SP_OFFSET as i32,
vm,
);
// prepare arguments on the new stack in the generated code
// check thread::MuStack::setup_args() for how we do it in the runtime
//
// 1. the stack arguments will be put to a reserved location during
// MuStack::new(), it is from (new_sp - 2*POINTER_SIZE) to
// (new_sp - 2*POINTER_SIZE - stack_arg_size)
// 2. the register arguments will be pushed to current SP, the start
// function will consume them.
{
use compiler::backend::x86_64::callconv::swapstack;
use compiler::backend::x86_64::callconv::CallConvResult;
use compiler::backend::x86_64::{ARGUMENT_FPRS, ARGUMENT_GPRS};
let arg_values =
self.process_arguments(&args, ops, f_content, f_context, vm);
// compute call convention
let arg_tys = arg_values.iter().map(|x| x.ty.clone()).collect();
let callconv = swapstack::compute_arguments(&arg_tys);
let mut gpr_args = vec![];
let mut fpr_args = vec![];
let mut stack_args = vec![];
for i in 0..callconv.len() {
let ref arg = arg_values[i];
let ref cc = callconv[i];
match cc {
&CallConvResult::GPR(_) => gpr_args.push(arg.clone()),
&CallConvResult::GPREX(_, _) => {
let (arg_l, arg_h) =
self.split_int128(arg, f_context, vm);
gpr_args.push(arg_l);
gpr_args.push(arg_h);
}
&CallConvResult::FPR(_) => fpr_args.push(arg.clone()),
&CallConvResult::STACK => stack_args.push(arg.clone()),
}
}
// for arguments that are not used, we push a 0
let zero = self.make_int64_const(0, vm);
let mut word_pushed = 0;
for i in 0..ARGUMENT_FPRS.len() {
let val = {
if i < fpr_args.len() {
&fpr_args[i]
} else {
&zero
}
};
word_pushed += 1;
self.emit_store_base_offset(
&new_sp,
-(word_pushed * WORD_SIZE as i32),
val,
vm,
);
}
for i in 0..ARGUMENT_GPRS.len() {
let val = {
if i < gpr_args.len() {
&gpr_args[i]
} else {
&zero
}
};
word_pushed += 1;
self.emit_store_base_offset(
&new_sp,
-(word_pushed * WORD_SIZE as i32),
val,
vm,
);
}
if !stack_args.is_empty() {
// need to put stack arguments to the preserved space
self.emit_store_stack_values(
&stack_args,
Some((&new_sp, 2 * WORD_SIZE as i32)),
MU_CALL_CONVENTION,
vm,
);
}
// adjust sp - we have pushed all argument registers
// (some could be 0 though)
self.backend
.emit_sub_r_imm(&new_sp, word_pushed * WORD_SIZE as i32);
// store the sp back to MuStack
self.emit_store_base_offset(
&stack,
*thread::MUSTACK_SP_OFFSET as i32,
&new_sp,
vm,
);
// call runtime entry
self.emit_runtime_entry(
&entrypoints::NEW_THREAD_NORMAL,
vec![attr, stack, tl],
Some(vec![res.clone()]),
Some(node),
f_content,
f_context,
vm,
);
}
}
}
Instruction_::CurrentStack => {
trace!("instsel on CURRENT_STACK");
......
......@@ -44,7 +44,7 @@ impl RuntimeEntrypoint {
}
// decl: thread/mod.rs
#[cfg(not(feature = "realtime"))]
//#[cfg(not(feature = "realtime"))]
lazy_static! {
// impl: runtime_ARCH_OS.c
pub static ref GET_THREAD_LOCAL : RuntimeEntrypoint = RuntimeEntrypoint::new(
......@@ -86,41 +86,7 @@ lazy_static! {
// decl: thread/mod.rs
#[cfg(feature = "realtime")]
lazy_static! {
// impl: runtime_ARCH_OS.c
pub static ref GET_THREAD_LOCAL : RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_get_thread_local",
vec![],
vec![ADDRESS_TYPE.clone()]);
pub static ref SET_RETVAL : RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_set_retval",
vec![UINT32_TYPE.clone()],
vec![]);
pub static ref THREAD_EXIT : RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_thread_exit",
vec![ADDRESS_TYPE.clone()],
vec![]);
// impl: thread/mod.rs
pub static ref NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_stack",
vec![ADDRESS_TYPE.clone(), ADDRESS_TYPE.clone()],
vec![STACKREF_TYPE.clone()]);
pub static ref KILL_STACK: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_kill_stack",
vec![STACKREF_TYPE.clone()],
vec![]);
pub static ref SAFECALL_KILL_STACK: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_safecall_kill_stack",
vec![STACKREF_TYPE.clone()],
vec![]);
pub static ref NEW_THREAD_NORMAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_thread_normal",
vec![REF_VOID_TYPE.clone(), STACKREF_TYPE.clone(), REF_VOID_TYPE.clone()],
vec![THREADREF_TYPE.clone()]);
pub static ref NEW_THREAD_EXCEPTIONAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_thread_exceptional",
vec![REF_VOID_TYPE.clone(), STACKREF_TYPE.clone(), REF_VOID_TYPE.clone(), REF_VOID_TYPE.clone()],
vec![THREADREF_TYPE.clone()]);
;
}
// impl/decl: gc/lib.rs
......
......@@ -31,6 +31,7 @@ use libc::c_void;
#[cfg(feature = "realtime")]
use runtime::thread::thread_rtmu::RTAttr;
use runtime::thread::MuThread;
/// a list of all entrypoints used by compiler to generate calls into runtime
/// (where generated code entries the runtime)
......@@ -300,7 +301,9 @@ pub extern "C" fn mu_main(
.as_ref()
.map(|name| resolve_symbol(Arc::new(name.clone())))
.unwrap_or(unsafe { Address::zero() });
thread::MuThread::new_thread_normal(stack, threadlocal, args, vm.clone());
let muthread = thread::MuThread::new_thread_normal(stack, threadlocal, args, vm.clone());
MuThread::notify_to_run(muthread);
loop {
let thread = vm.pop_join_handle();
......
......@@ -30,7 +30,7 @@ use std;
use std::fmt;
use std::option;
use std::ptr;
use std::sync::Arc;
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
use std::thread::JoinHandle;
......@@ -337,6 +337,8 @@ pub struct MuThread {
pub rt_attr: Arc<RTAttr>,
#[cfg(feature = "realtime")]
pub sys_thread_id: MuThreadID,
#[cfg(feature = "realtime")]
pub runnable: Arc<(Mutex<bool>, Condvar)>,
}
unsafe impl Sync for MuThread {}
......@@ -407,6 +409,33 @@ pub fn check_result() -> c_int {
}
impl MuThread {
/// a `MuThread` member function which
/// causes the calling thread to wait on its own `runnable` condition variable.
/// (used to synchronise creating a thread, setting its attributes and running it)
pub fn wait_for_run(muthread: *const MuThread) {
#[cfg(feature = "realtime")]
{
let &(ref lock, ref cvar) = unsafe { &*(*muthread).runnable };
let mut ready = lock.lock().unwrap();
while !*ready {
ready = cvar.wait(ready).unwrap();
}
}
}
/// a `MuThread` member function which
/// signals the calling thread of a change in its own `runnable` condition variable.
/// (this function is used in conjunction with the `wait_for_run` function)
pub fn notify_to_run(muthread: *const MuThread) {
#[cfg(feature = "realtime")]
{
let &(ref lock, ref cvar) = unsafe { &*(*muthread).runnable };
let mut ready = lock.lock().unwrap();
*ready = true;
cvar.notify_one();
}
}
/// is current thread a Mu thread?
#[inline(always)]
pub fn has_current() -> bool {
......@@ -472,6 +501,8 @@ impl MuThread {
rt_attr: Arc::new(RTAttr::new()),
#[cfg(feature = "realtime")]
sys_thread_id: 0 as MuThreadID,
#[cfg(feature = "realtime")]
runnable: Arc::new((Mutex::new(false), Condvar::new())),
};
}
......@@ -481,12 +512,13 @@ impl MuThread {
threadlocal: Address,
vals: Vec<ValueLocation>,
vm: Arc<VM>,
) {
) -> *mut MuThread {
// set up arguments on stack
stack.setup_args(vals);
let (join_handle, _) =
let (join_handle, muthread) =
MuThread::mu_thread_launch(vm.next_id(), stack, threadlocal, None, vm.clone());
vm.push_join_handle(join_handle);
muthread
}
/// creates and launches a mu thread, returns a JoinHandle and address to its MuThread structure
......@@ -500,13 +532,8 @@ impl MuThread {
let new_sp = stack.sp;
// FIXME - not all threads need a mutator
let mut thread: Box<MuThread> = Box::new(MuThread::new(
id,
mm::new_mutator(),
stack,
user_tls,
vm,
));
let mut thread: Box<MuThread> =
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;
......@@ -525,22 +552,12 @@ impl MuThread {
let muth_ptr = Box::into_raw(muthread);
#[cfg(feature = "realtime")]
unsafe {
unsafe {
(*muth_ptr).sys_thread_id = MuThread::muthread_self();
};
let muthread = unsafe { Box::from_raw(muth_ptr) };
// apply the initial rt attributes to the sys thread
// let res = sys_thread_apply_rtattr(muthread.sys_thread_id, attr.clone());
// FIXME check for failure
// assert_eq!(
// res, MU_SUCCESS,
// "Failed to apply new thread attributes with error #{}",
// res
// );
// trace!("Apply new thread attrs result #{}", res);
let muthread = Box::into_raw(muthread);
// set thread local
unsafe { set_thread_local(muthread) };
......@@ -550,6 +567,8 @@ impl MuThread {
debug!("new sp: 0x{:x}", new_sp);
debug!("sp_store: 0x{:x}", sp_threadlocal_loc);
MuThread::wait_for_run(muthread);
unsafe {
match exception {
Some(e) => muthread_start_exceptional(e, new_sp, sp_threadlocal_loc),
......@@ -618,6 +637,8 @@ impl MuThread {
rt_attr: Arc::new(RTAttr::new()),
#[cfg(feature = "realtime")]
sys_thread_id: MuThread::muthread_self(),
#[cfg(feature = "realtime")]
runnable: Arc::new((Mutex::new(false), Condvar::new())),
});
{
let mutator_ptr = &mut fake_mu_thread.allocator as *mut mm::Mutator;
......@@ -639,7 +660,7 @@ 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();
// specific to RTMu thread attributes
#[cfg(feature = "realtime")]
......@@ -648,47 +669,47 @@ impl fmt::Display for MuThread {
"- priority @{:?}\n",
&self.rt_attr.priority as *const MuPriority
)
.unwrap();
.unwrap();
#[cfg(feature = "realtime")]
write!(
f,
"- affinity @{:?}\n",
&self.rt_attr.affinity as *const MuAffinityMask
)
.unwrap();
.unwrap();
#[cfg(feature = "realtime")]
write!(
f,
"- affinity size @{:?}\n",
&self.rt_attr.affinity_size as *const MuAffinitySize
)
.unwrap();
.unwrap();
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(())
}
......@@ -725,3 +746,40 @@ pub unsafe extern "C" fn muentry_kill_stack(stack: *mut MuStack) {
// This new box will be destroyed upon returning
Box::from_raw(stack);
}
// 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
#[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
}
......@@ -15,41 +15,3 @@
/// MU (non-real-time) specific threading stuff goes to this module
/// Currently it's empty
use super::*;
// 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
#[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
}
......@@ -100,42 +100,55 @@ impl MuThread {
}
}
// Creates a new thread
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_exceptional(
attr: *mut 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(
vm.next_id(),
Box::from_raw(stack),
thread_local,
Some(exception),
vm.clone(),
);
vm.push_join_handle(join_handle);
muthread
}
// Creates a new thread
#[no_mangle]
pub unsafe extern "C" fn muentry_new_thread_normal(
attr: *mut RTAttr,
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
}
\ No newline at end of file
//// Creates a new thread
//#[no_mangle]
//pub unsafe extern "C" fn muentry_new_thread_exceptional(
// attr: *mut 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(
// vm.next_id(),
// Box::from_raw(stack),
// thread_local,
// Some(exception),
// vm.clone(),
// );
//
// // Apply the client requested thread attributes
// MuThread::muthread_apply_rtattr(unsafe { (*muthread).sys_thread_id } , Arc::from_raw(attr));
//
// // Now the new thread is ready to run, so we notify its condition variable
// MuThread::notify_to_run(muthread);
//
// vm.push_join_handle(join_handle);
// muthread
//}
//
//// Creates a new thread
//#[no_mangle]
//pub unsafe extern "C" fn muentry_new_thread_normal(
// attr: *mut RTAttr,
// 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(),
// );
//
// // Apply the client requested thread attributes
// MuThread::muthread_apply_rtattr(unsafe { (*muthread).sys_thread_id }, Arc::from_raw(attr));
//
// // Now the new thread is ready to run, so we notify its condition variable
// MuThread::notify_to_run(muthread);
//
// vm.push_join_handle(join_handle);
// muthread
//}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment