Use new run_without_applying_deferred
method in SingleThreadedExecutor
(#18684)
# Objective Simplify code in the `SingleThreadedExecutor` by removing a special case for exclusive systems. The `SingleThreadedExecutor` runs systems without immediately applying deferred buffers. That required calling `run_unsafe()` instead of `run()`, but that would `panic` for exclusive systems, so the code also needed a special case for those. Following #18076 and #18406, we have a `run_without_applying_deferred` method that has the exact behavior we want and works on exclusive systems. ## Solution Replace the code in `SingleThreadedExecutor` that runs systems with a single call to `run_without_applying_deferred()`. Also add this as a wrapper in the `__rust_begin_short_backtrace` module to preserve the special behavior for backtraces.
This commit is contained in:
parent
49f1827633
commit
3442e2556d
@ -271,38 +271,54 @@ impl IntoSystemSet<()> for ApplyDeferred {
|
||||
mod __rust_begin_short_backtrace {
|
||||
use core::hint::black_box;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use crate::world::unsafe_world_cell::UnsafeWorldCell;
|
||||
use crate::{
|
||||
error::Result,
|
||||
system::{ReadOnlySystem, ScheduleSystem},
|
||||
world::{unsafe_world_cell::UnsafeWorldCell, World},
|
||||
world::World,
|
||||
};
|
||||
|
||||
/// # Safety
|
||||
/// See `System::run_unsafe`.
|
||||
// This is only used by `MultiThreadedExecutor`, and would be dead code without `std`.
|
||||
#[cfg(feature = "std")]
|
||||
#[inline(never)]
|
||||
pub(super) unsafe fn run_unsafe(system: &mut ScheduleSystem, world: UnsafeWorldCell) -> Result {
|
||||
let result = system.run_unsafe((), world);
|
||||
// Call `black_box` to prevent this frame from being tail-call optimized away
|
||||
black_box(());
|
||||
result
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// See `ReadOnlySystem::run_unsafe`.
|
||||
#[cfg_attr(
|
||||
not(feature = "std"),
|
||||
expect(dead_code, reason = "currently only used with the std feature")
|
||||
)]
|
||||
// This is only used by `MultiThreadedExecutor`, and would be dead code without `std`.
|
||||
#[cfg(feature = "std")]
|
||||
#[inline(never)]
|
||||
pub(super) unsafe fn readonly_run_unsafe<O: 'static>(
|
||||
system: &mut dyn ReadOnlySystem<In = (), Out = O>,
|
||||
world: UnsafeWorldCell,
|
||||
) -> O {
|
||||
// Call `black_box` to prevent this frame from being tail-call optimized away
|
||||
black_box(system.run_unsafe((), world))
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub(super) fn run(system: &mut ScheduleSystem, world: &mut World) -> Result {
|
||||
let result = system.run((), world);
|
||||
// Call `black_box` to prevent this frame from being tail-call optimized away
|
||||
black_box(());
|
||||
result
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub(super) fn run_without_applying_deferred(
|
||||
system: &mut ScheduleSystem,
|
||||
world: &mut World,
|
||||
) -> Result {
|
||||
let result = system.run_without_applying_deferred((), world);
|
||||
// Call `black_box` to prevent this frame from being tail-call optimized away
|
||||
black_box(());
|
||||
result
|
||||
}
|
||||
@ -312,6 +328,7 @@ mod __rust_begin_short_backtrace {
|
||||
system: &mut dyn ReadOnlySystem<In = (), Out = O>,
|
||||
world: &mut World,
|
||||
) -> O {
|
||||
// Call `black_box` to prevent this frame from being tail-call optimized away
|
||||
black_box(system.run((), world))
|
||||
}
|
||||
}
|
||||
|
@ -128,33 +128,16 @@ impl SystemExecutor for SingleThreadedExecutor {
|
||||
}
|
||||
|
||||
let f = AssertUnwindSafe(|| {
|
||||
if system.is_exclusive() {
|
||||
if let Err(err) = __rust_begin_short_backtrace::run(system, world) {
|
||||
error_handler(
|
||||
err,
|
||||
ErrorContext::System {
|
||||
name: system.name(),
|
||||
last_run: system.get_last_run(),
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Use run_unsafe to avoid immediately applying deferred buffers
|
||||
let world = world.as_unsafe_world_cell();
|
||||
system.update_archetype_component_access(world);
|
||||
// SAFETY: We have exclusive, single-threaded access to the world and
|
||||
// update_archetype_component_access is being called immediately before this.
|
||||
unsafe {
|
||||
if let Err(err) = __rust_begin_short_backtrace::run_unsafe(system, world) {
|
||||
error_handler(
|
||||
err,
|
||||
ErrorContext::System {
|
||||
name: system.name(),
|
||||
last_run: system.get_last_run(),
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
if let Err(err) =
|
||||
__rust_begin_short_backtrace::run_without_applying_deferred(system, world)
|
||||
{
|
||||
error_handler(
|
||||
err,
|
||||
ErrorContext::System {
|
||||
name: system.name(),
|
||||
last_run: system.get_last_run(),
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user