aboutsummaryrefslogtreecommitdiffstats
path: root/erts/doc/src/erlang.xml
diff options
context:
space:
mode:
Diffstat (limited to 'erts/doc/src/erlang.xml')
-rw-r--r--erts/doc/src/erlang.xml574
1 files changed, 392 insertions, 182 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 24a091073d..105734d5b2 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -325,16 +325,11 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code>
is <c>latin1</c>, one byte exists for each character
in the text representation. If <c><anno>Encoding</anno></c> is
<c>utf8</c> or
- <c>unicode</c>, the characters are encoded using UTF-8
- (that is, characters from 128 through 255 are
- encoded in two bytes).</p>
+ <c>unicode</c>, the characters are encoded using UTF-8 where
+ characters may require multiple bytes.</p>
<note>
- <p><c>atom_to_binary(<anno>Atom</anno>, latin1)</c> never
- fails, as the text representation of an atom can only
- contain characters from 0 through 255. In a future release,
- the text representation
- of atoms can be allowed to contain any Unicode character and
- <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> then fails if the
+ <p>As from Erlang/OTP 20, atoms can contain any Unicode character
+ and <c>atom_to_binary(<anno>Atom</anno>, latin1)</c> may fail if the
text representation for <c><anno>Atom</anno></c> contains a Unicode
character &gt; 255.</p>
</note>
@@ -402,13 +397,11 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code>
translation of bytes in the binary is done.
If <c><anno>Encoding</anno></c>
is <c>utf8</c> or <c>unicode</c>, the binary must contain
- valid UTF-8 sequences. Only Unicode characters up
- to 255 are allowed.</p>
+ valid UTF-8 sequences.</p>
<note>
- <p><c>binary_to_atom(<anno>Binary</anno>, utf8)</c> fails if
- the binary contains Unicode characters &gt; 255.
- In a future release, such Unicode characters can be allowed and
- <c>binary_to_atom(<anno>Binary</anno>, utf8)</c> does then not fail.
+ <p>As from Erlang/OTP 20, <c>binary_to_atom(<anno>Binary</anno>, utf8)</c>
+ is capable of encoding any Unicode character. Earlier versions would
+ fail if the binary contained Unicode characters &gt; 255.
For more information about Unicode support in atoms, see the
<seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8
encoded atoms</seealso>
@@ -419,9 +412,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).</code>
> <input>binary_to_atom(&lt;&lt;"Erlang"&gt;&gt;, latin1).</input>
'Erlang'
> <input>binary_to_atom(&lt;&lt;1024/utf8&gt;&gt;, utf8).</input>
-** exception error: bad argument
- in function binary_to_atom/2
- called as binary_to_atom(&lt;&lt;208,128&gt;&gt;,utf8)</pre>
+'Ѐ'</pre>
</desc>
</func>
@@ -733,6 +724,19 @@ hello
</func>
<func>
+ <name name="ceil" arity="1"/>
+ <fsummary>Returns the smallest integer not less than the argument</fsummary>
+ <desc>
+ <p>Returns the smallest integer not less than
+ <c><anno>Number</anno></c>.
+ For example:</p>
+ <pre>
+> <input>ceil(5.5).</input>
+6</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
<name name="check_old_code" arity="1"/>
<fsummary>Check if a module has old code.</fsummary>
<desc>
@@ -1480,6 +1484,20 @@ true</pre>
</func>
<func>
+ <name name="floor" arity="1"/>
+ <fsummary>Returns the largest integer not greater than the argument</fsummary>
+ <desc>
+ <p>Returns the largest integer not greater than
+ <c><anno>Number</anno></c>.
+ For example:</p>
+ <pre>
+> <input>floor(-10.5).</input>
+-11</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="fun_info" arity="1"/>
<fsummary>Information about a fun.</fsummary>
<desc>
@@ -1667,6 +1685,12 @@ true</pre>
the form <c>{garbage_collect,
<anno>RequestId</anno>, <anno>GCResult</anno>}</c>.
</item>
+
+ <tag><c>{type, 'major' | 'minor'}</c></tag>
+ <item>Triggers garbage collection of requested type. Default value is
+ <c>'major'</c>, which would trigger a fullsweep GC.
+ The option <c>'minor'</c> is considered a hint and may lead to
+ either minor or major GC run.</item>
</taglist>
<p>If <c><anno>Pid</anno></c> equals <c>self()</c>, and
no <c>async</c> option has been passed, the garbage
@@ -1789,8 +1813,9 @@ true</pre>
<fsummary>Get the call stack back-trace of the last exception.</fsummary>
<type name="stack_item"/>
<desc>
- <p>Gets the call stack back-trace (<em>stacktrace</em>) of the
- last exception in the calling process as a list of
+ <p>Gets the call stack back-trace (<em>stacktrace</em>) for an
+ exception that has just been caught
+ in the calling process as a list of
<c>{<anno>Module</anno>,<anno>Function</anno>,<anno>Arity</anno>,<anno>Location</anno>}</c>
tuples. Field <c><anno>Arity</anno></c> in the first tuple can be the
argument list of that function call instead of an arity integer,
@@ -1798,6 +1823,29 @@ true</pre>
<p>If there has not been any exceptions in a process, the
stacktrace is <c>[]</c>. After a code change for the process,
the stacktrace can also be reset to <c>[]</c>.</p>
+ <p><c>erlang:get_stacktrace/0</c> is only guaranteed to return
+ a stacktrace if called (directly or indirectly) from within the
+ scope of a <c>try</c> expression. That is, the following call works:</p>
+<pre>
+try Expr
+catch
+ C:R ->
+ {C,R,erlang:get_stacktrace()}
+end</pre>
+ <p>As does this call:</p>
+<pre>
+try Expr
+catch
+ C:R ->
+ {C,R,helper()}
+end
+
+helper() ->
+ erlang:get_stacktrace().</pre>
+
+ <warning><p>In a future release,
+ <c>erlang:get_stacktrace/0</c> will return <c>[]</c> if called
+ from outside a <c>try</c> expression.</p></warning>
<p>The stacktrace is the same data as operator <c>catch</c>
returns, for example:</p>
<pre>
@@ -1922,26 +1970,6 @@ os_prompt%</pre>
</func>
<func>
- <name name="hash" arity="2"/>
- <fsummary>Hash function (deprecated).</fsummary>
- <desc>
- <p>Returns a hash value for <c><anno>Term</anno></c> within the range
- <c>1..<anno>Range</anno></c>. The maximum range is 1..2^27-1.</p>
- <warning>
- <p><em>This BIF is deprecated, as the hash value can differ on
- different architectures.</em> The hash values for integer
- terms &gt; 2^27 and large binaries are
- poor. The BIF is retained for backward compatibility
- reasons (it can have been used to hash records into a file),
- but all new code is to use one of the BIFs
- <seealso marker="#phash/2"><c>erlang:phash/2</c></seealso> or
- <seealso marker="#phash2/1"><c>erlang:phash2/1,2</c></seealso>
- instead.</p>
- </warning>
- </desc>
- </func>
-
- <func>
<name name="hd" arity="1"/>
<fsummary>Head of a list.</fsummary>
<desc>
@@ -2368,10 +2396,10 @@ os_prompt%</pre>
<desc>
<p>Returns the atom whose text representation is
<c><anno>String</anno></c>.</p>
- <p><c><anno>String</anno></c> can only contain ISO-latin-1
- characters (that is, numbers &lt; 256) as the implementation does not
- allow Unicode characters equal to or above 256 in atoms.
- For more information on Unicode support in atoms, see
+ <p>As from Erlang/OTP 20, <c><anno>String</anno></c> may contain
+ any Unicode character. Earlier versions allowed only ISO-latin-1
+ characters as the implementation did not allow Unicode characters
+ above 255. For more information on Unicode support in atoms, see
<seealso marker="erl_ext_dist#utf8_atoms">note on UTF-8
encoded atoms</seealso>
in section "External Term Format" in the User's Guide.</p>
@@ -2495,6 +2523,42 @@ os_prompt%</pre>
</func>
<func>
+ <name name="list_to_port" arity="1"/>
+ <fsummary>Convert from text representation to a port.</fsummary>
+ <desc>
+ <p>Returns a port identifier whose text representation is a
+ <c><anno>String</anno></c>, for example:</p>
+ <pre>
+> <input>list_to_port("#Port&lt;0.4>").</input>
+#Port&lt;0.4></pre>
+ <p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad
+ representation of a port identifier.</p>
+ <warning>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
+ </warning>
+ </desc>
+ </func>
+
+ <func>
+ <name name="list_to_ref" arity="1"/>
+ <fsummary>Convert from text representation to a ref.</fsummary>
+ <desc>
+ <p>Returns a reference whose text representation is a
+ <c><anno>String</anno></c>, for example:</p>
+ <pre>
+> <input>list_to_ref("#Ref&lt;0.4192537678.4073193475.71181>").</input>
+#Ref&lt;0.4192537678.4073193475.71181></pre>
+ <p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad
+ representation of a reference.</p>
+ <warning>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
+ </warning>
+ </desc>
+ </func>
+
+ <func>
<name name="list_to_tuple" arity="1"/>
<fsummary>Convert a list to a tuple.</fsummary>
<desc>
@@ -2544,13 +2608,6 @@ os_prompt%</pre>
<name name="load_nif" arity="2"/>
<fsummary>Load NIF library.</fsummary>
<desc>
- <note>
- <p>Before Erlang/OTP R14B, NIFs were an
- experimental feature. Versions before Erlang/OTP R14B can
- have different and possibly incompatible NIF semantics and
- interfaces. For example, in Erlang/OTP R13B03 the return value on
- failure was <c>{error,Reason,Text}</c>.</p>
- </note>
<p>Loads and links a dynamic library containing native
implemented functions (NIFs) for a module. <c><anno>Path</anno></c>
is a file path to the shareable object/dynamic library file minus
@@ -2580,14 +2637,22 @@ os_prompt%</pre>
<item>The library did not fulfill the requirements as a NIF
library of the calling module.
</item>
- <tag><c>load | reload | upgrade</c></tag>
+ <tag><c>load | upgrade</c></tag>
<item>The corresponding library callback was unsuccessful.
</item>
+ <tag><c>reload</c></tag>
+ <item>A NIF library is already loaded for this module instance.
+ The previously deprecated <c>reload</c> feature was removed in OTP 20.
+ </item>
<tag><c>old_code</c></tag>
<item>The call to <c>load_nif/2</c> was made from the old
code of a module that has been upgraded; this is not
allowed.
</item>
+ <tag><c>notsup</c></tag>
+ <item>Lack of support. Such as loading NIF library for a
+ HiPE compiled module.
+ </item>
</taglist>
</desc>
</func>
@@ -3784,9 +3849,6 @@ RealSystem = system + MissedSystem</code>
<c><anno>Term</anno></c> within the range
<c>1..<anno>Range</anno></c>. The maximum value for
<c><anno>Range</anno></c> is 2^32.</p>
- <p>This BIF can be used instead of the old deprecated BIF
- <c>erlang:hash/2</c>, as it calculates better hashes for
- all data types, but consider using <c>phash2/1,2</c> instead.</p>
</desc>
</func>
@@ -3821,10 +3883,6 @@ RealSystem = system + MissedSystem</code>
<desc>
<p>Returns a string corresponding to the text
representation of <c><anno>Pid</anno></c>.</p>
- <warning>
- <p>This BIF is intended for debugging and is not to be used
- in application programs.</p>
- </warning>
</desc>
</func>
@@ -4397,10 +4455,6 @@ RealSystem = system + MissedSystem</code>
<desc>
<p>Returns a string corresponding to the text
representation of the port identifier <c><anno>Port</anno></c>.</p>
- <warning>
- <p>This BIF is intended for debugging. It is not to be used
- in application programs.</p>
- </warning>
</desc>
</func>
@@ -4597,7 +4651,7 @@ RealSystem = system + MissedSystem</code>
<p>If the process potentially can get many messages,
you are advised to set the flag to <c>off_heap</c>. This
because a garbage collection with many messages placed on
- the heap can become extremly expensive and the process can
+ the heap can become extremely expensive and the process can
consume large amounts of memory. Performance of the
actual message passing is however generally better when not
using flag <c>off_heap</c>.</p>
@@ -6094,28 +6148,60 @@ true</pre>
<fsummary>Information about active processes and ports.</fsummary>
<desc>
<marker id="statistics_active_tasks"></marker>
+ <p>Returns the same as
+ <seealso marker="#statistics_active_tasks_all">
+ <c>statistics(active_tasks_all)</c></seealso>
+ with the exception that no information about the dirty
+ IO run queue and its associated schedulers is part of
+ the result. That is, only tasks that are expected to be
+ CPU bound are part of the result.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="statistics" arity="1" clause_i="2"/>
+ <fsummary>Information about active processes and ports.</fsummary>
+ <desc>
+ <marker id="statistics_active_tasks_all"></marker>
<p>Returns a list where each element represents the amount
of active processes and ports on each run queue and its
- associated scheduler. That is, the number of processes and
- ports that are ready to run, or are currently running. The
- element location in the list corresponds to the scheduler
- and its run queue. The first element corresponds to scheduler
- number 1 and so on. The information is <em>not</em> gathered
- atomically. That is, the result is not necessarily a
- consistent snapshot of the state, but instead quite
- efficiently gathered.</p>
+ associated schedulers. That is, the number of processes and
+ ports that are ready to run, or are currently running.
+ Values for normal run queues and their associated schedulers
+ are located first in the resulting list. The first element
+ corresponds to scheduler number 1 and so on. If support for
+ dirty schedulers exist, an element with the value for the
+ dirty CPU run queue and its associated dirty CPU schedulers
+ follow and then as last element the value for the the dirty
+ IO run queue and its associated dirty IO schedulers follow.
+ The information is <em>not</em> gathered atomically. That is,
+ the result is not necessarily a consistent snapshot of the
+ state, but instead quite efficiently gathered.</p>
+ <note><p>Each normal scheduler has one run queue that it
+ manages. If dirty schedulers schedulers are supported, all
+ dirty CPU schedulers share one run queue, and all dirty IO
+ schedulers share one run queue. That is, we have multiple
+ normal run queues, one dirty CPU run queue and one dirty
+ IO run queue. Work can <em>not</em> migrate between the
+ different types of run queues. Only work in normal run
+ queues can migrate to other normal run queues. This has
+ to be taken into account when evaluating the result.</p></note>
<p>See also
<seealso marker="#statistics_total_active_tasks">
<c>statistics(total_active_tasks)</c></seealso>,
<seealso marker="#statistics_run_queue_lengths">
- <c>statistics(run_queue_lengths)</c></seealso>, and
+ <c>statistics(run_queue_lengths)</c></seealso>,
+ <seealso marker="#statistics_run_queue_lengths_all">
+ <c>statistics(run_queue_lengths_all)</c></seealso>,
<seealso marker="#statistics_total_run_queue_lengths">
- <c>statistics(total_run_queue_lengths)</c></seealso>.</p>
+ <c>statistics(total_run_queue_lengths)</c></seealso>, and
+ <seealso marker="#statistics_total_run_queue_lengths_all">
+ <c>statistics(total_run_queue_lengths_all)</c></seealso>.</p>
</desc>
</func>
<func>
- <name name="statistics" arity="1" clause_i="2"/>
+ <name name="statistics" arity="1" clause_i="3"/>
<fsummary>Information about context switches.</fsummary>
<desc>
<p>Returns the total number of context switches since the
@@ -6124,7 +6210,7 @@ true</pre>
</func>
<func>
- <name name="statistics" arity="1" clause_i="3"/>
+ <name name="statistics" arity="1" clause_i="4"/>
<fsummary>Information about exact reductions.</fsummary>
<desc>
<marker id="statistics_exact_reductions"></marker>
@@ -6140,7 +6226,7 @@ true</pre>
</func>
<func>
- <name name="statistics" arity="1" clause_i="4"/>
+ <name name="statistics" arity="1" clause_i="5"/>
<fsummary>Information about garbage collection.</fsummary>
<desc>
<p>Returns information about garbage collection, for example:</p>
@@ -6152,7 +6238,7 @@ true</pre>
</func>
<func>
- <name name="statistics" arity="1" clause_i="5"/>
+ <name name="statistics" arity="1" clause_i="6"/>
<fsummary>Information about I/O.</fsummary>
<desc>
<p>Returns <c><anno>Input</anno></c>,
@@ -6163,7 +6249,7 @@ true</pre>
</func>
<func>
- <name name="statistics" arity="1" clause_i="6"/>
+ <name name="statistics" arity="1" clause_i="7"/>
<fsummary>Information about microstate accounting.</fsummary>
<desc>
<marker id="statistics_microstate_accounting"></marker>
@@ -6299,7 +6385,7 @@ lists:map(
</func>
<func>
- <name name="statistics" arity="1" clause_i="7"/>
+ <name name="statistics" arity="1" clause_i="8"/>
<fsummary>Information about reductions.</fsummary>
<desc>
<marker id="statistics_reductions"></marker>
@@ -6318,12 +6404,13 @@ lists:map(
</func>
<func>
- <name name="statistics" arity="1" clause_i="8"/>
+ <name name="statistics" arity="1" clause_i="9"/>
<fsummary>Information about the run-queues.</fsummary>
<desc><marker id="statistics_run_queue"></marker>
- <p>Returns the total length of the run-queues. That is, the number
+ <p>Returns the total length of all normal run-queues. That is, the number
of processes and ports that are ready to run on all available
- run-queues. The information is gathered atomically. That
+ normal run-queues. Dirty run queues are not part of the
+ result. The information is gathered atomically. That
is, the result is a consistent snapshot of the state, but
this operation is much more expensive compared to
<seealso marker="#statistics_total_run_queue_lengths">
@@ -6333,29 +6420,63 @@ lists:map(
</func>
<func>
- <name name="statistics" arity="1" clause_i="9"/>
+ <name name="statistics" arity="1" clause_i="10"/>
<fsummary>Information about the run-queue lengths.</fsummary>
<desc><marker id="statistics_run_queue_lengths"></marker>
+ <p>Returns the same as
+ <seealso marker="#statistics_run_queue_lengths_all">
+ <c>statistics(run_queue_lengths_all)</c></seealso>
+ with the exception that no information about the dirty
+ IO run queue is part of the result. That is, only
+ run queues with work that is expected to be CPU bound
+ is part of the result.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="statistics" arity="1" clause_i="11"/>
+ <fsummary>Information about the run-queue lengths.</fsummary>
+ <desc><marker id="statistics_run_queue_lengths_all"></marker>
<p>Returns a list where each element represents the amount
- of processes and ports ready to run for each run queue. The
- element location in the list corresponds to the run queue
- of a scheduler. The first element corresponds to the run
- queue of scheduler number 1 and so on. The information is
- <em>not</em> gathered atomically. That is, the result is
- not necessarily a consistent snapshot of the state, but
- instead quite efficiently gathered.</p>
+ of processes and ports ready to run for each run queue.
+ Values for normal run queues are located first in the
+ resulting list. The first element corresponds to the
+ normal run queue of scheduler number 1 and so on. If
+ support for dirty schedulers exist, values for the dirty
+ CPU run queue and the dirty IO run queue follow (in that
+ order) at the end. The information is <em>not</em>
+ gathered atomically. That is, the result is not
+ necessarily a consistent snapshot of the state, but
+ instead quite efficiently gathered.</p>
+ <note><p>Each normal scheduler has one run queue that it
+ manages. If dirty schedulers schedulers are supported, all
+ dirty CPU schedulers share one run queue, and all dirty IO
+ schedulers share one run queue. That is, we have multiple
+ normal run queues, one dirty CPU run queue and one dirty
+ IO run queue. Work can <em>not</em> migrate between the
+ different types of run queues. Only work in normal run
+ queues can migrate to other normal run queues. This has
+ to be taken into account when evaluating the result.</p></note>
<p>See also
+ <seealso marker="#statistics_run_queue_lengths">
+ <c>statistics(run_queue_lengths)</c></seealso>,
+ <seealso marker="#statistics_total_run_queue_lengths_all">
+ <c>statistics(total_run_queue_lengths_all)</c></seealso>,
<seealso marker="#statistics_total_run_queue_lengths">
<c>statistics(total_run_queue_lengths)</c></seealso>,
<seealso marker="#statistics_active_tasks">
- <c>statistics(active_tasks)</c></seealso>, and
+ <c>statistics(active_tasks)</c></seealso>,
+ <seealso marker="#statistics_active_tasks_all">
+ <c>statistics(active_tasks_all)</c></seealso>, and
<seealso marker="#statistics_total_active_tasks">
- <c>statistics(total_active_tasks)</c></seealso>.</p>
+ <c>statistics(total_active_tasks)</c></seealso>,
+ <seealso marker="#statistics_total_active_tasks_all">
+ <c>statistics(total_active_tasks_all)</c></seealso>.</p>
</desc>
</func>
<func>
- <name name="statistics" arity="1" clause_i="10"/>
+ <name name="statistics" arity="1" clause_i="12"/>
<fsummary>Information about runtime.</fsummary>
<desc>
<p>Returns information about runtime, in milliseconds.</p>
@@ -6373,7 +6494,7 @@ lists:map(
</func>
<func>
- <name name="statistics" arity="1" clause_i="11"/>
+ <name name="statistics" arity="1" clause_i="13"/>
<fsummary>Information about each schedulers work time.</fsummary>
<desc>
<marker id="statistics_scheduler_wall_time"></marker>
@@ -6386,12 +6507,17 @@ lists:map(
<c><anno>TotalTime</anno></c> is the total time duration since
<seealso marker="#system_flag_scheduler_wall_time">
<c>scheduler_wall_time</c></seealso>
- activation. The time unit is undefined and can be subject
- to change between releases, OSs, and system restarts.
- <c>scheduler_wall_time</c> is only to be used to
- calculate relative values for scheduler-utilization.
- <c><anno>ActiveTime</anno></c> can never exceed
- <c><anno>TotalTime</anno></c>.</p>
+ activation for the specific scheduler. Note that
+ activation time can differ significantly between
+ schedulers. Currently dirty schedulers are activated
+ at system start while normal schedulers are activated
+ some time after the <c>scheduler_wall_time</c>
+ functionality is enabled. The time unit is undefined
+ and can be subject to change between releases, OSs,
+ and system restarts. <c>scheduler_wall_time</c> is only
+ to be used to calculate relative values for scheduler
+ utilization. <c><anno>ActiveTime</anno></c> can never
+ exceed <c><anno>TotalTime</anno></c>.</p>
<p>The definition of a busy scheduler is when it is not idle
and is not scheduling (selecting) a process or port,
that is:</p>
@@ -6409,15 +6535,37 @@ lists:map(
<c>scheduler_wall_time</c></seealso> is turned off.</p>
<p>The list of scheduler information is unsorted and can
appear in different order between calls.</p>
+ <p>As of ERTS version 9.0, also dirty CPU schedulers will
+ be included in the result. That is, all scheduler threads
+ that are expected to handle CPU bound work. If you also
+ want information about dirty I/O schedulers, use
+ <seealso marker="#statistics_scheduler_wall_time_all"><c>statistics(scheduler_wall_time_all)</c></seealso>
+ instead.</p>
+
+ <p>Normal schedulers will have scheduler identifiers in
+ the range <c>1 =&lt; <anno>SchedulerId</anno> =&lt;
+ </c><seealso marker="#system_info_schedulers"><c>erlang:system_info(schedulers)</c></seealso>.
+ Dirty CPU schedulers will have scheduler identifiers in
+ the range <c>erlang:system_info(schedulers) &lt;
+ <anno>SchedulerId</anno> =&lt; erlang:system_info(schedulers)
+ +
+ </c><seealso marker="#system_info_dirty_cpu_schedulers"><c>erlang:system_info(dirty_cpu_schedulers)</c></seealso>.
+ </p>
+ <note><p>The different types of schedulers handle
+ specific types of jobs. Every job is assigned to a specific
+ scheduler type. Jobs can migrate between different schedulers
+ of the same type, but never between schedulers of different
+ types. This fact has to be taken under consideration when
+ evaluating the result returned.</p></note>
<p>Using <c>scheduler_wall_time</c> to calculate
- scheduler-utilization:</p>
+ scheduler utilization:</p>
<pre>
> <input>erlang:system_flag(scheduler_wall_time, true).</input>
false
> <input>Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input>
ok</pre>
<p>Some time later the user takes another snapshot and calculates
- scheduler-utilization per scheduler, for example:</p>
+ scheduler utilization per scheduler, for example:</p>
<pre>
> <input>Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input>
ok
@@ -6432,11 +6580,32 @@ ok
{7,0.973237033077876},
{8,0.9741297293248656}]</pre>
<p>Using the same snapshots to calculate a total
- scheduler-utilization:</p>
+ scheduler utilization:</p>
<pre>
> <input>{A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) ->
- {Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)), A/T.</input>
+ {Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)),
+ TotalSchedulerUtilization = A/T.</input>
+0.9769136803764825</pre>
+ <p>Total scheduler utilization will equal <c>1.0</c> when
+ all schedulers have been active all the time between the
+ two measurements.</p>
+ <p>Another (probably more) useful value is to calculate
+ total scheduler utilization weighted against maximum amount
+ of available CPU time:</p>
+ <pre>
+> <input>WeightedSchedulerUtilization = (TotalSchedulerUtilization
+ * (erlang:system_info(schedulers)
+ + erlang:system_info(dirty_cpu_schedulers)))
+ / erlang:system_info(logical_processors_available).</input>
0.9769136803764825</pre>
+ <p>This weighted scheduler utilization will reach <c>1.0</c>
+ when schedulers are active the same amount of time as
+ maximum available CPU time. If more schedulers exist
+ than available logical processors, this value may
+ be greater than <c>1.0</c>.</p>
+ <p>As of ERTS version 9.0, the Erlang runtime system
+ with SMP support will as default have more schedulers
+ than logical processors. This due to the dirty schedulers.</p>
<note>
<p><c>scheduler_wall_time</c> is by default disabled. To
enable it, use
@@ -6446,47 +6615,72 @@ ok
</func>
<func>
- <name name="statistics" arity="1" clause_i="12"/>
+ <name name="statistics" arity="1" clause_i="14"/>
+ <fsummary>Information about each schedulers work time.</fsummary>
+ <desc>
+ <marker id="statistics_scheduler_wall_time_all"></marker>
+ <p>The same as
+ <seealso marker="#statistics_scheduler_wall_time"><c>statistics(scheduler_wall_time)</c></seealso>,
+ except that it also include information about all dirty I/O
+ schedulers.</p>
+ <p>Dirty IO schedulers will have scheduler identifiers in
+ the range
+ <seealso marker="#system_info_schedulers"><c>erlang:system_info(schedulers)</c></seealso><c>
+ +
+ </c><seealso marker="#system_info_dirty_cpu_schedulers"><c>erlang:system_info(dirty_cpu_schedulers)</c></seealso><c> &lt;
+ <anno>SchedulerId</anno> =&lt; erlang:system_info(schedulers)
+ + erlang:system_info(dirty_cpu_schedulers)
+ +
+ </c><seealso marker="#system_info_dirty_io_schedulers"><c>erlang:system_info(dirty_io_schedulers)</c></seealso>.</p>
+ <note><p>Note that work executing on dirty I/O schedulers
+ are expected to mainly wait for I/O. That is, when you
+ get high scheduler utilization on dirty I/O schedulers,
+ CPU utilization is <em>not</em> expected to be high due to
+ this work.</p></note>
+ </desc>
+ </func>
+ <func>
+ <name name="statistics" arity="1" clause_i="15"/>
<fsummary>Information about active processes and ports.</fsummary>
<desc><marker id="statistics_total_active_tasks"></marker>
- <p>Returns the total amount of active processes and ports in
- the system. That is, the number of processes and ports that
- are ready to run, or are currently running. The information
- is <em>not</em> gathered atomically. That is, the result
- is not necessarily a consistent snapshot of the state, but
- instead quite efficiently gathered.</p>
- <p>See also
- <seealso marker="#statistics_active_tasks">
- <c>statistics(active_tasks)</c></seealso>,
- <seealso marker="#statistics_run_queue_lengths">
- <c>statistics(run_queue_lengths)</c></seealso>, and
- <seealso marker="#statistics_total_run_queue_lengths">
- <c>statistics(total_run_queue_lengths)</c></seealso>.</p>
+ <p>The same as calling
+ <c>lists:sum(</c><seealso marker="#statistics_active_tasks"><c>statistics(active_tasks)</c></seealso><c>)</c>,
+ but more efficient.</p>
</desc>
</func>
<func>
- <name name="statistics" arity="1" clause_i="13"/>
+ <name name="statistics" arity="1" clause_i="16"/>
+ <fsummary>Information about active processes and ports.</fsummary>
+ <desc><marker id="statistics_total_active_tasks_all"></marker>
+ <p>The same as calling
+ <c>lists:sum(</c><seealso marker="#statistics_active_tasks_all"><c>statistics(active_tasks_all)</c></seealso><c>)</c>,
+ but more efficient.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="statistics" arity="1" clause_i="17"/>
<fsummary>Information about the run-queue lengths.</fsummary>
<desc><marker id="statistics_total_run_queue_lengths"></marker>
- <p>Returns the total length of the run queues. That is, the number
- of processes and ports that are ready to run on all available
- run queues. The information is <em>not</em> gathered atomically.
- That is, the result is not necessarily a consistent snapshot of
- the state, but much more efficiently gathered compared to
- <seealso marker="#statistics_run_queue">
- <c>statistics(run_queue)</c></seealso>.</p>
- <p>See also <seealso marker="#statistics_run_queue_lengths">
- <c>statistics(run_queue_lengths)</c></seealso>,
- <seealso marker="#statistics_total_active_tasks">
- <c>statistics(total_active_tasks)</c></seealso>, and
- <seealso marker="#statistics_active_tasks">
- <c>statistics(active_tasks)</c></seealso>.</p>
+ <p>The same as calling
+ <c>lists:sum(</c><seealso marker="#statistics_run_queue_lengths"><c>statistics(run_queue_lengths)</c></seealso><c>)</c>,
+ but more efficient.</p>
</desc>
</func>
<func>
- <name name="statistics" arity="1" clause_i="14"/>
+ <name name="statistics" arity="1" clause_i="18"/>
+ <fsummary>Information about the run-queue lengths.</fsummary>
+ <desc><marker id="statistics_total_run_queue_lengths_all"></marker>
+ <p>The same as calling
+ <c>lists:sum(</c><seealso marker="#statistics_run_queue_lengths_all"><c>statistics(run_queue_lengths_all)</c></seealso><c>)</c>,
+ but more efficient.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name name="statistics" arity="1" clause_i="19"/>
<fsummary>Information about wall clock.</fsummary>
<desc>
<p>Returns information about wall clock. <c>wall_clock</c> can
@@ -6692,11 +6886,6 @@ ok
down to 3. Similarly, the number of dirty CPU schedulers
online increases proportionally to increases in the number of
schedulers online.</p>
- <note>
- <p>The dirty schedulers functionality is experimental.
- Enable support for dirty schedulers when building OTP to
- try out the functionality.</p>
- </note>
<p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">
<c>erlang:system_info(dirty_cpu_schedulers)</c></seealso> and
@@ -7199,8 +7388,8 @@ ok
</func>
<func>
- <name name="system_info" arity="1" clause_i="10"/>
- <name name="system_info" arity="1" clause_i="11"/>
+ <name name="system_info" arity="1" clause_i="12"/>
+ <name name="system_info" arity="1" clause_i="13"/>
<fsummary>Information about the CPU topology of the system.</fsummary>
<type name="cpu_topology"/>
<type name="level_entry"/>
@@ -7300,12 +7489,12 @@ ok
</func>
<func>
- <name name="system_info" arity="1" clause_i="27"/>
- <name name="system_info" arity="1" clause_i="28"/>
- <name name="system_info" arity="1" clause_i="36"/>
- <name name="system_info" arity="1" clause_i="37"/>
+ <name name="system_info" arity="1" clause_i="29"/>
+ <name name="system_info" arity="1" clause_i="30"/>
<name name="system_info" arity="1" clause_i="38"/>
<name name="system_info" arity="1" clause_i="39"/>
+ <name name="system_info" arity="1" clause_i="40"/>
+ <name name="system_info" arity="1" clause_i="41"/>
<fsummary>Information about the default process heap settings.</fsummary>
<type name="message_queue_data"/>
<type name="max_heap_size"/>
@@ -7348,12 +7537,6 @@ ok
see <seealso marker="#process_flag_max_heap_size">
<c>process_flag(max_heap_size, MaxHeapSize)</c></seealso>.</p>
</item>
- <tag><c>min_heap_size</c></tag>
- <item>
- <p>Returns <c>{min_heap_size, <anno>MinHeapSize</anno>}</c>,
- where <c><anno>MinHeapSize</anno></c> is the current
- system-wide minimum heap size for spawned processes.</p>
- </item>
<tag><marker id="system_info_message_queue_data"/>
<c>message_queue_data</c></tag>
<item>
@@ -7366,6 +7549,12 @@ ok
<seealso marker="#process_flag_message_queue_data">
<c>process_flag(message_queue_data, MQD)</c></seealso>.</p>
</item>
+ <tag><c>min_heap_size</c></tag>
+ <item>
+ <p>Returns <c>{min_heap_size, <anno>MinHeapSize</anno>}</c>,
+ where <c><anno>MinHeapSize</anno></c> is the current
+ system-wide minimum heap size for spawned processes.</p>
+ </item>
<tag><c>min_bin_vheap_size</c></tag>
<item>
<p>Returns <c>{min_bin_vheap_size,
@@ -7382,8 +7571,8 @@ ok
<name name="system_info" arity="1" clause_i="7"/>
<name name="system_info" arity="1" clause_i="8"/>
<name name="system_info" arity="1" clause_i="9"/>
- <name name="system_info" arity="1" clause_i="12"/>
- <name name="system_info" arity="1" clause_i="13"/>
+ <name name="system_info" arity="1" clause_i="10"/>
+ <name name="system_info" arity="1" clause_i="11"/>
<name name="system_info" arity="1" clause_i="14"/>
<name name="system_info" arity="1" clause_i="15"/>
<name name="system_info" arity="1" clause_i="16"/>
@@ -7397,15 +7586,15 @@ ok
<name name="system_info" arity="1" clause_i="24"/>
<name name="system_info" arity="1" clause_i="25"/>
<name name="system_info" arity="1" clause_i="26"/>
- <name name="system_info" arity="1" clause_i="29"/>
- <name name="system_info" arity="1" clause_i="30"/>
+ <name name="system_info" arity="1" clause_i="27"/>
+ <name name="system_info" arity="1" clause_i="28"/>
<name name="system_info" arity="1" clause_i="31"/>
<name name="system_info" arity="1" clause_i="32"/>
<name name="system_info" arity="1" clause_i="33"/>
<name name="system_info" arity="1" clause_i="34"/>
<name name="system_info" arity="1" clause_i="35"/>
- <name name="system_info" arity="1" clause_i="40"/>
- <name name="system_info" arity="1" clause_i="41"/>
+ <name name="system_info" arity="1" clause_i="36"/>
+ <name name="system_info" arity="1" clause_i="37"/>
<name name="system_info" arity="1" clause_i="42"/>
<name name="system_info" arity="1" clause_i="43"/>
<name name="system_info" arity="1" clause_i="44"/>
@@ -7434,16 +7623,28 @@ ok
<name name="system_info" arity="1" clause_i="67"/>
<name name="system_info" arity="1" clause_i="68"/>
<name name="system_info" arity="1" clause_i="69"/>
+ <name name="system_info" arity="1" clause_i="70"/>
+ <name name="system_info" arity="1" clause_i="71"/>
<fsummary>Information about the system.</fsummary>
<desc>
<p>Returns various information about the current system
(emulator) as specified by <c><anno>Item</anno></c>:</p>
<taglist>
- <tag><c>allocated_areas</c>, <c>allocator</c>,
- <c>alloc_util_allocators</c>, <c>allocator_sizes</c></tag>
+ <tag><c>atom_count</c></tag>
+ <item>
+ <marker id="system_info_atom_count"></marker>
+ <p>Returns the number of atoms currently existing at the
+ local node. The value is given as an integer.</p>
+ </item>
+ <tag><c>atom_limit</c></tag>
<item>
- <p>See <seealso marker="#system_info_allocator_tags">
- above</seealso>.</p>
+ <marker id="system_info_atom_limit"></marker>
+ <p>Returns the maximum number of atoms allowed.
+ This limit can be increased at startup by passing
+ command-line flag
+ <seealso marker="erts:erl#+t"><c>+t</c></seealso> to
+ <c>erl(1)</c>.
+ </p>
</item>
<tag><c>build_type</c></tag>
<item>
@@ -7529,9 +7730,6 @@ ok
<seealso marker="erts:erl#+SDcpu"><c>+SDcpu</c></seealso> or
<seealso marker="erts:erl#+SDPcpu"><c>+SDPcpu</c></seealso> in
<c>erl(1)</c>.</p>
- <p>Notice that the dirty schedulers functionality is
- experimental. Enable support for dirty schedulers when
- building OTP to try out the functionality.</p>
<p>See also
<seealso marker="#system_flag_dirty_cpu_schedulers_online">
<c>erlang:system_flag(dirty_cpu_schedulers_online,
@@ -7561,9 +7759,6 @@ ok
startup by passing command-line flag
<seealso marker="erts:erl#+SDcpu"><c>+SDcpu</c></seealso> in
<c>erl(1)</c>.</p>
- <p>Notice that the dirty schedulers functionality is
- experimental. Enable support for dirty schedulers when
- building OTP to try out the functionality.</p>
<p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">
<c>erlang:system_info(dirty_cpu_schedulers)</c></seealso>,
@@ -7585,9 +7780,6 @@ ok
<p>This value can be set at startup by passing command-line
argument <seealso marker="erts:erl#+SDio"><c>+SDio</c></seealso>
in <c>erl(1)</c>.</p>
- <p>Notice that the dirty schedulers functionality is
- experimental. Enable support for dirty schedulers when
- building OTP to try out the functionality.</p>
<p>For more information, see
<seealso marker="#system_info_dirty_cpu_schedulers">
<c>erlang:system_info(dirty_cpu_schedulers)</c></seealso>,
@@ -8671,18 +8863,36 @@ hello
<p>Option <c>{minor_version, <anno>Version</anno>}</c>
can be used to control some
encoding details. This option was introduced in Erlang/OTP R11B-4.
- The valid values for <c><anno>Version</anno></c> are
- <c>0</c> and <c>1</c>.</p>
- <p>As from Erlang/OTP 17.0, <c>{minor_version, 1}</c> is the default. It
- forces any floats in the term to be encoded in a more
- space-efficient and exact way (namely in the 64-bit IEEE format,
- rather than converted to a textual representation).</p>
- <p>As from Erlang/OTP R11B-4, <c>binary_to_term/1</c> can decode this
- representation.</p>
- <p><c>{minor_version, 0}</c> means that floats are encoded
- using a textual representation. This option is useful to
- ensure that releases before Erlang/OTP R11B-4 can decode resulting
- binary.</p>
+ The valid values for <c><anno>Version</anno></c> are:</p>
+ <taglist>
+ <tag><c>0</c></tag>
+ <item>
+ <p>Floats are encoded using a textual representation.
+ This option is useful to ensure that releases before Erlang/OTP
+ R11B-4 can decode resulting binary.</p>
+ <p>This version encode atoms that can be represented by a
+ latin1 string using latin1 encoding while only atoms that
+ cannot be represented by latin1 are encoded using utf8.</p>
+ </item>
+ <tag><c>1</c></tag>
+ <item>
+ <p>This is as of Erlang/OTP 17.0 the default. It forces any floats
+ in the term to be encoded in a more space-efficient and exact way
+ (namely in the 64-bit IEEE format, rather than converted to a
+ textual representation). As from Erlang/OTP R11B-4,
+ <c>binary_to_term/1</c> can decode this representation.</p>
+ <p>This version encode atoms that can be represented by a
+ latin1 string using latin1 encoding while only atoms that
+ cannot be represented by latin1 are encoded using utf8.</p>
+ </item>
+ <tag><c>2</c></tag>
+ <item>
+ <p>Drops usage of the latin1 atom encoding and unconditionally
+ use utf8 encoding for all atoms. This will be changed to the
+ default in a future major release of Erlang/OTP. Erlang/OTP
+ systems as of R16B can decode this representation.</p>
+ </item>
+ </taglist>
<p>See also <seealso marker="#binary_to_term/1">
<c>binary_to_term/1</c></seealso>.</p>
</desc>