summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock88
-rw-r--r--oryxc/Cargo.toml1
-rw-r--r--oryxc/src/compiler.rs105
3 files changed, 72 insertions, 122 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3748ff6..8bb0332 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -53,18 +53,6 @@ dependencies = [
]
[[package]]
-name = "bitflags"
-version = "2.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
-
-[[package]]
name = "clap"
version = "4.5.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -136,32 +124,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
-name = "dashmap"
-version = "6.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
- "hashbrown",
- "lock_api",
- "once_cell",
- "parking_lot_core",
-]
-
-[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
-name = "hashbrown"
-version = "0.14.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
-
-[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -180,27 +148,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "803ec87c9cfb29b9d2633f20cba1f488db3fd53f2158b1024cbefb47ba05d413"
[[package]]
-name = "libc"
-version = "0.2.182"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
-
-[[package]]
-name = "lock_api"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
-dependencies = [
- "scopeguard",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
-
-[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -212,26 +159,12 @@ version = "0.1.0"
dependencies = [
"clap",
"crossbeam-deque",
- "dashmap",
"phf",
"soa-rs",
"unicode-width",
]
[[package]]
-name = "parking_lot_core"
-version = "0.9.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall",
- "smallvec",
- "windows-link",
-]
-
-[[package]]
name = "phf"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -293,21 +226,6 @@ dependencies = [
]
[[package]]
-name = "redox_syscall"
-version = "0.5.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
-[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -343,12 +261,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
[[package]]
-name = "smallvec"
-version = "1.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
-
-[[package]]
name = "soa-rs"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/oryxc/Cargo.toml b/oryxc/Cargo.toml
index 4308b1a..267e889 100644
--- a/oryxc/Cargo.toml
+++ b/oryxc/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2024"
[dependencies]
crossbeam-deque = "0.8.6"
-dashmap = "6.1.0"
# icu = { version = "2.1.1", features = ["compiled_data"] }
clap = { version = "4", features = ["derive"] }
# num-rational = "0.4.2"
diff --git a/oryxc/src/compiler.rs b/oryxc/src/compiler.rs
index 5a16356..2a0a3c9 100644
--- a/oryxc/src/compiler.rs
+++ b/oryxc/src/compiler.rs
@@ -1,6 +1,7 @@
use std::ffi::OsString;
use std::io::{
self,
+ Read,
Write,
};
use std::iter::once;
@@ -24,7 +25,6 @@ use crossbeam_deque::{
Stealer,
Worker,
};
-use dashmap::DashMap;
use soa_rs::Soa;
use crate::errors::OryxError;
@@ -52,9 +52,12 @@ impl FileData {
fn new(name: OsString) -> Result<Self, io::Error> {
const PAD: [u8; 64] = [0; 64]; /* 512 bits */
+ // Pre-allocate to avoid reallocation when appending padding.
// Append extra data to the end so that we can safely read past
- // instead of branching on length
- let mut buffer = fs::read_to_string(&name)?;
+ // instead of branching on length.
+ let size = fs::metadata(&name)?.len() as usize;
+ let mut buffer = String::with_capacity(size + PAD.len());
+ fs::File::open(&name)?.read_to_string(&mut buffer)?;
buffer.push_str(unsafe { std::str::from_utf8_unchecked(&PAD) });
Ok(Self {
@@ -75,31 +78,56 @@ pub enum Job {
}
pub struct CompilerState {
- pub files: DashMap<FileId, Arc<FileData>>,
- pub globalq: Injector<Job>,
- pub njobs: AtomicUsize,
- pub flags: Flags,
+ #[allow(dead_code)]
+ pub files: Vec<Arc<FileData>>,
+ pub globalq: Injector<Job>,
+ pub njobs: AtomicUsize,
+ pub flags: Flags,
+ pub worker_threads: OnceLock<Box<[thread::Thread]>>,
+}
+
+impl CompilerState {
+ fn push_job(&self, queue: &Worker<Job>, job: Job) {
+ queue.push(job);
+ if let Some(threads) = self.worker_threads.get() {
+ for t in threads.iter() {
+ t.unpark();
+ }
+ }
+ }
}
pub fn start<T>(paths: T, flags: Flags)
where
T: IntoIterator<Item = OsString>,
{
- let state = Arc::new(CompilerState {
- files: DashMap::new(),
- globalq: Injector::new(),
- njobs: AtomicUsize::new(0),
- flags,
- });
+ let mut files = Vec::new();
+ let mut initial_jobs = Vec::new();
+
for (i, path) in paths.into_iter().enumerate() {
let id = FileId(i);
+
+ // take ownership of the OsString so we can store it in FileData without
+ // cloning
+ let display = path.to_string_lossy().into_owned();
let fdata = Arc::new(
- FileData::new(path.clone().into())
- .unwrap_or_else(|e| err!(e, "{}", path.display())),
+ FileData::new(path).unwrap_or_else(|e| err!(e, "{}", display)),
);
- state.files.insert(id, Arc::clone(&fdata));
- state.njobs.fetch_add(1, Ordering::Relaxed);
- state.globalq.push(Job::Lex { file: id, fdata });
+ files.push(Arc::clone(&fdata));
+ initial_jobs.push(Job::Lex { file: id, fdata });
+ }
+
+ let njobs = initial_jobs.len();
+ let state = Arc::new(CompilerState {
+ files,
+ globalq: Injector::new(),
+ njobs: AtomicUsize::new(njobs),
+ flags,
+ worker_threads: OnceLock::new(),
+ });
+
+ for job in initial_jobs {
+ state.globalq.push(job);
}
let mut workers = Vec::with_capacity(flags.threads);
@@ -110,19 +138,23 @@ where
workers.push(w);
}
- let mut threads = Vec::with_capacity(flags.threads);
let stealer_view: Arc<[_]> = Arc::from(stealers);
+ let handles: Vec<_> = workers
+ .into_iter()
+ .enumerate()
+ .map(|(id, w)| {
+ let stealer_view = Arc::clone(&stealer_view);
+ let state = Arc::clone(&state);
+ thread::spawn(move || worker_loop(id, state, w, stealer_view))
+ })
+ .collect();
- for (id, w) in workers.into_iter().enumerate() {
- let stealer_view = Arc::clone(&stealer_view);
- let state = Arc::clone(&state);
- threads.push(thread::spawn(move || {
- worker_loop(id, state, w, stealer_view)
- }));
- }
+ let worker_threads: Box<[thread::Thread]> =
+ handles.iter().map(|h| h.thread().clone()).collect();
+ let _ = state.worker_threads.set(worker_threads);
- for t in threads {
- if let Err(e) = t.join() {
+ for h in handles {
+ if let Err(e) = h.join() {
std::panic::resume_unwind(e)
}
}
@@ -149,7 +181,7 @@ fn worker_loop(
}
let Some(job) = find_task(&queue, &state.globalq, &stealers) else {
- thread::yield_now();
+ thread::park();
continue;
};
@@ -172,7 +204,7 @@ fn worker_loop(
fdata.tokens.set(tokens).unwrap();
state.njobs.fetch_add(1, Ordering::Relaxed);
- queue.push(Job::Parse { file, fdata });
+ state.push_job(&queue, Job::Parse { file, fdata });
},
Job::Parse { file, fdata } => {
let (ast, extra_data) =
@@ -194,15 +226,22 @@ fn worker_loop(
fdata.ast.set(ast).unwrap();
fdata.extra_data.set(extra_data).unwrap();
state.njobs.fetch_add(1, Ordering::Relaxed);
- queue.push(Job::ResolveSymbols { file, fdata });
+ state.push_job(&queue, Job::ResolveSymbols { file, fdata });
},
Job::ResolveSymbols { file: _, fdata: _ } => {
err!("not implemented");
- // unimplemented!()
},
}
- state.njobs.fetch_sub(1, Ordering::Release);
+ if state.njobs.fetch_sub(1, Ordering::Release) == 1 {
+ // njobs is 0; wake all threads so they can observe the termination
+ // condition and exit.
+ if let Some(threads) = state.worker_threads.get() {
+ for t in threads.iter() {
+ t.unpark();
+ }
+ }
+ }
}
}