timer works now

parent ffe7295c
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)
#set(triple x86_64-pc-linux-gnu)
#set(CMAKE_C_COMPILER gcc)
#set(CMAKE_C_COMPILER_TARGET ${triple})
#set(CMAKE_CXX_COMPILER g++)
#set(CMAKE_CXX_COMPILER_TARGET ${triple})
project(cmake_zebu_runtime_helpers)
add_library(runtime_c_x64 STATIC src/runtime/runtime_c_x64_sysv.c)
add_library(runtime_asm_x64 STATIC src/runtime/runtime_asm_x64_sysv.S)
set_target_properties(runtime_asm_x64 PROPERTIES LINKER_LANGUAGE C)
add_library(runtime_c_aarch64 STATIC src/runtime/runtime_c_aarch64_sysv.c)
add_library(runtime_asm_aarch64 STATIC src/runtime/runtime_asm_aarch64_sysv.S)
set_target_properties(runtime_asm_aarch64 PROPERTIES LINKER_LANGUAGE C)
......@@ -40,23 +40,26 @@ rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version
libc="*"
field-offset = "*"
libloading = "*"
lazy_static = "0.2.11"
log = "0.3.8"
stderrlog = "0.2.3"
lazy_static = "*"
log = "*"
stderrlog = "*"
num = "*"
hprof = "*"
memmap = "*"
memsec = "0.1.9"
memsec = "*"
serde = { version = "*", features = ["derive"]}
bincode = "*"
serde_derive = "*"
time = "*"
maplit = "*"
docopt = "0.8.1"
docopt = "*"
petgraph = "*"
extprim = "*"
num-traits = "*"
built = "*"
mu_gc = { path = "src/gc"}
cfg-if = "*"
rand = "*"
\ No newline at end of file
rand = "*"
rusty-asm = "*"
timer = "*"
chrono = "*"
#!/bin/sh
export MU_ZEBU=$PWD
export ZEBU_BUILD=release
export ZEBU_BUILD=debug
export CARGO_HOME=~/.cargo
export CC=clang
export CXX=clang++
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
// 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.
fn main() {
}
\ No newline at end of file
......@@ -87,6 +87,10 @@ impl Instruction {
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NewFutex
| DeleteFutex(_)
| LockFutex(_)
| UnlockFutex(_)
| AllocAU(_)
| AllocAUHybrid(_,_)
| NewReg(_)
......@@ -104,6 +108,11 @@ impl Instruction {
| AffinityIsset(_,_)
| GetTime
| SetTime(_)
| NewTimer
| SetTimer(_,_,_,_)
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -176,12 +185,21 @@ impl Instruction {
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NewFutex
| DeleteFutex(_)
| LockFutex(_)
| UnlockFutex(_)
| NotifyThread(_)
| SetPriority(_, _)
| AffinityClear(_, _)
| AffinitySet(_, _)
// | AffinityZero(_)
| SetTime(_)
| NewTimer
| SetTimer(_,_,_,_)
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
| NewFrameCursor(_)
| Fence(_)
| Return(_)
......@@ -278,6 +296,10 @@ impl Instruction {
| eDelete(_)
| NewThread { .. }
| NewRTThread { .. }
| NewFutex
| DeleteFutex(_)
| LockFutex(_)
| UnlockFutex(_)
| NotifyThread(_)
| SetPriority(_, _)
| GetPriority(_)
......@@ -286,6 +308,11 @@ impl Instruction {
| AffinityIsset(_, _)
| GetTime
| SetTime(_)
| NewTimer
| SetTimer(_,_,_,_)
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -376,6 +403,10 @@ impl Instruction {
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NewFutex
| DeleteFutex(_)
| LockFutex(_)
| UnlockFutex(_)
| NotifyThread(_)
| SetPriority(_,_) // FIXME - Not sure about these
| GetPriority(_)
......@@ -386,6 +417,11 @@ impl Instruction {
// | AffinityZero(_)
| SetTime(_)
| GetTime
| NewTimer
| SetTimer(_,_,_,_)
| CancelTimer(_)
| DeleteTimer(_)
| Sleep(_)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -466,7 +502,11 @@ impl Instruction {
NewStack(_) |
NewThread { .. } |
NewRTThread { .. } |
NotifyThread(_) |
NewFutex
| DeleteFutex(_)
| LockFutex(_)
| UnlockFutex(_)
| NotifyThread(_) |
SetPriority(_,_) |
NewFrameCursor(_) |
GetIRef(_) |
......@@ -661,7 +701,7 @@ impl Instruction {
// ),
&Instruction_::eAlloc(ref ty) => {
format!("COMMINST @uvm.eAlloc({})", ty.id())
}
},
&Instruction_::eAllocHybrid(ref ty, var_len) => format!(
"COMMINST @uvm.eAllocHybrid({}, {})",
ty.id(),
......@@ -673,7 +713,7 @@ impl Instruction {
// ),
&Instruction_::eDelete(obj) => {
format!("COMMINST @uvm.eDelete({})", ops[obj])
}
},
// &Instruction_::eDeleteT( obj) => format!(
// "COMMINST @uvm.eDeleteT({})",
// ops[obj]
......@@ -693,7 +733,27 @@ impl Instruction {
"NEWTHREAD {}{} {}",
ops[stack], thread_local, new_stack_clause,
)
}
},
&Instruction_::NewFutex => format!("NEWFUTEX"),
&Instruction_::DeleteFutex(futexref) => {
format!(
"DELETEFUTEX {}",
ops[futexref]
)
},
&Instruction_::LockFutex(futexref) => {
format!(
"LockFUTEX {}",
ops[futexref]
)
},
&Instruction_::UnlockFutex(futexref) => {
format!(
"UNLOCKFUTEX {}",
ops[futexref]
)
},
&Instruction_::NewRTThread {
attr,
......@@ -711,11 +771,11 @@ impl Instruction {
"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]
......@@ -742,6 +802,28 @@ impl Instruction {
"COMMINST @uvm.settime({})",
ops[time]
),
&Instruction_::NewTimer => format!(
"COMMINST @uvm.newtimer"
),
&Instruction_::SetTimer(tmr, tm, func, args) => format!(
"COMMINST @uvm.settimer({}, {}, {}, {})",
ops[tmr],
ops[tm],
ops[func],
ops[args]
),
&Instruction_::CancelTimer(tmr) => format!(
"COMMINST @uvm.canceltimer({})",
ops[tmr]
),
&Instruction_::DeleteTimer(tmr) => format!(
"COMMINST @uvm.deletetimer({})",
ops[tmr]
),
&Instruction_::Sleep(dur) => format!(
"COMMINST @uvm.sleep_ns({})",
ops[dur]
),
&Instruction_::NewFrameCursor(stack) => {
format!("COMMINST @uvm.meta.new_cursor({})", ops[stack])
}
......@@ -1222,6 +1304,11 @@ pub enum Instruction_ {
args: Vec<OpIndex>
},
NewFutex,
DeleteFutex(OpIndex),
LockFutex(OpIndex),
UnlockFutex(OpIndex),
// #[cfg(feature = "realtime")]
/// notify a thread to start running
/// args: threadref for the target thread
......@@ -1262,6 +1349,12 @@ pub enum Instruction_ {
GetTime,
SetTime(OpIndex),
NewTimer,
SetTimer(OpIndex, OpIndex, OpIndex, OpIndex),
CancelTimer(OpIndex),
DeleteTimer(OpIndex),
Sleep(OpIndex),
/// create a frame cursor reference
/// args: stackref of a Mu stack
NewFrameCursor(OpIndex), // stack
......
......@@ -133,12 +133,12 @@ impl fmt::Display for MuFunction {
}
}
/// MuFunctionVersion represents a specific definition of a Mu function
/// It owns the tree structure of MuIRs for the function version
// FIXME: currently part of compilation information is also stored in this data
// structure we should move them (see Issue #18)
rodal_named!(MuFunctionVersion);
/// MuFunctionVersion represents a specific definition of a Mu function
/// It owns the tree structure of MuIRs for the function version
pub struct MuFunctionVersion {
pub hdr: MuEntityHeader,
......
// 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;
......@@ -70,6 +70,8 @@ lazy_static! {
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 FUTEXREF_TYPE: P<MuType> =
P(MuType::new(new_internal_id(), MuType_::futexref()));
}
#[cfg(not(feature = "realtime"))]
......@@ -90,6 +92,7 @@ lazy_static! {
IREF_VOID_TYPE.clone(),
STACKREF_TYPE.clone(),
THREADREF_TYPE.clone(),
FUTEXREF_TYPE.clone(),
UPTR_U8_TYPE.clone(),
UPTR_U64_TYPE.clone()
];
......@@ -130,6 +133,7 @@ lazy_static! {
RTATTR_TYPE.clone(),
UPTR_RTATTR_TYPE.clone(),
REGREF_TYPE.clone(),
FUTEXREF_TYPE.clone(),
];
}
......@@ -244,7 +248,7 @@ impl MuType {
pub fn is_opaque_reference(&self) -> bool {
match self.v {
MuType_::FuncRef(_) | MuType_::StackRef | MuType_::ThreadRef => {
MuType_::FuncRef(_) | MuType_::StackRef | MuType_::ThreadRef | MuType_::FutexRef => {
true
}
......@@ -306,6 +310,7 @@ impl MuType {
| MuType_::ThreadRef
| MuType_::StackRef
| MuType_::Tagref64
| MuType_::FutexRef
| MuType_::UPtr(_) => true,
#[cfg(feature = "realtime")]
MuType_::RTAttr
......@@ -536,7 +541,7 @@ impl MuType {
use types::MuType_::*;
match self.v {
Int(len) => Some(len),
Ref(_) | IRef(_) | WeakRef(_) | UPtr(_) | ThreadRef | StackRef
Ref(_) | IRef(_) | WeakRef(_) | UPtr(_) | ThreadRef | StackRef | FutexRef
| Tagref64 | FuncRef(_) | UFuncPtr(_) => Some(64),
#[cfg(feature = "realtime")]
......@@ -573,17 +578,17 @@ impl MuType {
}
// #[cfg(feature = "realtime")]
pub fn containsIRef(&self) -> bool {
pub fn contains_iref(&self) -> bool {
let res = match &self.v {
MuType_::IRef(_) => true,
MuType_::Array(ty, size) => ty.is_iref() && *size > 0,
MuType_::Struct(tag) => {
let structMap = STRUCT_TAG_MAP.read().unwrap();
let _struct: &StructType_ = structMap.get(tag).unwrap();
let struct_map = STRUCT_TAG_MAP.read().unwrap();
let _struct: &StructType_ = struct_map.get(tag).unwrap();
let _types = _struct.get_tys();
for _type in _types {
if _type.is_iref() || _type.containsIRef() {
if _type.is_iref() || _type.contains_iref() {
return true;
}
}
......@@ -597,12 +602,12 @@ impl MuType {
let var_ty = _hybrid.get_var_ty();
for _type in fix_tys.iter() {
if _type.is_iref() || _type.containsIRef() {
if _type.is_iref() || _type.contains_iref() {
return true;
}
}
if var_ty.is_iref() || var_ty.containsIRef() {
if var_ty.is_iref() || var_ty.contains_iref() {
return true;
}
......@@ -667,6 +672,8 @@ pub enum MuType_ {
/// ufuncptr<@sig>
UFuncPtr(P<MuFuncSig>),
FutexRef,
/// RTMu-specific
/// Real-Time Threads' attributes
#[cfg(feature = "realtime")]
......@@ -690,12 +697,12 @@ impl MuType_ {
#[cfg(not(feature = "realtime"))]
rodal_enum!(MuType_{(Int: size), Float, Double, (Ref: ty), (IRef: ty), (WeakRef: ty), (UPtr: ty),
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, StackRef, Tagref64,
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, StackRef, FutexRef, Tagref64,
(Vector: ty, size), (FuncRef: ty), (UFuncPtr: ty)});
#[cfg(feature = "realtime")]
rodal_enum!(MuType_{(Int: size), Float, Double, (Ref: ty), (IRef: ty), (WeakRef: ty), (UPtr: ty),
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, RegionRef, TimerRef, TimeVal, RTAttr, StackRef, Tagref64,
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, RegionRef, TimerRef, FutexRef, TimeVal, RTAttr, StackRef, Tagref64,
(Vector: ty, size), (FuncRef: ty), (UFuncPtr: ty)});
impl fmt::Display for MuType {
......@@ -708,7 +715,7 @@ impl fmt::Display for MuType_ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&MuType_::Int(n) => write!(f, "int<{}>", n),
&MuType_::Float => write!(f, "float"),
&MuType_::Float => write!(f,"float"),
&MuType_::Double => write!(f, "double"),
&MuType_::Ref(ref ty) => write!(f, "ref<{}>", ty),
&MuType_::IRef(ref ty) => write!(f, "iref<{}>", ty),
......@@ -719,6 +726,7 @@ impl fmt::Display for MuType_ {
}
&MuType_::Void => write!(f, "void"),
&MuType_::ThreadRef => write!(f, "threadref"),
&MuType_::FutexRef => write!(f, "futexref"),
#[cfg(feature = "realtime")]
&MuType_::RTAttr => write!(f, "rtattr"),
......@@ -901,6 +909,9 @@ impl MuType_ {
pub fn threadref() -> MuType_ {
MuType_::ThreadRef
}
pub fn futexref() -> MuType_ {
MuType_::FutexRef
}
#[cfg(feature = "realtime")]
pub fn rtattr() -> MuType_ {
......
......@@ -4103,7 +4103,7 @@ fn check_align(align: ByteSize) -> ByteSize {
/// writes alignment in bytes for linux
#[cfg(target_os = "linux")]
fn write_align(f: &mut File, align: ByteSize) {
use std::io::Write;
// use std::io::Write;
f.write_fmt(format_args!("\t.align {}\n", check_align(align)))
.unwrap();
}
......@@ -4126,7 +4126,7 @@ fn write_align(f: &mut File, align: ByteSize) {
/// writes a constant to assembly output
fn write_const(f: &mut File, constant: P<Value>, loc: P<Value>) {
use std::io::Write;
// use std::io::Write;
// label
let label = match loc.v {
......@@ -4147,7 +4147,7 @@ fn write_const(f: &mut File, constant: P<Value>, loc: P<Value>) {
/// writes a constant value based on its type and value
fn write_const_value(f: &mut File, constant: P<Value>) {
use std::io::Write;
// use std::io::Write;
let ref ty = constant.ty;
......@@ -4415,7 +4415,7 @@ pub fn emit_context_with_reloc(
// Deserializing from this is extremely slow, we need to fix this. See Issue
// #41
trace!("start serializing vm");
use rodal;
// use rodal;
// use std::time::Instant;
// let now = Instant::now();
......@@ -4462,7 +4462,7 @@ fn write_obj_header(f: &mut File, obj: &ObjectEncode) {
/// writes raw bytes from memory between from_address (inclusive) to to_address
/// (exclusive)
fn write_data_bytes(f: &mut File, from: Address, to: Address) {
use std::io::Write;
// use std::io::Write;
if from < to {
f.write("\t.byte ".as_bytes()).unwrap();
......
......@@ -1863,7 +1863,7 @@ impl<'a> InstructionSelection {
| MemoryOrder::SeqCst
| MemoryOrder::NotAtomic => {}
_ => panic!(
"unsupported ofrder {:?} for LOAD",
"unsupported order {:?} for LOAD",
order
)
}
......@@ -2127,7 +2127,7 @@ impl<'a> InstructionSelection {
// FIXME: the semantic of Pin/Unpin is different from spec
// See Issue #33
Instruction_::CommonInst_Pin(op) => {
use runtime::mm::GC_MOVES_OBJECT;
// use runtime::mm::GC_MOVES_OBJECT;
trace!("instsel on PIN");
// call pin() in GC
......@@ -2156,7 +2156,7 @@ impl<'a> InstructionSelection {
}
}
Instruction_::CommonInst_Unpin(op) => {
use runtime::mm::GC_MOVES_OBJECT;
// use runtime::mm::GC_MOVES_OBJECT;
trace!("instsel on UNPIN");
// call unpin() in GC
......@@ -2372,9 +2372,7 @@ impl<'a> InstructionSelection {
let tmp_region =
self.emit_ireg(region, f_content, f_context, vm);
let ty_info = vm.get_backend_type_info(ty.id());
if ty.containsIRef() {
if ty.contains_iref() {
let ty_id: MuID = ty.id();
let tmp_id =
self.make_int64_const(ty_id as u64, vm);
......@@ -2416,7 +2414,7 @@ impl<'a> InstructionSelection {
assert!(ty.is_hybrid());
let ty_info = vm.get_backend_type_info(ty.id());
let ty_align = ty_info.alignment;
// let ty_align = ty_info.alignment;
let fix_part_size = ty_info.size;
let var_ty_size = match ty_info.elem_size {
Some(sz) => sz,
......@@ -2434,7 +2432,7 @@ impl<'a> InstructionSelection {
self.emit_ireg(region, f_content, f_context, vm);
// if the type contains iref to heap objects
if ty.containsIRef() {
if ty.contains_iref() {
let ty_id: MuID = ty.id();
let tmp_id =
self.make_int64_const(ty_id as u64, vm);
......@@ -2506,10 +2504,10 @@ impl<'a> InstructionSelection {
trace!("instsel on eAlloc: {}", ty.print_details());
assert!(!ty.is_hybrid());
let ty_info = vm.get_backend_type_info(ty.id());
// let ty_info = vm.get_backend_type_info(ty.id());
let tmp_res = self.get_result_value(node);
if ty.containsIRef() {
if ty.contains_iref() {
let ty_id: MuID = ty.id();
let tmp_id =
self.make_int64_const(ty_id as u64, vm);
......@@ -2550,7 +2548,7 @@ impl<'a> InstructionSelection {
assert!(ty.is_hybrid());
let ty_info = vm.get_backend_type_info(ty.id());
let ty_align = ty_info.alignment;
// let ty_align = ty_info.alignment;
let fix_part_size = ty_info.size;
let var_ty_size = match ty_info.elem_size {
Some(sz) => sz,
......@@ -2564,7 +2562,7 @@ impl<'a> InstructionSelection {
let tmp_res = self.get_result_value(node);
// if the type contains iref to heap objects
if ty.containsIRef() {
if ty.contains_iref() {
let ty_id: MuID = ty.id();
let tmp_id =
self.make_int64_const(ty_id as u64, vm);
......@@ -2882,6 +2880,80 @@ impl<'a> InstructionSelection {
// vm,
// );
// }
Instruction_::NewFutex => {
trace!("instsel on NewFutex");
let res = self.get_result_value(node);
self.emit_runtime_entry(
&entrypoints::NEW_FUTEX,
vec![],
Some(vec![res]),
Some(node),
f_content,
f_context,
vm
);
}
Instruction_::DeleteFutex(futexref) => {
trace!("instsel on DeleteFutex");
let ref ops = inst.ops;
let ref futexref = ops[futexref];
let tmp_futex =
self.emit_ireg(futexref, f_content, f_context, vm);
self.emit_runtime_entry(
&entrypoints::DELETE_FUTEX,
vec![tmp_futex],
None,
Some(node),
f_content,
f_context,
vm
);
}
Instruction_::LockFutex(futexref) => {
trace!("instsel on LockFutex");
let ref ops = inst.ops;
let ref futexref = ops[futexref];
let tmp_futex =
self.emit_ireg(futexref, f_content, f_context, vm);
self.emit_runtime_entry(
&entrypoints::LOCK_FUTEX,
vec![tmp_futex],
None,
Some(node),
f_content,
f_context,
vm
);
}
Instruction_::UnlockFutex(futexref) => {
trace!("instsel on UnlockFutex");
let ref ops = inst.ops;
let ref futexref = ops[futexref];
let tmp_futex =
self.emit_ireg(futexref, f_content, f_context, vm);
self.emit_runtime_entry(
&entrypoints::UNLOCK_FUTEX,
vec![tmp_futex],
None,
Some(node),
f_content,
f_context,
vm
);
}
#[cfg(feature = "realtime")]
Instruction_::GetPriority(thread) => {
trace!("instsel on GetPriority");
......@@ -3041,6 +3113,110 @@ impl<'a> InstructionSelection {
);
}
#[cfg(feature = "realtime")]
Instruction_::NewTimer => {
trace!("instsel on NewTimer");
let res = self.get_result_value(node);
self.emit_runtime_entry(
&entrypoints::NEWTIMER,
vec![],
Some(vec![res.clone()]),
Some(node),
f_content,
f_context,
vm
);
}
#[cfg(feature = "realtime")]
Instruction_::SetTimer(tmr, tm, func, args) => {
trace!("instsel on SetTimer");
let ref ops = inst.ops;
let ref tmr = ops[tmr];