Skip to content

Commit

Permalink
Threading safe and unsafe (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
meloalright authored Nov 4, 2024
1 parent 23d0721 commit 4c44de9
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 53 deletions.
80 changes: 76 additions & 4 deletions .github/workflows/Threading.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,80 @@ jobs:
run: |
cargo build --features="repl" --release
- name: Threading
- name: Thread Safe (still unsafe)
run: |
./target/release/3body -V
./target/release/3body -c '给 cx 以 程心(); 给 星环公司 以 法则(name, y, limit) { 给 掩体纪年 以 y; 面壁 (掩体纪年 <= limit) { 冬眠(1000); 广播([name, 掩体纪年]); 掩体纪年 = 掩体纪年 + 1; } } cx.thread(星环公司, ["掩体工程", 0, 11]) 冬眠(5000) cx.thread(星环公司, ["研制曲率飞船", 5, 11]) 冬眠(6000)'
./target/release/3body -c '给 cx 以 程心(); 给 星环公司 以 法则(name, y, limit) { 给 掩体纪年 以 y; 面壁 (掩体纪年 <= limit) { 冬眠(1000); 广播([name, 掩体纪年]); 掩体纪年 = 掩体纪年 + 1; } } 给 秘密研究 以 cx.thread(星环公司, ["重启光速飞船的研究", 11, 66]) cx.join(秘密研究)'
./target/release/3body -c '
给 cx 以 程心();
给 掩体工程进展 以 0;
给 研制曲率飞船进展 以 0;
cx.thread(法则() {
给 掩体纪年 以 0;
面壁 (掩体纪年 <= 11) {
冬眠(1000);
广播(["掩体工程进展", 掩体工程进展]);
掩体工程进展 = 掩体工程进展 + 1;
掩体纪年 = 掩体纪年 + 1;
}
}, [])
冬眠(5000)
cx.thread(法则() {
给 掩体纪年 以 5;
面壁 (掩体纪年 <= 11) {
冬眠(1000);
广播(["研制曲率飞船进展", 研制曲率飞船进展]);
研制曲率飞船进展 = 研制曲率飞船进展 + 1;
掩体纪年 = 掩体纪年 + 1;
}
}, [])
冬眠(6000)'
./target/release/3body -c '
给 cx 以 程心();
给 星环公司 以 法则(name, y, limit) {
给 掩体纪年 以 y;
面壁 (掩体纪年 <= limit) {
冬眠(1000);
广播([name, 掩体纪年]);
掩体纪年 = 掩体纪年 + 1;
}
}
给 秘密研究 以 cx.thread(星环公司, ["重启光速飞船的研究", 11, 66])
cx.join(秘密研究)'
- name: Thread Unsafe
run: |
./target/release/3body -c '
给 cx 以 程心();
给 总进展 以 0;
cx.thread(法则() {
给 掩体纪年 以 0;
面壁 (掩体纪年 <= 11) {
冬眠(1000);
广播(["总进展", 总进展]);
总进展 = 总进展 + 1; // unsafe
掩体纪年 = 掩体纪年 + 1;
}
}, [])
冬眠(5000)
cx.thread(法则() {
给 掩体纪年 以 5;
面壁 (掩体纪年 <= 11) {
冬眠(1000);
广播(["总进展", 总进展]);
总进展 = 总进展 + 1; // unsafe
掩体纪年 = 掩体纪年 + 1;
}
}, [])
冬眠(6000)
广播([总进展])'
80 changes: 31 additions & 49 deletions interpreter/src/evaluator/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,66 +351,48 @@ fn three_body_sophon_engineering(args: Vec<Object>) -> Object {


#[cfg(feature="threading")]
fn three_body_threading(args: Vec<Object>) -> Object {
fn three_body_threading(_: Vec<Object>) -> Object {
let mut session_hash = HashMap::new();
{
fn three_body_thread_new(args: Vec<Object>) -> Object {
match &args[0] {
Object::Function(params, ast, env ) => {

let stmts = ast.clone();
let params = params.clone();

let literals: Vec<crate::ast::Literal> = match &args[1] {
Object::Array(arr) => {
arr.iter().map(|o| match o {
Object::Int(i) => ast::Literal::Int(i.clone()),
Object::String(str) => ast::Literal::String(str.clone()),
Object::Bool(bool) => ast::Literal::Bool(bool.clone()),
_ => todo!(),
}).collect()
},
_ => panic!()
};

let mut handle = std::thread::spawn(move || {
let local_set = tokio::task::LocalSet::new();
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();

local_set.spawn_local(async move {
let handle = std::thread::spawn(|| {
let local_set = tokio::task::LocalSet::new();
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();

local_set.spawn_local(async move {
match &args[0] {
Object::Function(params, stmts, env ) => {
let mut ev = Evaluator {
env: {
let scoped_env = Rc::new(RefCell::new(Env::from(new_builtins())));

for (i, ident) in params.iter().enumerate() {
let crate::ast::Ident(name) = ident.clone();
let o = match &literals[i] {
ast::Literal::Int(i) => Object::Int(i.clone()),
ast::Literal::String(str) => Object::String(str.clone()),
ast::Literal::Bool(bo) => Object::Bool(bo.clone()),
_ => todo!(),
};
scoped_env.borrow_mut().set(name, o.clone());
let mut scoped_env = Env::new_with_outer(Rc::clone(&env)); // still thread unsafe
let list = params.iter().zip({
match &args[1] {
Object::Array(arr) => arr,
_ => panic!()
}
}.iter());
for (_, (ident, o)) in list.enumerate() {
let ast::Ident(name) = ident.clone();
scoped_env.set(name, o.clone());
}

scoped_env
Rc::new(RefCell::new(scoped_env))
},
};
ev.eval(&stmts);
});
},
_ => panic!()
}
});

rt.block_on(local_set);
});
rt.block_on(local_set);
});

let handle = Box::leak(Box::new(handle));
let handle_ptr = &mut *handle as *mut std::thread::JoinHandle<()>;
Object::Native(Box::new(NativeObject::Thread(handle_ptr)))
}
_ => panic!()
}
let handle = Box::leak(Box::new(handle));
let handle_ptr = &mut *handle as *mut std::thread::JoinHandle<()>;
Object::Native(Box::new(NativeObject::Thread(handle_ptr)))
}
session_hash.insert(Object::String("thread".to_owned()), Object::Builtin(2, three_body_thread_new));
}
Expand Down
2 changes: 2 additions & 0 deletions interpreter/src/evaluator/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub enum Object {
Native(Box<NativeObject>),
}

unsafe impl Send for Object {}

/// This is actually repr
impl fmt::Display for Object {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down

0 comments on commit 4c44de9

Please sign in to comment.