To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 9f925eb2 authored by Javad Ebrahimian Amiri's avatar Javad Ebrahimian Amiri
Browse files

Implemented and tested: RTAttr, NewRTThread, Get/SetPriority.

Plus fixing rust source code warnings
parent e226933e
......@@ -84,7 +84,15 @@ impl Instruction {
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread { .. }
| NotifyThread(_)
| NewRTThread { .. }
| NotifyThread(_) // TODO remove - not needed anymore
| SetPriority(_,_)
| GetPriority(_)
| AffinitySet(_,_)
| AffinityClear(_,_)
| AffinityEqual(_,_)
| AffinityIsset(_,_)
| AffinityZero(_)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -143,7 +151,12 @@ impl Instruction {
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_, _)
| AffinityClear(_, _)
| AffinitySet(_, _)
| AffinityZero(_)
| NewFrameCursor(_)
| Fence(_)
| Return(_)
......@@ -191,7 +204,10 @@ impl Instruction {
| CommonInst_Tr64ToTag(_)
| Move(_)
| CurrentStack
| GetVMThreadLocal => false,
| GetVMThreadLocal
| GetPriority(_)
| AffinityIsset(_, _)
| AffinityEqual(_, _) => false,
}
}
......@@ -222,7 +238,15 @@ impl Instruction {
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_, _)
| GetPriority(_)
| AffinityZero(_)
| AffinityClear(_, _)
| AffinitySet(_, _)
| AffinityEqual(_, _)
| AffinityIsset(_, _)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -296,7 +320,15 @@ impl Instruction {
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_,_) // FIXME - Not sure about these
| GetPriority(_)
| AffinityClear(_,_)
| AffinityEqual(_,_)
| AffinityIsset(_,_)
| AffinitySet(_,_)
| AffinityZero(_)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -372,7 +404,9 @@ impl Instruction {
AllocAHybrid(_, _) |
NewStack(_) |
NewThread { .. } |
NewRTThread { .. } |
NotifyThread(_) |
SetPriority(_,_) |
NewFrameCursor(_) |
GetIRef(_) |
GetFieldIRef { .. } |
......@@ -544,13 +578,54 @@ impl Instruction {
.map(|t| format!(" THREADLOCAL({})", ops[t]))
.unwrap_or("".to_string());
format!(
"NEWSTACK {}{} {}",
"NEWTHREAD {}{} {}",
ops[stack], thread_local, new_stack_clause,
)
}
&Instruction_::NewRTThread {
attr,
stack,
thread_local,
is_exception,
ref args,
} => {
let new_stack_clause = format_new_stack_clause(is_exception, args, ops);
let thread_local = thread_local
.map(|t| format!(" THREADLOCAL({})", ops[t]))
.unwrap_or("".to_string());
format!(
"NEWRTTHREAD {}, {}, {}, {}",
ops[attr], ops[stack], thread_local, new_stack_clause,
)
}
&Instruction_::NotifyThread(thread) => {
format!("COMMINST @uvm.notifythread({})", ops[thread])
}
&Instruction_::SetPriority(thread, priority) => format!(
"COMMINST @uvm.setpriority({}, {})",
ops[thread], ops[priority]
),
&Instruction_::GetPriority(thread) => {
format!("COMMINST @uvm.getpriority({})", ops[thread])
}
&Instruction_::AffinityClear(thread, cpu) => {
format!("COMMINST @uvm.affinityclear({}, {})", ops[thread], ops[cpu])
}
&Instruction_::AffinitySet(thread, cpu) => {
format!("COMMINST @uvm.affinityset({}, {})", ops[thread], ops[cpu])
}
&Instruction_::AffinityEqual(thread1, thread2) => format!(
"COMMINST @uvm.affinityequal({}, {})",
ops[thread1], ops[thread2]
),
&Instruction_::AffinityIsset(thread, cpu) => {
format!("COMMINST @uvm.affinityisset({}, {})", ops[thread], ops[cpu])
}
&Instruction_::AffinityZero(thread) => {
format!("COMMINST @uvm.affinityzero({})", ops[thread])
}
&Instruction_::NewFrameCursor(stack) => {
format!("COMMINST @uvm.meta.new_cursor({})", ops[stack])
}
......@@ -868,10 +943,7 @@ pub enum Instruction_ {
/// a non-terminating CCall instruction (the call does not have an exceptional branch)
/// This instruction is not in the Mu spec, but is documented in the HOL formal spec
ExprCCall {
data: CallData,
is_abort: bool,
},
ExprCCall { data: CallData, is_abort: bool },
/// load instruction
Load {
......@@ -934,6 +1006,7 @@ pub enum Instruction_ {
/// create a new Mu thread, yields thread reference
/// args: stackref of a Mu stack, a list of arguments
// #[cfg(not(feature = "realtime"))]
NewThread {
stack: OpIndex,
thread_local: Option<OpIndex>,
......@@ -941,8 +1014,60 @@ pub enum Instruction_ {
args: Vec<OpIndex>,
},
/// create a new Mu thread, yields thread reference
/// args: stackref of a Mu stack, a list of arguments
// #[cfg(feature = "realtime")]
NewRTThread {
attr: OpIndex,
stack: OpIndex,
thread_local: Option<OpIndex>,
is_exception: bool,
args: Vec<OpIndex>,
},
// #[cfg(feature = "realtime")]
/// notify a thread to start running
/// args: threadref for the target thread
NotifyThread(OpIndex),
/// set the priority of a target thread
/// args:
/// - threadref for the target thread
/// - the new priority value (int64)
SetPriority(OpIndex, OpIndex),
/// get the current priority of a target thread
/// args:
/// - threadref for the target thread
/// returns:
/// - an int64 representing the current priority value
GetPriority(OpIndex),
/// clear the cpu set of a thread, so that it contains not CPUs
/// args:
/// - threadref for the target thread
AffinityZero(OpIndex),
/// add a cpu to the cpu set of a thread
/// args:
/// - threadref of the target thread
/// - number of the cpu to add (e.g. #0 is the 1st cpu)
AffinitySet(OpIndex, OpIndex),
/// remove a cpu from the cpu set of a thread
/// args:
/// - threadref of the target thread
/// - number of the cpu to remove (e.g. #0 is the 1st cpu)
AffinityClear(OpIndex, OpIndex),
/// check whether a cpu is a member of the cpu set of a thread
/// args:
/// - threadref of the target thread
/// - number of the cpu to check (e.g. #0 is the 1st cpu)
AffinityIsset(OpIndex, OpIndex),
/// check whether two cpu sets contain exactly the same CPUs
/// args:
/// - threadref of the thread #1
/// - threadref of the thread #2
AffinityEqual(OpIndex, OpIndex),
/// create a frame cursor reference
/// args: stackref of a Mu stack
......@@ -974,10 +1099,7 @@ pub enum Instruction_ {
},
/// get internal reference to an element in hybrid var part
GetVarPartIRef {
is_ptr: bool,
base: OpIndex,
},
GetVarPartIRef { is_ptr: bool, base: OpIndex },
/// a fence of certain memory order
Fence(MemoryOrder),
......
......@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#[cfg(feature = "realtime")]
pub use ir_rt::*;
use inst::*;
use ptr::P;
use types::*;
......
......@@ -11,13 +11,3 @@
// 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 MuThreadID = SysThreadID;
pub type MuThreadAttr = SysThreadAttr;
pub type MuPriority = SysPriority;
pub type MuTime = SysTime;
pub type MuAffinityMask = SysAffinityMask;
pub type MuAffinitySize = SysAffinitySize;
......@@ -11,12 +11,3 @@
// 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;
......@@ -83,4 +83,4 @@ pub mod types;
pub mod ir_rt;
#[cfg(all(feature = "realtime", target_os = "linux"))]
pub mod ir_rt_linux;
pub mod ir_rt_posix;
......@@ -26,7 +26,7 @@ use std::sync::atomic::{AtomicPtr, Ordering};
use std::sync::RwLock;
// some common types that the compiler may use internally
#[cfg(not(feature = "realtime"))]
//#[cfg(not(feature = "realtime"))]
lazy_static! {
pub static ref ADDRESS_TYPE: P<MuType> = P(MuType::new(
new_internal_id(),
......@@ -57,9 +57,14 @@ lazy_static! {
new_internal_id(),
MuType_::uptr(UINT64_TYPE.clone())
));
pub static ref STACKREF_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::StackRef));
pub static ref STACKREF_TYPE: P<MuType> =
P(MuType::new(new_internal_id(), MuType_::stackref()));
pub static ref THREADREF_TYPE: P<MuType> =
P(MuType::new(new_internal_id(), MuType_::ThreadRef));
P(MuType::new(new_internal_id(), MuType_::threadref()));
}
#[cfg(not(feature = "realtime"))]
lazy_static! {
pub static ref INTERNAL_TYPES: Vec<P<MuType>> = vec![
ADDRESS_TYPE.clone(),
UINT1_TYPE.clone(),
......@@ -83,39 +88,11 @@ lazy_static! {
#[cfg(feature = "realtime")]
lazy_static! {
pub static ref ADDRESS_TYPE: P<MuType> = P(MuType::new(
pub static ref RTATTR_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::rtattr()));
pub static ref UPTR_RTATTR_TYPE: P<MuType> = P(MuType::new(
new_internal_id(),
MuType_::int(POINTER_SIZE * 8)
MuType_::uptr(RTATTR_TYPE.clone())
));
pub static ref UINT1_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::int(1)));
pub static ref UINT8_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::int(8)));
pub static ref UINT16_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::int(16)));
pub static ref UINT32_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::int(32)));
pub static ref UINT64_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::int(64)));
pub static ref UINT128_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::int(128)));
pub static ref FLOAT_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::float()));
pub static ref DOUBLE_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::double()));
pub static ref VOID_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::void()));
pub static ref REF_VOID_TYPE: P<MuType> = P(MuType::new(
new_internal_id(),
MuType_::muref(VOID_TYPE.clone())
));
pub static ref IREF_VOID_TYPE: P<MuType> = P(MuType::new(
new_internal_id(),
MuType_::iref(VOID_TYPE.clone())
));
pub static ref UPTR_U8_TYPE: P<MuType> = P(MuType::new(
new_internal_id(),
MuType_::uptr(UINT8_TYPE.clone())
));
pub static ref UPTR_U64_TYPE: P<MuType> = P(MuType::new(
new_internal_id(),
MuType_::uptr(UINT64_TYPE.clone())
));
pub static ref RTATTR_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::RTAttr));
pub static ref STACKREF_TYPE: P<MuType> = P(MuType::new(new_internal_id(), MuType_::StackRef));
pub static ref THREADREF_TYPE: P<MuType> =
P(MuType::new(new_internal_id(), MuType_::ThreadRef));
pub static ref INTERNAL_TYPES: Vec<P<MuType>> = vec![
ADDRESS_TYPE.clone(),
UINT1_TYPE.clone(),
......@@ -134,7 +111,8 @@ lazy_static! {
THREADREF_TYPE.clone(),
UPTR_U8_TYPE.clone(),
UPTR_U64_TYPE.clone(),
RTATTR_TYPE.clone()
RTATTR_TYPE.clone(),
UPTR_RTATTR_TYPE.clone()
];
}
......
......@@ -685,7 +685,18 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
// runtime call
New(_) | NewHybrid(_, _) => 10,
NewStack(_) | NewThread { .. } | NotifyThread(_) | NewFrameCursor(_) => 10,
NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_, _)
| GetPriority(_)
| AffinityEqual(_, _)
| AffinityZero(_)
| AffinityClear(_, _)
| AffinitySet(_, _)
| AffinityIsset(_, _)
| NewFrameCursor(_) => 10,
ThreadExit => 10,
CurrentStack => 10,
KillStack(_) => 10,
......
......@@ -79,7 +79,15 @@ fn is_suitable_child(inst: &Instruction) -> bool {
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_, _)
| GetPriority(_)
| AffinityIsset(_, _)
| AffinitySet(_, _)
| AffinityClear(_, _)
| AffinityZero(_)
| AffinityEqual(_, _)
| NewFrameCursor(_)
| Select { .. }
| Fence(_)
......
......@@ -13,7 +13,6 @@
// limitations under the License.
use heap::*;
use utils::*;
mod immix_mutator;
mod immix_space;
......
......@@ -35,6 +35,7 @@ extern crate num;
pub extern crate mu_ast as ast;
#[macro_use]
pub extern crate mu_utils as utils;
extern crate core;
pub extern crate mu_gc as gc;
extern crate proc_macro;
......
......@@ -73,24 +73,85 @@ lazy_static! {
"muentry_safecall_kill_stack",
vec![STACKREF_TYPE.clone()],
vec![]);
// pub static ref NEW_THREAD_NORMAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
// "muentry_new_thread_normal",
// vec![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![STACKREF_TYPE.clone(), REF_VOID_TYPE.clone(), REF_VOID_TYPE.clone()],
// vec![THREADREF_TYPE.clone()]);
}
#[cfg(not(feature = "realtime"))]
lazy_static! {
pub static ref NEW_THREAD_NORMAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_thread_normal",
vec![STACKREF_TYPE.clone(), REF_VOID_TYPE.clone()],
vec![THREADREF_TYPE.clone()]);
vec![THREADREF_TYPE.clone()]
);
pub static ref NEW_THREAD_EXCEPTIONAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_thread_exceptional",
vec![STACKREF_TYPE.clone(), REF_VOID_TYPE.clone(), REF_VOID_TYPE.clone()],
vec![THREADREF_TYPE.clone()]);
vec![
STACKREF_TYPE.clone(),
REF_VOID_TYPE.clone(),
REF_VOID_TYPE.clone()
],
vec![THREADREF_TYPE.clone()]
);
}
// decl: thread/mod.rs
#[cfg(feature = "realtime")]
lazy_static! {
pub static ref NOTIFY_THREAD: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_notify_to_run",
pub static ref NEW_RT_THREAD_NORMAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_rt_thread_normal",
vec![UPTR_RTATTR_TYPE.clone(), STACKREF_TYPE.clone(), REF_VOID_TYPE.clone()],
vec![THREADREF_TYPE.clone()]);
pub static ref NEW_RT_THREAD_EXCEPTIONAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muentry_new_rt_thread_exceptional",
vec![UPTR_RTATTR_TYPE.clone(), STACKREF_TYPE.clone(), REF_VOID_TYPE.clone(), REF_VOID_TYPE.clone()],
vec![THREADREF_TYPE.clone()]);
// pub static ref NOTIFY_THREAD: RuntimeEntrypoint = RuntimeEntrypoint::new(
// "muentry_notify_to_run",
// vec![THREADREF_TYPE.clone()],
// vec![]
// );
pub static ref SET_PRIORITY: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muthread_set_priority",
vec![THREADREF_TYPE.clone(), UINT64_TYPE.clone()],
vec![]
);
pub static ref GET_PRIORITY: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muthread_get_priority",
vec![THREADREF_TYPE.clone()],
vec![UINT64_TYPE.clone()]
);
pub static ref AFF_ZERO: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muthread_affinity_zero",
vec![THREADREF_TYPE.clone()],
vec![]
);
pub static ref AFF_CLEAR: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muthread_affinity_clear",
vec![THREADREF_TYPE.clone(), UINT64_TYPE.clone()],
vec![]
);
pub static ref AFF_SET: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muthread_affinity_set",
vec![THREADREF_TYPE.clone(), UINT64_TYPE.clone()],
vec![]
);
pub static ref AFF_ISSET: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muthread_affinity_isset",
vec![THREADREF_TYPE.clone(), UINT64_TYPE.clone()],
vec![UINT1_TYPE.clone()]
);
pub static ref AFF_EQUAL: RuntimeEntrypoint = RuntimeEntrypoint::new(
"muthread_affinity_equal",
vec![THREADREF_TYPE.clone(), THREADREF_TYPE.clone()],
vec![UINT1_TYPE.clone()]
);
}
// impl/decl: gc/lib.rs
......
......@@ -29,10 +29,6 @@ use std::sync::Arc;
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)
pub mod entrypoints;
......@@ -301,16 +297,17 @@ pub extern "C" fn mu_main(
.as_ref()
.map(|name| resolve_symbol(Arc::new(name.clone())))
.unwrap_or(unsafe { Address::zero() });
let muthread = thread::MuThread::new_thread_normal(stack, threadlocal, args, vm.clone());
MuThread::notify_to_run(muthread);
let _muthread = thread::MuThread::new_thread_normal(stack, threadlocal, args, vm.clone());
loop {
let thread = vm.pop_join_handle();
if thread.is_none() {
break;
}
thread.unwrap().join().unwrap();
unsafe {
(*thread.unwrap()).join();
};
}
info!("All threads have exited, quiting...");
......
......@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use ast::ir::*;
use ast::ptr::*;
use ast::types::*;
use runtime::mm;
......@@ -27,21 +26,24 @@ use utils::Word;
use utils::POINTER_SIZE;
use std;
pub use std::clone::Clone;
use std::fmt;
use std::option;
use std::ptr;
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
use std::thread::JoinHandle;
use std::sync::Arc;
#[cfg(unix)]
pub(self) mod thread_posix;
#[cfg(not(feature = "realtime"))]
pub(self) mod thread_mu;
#[cfg(not(feature = "realtime"))]
pub mod thread_mu;
pub(self) mod thread_mu_posix;
#[cfg(feature = "realtime")]
#[macro_use]
pub mod thread_rtmu;
pub(super) mod thread_rtmu;
#[cfg(all(feature = "realtime", target_os = "linux"))]
mod thread_rtmu_linux;
pub(self) mod thread_rtmu_linux;
#[cfg(not(feature = "realtime"))]
pub use self::thread_mu::*;
......@@ -334,12 +336,14 @@ pub struct MuThread {
/// Attributes specific to RTMu threads
#[cfg(feature = "realtime")]
pub rt_attr: Arc<RTAttr>,
#[cfg(feature = "realtime")]
pub sys_thread_id: MuThreadID,
#[cfg(feature = "realtime")]
pub runnable: Arc<(Mutex<bool>, Condvar)>,
pub rt_attr: Box<RTAttr>,
// #[cfg(feature = "realtime")]
pub sys_thread_id: SysThreadID,
pub sys_thread_context: *mut SysVoid,
// #[cfg(feature = "realtime")]
// pub runnable: Arc<(Mutex<bool>, Condvar)>,
}
rodal_named!(MuThread);
unsafe impl Sync for MuThread {}
......@@ -409,32 +413,32 @@ 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();
}
}
pub fn join(&self) {
unsafe {
sys_thread_join(self.sys_thread_id);
};
}