Commit 8f5cfd09 authored by qinsoon's avatar qinsoon

simple threadlocal impl. launching thread works

parent 6efaae9b
...@@ -5,7 +5,7 @@ authors = [ "Your name <you@example.com>" ] ...@@ -5,7 +5,7 @@ authors = [ "Your name <you@example.com>" ]
build = "build.rs" build = "build.rs"
[lib] [lib]
crate-type = ["cdylib", "rlib"] crate-type = ["staticlib", "rlib"]
[build-dependencies.gcc] [build-dependencies.gcc]
git = "https://github.com/alexcrichton/gcc-rs" git = "https://github.com/alexcrichton/gcc-rs"
...@@ -23,4 +23,4 @@ rustc-serialize = "*" ...@@ -23,4 +23,4 @@ rustc-serialize = "*"
time = "0.1.34" time = "0.1.34"
aligned_alloc = "0.1.2" aligned_alloc = "0.1.2"
crossbeam = "0.2.8" crossbeam = "0.2.8"
byteorder = "0.5.3" byteorder = "0.5.3"
\ No newline at end of file
...@@ -14,6 +14,7 @@ use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; ...@@ -14,6 +14,7 @@ use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
pub type WPID = usize; pub type WPID = usize;
pub type MuID = usize; pub type MuID = usize;
pub type MuName = String; pub type MuName = String;
pub type CName = MuName;
pub type OpIndex = usize; pub type OpIndex = usize;
...@@ -203,6 +204,20 @@ impl FunctionContext { ...@@ -203,6 +204,20 @@ impl FunctionContext {
values: HashMap::new() values: HashMap::new()
} }
} }
pub fn make_temporary(&mut self, id: MuID, ty: P<MuType>) -> P<TreeNode> {
self.values.insert(id, SSAVarEntry::new(id, ty.clone()));
P(TreeNode {
hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_ssa(&ty),
v: TreeNode_::Value(P(Value{
hdr: MuEntityHeader::unnamed(id),
ty: ty,
v: Value_::SSAVar(id)
}))
})
}
pub fn get_value(&self, id: MuID) -> Option<&SSAVarEntry> { pub fn get_value(&self, id: MuID) -> Option<&SSAVarEntry> {
self.values.get(&id) self.values.get(&id)
...@@ -479,6 +494,18 @@ impl Value { ...@@ -479,6 +494,18 @@ impl Value {
_ => false _ => false
} }
} }
pub fn extract_int_const(&self) -> u64 {
match self.v {
Value_::Constant(ref c) => {
match c {
&Constant::Int(val) => val,
_ => panic!("expect int const")
}
},
_ => panic!("expect int const")
}
}
pub fn extract_ssa_id(&self) -> Option<MuID> { pub fn extract_ssa_id(&self) -> Option<MuID> {
match self.v { match self.v {
......
...@@ -323,6 +323,8 @@ macro_rules! is_type ( ...@@ -323,6 +323,8 @@ macro_rules! is_type (
) )
); );
pub type CFuncSig = MuFuncSig;
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)] #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct MuFuncSig { pub struct MuFuncSig {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
......
...@@ -844,9 +844,9 @@ impl CodeGenerator for ASMCodeGen { ...@@ -844,9 +844,9 @@ impl CodeGenerator for ASMCodeGen {
fn emit_add_r64_imm32(&mut self, dest: &P<Value>, src: u32) { fn emit_add_r64_imm32(&mut self, dest: &P<Value>, src: u32) {
trace!("emit: add {}, {} -> {}", dest, src, dest); trace!("emit: add {}, {} -> {}", dest, src, dest);
let (reg1, id1, loc1) = self.prepare_reg(dest, 4 + 1); let (reg1, id1, loc1) = self.prepare_reg(dest, 4 + 1 + 1 + src.to_string().len() + 1);
let asm = format!("addq {},${}", src, reg1); let asm = format!("addq ${},{}", src, reg1);
self.add_asm_inst( self.add_asm_inst(
asm, asm,
......
...@@ -12,12 +12,22 @@ use std::sync::RwLock; ...@@ -12,12 +12,22 @@ use std::sync::RwLock;
pub type EntryFuncSig = MuFuncSig; pub type EntryFuncSig = MuFuncSig;
pub struct RuntimeEntrypoint { pub struct RuntimeEntrypoint {
sig: P<MuFuncSig>, pub sig: P<MuFuncSig>,
aot: ValueLocation, pub aot: ValueLocation,
jit: RwLock<Option<ValueLocation>> pub jit: RwLock<Option<ValueLocation>>
} }
lazy_static! { lazy_static! {
pub static ref GET_THREAD_LOCAL : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![runtime::ADDRESS_TYPE.clone()],
arg_tys: vec![]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("get_thread_local")),
jit: RwLock::new(None),
};
pub static ref SWAP_BACK_TO_NATIVE_STACK : RuntimeEntrypoint = RuntimeEntrypoint { pub static ref SWAP_BACK_TO_NATIVE_STACK : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{ sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()), hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
......
...@@ -5,10 +5,14 @@ ...@@ -5,10 +5,14 @@
__thread void* mu_tls; __thread void* mu_tls;
void* init_thread_local(void* thread) { void set_thread_local(void* thread) {
printf("setting mu_tls to %p\n", thread);
mu_tls = thread; mu_tls = thread;
}
return &mu_tls; void* get_thread_local() {
printf("getting mu_tls as %p\n", mu_tls);
return mu_tls;
} }
void* resolve_symbol(const char* sym) { void* resolve_symbol(const char* sym) {
......
...@@ -210,12 +210,20 @@ pub struct MuThread { ...@@ -210,12 +210,20 @@ pub struct MuThread {
user_tls: Option<Address> user_tls: Option<Address>
} }
// this depends on the layout of MuThread
lazy_static! {
pub static ref NATIVE_SP_LOC_OFFSET : usize = mem::size_of::<MuEntityHeader>()
+ mem::size_of::<Box<mm::Mutator>>()
+ mem::size_of::<Option<Box<MuStack>>>();
}
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[link(name = "runtime")] #[link(name = "runtime")]
extern "C" { extern "C" {
#[allow(improper_ctypes)] #[allow(improper_ctypes)]
fn init_thread_local(thread: *mut MuThread) -> Address; fn set_thread_local(thread: *mut MuThread);
pub fn get_thread_local() -> Address;
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
...@@ -248,10 +256,15 @@ impl MuThread { ...@@ -248,10 +256,15 @@ impl MuThread {
let muthread : *mut MuThread = Box::into_raw(Box::new(MuThread::new(id, mm::new_mutator(), stack, user_tls))); let muthread : *mut MuThread = Box::into_raw(Box::new(MuThread::new(id, mm::new_mutator(), stack, user_tls)));
// set thread local // set thread local
let addr = unsafe {init_thread_local(muthread)}; unsafe {set_thread_local(muthread)};
let sp_threadlocal_loc = addr.plus(mem::size_of::<MuEntityHeader>())
.plus(mem::size_of::<Box<mm::Mutator>>()) let addr = unsafe {get_thread_local()};
.plus(mem::size_of::<Option<Box<MuStack>>>()); unsafe {get_thread_local()};
unsafe {get_thread_local()};
unsafe {get_thread_local()};
unsafe {get_thread_local()};
unsafe {get_thread_local()};
let sp_threadlocal_loc = addr.plus(*NATIVE_SP_LOC_OFFSET);
debug!("new sp: 0x{:x}", new_sp); debug!("new sp: 0x{:x}", new_sp);
debug!("sp_store: 0x{:x}", sp_threadlocal_loc); debug!("sp_store: 0x{:x}", sp_threadlocal_loc);
...@@ -259,6 +272,8 @@ impl MuThread { ...@@ -259,6 +272,8 @@ impl MuThread {
unsafe { unsafe {
swap_to_mu_stack(new_sp, entry, sp_threadlocal_loc); swap_to_mu_stack(new_sp, entry, sp_threadlocal_loc);
} }
debug!("returned to Rust stack. Going to quit");
}) { }) {
Ok(handle) => handle, Ok(handle) => handle,
Err(_) => panic!("failed to create a thread") Err(_) => panic!("failed to create a thread")
......
...@@ -19,6 +19,8 @@ use std::collections::HashMap; ...@@ -19,6 +19,8 @@ use std::collections::HashMap;
#[test] #[test]
fn test_thread_create() { fn test_thread_create() {
simple_logger::init_with_level(log::LogLevel::Trace).ok();
let vm = Arc::new(primordial_main()); let vm = Arc::new(primordial_main());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone()); let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
......
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