1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
//! Implements the performance optimization that allows a SIMD-enabled Task
//! to skip saving/restoring SIMD registers when context switching,
//! if and only if it is the only SIMD-enabled Task on its entire core.
//!
//! See the documentation of the [`simd_personality`](../simd_personality/index.html#context-switching) crate
//! for further discussion.
//!
#![no_std]
#[cfg(all(single_simd_task_optimization, not(simd_personality)))]
compile_error!("The `single_simd_task_optimization` cfg requires the `simd_personality` cfg!");
// NOTE: the `cfg_if` macro makes the entire file dependent upon the below config.
#[macro_use] extern crate cfg_if;
cfg_if! { if #[cfg(single_simd_task_optimization)] {
#[macro_use] extern crate log;
extern crate task;
use task::TaskRef;
/// This function should be called when there was a new SIMD-enabled Task
/// that was added to the list of Tasks eligible to run on the given core.
/// # Arguments
/// `tasks_on_core` is an Iterator over all of the `TaskRef`s that
/// are eligible to run on the given core `which_core`.
pub fn simd_tasks_added_to_core<'t, I>(tasks_on_core: I, _which_core: u8)
where I: Iterator<Item = &'t TaskRef>
{
let num_simd_tasks = &tasks_on_core
.filter(|taskref| taskref.simd)
.count();
warn!("simd_tasks_added_to_core(): core {} now has {} SIMD tasks total.",
_which_core, num_simd_tasks);
match num_simd_tasks {
0 => {
error!("BUG: simd_tasks_added_to_core(): there were no SIMD tasks on this core.");
}
1 => {
// Here, we previously had 0 SIMD tasks, and now we have 1.
// TODO: So, convert that one SIMD Task into a non-SIMD Context
// We have to do this conversion here because all SIMD Tasks start out
// using the SIMD-enabled Context by default, just to ensure correcntess.
}
2 => {
// Here, we previously had 1 SIMD task, and now we have 2.
// TODO: Convert all SIMD tasks back to their default state of using the SIMD Context.
}
_ => {
// Here, we had more than one SIMD task, and now we still have more than 1.
// So, those tasks have already been converted back to using the regular SIMD Context,
// therefore, we do not need to do anything
}
}
}
/// This function should be called when there was a SIMD-enabled Task
/// removed from the list of Tasks eligible to run on the given core.
/// # Arguments
/// `tasks_on_core` is an Iterator over all of the `TaskRef`s that
/// are eligible to run on the given core `which_core`.
pub fn simd_tasks_removed_from_core<'t, I>(tasks_on_core: I, _which_core: u8)
where I: Iterator<Item = &'t TaskRef>
{
let num_simd_tasks = &tasks_on_core
.filter(|taskref| taskref.simd)
.count();
warn!("simd_tasks_removed_from_core(): core {} now has {} SIMD tasks total.",
_which_core, num_simd_tasks);
match num_simd_tasks {
0 => {
// Here, we previously had one SIMD Task on this core, but now we have 0.
// Thus, we don't need to do anything because there are no SIMD Tasks to do anything with.
}
1 => {
// Here, we previously had 2 or more SIMD tasks, and now we have 1.
// That means that those SIMD Tasks were all using the SIMD Context,
// but now according to this crate's optimization,
// we can now convert that Task to use non-SIMD context.
// TODO FIXME: So, convert that one SIMD Task into a non-SIMD Context
}
_ => {
// Here, we had more than one SIMD task, and now we still have more than 1.
// So, those tasks have already been converted back to using the regular SIMD Context,
// therefore, we do not need to do anything
}
}
}
}} // end of cfg_if block