Search documentation of runtime_tools

# View Source scheduler (runtime_tools v2.1)

Measure scheduler utilization

This module contains utility functions for easy measurement and calculation of scheduler utilization. It act as a wrapper around the more primitive API `erlang:statistics(scheduler_wall_time)`.

The simplest usage is to call the blocking `scheduler:utilization(Seconds)`.

For non blocking and/or continuous calculation of scheduler utilization, the recommended usage is:

- First call `erlang:system_flag(scheduler_wall_time, true)` to enable scheduler wall time measurements.
- Call `get_sample/0` to collect samples with some time in between.
- Call `utilization/2` to calculate the scheduler utilization in the interval between two samples.
- When done call `erlang:system_flag(scheduler_wall_time, false)` to disable scheduler wall time measurements and avoid unecessary CPU overhead.

To get correct values from `utilization/2`, it is important that `scheduler_wall_time` is kept enabled during the entire interval between the two samples. To ensure this, the process that called `erlang:system_flag(scheduler_wall_time, true)` must be kept alive, as `scheduler_wall_time` will automatically be disabled if it terminates.

# Summary

## Types

sched_id()
sched_sample()
sched_type()
sched_util_result()

A list of tuples containing results for individual schedulers as well as aggregated averages. `Util` is the scheduler utilization as a floating point value between 0.0 and 1.0. `Percent` is the same utilization as a more human readable string expressed in percent.

## Functions

get_sample()

Returns a scheduler utilization sample for normal and dirty-cpu schedulers. Returns `undefined` if system flag `scheduler_wall_time` has not been enabled.

get_sample_all()

Return a scheduler utilization sample for all schedulers, including dirty-io schedulers. Returns `undefined` if system flag `scheduler_wall_time` has not been enabled.

sample()

Return a scheduler utilization sample for normal and dirty-cpu schedulers. Will call `erlang:system_flag(scheduler_wall_time, true)` first if not already already enabled.

sample_all()

Return a scheduler utilization sample for all schedulers, including dirty-io schedulers. Will call `erlang:system_flag(scheduler_wall_time, true)` first if not already already enabled.

utilization/1

Measure utilization for normal and dirty-cpu schedulers during `Seconds` seconds, and then return the result.

utilization(Sample1, Sample2)

Calculates scheduler utilizations for the time interval between the two samples obtained from calling `get_sample/0` or `get_sample_all/0`.

# Types

Link to this type

# sched_id()

View Source (not exported) (since OTP 21.0)

    -type sched_id() :: integer().

Link to this opaque

# sched_sample()

View Source (since OTP 21.0)

    -opaque sched_sample()

Link to this type

# sched_type()

View Source (not exported) (since OTP 21.0)

    -type sched_type() :: normal | cpu | io.

Link to this type

# sched_util_result()

View Source (not exported) (since OTP 21.0)

    -type sched_util_result() ::
              [{sched_type(), sched_id(), float(), string()} |
               {total, float(), string()} |
               {weighted, float(), string()}].

A list of tuples containing results for individual schedulers as well as aggregated averages. `Util` is the scheduler utilization as a floating point value between 0.0 and 1.0. `Percent` is the same utilization as a more human readable string expressed in percent.

- `{normal, SchedulerId, Util, Percent}` - Scheduler utilization of a normal scheduler with number `SchedulerId`. Schedulers that are not online will also be included. Online schedulers have the lowest `SchedulerId`.

- `{cpu, SchedulerId, Util, Percent}` - Scheduler utilization of a dirty-cpu scheduler with number `SchedulerId`.

- `{io, SchedulerId, Util, Percent}` - Scheduler utilization of a dirty-io scheduler with number `SchedulerId`. This tuple will only exist if both samples were taken with `sample_all/0`.

- `{total, Util, Percent}` - Total utilization of all normal and dirty-cpu schedulers.

- `{weighted, Util, Percent}` - Total utilization of all normal and dirty-cpu schedulers, weighted against maximum amount of available CPU time.

# Functions

Link to this function

# get_sample()

View Source (since OTP 24.3)

    -spec get_sample() -> sched_sample() | undefined.

Returns a scheduler utilization sample for normal and dirty-cpu schedulers. Returns `undefined` if system flag `scheduler_wall_time` has not been enabled.

Link to this function

# get_sample_all()

View Source (since OTP 24.3)

    -spec get_sample_all() -> sched_sample() | undefined.

Return a scheduler utilization sample for all schedulers, including dirty-io schedulers. Returns `undefined` if system flag `scheduler_wall_time` has not been enabled.

Link to this function

# sample()

View Source (since OTP 21.0)

    -spec sample() -> sched_sample().

Return a scheduler utilization sample for normal and dirty-cpu schedulers. Will call `erlang:system_flag(scheduler_wall_time, true)` first if not already already enabled.

> #### Note

> This function is not recommended as there is no way to detect if `scheduler_wall_time` already was enabled or not. If `scheduler_wall_time` has been disabled between two samples, passing them to `utilization/2` will yield invalid results.

> Instead use `get_sample/0` together with `erlang:system_flag(scheduler_wall_time, _)`.

Link to this function

# sample_all()

View Source (since OTP 21.0)

    -spec sample_all() -> sched_sample().

Return a scheduler utilization sample for all schedulers, including dirty-io schedulers. Will call `erlang:system_flag(scheduler_wall_time, true)` first if not already already enabled.

> #### Note

> This function is not recommended for same reason as `sample/0`. Instead use `get_sample_all/0` together with `erlang:system_flag(scheduler_wall_time,_)`.

Link to this function

# utilization/1

View Source (since OTP 21.0)

    -spec utilization(Seconds) -> sched_util_result() when Seconds :: pos_integer();
                     (Sample) -> sched_util_result() when Sample :: sched_sample().

Measure utilization for normal and dirty-cpu schedulers during `Seconds` seconds, and then return the result.

Will automatically first enable and then disable `scheduler_wall_time`.

Calculate scheduler utilizations for the time interval from when `Sample` was taken and "now". The same as calling `scheduler:utilization(Sample, scheduler:sample_all())`.

> #### Note

> This function is not recommended as it's so easy to get invalid results without noticing. In particular do not do this:

>     scheduler:utilization(scheduler:sample()). % DO NOT DO THIS!

> The above example takes two samples in rapid succession and calculates the scheduler utilization between them. The resulting values will probably be more misleading than informative.

> Instead use `scheduler:utilization/2` and call `get_sample/0` to get samples with some time in between.

Link to this function

# utilization(Sample1, Sample2)

View Source (since OTP 21.0)

    -spec utilization(Sample1, Sample2) -> sched_util_result()
                         when Sample1 :: sched_sample(), Sample2 :: sched_sample().

Calculates scheduler utilizations for the time interval between the two samples obtained from calling `get_sample/0` or `get_sample_all/0`.

This function itself, does not need `scheduler_wall_time` to be enabled. However, for a correct result, `scheduler_wall_time` must have been enabled during the entire interval between the two samples.