mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 17:29:36 +00:00
refactor: optimize parallel build and fix architectural issues
This commit is contained in:
@@ -153,6 +153,49 @@ pub fn has_glob_magic(value: &str) -> bool {
|
|||||||
value.chars().any(|c| matches!(c, '*' | '?' | '['))
|
value.chars().any(|c| matches!(c, '*' | '?' | '['))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parallel_build<F>(total_tasks: usize, task_fn: F) -> Result<(), String>
|
||||||
|
where
|
||||||
|
F: Fn(usize) -> Result<(), String> + Sync + Send,
|
||||||
|
{
|
||||||
|
let num_threads = std::thread::available_parallelism()
|
||||||
|
.map(|n| n.get())
|
||||||
|
.unwrap_or(1);
|
||||||
|
|
||||||
|
let counter = std::sync::atomic::AtomicUsize::new(0);
|
||||||
|
let err_msg = std::sync::Mutex::new(None);
|
||||||
|
|
||||||
|
std::thread::scope(|s| {
|
||||||
|
for _ in 0..num_threads {
|
||||||
|
s.spawn(|| {
|
||||||
|
loop {
|
||||||
|
if err_msg.lock().unwrap().is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
if i >= total_tasks {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = task_fn(i) {
|
||||||
|
let mut err = err_msg.lock().unwrap();
|
||||||
|
if err.is_none() {
|
||||||
|
*err = Some(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(err) = err_msg.into_inner().unwrap() {
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn normalize_source_path(path: &Path) -> String {
|
pub fn normalize_source_path(path: &Path) -> String {
|
||||||
if !path.is_absolute() {
|
if !path.is_absolute() {
|
||||||
return path.to_string_lossy().to_string();
|
return path.to_string_lossy().to_string();
|
||||||
|
|||||||
@@ -112,44 +112,9 @@ fn build_objects(
|
|||||||
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let num_threads = std::thread::available_parallelism()
|
common::parallel_build(sources.len(), |i| {
|
||||||
.map(|n| n.get())
|
build_object(assembler, &sources[i], &objects[i], ctx)
|
||||||
.unwrap_or(1);
|
})?;
|
||||||
|
|
||||||
let counter = std::sync::atomic::AtomicUsize::new(0);
|
|
||||||
let err_msg = std::sync::Mutex::new(None);
|
|
||||||
|
|
||||||
std::thread::scope(|s| {
|
|
||||||
for _ in 0..num_threads {
|
|
||||||
s.spawn(|| {
|
|
||||||
loop {
|
|
||||||
if err_msg.lock().unwrap().is_some() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
|
||||||
if i >= sources.len() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let source = &sources[i];
|
|
||||||
let obj_path = &objects[i];
|
|
||||||
|
|
||||||
if let Err(e) = build_object(assembler, source, obj_path, ctx) {
|
|
||||||
let mut err = err_msg.lock().unwrap();
|
|
||||||
if err.is_none() {
|
|
||||||
*err = Some(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(err) = err_msg.into_inner().unwrap() {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(objects)
|
Ok(objects)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,6 +185,8 @@ fn default_flags(profile: &str) -> &'static [&'static str] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static OUTPUT_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(());
|
||||||
|
|
||||||
fn build_objects(
|
fn build_objects(
|
||||||
compiler: &str,
|
compiler: &str,
|
||||||
sources: &[String],
|
sources: &[String],
|
||||||
@@ -197,44 +199,9 @@ fn build_objects(
|
|||||||
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let num_threads = std::thread::available_parallelism()
|
common::parallel_build(sources.len(), |i| {
|
||||||
.map(|n| n.get())
|
build_object(compiler, &sources[i], &objects[i], ctx)
|
||||||
.unwrap_or(1);
|
})?;
|
||||||
|
|
||||||
let counter = std::sync::atomic::AtomicUsize::new(0);
|
|
||||||
let err_msg = std::sync::Mutex::new(None);
|
|
||||||
|
|
||||||
std::thread::scope(|s| {
|
|
||||||
for _ in 0..num_threads {
|
|
||||||
s.spawn(|| {
|
|
||||||
loop {
|
|
||||||
if err_msg.lock().unwrap().is_some() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
|
||||||
if i >= sources.len() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let source = &sources[i];
|
|
||||||
let obj_path = &objects[i];
|
|
||||||
|
|
||||||
if let Err(e) = build_object(compiler, source, obj_path, ctx) {
|
|
||||||
let mut err = err_msg.lock().unwrap();
|
|
||||||
if err.is_none() {
|
|
||||||
*err = Some(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(err) = err_msg.into_inner().unwrap() {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(objects)
|
Ok(objects)
|
||||||
}
|
}
|
||||||
@@ -315,6 +282,8 @@ fn build_object(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _lock = OUTPUT_MUTEX.lock().unwrap();
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
eprint!("{}", clean_stdout);
|
eprint!("{}", clean_stdout);
|
||||||
eprint!("{}", stderr);
|
eprint!("{}", stderr);
|
||||||
|
|||||||
@@ -112,45 +112,11 @@ fn build_objects(
|
|||||||
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let num_threads = std::thread::available_parallelism()
|
|
||||||
.map(|n| n.get())
|
|
||||||
.unwrap_or(1);
|
|
||||||
|
|
||||||
let counter = std::sync::atomic::AtomicUsize::new(0);
|
|
||||||
let err_msg = std::sync::Mutex::new(None);
|
|
||||||
let format = nasm_format(ctx.platform);
|
let format = nasm_format(ctx.platform);
|
||||||
|
|
||||||
std::thread::scope(|s| {
|
common::parallel_build(sources.len(), |i| {
|
||||||
for _ in 0..num_threads {
|
build_object(assembler, &sources[i], &objects[i], format, ctx)
|
||||||
s.spawn(|| {
|
})?;
|
||||||
loop {
|
|
||||||
if err_msg.lock().unwrap().is_some() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
|
||||||
if i >= sources.len() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let source = &sources[i];
|
|
||||||
let obj_path = &objects[i];
|
|
||||||
|
|
||||||
if let Err(e) = build_object(assembler, source, obj_path, format, ctx) {
|
|
||||||
let mut err = err_msg.lock().unwrap();
|
|
||||||
if err.is_none() {
|
|
||||||
*err = Some(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(err) = err_msg.into_inner().unwrap() {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(objects)
|
Ok(objects)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,44 +137,9 @@ fn build_objects(
|
|||||||
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
.map(|s| common::object_path(obj_dir, s, obj_ext))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let num_threads = std::thread::available_parallelism()
|
common::parallel_build(sources.len(), |i| {
|
||||||
.map(|n| n.get())
|
build_object(compiler, &sources[i], &objects[i], ctx)
|
||||||
.unwrap_or(1);
|
})?;
|
||||||
|
|
||||||
let counter = std::sync::atomic::AtomicUsize::new(0);
|
|
||||||
let err_msg = std::sync::Mutex::new(None);
|
|
||||||
|
|
||||||
std::thread::scope(|s| {
|
|
||||||
for _ in 0..num_threads {
|
|
||||||
s.spawn(|| {
|
|
||||||
loop {
|
|
||||||
if err_msg.lock().unwrap().is_some() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
|
||||||
if i >= sources.len() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let source = &sources[i];
|
|
||||||
let obj_path = &objects[i];
|
|
||||||
|
|
||||||
if let Err(e) = build_object(compiler, source, obj_path, ctx) {
|
|
||||||
let mut err = err_msg.lock().unwrap();
|
|
||||||
if err.is_none() {
|
|
||||||
*err = Some(e);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(err) = err_msg.into_inner().unwrap() {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(objects)
|
Ok(objects)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user