Skip to content

Commit

Permalink
feat: Compile modules in parallel
Browse files Browse the repository at this point in the history
Utilizes some changes to salsa to perform all module compilation in
parallel as long as a parallel future executor is supplied.
  • Loading branch information
Marwes committed Jan 12, 2020
1 parent 7b06abd commit 57fca16
Show file tree
Hide file tree
Showing 43 changed files with 4,150 additions and 3,008 deletions.
3,261 changes: 1,842 additions & 1,419 deletions Cargo.lock

Large diffs are not rendered by default.

34 changes: 22 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,36 @@ gluon_codegen = { path = "codegen", version = "0.13.1" } # GLUON
gluon_vm = { path = "vm", version = "0.13.1", default-features = false } # GLUON
gluon_format = { path = "format", version = "0.13.1", default-features = false } # GLUON

async-trait = "0.1"
log = "0.4"
quick-error = "1.0.0"
collect-mac = "0.1.0"
either = "1.0.0"
itertools = "0.8"
futures = "0.1.11"
futures = { version = "0.3.1", features = ["thread-pool"] }
futures-preview = { version = "0.3.0-alpha.19", package = "futures-preview" }
codespan = "0.3"
codespan-reporting = "0.3"
salsa = "0.13.1"
pin-project = "0.4"
salsa = { version = "0.13.0", path = "../salsa" }

serde = { version = "1.0.0", optional = true }
serde_state = { version = "0.4", optional = true }
serde_derive_state = { version = "0.4.7", optional = true }

tokio = "0.2.0-alpha.6"
tokio-executor = "0.2.0-alpha.6"
tokio-sync = "0.2.0-alpha.6"

# Binding crates
regex = { version = "1", optional = true }
# web
tower-service = { version = "0.3.0-alpha.1", optional = true }
http = { version = "0.1", optional = true }
hyper = { version = "0.12", optional = true }
hyper = { version = "0.13.0-alpha.4", optional = true, features = ["unstable-stream"] }
native-tls = { version = "0.2", optional = true }
tokio-tls = { version = "0.2", optional = true }
tokio-tcp = { version = "0.1", optional = true }
tokio-tls = { version = "0.3.0-alpha.6", optional = true }
tokio-net = { version = "0.2.0-alpha.6", optional = true, features = ["tcp", "async-traits"] }

# Crates used in testing
compiletest_rs = { version = "0.3.23", optional = true }
Expand All @@ -71,17 +79,18 @@ walkdir = "2"

[dev-dependencies]
criterion = "0.3"
tensile = "0.5"
collect-mac = "0.1.0"
env_logger = "0.7"
pretty_assertions = "0.6"
futures-cpupool = "0.1.8"
tokio = "0.1.7"
tokio-retry = "0.2"
walkdir = "2"
failure = "0.1"
failure_derive = "0.1"
pretty_assertions = "0.6"
structopt = "0.3"
tempfile = "3.0.4"
tensile = { path = "../tensile", features = ["tokio-executor"] }
tokio = "0.2.0-alpha.6"
tokio-executor = "0.2.0-alpha.6"
tokio-retry = "0.2"
walkdir = "2"

serde = "1.0.0"
serde_derive = "1.0.0"
Expand All @@ -98,7 +107,7 @@ gluon_codegen = { path = "codegen", version = "0.13.1" } # GLUON
default = ["regex", "random"]
random = ["rand", "rand_xorshift"]
serialization = ["serde", "serde_state", "serde_derive_state", "gluon_vm/serialization"]
web = ["hyper", "http", "native-tls", "tokio-tcp", "tokio-tls"]
web = ["hyper", "http", "tower-service", "native-tls", "tokio-net", "tokio-tls"]

docs_rs = ["serialization"]

Expand All @@ -121,6 +130,7 @@ harness = false
[[test]]
name = "main"
harness = false
required-features = ["serialization"]

[[example]]
name = "marshalling"
Expand Down
2 changes: 1 addition & 1 deletion base/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ where
}
}

impl AsDiagnostic for Box<dyn::std::error::Error + Send + Sync> {
impl AsDiagnostic for Box<dyn ::std::error::Error + Send + Sync> {
fn as_diagnostic(&self) -> Diagnostic {
Diagnostic::new_error(self.to_string())
}
Expand Down
1 change: 1 addition & 0 deletions c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ crate-type = ["cdylib"]

[dependencies]
gluon = { version = "0.13.1", path = ".." } # GLUON
futures = "0.3"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
libc = "0.2.14"
Expand Down
8 changes: 6 additions & 2 deletions c-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

use std::{slice, str};

use futures::{executor::block_on, future};

use gluon::{
vm::{
api::{CPrimitive, Getable, Hole, OpaqueValue, Pushable},
Expand Down Expand Up @@ -83,8 +85,10 @@ pub unsafe extern "C" fn glu_load_script(

#[no_mangle]
pub extern "C" fn glu_call_function(thread: &Thread, args: VmIndex) -> Error {
let context = thread.context();
match thread.call_function(context, args) {
match block_on(future::poll_fn(|cx| {
let context = thread.context();
thread.call_function(cx, context, args)
})) {
Ok(_) => Error::Ok,
Err(_) => Error::Unknown,
}
Expand Down
3 changes: 0 additions & 3 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,6 @@ impl<'a> Typecheck<'a> {
}

fn find(&mut self, id: &Symbol) -> TcResult<ModType> {
if id.declared_name().contains("test") {
"".to_string();
}
match self.environment.find_mod_type(id).map(|t| t.to_owned()) {
Some(typ) => {
self.named_variables.clear();
Expand Down
9 changes: 7 additions & 2 deletions codegen/src/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ fn gen_struct_cons<'a, I>(_ident: &Ident, fields: I) -> TokenStream
where
I: IntoIterator<Item = &'a Field>,
{
let fields = fields.into_iter().map(|field| &field.ident).collect::<Vec<_>>();
let fields = fields
.into_iter()
.map(|field| &field.ident)
.collect::<Vec<_>>();
quote! {
match self {
Self { #(#fields),* } => {
Expand Down Expand Up @@ -90,7 +93,9 @@ fn derive_enum(
ident: Ident,
generics: Generics,
) -> TokenStream {
let cons = if ast.variants.is_empty() {quote!() } else {
let cons = if ast.variants.is_empty() {
quote!()
} else {
let variants = ast
.variants
.iter()
Expand Down
1 change: 1 addition & 0 deletions doc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ documentation = "https://docs.rs/gluon"
clap = "2.22.0"
env_logger = "0.7"
failure = { version = "0.1", features = ["backtrace"] }
futures = "0.3"
handlebars = "2"
itertools = "0.8"
lazy_static = "1"
Expand Down
37 changes: 15 additions & 22 deletions examples/http/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
//!
//! [hyper]:https://hyper.rs

use std::{env, fs::File, io::Read};

use futures::{future, prelude::*};
use std::{env, fs};

use gluon::{
new_vm,
vm::api::{OwnedFunction, IO},
Thread, ThreadExt,
};

fn main() {
#[tokio::main]
async fn main() {
env_logger::init();

let port = env::args()
Expand All @@ -24,27 +23,21 @@ fn main() {
.unwrap_or(80);

let thread = new_vm();
tokio::run(start(&thread, port).map_err(|err| panic!("{}", err)));
if let Err(err) = start(&thread, port).await {
panic!("{}", err)
}
}

fn start(thread: &Thread, port: u16) -> impl Future<Item = (), Error = failure::Error> {
async fn start(thread: &Thread, port: u16) -> Result<(), failure::Error> {
let thread = thread.root_thread();
future::lazy(|| -> Result<_, failure::Error> {
// Last we run our `http_server.glu` module which returns a function which starts listening
// on the port we passed from the command line
let mut expr = String::new();
{
let mut file = File::open("examples/http/server.glu")?;
file.read_to_string(&mut expr)?;
}
Ok(expr)
})
.and_then(move |expr| {
thread
.run_expr_async::<OwnedFunction<fn(u16) -> IO<()>>>("examples/http/server.glu", &expr)
.from_err()
.and_then(move |(mut listen, _)| listen.call_async(port).from_err().map(|_| ()))
})
// Last we run our `http_server.glu` module which returns a function which starts listening
// on the port we passed from the command line
let expr = fs::read_to_string("examples/http/server.glu")?;
let (mut listen, _) = thread
.run_expr_async::<OwnedFunction<fn(u16) -> IO<()>>>("examples/http/server.glu", &expr)
.await?;
listen.call_async(port).await?;
Ok(())
}

#[cfg(test)]
Expand Down
4 changes: 3 additions & 1 deletion format/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ codespan = "0.3"
gluon_base = { path = "../base", version = "0.13.1" } # GLUON

[dev-dependencies]
env_logger = "0.7"
difference = "2"
env_logger = "0.7"
futures = "0.3.1"
pretty_assertions = "0.6"

gluon_base = { path = "../base", version = "0.13.1" } # GLUON
gluon = { path = "..", version = ">=0.9" }

Expand Down
5 changes: 2 additions & 3 deletions repl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ gluon_format = { version = "0.13.1", path = "../format" } # GLUON
gluon_doc = { version = "0.13.1", path = "../doc" } # GLUON

app_dirs = "1.0.0"
futures = "0.1.11"
futures-cpupool = "0.1"
tokio = "0.1"
futures = { version = "0.3", features = ["compat"] }
tokio = "0.2.0-alpha.6"
tokio-signal = "0.2"
clap = "2.22.0"
structopt = "0.3"
Expand Down
41 changes: 21 additions & 20 deletions repl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use codespan_reporting::termcolor;
use structopt::StructOpt;
use walkdir::WalkDir;

use futures::future;
use tokio::runtime::Runtime;

use gluon::{base, parser, vm};
Expand Down Expand Up @@ -158,18 +157,20 @@ fn init_env_logger() {
#[cfg(not(feature = "env_logger"))]
fn init_env_logger() {}

fn format(file: &str, file_map: Arc<codespan::FileMap>, opt: &Opt) -> Result<String> {
async fn format(file: &str, file_map: Arc<codespan::FileMap>, opt: &Opt) -> Result<String> {
let thread = new_vm();
thread.get_database_mut().use_standard_lib(!opt.no_std);

Ok(thread.format_expr(
&mut gluon_format::Formatter::default(),
file,
file_map.src(),
)?)
Ok(thread
.format_expr_async(
&mut gluon_format::Formatter::default(),
file,
file_map.src(),
)
.await?)
}

fn fmt_file(name: &Path, opt: &Opt) -> Result<()> {
async fn fmt_file(name: &Path, opt: &Opt) -> Result<()> {
use std::fs::File;
use std::io::Read;

Expand All @@ -182,7 +183,7 @@ fn fmt_file(name: &Path, opt: &Opt) -> Result<()> {
let module_name = filename_to_module(&name.display().to_string());
let mut code_map = codespan::CodeMap::new();
let file_map = code_map.add_filemap(module_name.clone().into(), buffer);
let formatted = format(&module_name, file_map.clone(), opt)?;
let formatted = format(&module_name, file_map.clone(), opt).await?;

// Avoid touching the .glu file if it did not change
if file_map.src() != formatted {
Expand All @@ -198,7 +199,7 @@ fn fmt_file(name: &Path, opt: &Opt) -> Result<()> {
Ok(())
}

fn fmt_stdio(opt: &Opt) -> Result<()> {
async fn fmt_stdio(opt: &Opt) -> Result<()> {
use std::io::{stdin, stdout, Read};

let mut buffer = String::new();
Expand All @@ -207,12 +208,12 @@ fn fmt_stdio(opt: &Opt) -> Result<()> {
let mut code_map = codespan::CodeMap::new();
let file_map = code_map.add_filemap("STDIN".into(), buffer);

let formatted = format("STDIN", file_map, opt)?;
let formatted = format("STDIN", file_map, opt).await?;
stdout().write_all(formatted.as_bytes())?;
Ok(())
}

fn run(opt: &Opt, color: Color, vm: &Thread) -> std::result::Result<(), gluon::Error> {
async fn run(opt: &Opt, color: Color, vm: &Thread) -> std::result::Result<(), gluon::Error> {
vm.global_env().set_debug_level(opt.debug_level.clone());
match opt.subcommand_opt {
Some(SubOpt::Fmt(ref fmt_opt)) => {
Expand All @@ -238,10 +239,10 @@ fn run(opt: &Opt, color: Color, vm: &Thread) -> std::result::Result<(), gluon::E
gluon_files.dedup();

for file in gluon_files {
fmt_file(&file, opt)?;
fmt_file(&file, opt).await?;
}
} else {
fmt_stdio(opt)?;
fmt_stdio(opt).await?;
}
}
Some(SubOpt::Doc(ref doc_opt)) => {
Expand All @@ -252,13 +253,10 @@ fn run(opt: &Opt, color: Color, vm: &Thread) -> std::result::Result<(), gluon::E
}
None => {
if opt.interactive {
let mut runtime = Runtime::new()?;
let prompt = opt.prompt.clone();
let debug_level = opt.debug_level.clone();
let use_std_lib = !opt.no_std;
runtime.block_on(future::lazy(move || {
repl::run(color, &prompt, debug_level, use_std_lib)
}))?;
repl::run(color, &prompt, debug_level, use_std_lib).await?;
} else if !opt.input.is_empty() {
run_files(&vm, &opt.input)?;
} else {
Expand All @@ -280,11 +278,14 @@ fn main() {
.use_standard_lib(!opt.no_std)
.run_io(true);

if let Err(err) = run(&opt, opt.color, &vm) {
let runtime = Runtime::new().unwrap();
let color = opt.color;
let result = runtime.block_on(run(&opt, opt.color, &vm));
if let Err(err) = result {
match err {
Error::VM(VMError::Message(_)) => eprintln!("{}\n{}", err, vm.context().stacktrace(0)),
_ => {
let mut stderr = termcolor::StandardStream::stderr(opt.color.into());
let mut stderr = termcolor::StandardStream::stderr(color.into());
if let Err(err) = err.emit(&mut stderr, &vm.get_database().code_map()) {
eprintln!("{}", err);
} else {
Expand Down
Loading

0 comments on commit 57fca16

Please sign in to comment.