Skip to content

Instantly share code, notes, and snippets.

@Jarak-Jakar
Last active February 14, 2019 00:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jarak-Jakar/caca74fe2c16e2eefc9e0d08e010e0de to your computer and use it in GitHub Desktop.
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
[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"
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