Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Executor work #53

Merged
merged 41 commits into from
Nov 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
116c81f
Initial executor design
vertexclique Oct 26, 2019
4ffe7d5
Cargo fix
vertexclique Oct 26, 2019
b3d8e8f
Cargo format
vertexclique Oct 26, 2019
8902488
Stack representation
vertexclique Oct 27, 2019
e41926a
Stack copy implementation
vertexclique Oct 27, 2019
2cb4ae3
Run queue size
vertexclique Oct 27, 2019
8301043
Load balancer schedule timing
vertexclique Oct 27, 2019
b747429
LoadBalancer
vertexclique Oct 28, 2019
cc4fbbb
Global allocator
vertexclique Oct 30, 2019
1590cd3
cargo fix & format
vertexclique Oct 30, 2019
056a455
Stat struct
vertexclique Oct 30, 2019
b825af1
Reduce allocator dependencies
vertexclique Oct 30, 2019
1ea3cb9
Spawn async problems
vertexclique Oct 30, 2019
089e3f2
Scheduler complete
vertexclique Oct 30, 2019
92c4ca8
Fix panic example
vertexclique Oct 30, 2019
77fa780
Remove debug points
vertexclique Oct 30, 2019
7438669
Run queue docs
vertexclique Oct 30, 2019
0ebcbf3
Cargo fix for all
vertexclique Oct 30, 2019
960fee6
Code format
vertexclique Oct 30, 2019
a748b8c
Better messages for example
vertexclique Oct 30, 2019
c9bc705
Allocator implementation ordeR
vertexclique Oct 30, 2019
cc3547f
Cleaning the tests
vertexclique Oct 30, 2019
566c408
Add benchmarks
vertexclique Nov 2, 2019
d1d7062
Enable numa-aware allocator
vertexclique Nov 3, 2019
7078d0b
Lightproc data
vertexclique Nov 3, 2019
53e5654
(cargo-release) version 0.3.0
vertexclique Nov 3, 2019
845ea8c
Fill missing fields for Cargo.toml
vertexclique Nov 3, 2019
c4cb935
(cargo-release) version 0.3.1
vertexclique Nov 3, 2019
324c2af
Add readmes
vertexclique Nov 3, 2019
4d478f0
(cargo-release) version 0.3.2
vertexclique Nov 3, 2019
5dc3ebc
(cargo-release) start next development iteration 0.3.2
vertexclique Nov 3, 2019
46081af
Fix dep order
vertexclique Nov 3, 2019
3e665b6
Change description of executor
vertexclique Nov 3, 2019
5628389
Load balancer wait for it
vertexclique Nov 3, 2019
c8792a9
Address comments
vertexclique Nov 3, 2019
04ad717
Remove feature enablers
vertexclique Nov 3, 2019
2cca130
Add features back
vertexclique Nov 3, 2019
44f744b
Select SMP core fix
vertexclique Nov 4, 2019
7e9a938
Rework on the scheduler
vertexclique Nov 5, 2019
c4cd383
Remove old scheduler
vertexclique Nov 5, 2019
caa6b02
Use unstable feature gate for NUMA allocator
vertexclique Nov 5, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 28 additions & 2 deletions bastion-executor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
[package]
name = "bastion-executor"
version = "0.2.1-alpha.0"
description = "Fault-tolerant Runtime for Rust applications"
description = "Cache affine NUMA-aware executor for Rust"
authors = ["Mahmut Bulut <vertexclique@gmail.com>"]
keywords = ["fault-tolerant", "runtime", "actor", "system"]
categories = []
categories = ["concurrency", "asynchronous"]
homepage = "https://github.com/bastion-rs/bastion"
repository = "https://github.com/bastion-rs/bastion"
documentation = "https://docs.rs/bastion"
readme = "README.md"
license = "Apache-2.0/MIT"
edition = "2018"

[features]
unstable = ["numanji", "allocator-suite"]

[dependencies]
crossbeam-utils = "0.6"
crossbeam-epoch = "0.7"
lazy_static = "1.4"
libc = "0.2"
num_cpus = "1.10"
rustc-hash = "1.0.1"
pin-utils = "0.1.0-alpha.4"
lightproc = { "path" = "../lightproc" }

# Allocator
numanji = { version = "^0.1", optional = true, default-features = false}
allocator-suite = { version = "^0.1", optional = true, default-features = false}

[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
jemallocator = "^0.3"
3 changes: 3 additions & 0 deletions bastion-executor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Bastion Executor

SMP enabled NUMA-aware executor for Rust
20 changes: 20 additions & 0 deletions bastion-executor/benches/perf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#![feature(test)]

extern crate test;

use bastion_executor::prelude::*;
use test::{black_box, Bencher};
use lightproc::proc_stack::ProcStack;

#[bench]
fn increment(b: &mut Bencher) {
let mut sum = 0;

b.iter( || {
run(async {
(0..10_000_000).for_each(|_| { sum += 1; });
}, ProcStack::default());
});

black_box(sum);
}
12 changes: 12 additions & 0 deletions bastion-executor/examples/blocking_run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use bastion_executor::prelude::*;
use lightproc::proc_stack::ProcStack;

fn main() {
run(
async {
println!("Example execution");
panic!("fault");
},
ProcStack::default().with_after_panic(|| println!("after panic")),
);
}
26 changes: 26 additions & 0 deletions bastion-executor/examples/spawn_async.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use bastion_executor::prelude::*;
use lightproc::proc_stack::ProcStack;

fn main() {
let pid = 1;
let stack = ProcStack::default()
.with_pid(pid)
.with_after_panic(move || println!("after panic {}", pid.clone()));

let handle = spawn(
async {
panic!("test");
},
stack,
);

let pid = 2;
let stack = ProcStack::default().with_pid(pid);

run(
async {
handle.await;
},
stack.clone(),
);
}
7 changes: 7 additions & 0 deletions bastion-executor/src/allocator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
unstable_api! {
// Allocation selector import
use numanji::*;

// Drive selection of allocator here
autoselect!();
}
1 change: 1 addition & 0 deletions bastion-executor/src/blocking_pool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// FIXME: Blocking pool implementation goes here.
48 changes: 48 additions & 0 deletions bastion-executor/src/distributor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use super::placement;
use super::placement::CoreId;
use super::run_queue::{Stealer, Worker};

use lightproc::prelude::*;

use crate::worker;
use std::thread;

pub(crate) struct Distributor {
pub round: usize,
pub last_dead: usize,
pub cores: Vec<CoreId>,
}

impl Distributor {
pub fn new() -> Self {
Distributor {
round: 0_usize,
last_dead: usize::max_value(),
cores: placement::get_core_ids().expect("Core mapping couldn't be fetched"),
}
}

pub fn assign(mut self) -> Vec<Stealer<LightProc>> {
let mut stealers = Vec::<Stealer<LightProc>>::new();

for core in self.cores {
self.round = core.id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Distributor.round doesn't seem to be used anywhere else


let wrk = Worker::new_fifo();
stealers.push(wrk.stealer());

thread::Builder::new()
.name("bastion-async-thread".to_string())
.spawn(move || {
// affinity assignment
placement::set_for_current(core);

// actual execution
worker::main_loop(core.id.clone(), wrk);
})
.expect("cannot start the thread for running proc");
}

stealers
}
}
32 changes: 30 additions & 2 deletions bastion-executor/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
mod pool;
mod blocking_pool;
//!
//!
//!
//! NUMA-aware SMP based Fault-tolerant Executor
//!
//!

// Force missing implementations
#![warn(missing_docs)]
#![warn(missing_debug_implementations)]

#[macro_use]
mod macros;

pub mod allocator;
pub mod blocking_pool;
pub mod distributor;
pub mod load_balancer;
pub mod placement;
pub mod pool;
pub mod run;
pub mod run_queue;
pub mod sleepers;
pub mod thread_recovery;
pub mod worker;

pub mod prelude {
pub use crate::pool::*;
pub use crate::run::*;
}
67 changes: 67 additions & 0 deletions bastion-executor/src/load_balancer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use super::placement;
use lazy_static::*;

use std::thread;

use super::load_balancer;
use crossbeam_utils::sync::ShardedLock;
use rustc_hash::FxHashMap;

pub struct LoadBalancer();

impl LoadBalancer {
pub fn sample() {
thread::Builder::new()
.name("load-balancer-thread".to_string())
.spawn(move || {
loop {
let mut m = 0_usize;
if let Ok(stats) = load_balancer::stats().try_read() {
m = stats
.smp_queues
.values()
.sum::<usize>()
.wrapping_div(placement::get_core_ids().unwrap().len());
}

if let Ok(mut stats) = load_balancer::stats().try_write() {
stats.mean_level = m;
}
}
})
.expect("load-balancer couldn't start");
}
}

#[derive(Clone)]
pub struct Stats {
pub(crate) global_run_queue: usize,
pub(crate) mean_level: usize,
pub(crate) smp_queues: FxHashMap<usize, usize>,
}

unsafe impl Send for Stats {}
unsafe impl Sync for Stats {}

#[inline]
pub fn stats() -> &'static ShardedLock<Stats> {
lazy_static! {
static ref LB_STATS: ShardedLock<Stats> = {
let stats = Stats {
global_run_queue: 0,
mean_level: 0,
smp_queues: FxHashMap::with_capacity_and_hasher(
placement::get_core_ids().unwrap().len(),
Default::default()
)
};

// Start sampler
LoadBalancer::sample();

// Return stats
ShardedLock::new(stats)
};
}
&*LB_STATS
}
9 changes: 9 additions & 0 deletions bastion-executor/src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[doc(hidden)]
macro_rules! unstable_api {
($($block:item)*) => {
$(
#[cfg(feature = "unstable")]
$block
)*
}
}