pub(crate) struct Opts {Show 43 fields
pub(crate) exit_dump_len: u32,
pub(crate) slice_us: Option<u64>,
pub(crate) migration_cost_us: u64,
pub(crate) cache_nice_tries: u32,
pub(crate) no_newidle_cost: bool,
pub(crate) no_newidle_sampling: bool,
pub(crate) no_sis_util: bool,
pub(crate) llc_extend: bool,
pub(crate) disable_numa: bool,
pub(crate) disable_cpufreq: bool,
pub(crate) disable_smt: bool,
pub(crate) disable_cgroups: bool,
pub(crate) enable_cgroups: bool,
pub(crate) disable_cpu_max: bool,
pub(crate) uniform_capacity: bool,
pub(crate) asym_capacity: bool,
pub(crate) capacity_tier_tolerance_pct: Option<u32>,
pub(crate) disable_asym_packing: bool,
pub(crate) smt_asym_packing: bool,
pub(crate) smt_whole_core: bool,
pub(crate) no_wake_sync: bool,
pub(crate) no_wa_weight: bool,
pub(crate) busy_balance_factor: u32,
pub(crate) no_capacity_pressure: bool,
pub(crate) no_task_clock: bool,
pub(crate) no_eligibility: bool,
pub(crate) no_eligible_scan: bool,
pub(crate) no_run_to_parity: bool,
pub(crate) no_preempt_short: bool,
pub(crate) no_place_lag: bool,
pub(crate) no_place_rel_deadline: bool,
pub(crate) no_delay_dequeue: bool,
pub(crate) no_delay_requeue: bool,
pub(crate) no_proxy_exec: bool,
pub(crate) no_hrtick: bool,
pub(crate) no_wakeup_preempt: bool,
pub(crate) no_vref_update: bool,
pub(crate) stats: Option<f64>,
pub(crate) monitor: Option<f64>,
pub(crate) verbose: bool,
pub(crate) version: bool,
pub(crate) help_stats: bool,
pub libbpf: LibbpfOpts,
}Fields§
§exit_dump_len: u32Exit debug dump buffer length. 0 indicates default.
slice_us: Option<u64>Maximum scheduling slice duration in microseconds.
The default is fair.c’s sysctl_sched_base_slice as update_sysctl() sets it: the normalized 700 us scaled by 1 + ilog2(min(nr_cpus, 8)), 2.8 ms on eight CPUs or more, so the two schedulers issue requests of the same size on the same machine. A kernel that runs fair.c at some other slice, /sys/kernel/debug/sched/base_slice_ns says which, is matched by setting it here. A task that has company on its CPU is asked for the CPU when its request runs out, by a timer armed for its deadline, see –no-hrtick, so the slice is what it says whatever the kernel’s HZ. Without the timer a slice is only acted on from the tick, and one of exactly a tick buys two: the task is handed the CPU a few microseconds after the tick that freed it, so at the next tick it is those few microseconds short of its slice and runs a whole further tick.
migration_cost_us: u64Time, in microseconds, that a task stays cache hot on the CPU it last ran on.
A task that stopped running within this long is left alone by the idle CPUs looking for work to steal: its own CPU takes it back within a slice, while moving it costs its cache. This is the equivalent of task_hot() with sysctl_sched_migration_cost in fair.c. 0 makes every queued task stealable right away, which spreads the load faster at the cost of cache locality.
cache_nice_tries: u32Failed scans an idle CPU tolerates before it stops honouring cache hotness.
An idle CPU that finds nothing it is allowed to take, while work is queued somewhere it could have run, counts the attempt; once it has counted more than this many in a row it takes the head of a queue whether or not the task is still hot on the CPU it ran on. This is sd->cache_nice_tries against sd->nr_balance_failed in can_migrate_task(), and the value applies to a scan within the LLC; one more is allowed beyond it. 0 gives up cache locality on the first failure, a large value never gives it up and lets a CPU stay idle beside a runnable task for as long as the task keeps being hot.
no_newidle_cost: boolScan for work on an idle CPU whatever the scan costs.
An idle CPU keeps an average of how long it stays idle after a scan and the most a scan at each level has cost, and does not start a scan its idle time would not pay for, since a CPU its own wakeups keep bringing back is about to have work of its own: sched_balance_newidle()’s avg_idle against sd->max_newidle_lb_cost. This drops only the cost budget; –no-newidle-sampling separately disables success-rate sampling.
no_newidle_sampling: boolDo not sample new-idle scans from their observed success rate.
fair.c’s NI_RANDOM and NI_RATE features avoid repeatedly scanning a domain that rarely supplies work. Each cid and topology level tracks successful pulls and call frequency, then probabilistically admits scans in proportion to that estimate. The estimator compensates a successful sampled scan by its inverse sampling probability.
Sampling is enabled by default, as both fair.c features are. This option makes every new-idle level eligible to scan, subject only to the separate avg-idle cost budget controlled by –no-newidle-cost.
no_sis_util: boolDo not bound wakeup idle scans by the target LLC’s utilization.
fair.c stops looking for an idle CPU once the LLC it is searching is busy enough to make the search unlikely to pay, SIS_UTIL: periodic load balance leaves a scan budget behind, computed from the LLC’s average utilization, which falls quadratically and reaches zero at about 85%. scx_eevdf does the same, over a window that starts at the target and wraps inside the LLC so a bounded scan still reaches every CPU across successive wakeups, and gives up where select_idle_cpu() returns -1 rather than carrying the search on to the node and the machine.
This disables it and scans the whole LLC on every wakeup. Worth trying on a machine whose LLC is small: the scan reads the idle bitmap a word at a time, so an LLC of 64 CPUs or fewer costs one read whatever the budget says, and the bound then only loses idle CPUs it would have found.
llc_extend: boolLook past the target LLC for an idle CPU.
By default, match select_idle_sibling(), which is scoped to sd_llc: when the LLC has no idle CPU, queue the task on its affine target and leave spreading across LLCs to load balance, where the migration cost is weighed against the idle time it would use. This instead extends the wakeup scan to the node and then the whole machine.
This can keep work off a busy SMT sibling when a whole idle core exists in another LLC, at the cost of weaker cache locality and a scan fair.c never pays. It has no effect when one LLC spans every CPU.
disable_numa: boolDisable NUMA optimizations.
disable_cpufreq: boolDisable CPU frequency control.
disable_smt: boolDisable SMT.
disable_cgroups: boolDo not schedule the cpu controller’s cgroups as groups.
By default, a cgroup competes with its siblings at its cpu.weight and its tasks share what it gets, the way fair.c’s group scheduling does, with cpu.weight meaning the weight per active CPU (fair.c’s default cgroup_mode, “concur”).
This schedules tasks on their nice levels alone and ignores cpu.weight. It avoids walking a nested cgroup hierarchy as tasks wake and sleep, trading the cpu controller’s isolation semantics for some throughput.
Group scheduling needs a kernel built with CONFIG_EXT_GROUP_SCHED. If the running kernel lacks it, scx_eevdf falls back to this behavior.
enable_cgroups: boolDeprecated compatibility alias; cgroup scheduling is already enabled.
disable_cpu_max: boolIgnore cpu.max while scheduling cgroups as groups.
A cgroup is normally held to the bandwidth its cpu.max asks for: it runs for at most its quota in every period, and its tasks wait for the next one once it is spent. This turns that off and leaves cpu.weight and cpu.idle in place, which is what the comparison against a kernel with no bandwidth control needs.
Has no further effect with –disable-cgroups.
uniform_capacity: boolForce every CPU to have the same capacity.
By default scx_eevdf uses the kernel-exported cpu_capacity values when the kernel has an active SD_ASYM_CPUCAPACITY domain.
asym_capacity: boolForce asymmetric capacities using the best available hardware estimate.
This uses ACPI CPPC, cpufreq, or cpu_capacity through scx_utils rather than following the kernel’s selected capacity classes. It can therefore expose hybrid x86 capacity differences that fair.c does not use.
capacity_tier_tolerance_pct: Option<u32>Maximum capacity difference, in percent, within one capacity tier.
Capacities are compared with the fastest CPU in the current tier, so small differences such as favored versus ordinary P-cores do not make wakeups chase a marginally faster CPU. A larger gap still starts a new tier and retains the preference for P-cores over E-cores. 0 restores one tier per distinct reported capacity. The default is 0 when following the kernel and 5 with –asym-capacity.
disable_asym_packing: boolDisable the kernel’s SD_ASYM_PACKING CPU preference.
Placement then follows the capacity tiers selected by the default kernel capacity, –uniform-capacity, or –asym-capacity mode.
smt_asym_packing: boolPrefer lower-numbered CPUs within each SMT core.
When the kernel exposes no priority between the threads of a core, pick the lowest-numbered idle sibling of the selected core, at wakeup and for balance destinations. Placement only: cores are not ranked by CPU ID and no task is migrated between the threads of one core. A determinism aid for comparisons, not a performance policy.
smt_whole_core: boolLet a wakeup leave its LLC to find a whole idle core.
An idle SMT sibling of a busy core is half of a core that is already working: placing a task there costs the thread running on the other sibling about half its throughput for as long as the two overlap. By default the idle scan follows select_idle_sibling() and takes that sibling, because fair.c stops at the LLC and leaves the rest to the periodic balancer. This makes the scan prefer a whole idle core in another LLC instead, trading cache locality for core throughput, and only while such a core exists.
It matters on machines whose LLC spans a whole NUMA node: once that node is saturated, everything the machine wakes lands on its busy cores’ siblings while another node’s cores sit fully idle. Barrier- synchronized workloads pay for it many times over, since every thread waits for the halved one. Balancing cannot repair it, as those visits are far shorter than any balance interval.
no_wake_sync: boolDisable direct dispatch during synchronous wakeups.
Enabling this option can lead to a more uniform load distribution across available cores, potentially improving performance in certain scenarios. However, it may come at the cost of reduced efficiency for pipe-intensive workloads that benefit from tighter producer-consumer coupling.
no_wa_weight: boolDo not weigh the waking CPU against the previous one when both are busy.
By default, send the wakee to whichever of its previous CPU and the waking CPU would be lighter after the move. Cid load is sampled from the tick and task load reuses its execution-utilization estimate, so the comparison adds no runnable-state accounting. Disable this on systems where the resulting placement performs worse, such as large asymmetric-SMT systems.
busy_balance_factor: u32Periodic busy load balancing runs every domain-weight milliseconds times this factor, sd->busy_factor (16 in fair.c).
no_capacity_pressure: boolDo not account for CPU capacity unavailable to sched_ext.
By default, measure higher-class displacement from stopping/running events and IRQ/steal time from rq_clock - rq_clock_task. Periodic balance normalizes load by the resulting effective capacity, while retaining its normal imbalance, affinity, hotness, and EEVDF gates. A task displaced by a higher class may be requeued into a less-loaded cid’s EDQ, where it still competes in EEVDF order. Hardware capacity and wakeup placement remain unchanged.
no_task_clock: boolService is charged in rq_clock_task(), the clock update_curr() uses: wall time less the interrupt time and the hypervisor steal time the CPU spent on something else. This charges plain wall time, the rq clock, instead, so a task pays for the interrupts that land on its CPU and for the time the host took from its vCPU.
no_eligibility: boolInterrupt on the deadlines alone, without asking who is owed service.
The wakeup preemption normally fires only when the woken task is owed service and the running one is not, the way pick_eevdf() drops an ineligible current task and then picks an eligible waiter. This skips both tests and decides on the deadlines alone. For comparing the two rules against each other.
no_eligible_scan: boolTake the head of a deadline-ordered queue at dispatch, eligible or not.
The EDQ normally uses its augmented tree to find the earliest-deadline task whose vruntime is eligible in logarithmic time. This option takes the head instead; –no-eligibility implies it. Wakeup preemption and keep-running decisions are head-based either way because they cannot observe the current task, queue, and virtual-time frontier atomically.
no_run_to_parity: boolInterrupt a running task that is still owed service.
The wakeup preemption normally leaves a running task alone until it has had the share its pack owes it, so a woken task with an earlier deadline waits for parity rather than for the slice to end. This drops that protection: the woken task takes the CPU as soon as it is eligible itself. Unlike –no-eligibility the woken task is still asked whether it is owed service; only the task already running loses its protection.
This is RUN_TO_PARITY off, in the sense the feature had when EEVDF was merged. For comparing the two rules against each other.
no_preempt_short: boolKeep a longer-request running task protected from shorter wakees.
Normally an eligible waking task that asks for a shorter request than the task currently running can preempt it despite RUN_TO_PARITY. The wakee is put on an available local DSQ as a one-shot short buddy, matching the wakeup side of PREEMPT_SHORT in fair.c. This option keeps the ordinary protection for comparison.
no_place_lag: boolDo not compensate placement lag for joining a virtual-time pack.
Normally scx_eevdf inflates a task’s placement offset before adding its weight to the destination pack, so the movement of the weighted-average reference does not dilute the requested lag. This disables that PLACE_LAG compensation and restores the older behavior where lag can evaporate as a task repeatedly sleeps and wakes. For comparing the two placement rules against each other.
no_place_rel_deadline: boolGive a task a new request every time it is placed.
A task that is moved to another CPU, or queued again without having slept, normally keeps what is left of the request it was in the middle of: its deadline is carried relative to its vruntime and re-based where it lands. This grants it a whole new request instead, so it sorts behind tasks that were queued after it. A task that slept gets a new request either way.
This is PLACE_REL_DEADLINE off. For comparing the two rules against each other.
no_delay_dequeue: boolLet a task that blocks over-served carry its whole debt across the sleep.
A task that blocks while it is over-served normally has the debt paid off by the pack it left, with the service delivered there while it slept, and never more than paid off: it wakes owing at most what it owed, and often nothing. This makes it carry the whole debt to its next placement instead, however long it slept.
This is DELAY_DEQUEUE and DELAY_ZERO off. For comparing the two rules against each other.
no_delay_requeue: boolWake a task that blocked over-served through the placement.
A task that blocks while it is over-served is still on the runqueue it blocked on as far as fair.c is concerned, and a wakeup that comes before its debt is paid requeues it there, ttwu_runnable(), without choosing a CPU for it: it runs there once it is picked, or wherever a balance moves it. That is what happens here too. This option sends such a task through wake_affine() and the idle scan like any other wakeup instead, so it gets an idle CPU when there is one. Implied by –no-delay-dequeue. For comparing the two rules against each other.
no_proxy_exec: boolLet a task blocked on a mutex block instead of donating its turn.
With proxy execution, a task that blocks on a mutex stays runnable as a donor, and when it is picked its scheduling context runs the mutex owner, which gets the lock released sooner. The donor keeps its place in the queue and is charged for what the owner runs on its behalf, as fair.c does. This makes such a task block and leave the queue instead. Proxy execution is used only on kernels that support it for sched_ext.
no_hrtick: boolNotice the end of a request at the tick after it, not when it happens.
A request is normally ended on the spot by a timer armed for the running task’s deadline whenever it has company, the way HRTICK does in fair.c. Without it a task holds the CPU until the tick that follows the end of its request, up to a whole tick late, and a task waiting behind it waits that long. For comparing the two against each other.
no_wakeup_preempt: boolNever interrupt a running task for a woken one with an earlier deadline.
Every task then runs until its slice ends or it blocks, and a woken task waits for that, up to a full slice. This is the behavior before wakeup preemption was added, kept for comparison.
no_vref_update: boolPlace and test tasks against a pack reference that is not up to date.
A running task’s vruntime is only charged when it stops, so the reference of its pack stands still while it runs and everything read off it in between is behind by up to a request. It is normally brought up to date on the spot, the way update_curr() does before every place_entity() and every entity_eligible(). This reads it as stored, for comparing the two against each other.
stats: Option<f64>Enable stats monitoring with the specified interval.
monitor: Option<f64>Run in stats monitoring mode with the specified interval. Scheduler is not launched.
verbose: boolEnable verbose output, including libbpf details.
version: boolPrint scheduler version and exit.
help_stats: boolShow descriptions for statistics.
libbpf: LibbpfOptsTrait Implementations§
Source§impl Args for Opts
impl Args for Opts
Source§fn group_id() -> Option<Id>
fn group_id() -> Option<Id>
ArgGroup::id][crate::ArgGroup::id] for this set of argumentsSource§fn augment_args<'b>(__clap_app: Command) -> Command
fn augment_args<'b>(__clap_app: Command) -> Command
Source§fn augment_args_for_update<'b>(__clap_app: Command) -> Command
fn augment_args_for_update<'b>(__clap_app: Command) -> Command
Command] so it can instantiate self via
[FromArgMatches::update_from_arg_matches_mut] Read moreSource§impl FromArgMatches for Opts
impl FromArgMatches for Opts
Source§fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
Source§fn from_arg_matches_mut(
__clap_arg_matches: &mut ArgMatches,
) -> Result<Self, Error>
fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>
Source§fn update_from_arg_matches(
&mut self,
__clap_arg_matches: &ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§fn update_from_arg_matches_mut(
&mut self,
__clap_arg_matches: &mut ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches_mut( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§impl Parser for Opts
impl Parser for Opts
§fn parse_from<I, T>(itr: I) -> Self
fn parse_from<I, T>(itr: I) -> Self
§fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
§fn update_from<I, T>(&mut self, itr: I)
fn update_from<I, T>(&mut self, itr: I)
§fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
Auto Trait Implementations§
impl Freeze for Opts
impl RefUnwindSafe for Opts
impl Send for Opts
impl Sync for Opts
impl Unpin for Opts
impl UnsafeUnpin for Opts
impl UnwindSafe for Opts
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.