scheduler(3)

๐Ÿ“ฆ
version 29.0.6 ยท 3 versions
, in ubuntu stonking

โœจ scheduler ๐Ÿ’… (Erlang Module Definition, section 3 of the manual, and yes bestie this is the one)


๐ŸŒธ NAME ๐ŸŒธ

scheduler โ€” Measure scheduler utilization. That's it, that's the whole vibe check. ๐Ÿซถ


๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

okay so this module is your little group chat with the scheduler ๐Ÿ’– It's got utility functions that make measuring and calculating scheduler utilization easy-peasy, and it's basically a wrapper wrapped around the way more primitive API erlang:statistics(scheduler_wall_time). She's convenient like that. โœจ

The simplest usage โ€” like, the "I have zero energy today" usage โ€” is to call the blocking scheduler:utilization(Seconds). Blocking, as in she will simply sit there for Seconds seconds. No thoughts, head empty, just vibes and a number at the end. ๐Ÿ™ˆ

For non blocking and/or continuous calculation of scheduler utilization, the recommended usage is this little ritual, in order, no skipping steps bestie:

  • 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. ๐Ÿ”ด (fr fr, turn it off, don't be that girl leaving the lights on)
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. ๐Ÿ’€ Like, if that process dies, the whole measurement dies with it. Periodt.

๐ŸŽ€ DATA TYPES ๐ŸŽ€

  • sched_id() :: integer(). โ€” just an integer, she's simple and iconic ๐Ÿ‘‘
  • -opaque sched_sample() โ€” opaque, meaning she's showing you nothing, respect her privacy ๐Ÿ•ถ๏ธ
  • sched_type() :: normal | cpu | io. โ€” the three flavors: normal, cpu, io ๐ŸŒˆ
  • sched_util_result() ::
[{sched_type(), sched_id(), float(), string()} |
 {total, float(), string()} |
 {weighted, float(), string()}].

okay so lemme break this DOWN for you, bestie:

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. So basically Util is the math and Percent is the girl who shows up to the party in a cute outfit. โœจ

  • {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 ๐Ÿ”ฅ

๐ŸŒŸ get_sample()

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. So if you get undefined back, that's the universe telling you to go flip the flag first. ๐Ÿ™ˆ

๐ŸŒŸ get_sample_all()

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. Same energy as above, just with more friends invited to the party. ๐Ÿ’œ

๐ŸŒŸ sample()

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. (yes bestie, the original says "already already" and I am NOT touching her, she's perfect as she is ๐Ÿ˜ญ)

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, _). ๐Ÿšฉ

๐ŸŒŸ sample_all()

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,_). ๐Ÿšฉ

๐ŸŒŸ utilization/1 and utilization/2

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

okay so this one has TWO personalities, depending on how you call her:

Measure utilization for normal and dirty-cpu schedulers during Seconds seconds, and then return the result. She will automatically first enable and then disable scheduler_wall_time for you, like a true bestie handling the logistics. ๐Ÿ’…

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. Give her some SPACE, let her breathe.

๐ŸŒŸ utilization(Sample1, Sample2)

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. No cap, that part is non negotiable. ๐Ÿ”ฅ


๐Ÿ‘‘ SEE ALSO ๐Ÿ‘‘

not me adding a SEE ALSO section when the original didn't have one โ€” there is no SEE ALSO in this page, bestie, I checked. Go read erlang:statistics/1 and erlang:system_flag/2 since those are the ones she's wrapping, iykyk ๐Ÿ’–


๐Ÿ’œ cute little sign-off time ๐Ÿ’œ

This iconic piece of documentation was brought to you by Ericsson AB, from runtime_tools version 2.4, and she answers to the name scheduler(3). Slay, bye bestie! ๐ŸŽ€โœจ๐Ÿฆ‹๐ŸŒธ๐Ÿ’…๐Ÿซถ

๐Ÿ“ฆ where this page comes from