Last active
February 14, 2019 00:35
-
-
Save Jarak-Jakar/caca74fe2c16e2eefc9e0d08e010e0de to your computer and use it in GitHub Desktop.
A (slightly obfuscated) copy of a short Rust program to test efficiency/implementation of message exchanges over channels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "thor_rust" | |
version = "0.1.0" | |
authors = ["Anon <anon@hidden.com>"] | |
edition = "2018" | |
[dependencies] | |
rayon = "1.0.3" | |
crossbeam-channel = "0.3" | |
[[bin]] | |
name = "thor_rust" | |
path = "thor_rust.rs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate crossbeam_channel; | |
extern crate rayon; | |
use crossbeam_channel::bounded; | |
use crossbeam_channel::Receiver; | |
use crossbeam_channel::Sender; | |
use std::env; | |
enum Message { | |
Done, | |
Mount, | |
Dismount, | |
Finished, | |
Answer, | |
Wake, | |
Invite, | |
Return, | |
} | |
struct ThorReceivers { | |
wakeup_by_valkyrie: Receiver<Message>, | |
wakeup_by_jotnar: Receiver<Message>, | |
valkyrie_confirm: Receiver<Message>, | |
question: Receiver<usize>, | |
} | |
struct ThorSenders { | |
done: Sender<Message>, | |
mount: Vec<Sender<Message>>, | |
dismount: Vec<Sender<Message>>, | |
enter: Sender<Message>, | |
answer: Vec<Sender<Message>>, | |
finished: Sender<Message>, | |
} | |
fn pointless_busy_work() {} | |
fn thor(years: i32, thunders_per_year: i32, receivers: ThorReceivers, senders: ThorSenders) { | |
let mut b = false; | |
let mut p = false; // valkyrie back, jotnar puzzled | |
let mut thunders_this_year = 0; | |
let mut years_ = years; | |
loop { | |
// inlet mut iant : ! b | |
if years_ == 0 { | |
senders.done.send(Message::Done).unwrap(); | |
break; | |
} | |
if receivers.wakeup_by_valkyrie.try_recv().is_ok() { | |
b = true; | |
} | |
if receivers.wakeup_by_jotnar.try_recv().is_ok() { | |
p = true; | |
} | |
// either b or p is true , pick one | |
if b && thunders_this_year >= thunders_per_year { | |
// prefer valkyrie | |
thunders_this_year = 0; | |
years_ -= 1; | |
for i in senders.mount.iter().take(9) { | |
i.send(Message::Mount).unwrap(); | |
} | |
for _i in 0..9 { | |
receivers.valkyrie_confirm.recv().unwrap(); | |
} | |
pointless_busy_work(); | |
for i in senders.dismount.iter().take(9) { | |
i.send(Message::Dismount).unwrap(); | |
} | |
b = false; | |
} else if p { | |
// otherwise jotnar | |
thunders_this_year += 1; | |
senders.enter.send(Message::Invite).unwrap(); | |
for _i in 1..4 { | |
let jotunn_with_question = receivers.question.recv().unwrap(); | |
senders.answer[jotunn_with_question] | |
.send(Message::Answer) | |
.unwrap(); | |
} | |
p = false; | |
senders.finished.send(Message::Finished).unwrap(); | |
} | |
} | |
} | |
fn sleipnir(valkyrie_back_r: Receiver<Message>, wakeup_by_valkyrie_s: Sender<Message>) { | |
loop { | |
for _i in 1..10 { | |
valkyrie_back_r.recv().unwrap(); | |
} | |
wakeup_by_valkyrie_s.send(Message::Wake).unwrap(); | |
} | |
} | |
fn asgard( | |
jotunn_puzzled_r: Receiver<usize>, | |
wakeup_by_jotnar_s: Sender<Message>, | |
enter_r: Receiver<Message>, | |
jotunn_enter_s: Vec<Sender<Message>>, | |
finished_r: Receiver<Message>, | |
) { | |
let mut omega: Vec<usize> = Vec::new(); | |
loop { | |
for _i in 1..4 { | |
omega.push(jotunn_puzzled_r.recv().unwrap()); | |
} | |
wakeup_by_jotnar_s.send(Message::Wake).unwrap(); | |
enter_r.recv().unwrap(); //when this is hit the jotnar are now allowed to enter | |
for _i in 1..4 { | |
jotunn_enter_s[omega.pop().unwrap()] | |
.send(Message::Invite) | |
.unwrap(); | |
} | |
finished_r.recv().unwrap(); | |
} | |
} | |
fn valkyrie( | |
valkyrie_back_s: Sender<Message>, | |
mount_r: Receiver<Message>, | |
valkyrie_confirm_s: Sender<Message>, | |
dismount_r: Receiver<Message>, | |
) { | |
loop { | |
pointless_busy_work(); | |
valkyrie_back_s.send(Message::Return).unwrap(); | |
mount_r.recv().unwrap(); | |
valkyrie_confirm_s.send(Message::Mount).unwrap(); | |
dismount_r.recv().unwrap(); | |
} | |
} | |
fn jotunn( | |
id: usize, | |
jotunn_puzzled_s: Sender<usize>, | |
jotunn_enter_r: Receiver<Message>, | |
question_s: Sender<usize>, | |
answer_r: Receiver<Message>, | |
) { | |
loop { | |
pointless_busy_work(); | |
jotunn_puzzled_s.send(id).unwrap(); | |
jotunn_enter_r.recv().unwrap(); | |
question_s.send(id).unwrap(); | |
answer_r.recv().unwrap(); | |
} | |
} | |
fn main() { | |
let now = std::time::Instant::now(); | |
let args: Vec<String> = env::args().collect(); | |
let years = (&args[1]).parse::<i32>().unwrap();; | |
let thunders_per_year = (&args[2]).parse::<i32>().unwrap();; | |
let number_jotnar = (&args[3]).parse::<i32>().unwrap();; | |
let (finished_s, finished_r) = bounded(0); | |
let (valkyrie_back_s, valkyrie_back_r) = bounded(0); | |
let (wakeup_by_valkyrie_s, wakeup_by_valkyrie_r) = bounded(0); | |
let (valkyrie_confirm_s, valkyrie_confirm_r) = bounded(0); | |
let (jotunn_puzzled_s, jotunn_puzzled_r) = bounded(0); | |
let (question_s, question_r) = bounded(0); | |
let (wakeup_by_jotnar_s, wakeup_by_jotnar_r) = bounded(0); | |
let (enter_s, enter_r) = bounded(0); | |
let (done_s, done_r) = bounded(0); | |
let mut jotunn_enter_s_vec: Vec<Sender<Message>> = Vec::new(); | |
let mut answer_s_vec: Vec<Sender<Message>> = Vec::new(); | |
let mut mount_s_vec: Vec<Sender<Message>> = Vec::new(); | |
let mut dismount_s_vec: Vec<Sender<Message>> = Vec::new(); | |
let pool = rayon::ThreadPoolBuilder::new() | |
.num_threads(12 + number_jotnar as usize) | |
.build() | |
.unwrap(); | |
for i in 0..number_jotnar { | |
let (jotunn_enter_s, jotunn_enter_r) = bounded(0); | |
let (answer_s, answer_r) = bounded(0); | |
jotunn_enter_s_vec.push(jotunn_enter_s); | |
answer_s_vec.push(answer_s); | |
let question_s_copy = question_s.clone(); | |
let jotunn_puzzled_s_copy = jotunn_puzzled_s.clone(); | |
pool.spawn(move || { | |
jotunn( | |
i as usize, | |
jotunn_puzzled_s_copy, | |
jotunn_enter_r, | |
question_s_copy, | |
answer_r, | |
); | |
}); | |
} | |
for _i in 1..10 { | |
let (mount_s, mount_r) = bounded(0); | |
let (dismount_s, dismount_r) = bounded(0); | |
let valkyrie_back_s_copy = valkyrie_back_s.clone(); | |
let valkyrie_confirm_s_copy = valkyrie_confirm_s.clone(); | |
mount_s_vec.push(mount_s); | |
dismount_s_vec.push(dismount_s); | |
pool.spawn(|| { | |
valkyrie( | |
valkyrie_back_s_copy, | |
mount_r, | |
valkyrie_confirm_s_copy, | |
dismount_r, | |
); | |
}); | |
} | |
pool.spawn(|| { | |
asgard( | |
jotunn_puzzled_r, | |
wakeup_by_jotnar_s, | |
enter_r, | |
jotunn_enter_s_vec, | |
finished_r, | |
); | |
}); | |
pool.spawn(|| { | |
sleipnir(valkyrie_back_r, wakeup_by_valkyrie_s); | |
}); | |
pool.spawn(move || { | |
thor( | |
years, | |
thunders_per_year, | |
ThorReceivers { | |
wakeup_by_valkyrie: wakeup_by_valkyrie_r, | |
wakeup_by_jotnar: wakeup_by_jotnar_r, | |
valkyrie_confirm: valkyrie_confirm_r, | |
question: question_r, | |
}, | |
ThorSenders { | |
done: done_s, | |
mount: mount_s_vec, | |
dismount: dismount_s_vec, | |
enter: enter_s, | |
answer: answer_s_vec, | |
finished: finished_s, | |
}, | |
); | |
}); | |
done_r.recv().unwrap(); | |
let elapsed = now.elapsed(); | |
let sec = (elapsed.as_secs() as f64) + (f64::from(elapsed.subsec_nanos()) / 1_000_000_000.0); | |
println!("Seconds: {}", sec); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment