Skip to content

Commit

Permalink
Documentation for stage traits.
Browse files Browse the repository at this point in the history
  • Loading branch information
Anders429 committed Jan 31, 2023
1 parent bc2dd3a commit 96a98e0
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 10 deletions.
47 changes: 41 additions & 6 deletions src/system/schedule/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,21 @@ use super::Stages;

define_null!();

/// A stage within a schedule.
///
/// A single stage contains only tasks that can always be run in parallel.
pub trait Stage<'a, R, FI, VI, P, I, Q>: Send
where
R: Registry,
{
/// A list of booleans indicating whether each task within the stage has already been run.
type HasRun: Send;

/// Run all of the tasks within this stage in parallel.
///
/// After the tasks have been scheduled to run, tasks within the following stage will also
/// be attempted to be scheduled. Any tasks that are dynamically found to be able to run in
/// parallel with the current tasks will be executed as well.
fn run<'b, N, NFI, NVI, NP, NI, NQ>(
&mut self,
world: SendableWorld<R>,
Expand All @@ -40,12 +49,24 @@ where
where
N: Stages<'b, R, NFI, NVI, NP, NI, NQ>;

fn run_add_ons(
/// Attempt to run as many tasks within this stage as possible as add-ons to the previous
/// stage.
///
/// `borrowed_archetypes` contains a set of dynamic claims that are already borrowed by the
/// previous stage. This method respects those claims when evaluating whether new tasks can be
/// executed.
///
/// # Safety
/// `borrowed_archetypes` must accurately represent the dynamic claims already made on the
/// component columns within `world`.
unsafe fn run_add_ons(
&mut self,
world: SendableWorld<R>,
borrowed_archetypes: HashMap<archetype::IdentifierRef<R>, R::Claims, FnvBuildHasher>,
) -> Self::HasRun;

/// Creates a new default set of booleans to indicate that each task within the stage has not
/// been run.
fn new_has_run() -> Self::HasRun;
}

Expand All @@ -71,11 +92,13 @@ where
N::new_has_run()
} else {
// Run tasks from next stage that can be parallelized dynamically.
next_stage.run_add_ons(world, borrowed_archetypes)
// SAFETY: The safety contract of this method call is upheld by the safety contract of
// this method.
unsafe { next_stage.run_add_ons(world, borrowed_archetypes) }
}
}

fn run_add_ons(
unsafe fn run_add_ons(
&mut self,
_world: SendableWorld<R>,
_borrowed_archetypes: HashMap<archetype::IdentifierRef<R>, R::Claims, FnvBuildHasher>,
Expand Down Expand Up @@ -186,19 +209,31 @@ where
}
}

fn run_add_ons(
unsafe fn run_add_ons(
&mut self,
world: SendableWorld<R>,
mut borrowed_archetypes: HashMap<archetype::IdentifierRef<R>, R::Claims, FnvBuildHasher>,
) -> Self::HasRun {
if query_archetype_identifiers::<R, T, FI, VI, P, I, Q>(world, &mut borrowed_archetypes) {
rayon::join(
|| (true, self.1.run_add_ons(world, borrowed_archetypes)),
|| {
(
true,
// SAFETY: The safety contract of this method call is upheld by the safety
// contract of this method.
unsafe { self.1.run_add_ons(world, borrowed_archetypes) },
)
},
|| self.0.run(world),
)
.0
} else {
(false, self.1.run_add_ons(world, borrowed_archetypes))
(
false,
// SAFETY: The safety contract of this method call is upheld by the safety contract
// of this method.
unsafe { self.1.run_add_ons(world, borrowed_archetypes) },
)
}
}

Expand Down
34 changes: 30 additions & 4 deletions src/system/schedule/stages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,44 @@ use hashbrown::HashMap;

define_null!();

/// The stages within a schedule.
pub trait Stages<'a, R, FI, VI, P, I, Q>: Send
where
R: Registry,
{
/// A list of booleans indicating whether each task within the first stage has already been run.
type HasRun: Send;

/// Run all of the stages, parallelizing as much work as possible.
///
/// The parallelization strategy involves two parts:
///
/// 1. Compile-time scheduling: at compile time, tasks are split into stages, where all tasks
/// in a stage can always be run in parallel with each other, no matter the `World`.
/// 2. Run-time optimization: at run-time, component claims on archetype tables within the
/// `World` are tracked when scheduling a single stage. Then, any tasks within the next stage
/// whose borrowed components do not interfere with the tasks in the current stage's dynamic
/// claims are run as well.
fn run(&mut self, world: &mut World<R>, has_run: Self::HasRun);

fn run_add_ons(
/// Attempt to run as many tasks within the first stage in the list as possible as add-ons to
/// the previous stage.
///
/// `borrowed_archetypes` contains a set of dynamic claims that are already borrowed by the
/// previous stage. This method respects those claims when evaluating whether new tasks can be
/// executed.
///
/// # Safety
/// `borrowed_archetypes` must accurately represent the dynamic claims already made on the
/// component columns within `world`.
unsafe fn run_add_ons(
&mut self,
world: SendableWorld<R>,
borrowed_archetypes: HashMap<archetype::IdentifierRef<R>, R::Claims, FnvBuildHasher>,
) -> Self::HasRun;

/// Creates a new default set of booleans to indicate that each task within the first stage has
/// not been run.
fn new_has_run() -> Self::HasRun;
}

Expand All @@ -38,7 +62,7 @@ where

fn run(&mut self, _world: &mut World<R>, _has_run: Self::HasRun) {}

fn run_add_ons(
unsafe fn run_add_ons(
&mut self,
_world: SendableWorld<R>,
_borrowed_archetypes: HashMap<archetype::IdentifierRef<R>, R::Claims, FnvBuildHasher>,
Expand Down Expand Up @@ -72,12 +96,14 @@ where
self.1.run(world, next_has_run);
}

fn run_add_ons(
unsafe fn run_add_ons(
&mut self,
world: SendableWorld<R>,
borrowed_archetypes: HashMap<archetype::IdentifierRef<R>, R::Claims, FnvBuildHasher>,
) -> Self::HasRun {
self.0.run_add_ons(world, borrowed_archetypes)
// SAFETY: The safety contract of this method call is upheld by the safety contract of this
// method.
unsafe { self.0.run_add_ons(world, borrowed_archetypes) }
}

fn new_has_run() -> Self::HasRun {
Expand Down

0 comments on commit 96a98e0

Please sign in to comment.