Skip to content

Commit c303c8a

Browse files
committed
Use a parallel_guard function to handle the parallel guard
1 parent d36393b commit c303c8a

File tree

1 file changed

+55
-60
lines changed
  • compiler/rustc_data_structures/src

1 file changed

+55
-60
lines changed

compiler/rustc_data_structures/src/sync.rs

+55-60
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,25 @@ pub struct ParallelGuard {
115115
}
116116

117117
impl ParallelGuard {
118-
#[inline]
119-
pub fn new() -> Self {
120-
ParallelGuard { panic: Mutex::new(None) }
121-
}
122-
123118
pub fn run<R>(&self, f: impl FnOnce() -> R) -> Option<R> {
124119
catch_unwind(AssertUnwindSafe(f))
125120
.map_err(|err| {
126121
*self.panic.lock() = Some(err);
127122
})
128123
.ok()
129124
}
125+
}
130126

131-
#[inline]
132-
pub fn unwind(self) {
133-
if let Some(panic) = self.panic.into_inner() {
134-
resume_unwind(panic);
135-
}
127+
/// This gives access to a fresh parallel guard in the closure and will unwind any panics
128+
/// caught in it after the closure returns.
129+
#[inline]
130+
pub fn parallel_guard<R>(f: impl FnOnce(&ParallelGuard) -> R) -> R {
131+
let guard = ParallelGuard { panic: Mutex::new(None) };
132+
let ret = f(&guard);
133+
if let Some(panic) = guard.panic.into_inner() {
134+
resume_unwind(panic);
136135
}
136+
ret
137137
}
138138

139139
cfg_if! {
@@ -231,38 +231,38 @@ cfg_if! {
231231
where A: FnOnce() -> RA,
232232
B: FnOnce() -> RB
233233
{
234-
let guard = ParallelGuard::new();
235-
let a = guard.run(oper_a);
236-
let b = guard.run(oper_b);
237-
guard.unwind();
234+
let (a, b) = parallel_guard(|guard| {
235+
let a = guard.run(oper_a);
236+
let b = guard.run(oper_b);
237+
(a, b)
238+
});
238239
(a.unwrap(), b.unwrap())
239240
}
240241

241242
#[macro_export]
242243
macro_rules! parallel {
243244
($($blocks:block),*) => {{
244-
let mut guard = $crate::sync::ParallelGuard::new();
245-
$(guard.run(|| $blocks);)*
246-
guard.unwind();
245+
$crate::sync::parallel_guard(|guard| {
246+
$(guard.run(|| $blocks);)*
247+
});
247248
}}
248249
}
249250

250251
pub fn par_for_each_in<T: IntoIterator>(t: T, mut for_each: impl FnMut(T::Item) + Sync + Send) {
251-
let guard = ParallelGuard::new();
252-
t.into_iter().for_each(|i| {
253-
guard.run(|| for_each(i));
254-
});
255-
guard.unwind();
252+
parallel_guard(|guard| {
253+
t.into_iter().for_each(|i| {
254+
guard.run(|| for_each(i));
255+
});
256+
})
256257
}
257258

258259
pub fn par_map<T: IntoIterator, R, C: FromIterator<R>>(
259260
t: T,
260261
mut map: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item) -> R,
261262
) -> C {
262-
let guard = ParallelGuard::new();
263-
let r = t.into_iter().filter_map(|i| guard.run(|| map(i))).collect();
264-
guard.unwind();
265-
r
263+
parallel_guard(|guard| {
264+
t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
265+
})
266266
}
267267

268268
pub use std::rc::Rc as Lrc;
@@ -382,10 +382,11 @@ cfg_if! {
382382
let (a, b) = rayon::join(move || FromDyn::from(oper_a.into_inner()()), move || FromDyn::from(oper_b.into_inner()()));
383383
(a.into_inner(), b.into_inner())
384384
} else {
385-
let guard = ParallelGuard::new();
386-
let a = guard.run(oper_a);
387-
let b = guard.run(oper_b);
388-
guard.unwind();
385+
let (a, b) = parallel_guard(|guard| {
386+
let a = guard.run(oper_a);
387+
let b = guard.run(oper_b);
388+
(a, b)
389+
});
389390
(a.unwrap(), b.unwrap())
390391
}
391392
}
@@ -421,10 +422,10 @@ cfg_if! {
421422
// of a single threaded rustc.
422423
parallel!(impl $fblock [] [$($blocks),*]);
423424
} else {
424-
let guard = $crate::sync::ParallelGuard::new();
425-
guard.run(|| $fblock);
426-
$(guard.run(|| $blocks);)*
427-
guard.unwind();
425+
$crate::sync::parallel_guard(|guard| {
426+
guard.run(|| $fblock);
427+
$(guard.run(|| $blocks);)*
428+
});
428429
}
429430
};
430431
}
@@ -435,20 +436,18 @@ cfg_if! {
435436
t: T,
436437
for_each: impl Fn(I) + DynSync + DynSend
437438
) {
438-
if mode::is_dyn_thread_safe() {
439-
let for_each = FromDyn::from(for_each);
440-
let guard = ParallelGuard::new();
441-
t.into_par_iter().for_each(|i| {
442-
guard.run(|| for_each(i));
443-
});
444-
guard.unwind();
445-
} else {
446-
let guard = ParallelGuard::new();
447-
t.into_iter().for_each(|i| {
448-
guard.run(|| for_each(i));
449-
});
450-
guard.unwind();
451-
}
439+
parallel_guard(|guard| {
440+
if mode::is_dyn_thread_safe() {
441+
let for_each = FromDyn::from(for_each);
442+
t.into_par_iter().for_each(|i| {
443+
guard.run(|| for_each(i));
444+
});
445+
} else {
446+
t.into_iter().for_each(|i| {
447+
guard.run(|| for_each(i));
448+
});
449+
}
450+
});
452451
}
453452

454453
pub fn par_map<
@@ -460,18 +459,14 @@ cfg_if! {
460459
t: T,
461460
map: impl Fn(I) -> R + DynSync + DynSend
462461
) -> C {
463-
if mode::is_dyn_thread_safe() {
464-
let map = FromDyn::from(map);
465-
let guard = ParallelGuard::new();
466-
let r = t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect();
467-
guard.unwind();
468-
r
469-
} else {
470-
let guard = ParallelGuard::new();
471-
let r = t.into_iter().filter_map(|i| guard.run(|| map(i))).collect();
472-
guard.unwind();
473-
r
474-
}
462+
parallel_guard(|guard| {
463+
if mode::is_dyn_thread_safe() {
464+
let map = FromDyn::from(map);
465+
t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect()
466+
} else {
467+
t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
468+
}
469+
})
475470
}
476471

477472
/// This makes locks panic if they are already held.

0 commit comments

Comments
 (0)