aboutsummaryrefslogtreecommitdiffstats
path: root/erts/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'erts/doc/src')
-rw-r--r--erts/doc/src/absform.xml20
-rw-r--r--erts/doc/src/epmd.xml2
-rw-r--r--erts/doc/src/erl.xml22
-rw-r--r--erts/doc/src/erl_nif.xml308
-rw-r--r--erts/doc/src/erlang.xml102
-rw-r--r--erts/doc/src/erts_alloc.xml15
-rw-r--r--erts/doc/src/notes.xml251
7 files changed, 600 insertions, 120 deletions
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml
index ccdecf44ec..13756ddfdc 100644
--- a/erts/doc/src/absform.xml
+++ b/erts/doc/src/absform.xml
@@ -182,7 +182,7 @@
<p>Individual patterns are represented as follows:</p>
<list type="bulleted">
<item>If P is an atomic literal <c>L</c>, then Rep(P) = Rep(L).</item>
- <item>If P is a binary pattern
+ <item>If P is a bit string pattern
<c>&lt;&lt;P_1:Size_1/TSL_1, ..., P_k:Size_k/TSL_k>></c>, where each
<c>Size_i</c> is an expression that can be evaluated to an integer
and each <c>TSL_i</c> is a type specificer list, then
@@ -241,12 +241,13 @@
<p>An expression E is one of the following alternatives:</p>
<list type="bulleted">
<item>If E is an atomic literal <c>L</c>, then Rep(E) = Rep(L).</item>
- <item>If E is a binary comprehension
+ <item>If E is a bit string comprehension
<c>&lt;&lt;E_0 || Q_1, ..., Q_k>></c>,
where each <c>Q_i</c> is a qualifier, then
Rep(E) = <c>{bc,LINE,Rep(E_0),[Rep(Q_1), ..., Rep(Q_k)]}</c>.
For Rep(Q), see below.</item>
- <item>If E is a binary constructor <c>&lt;&lt;E_1:Size_1/TSL_1, ..., E_k:Size_k/TSL_k>></c>,
+ <item>If E is a bit string constructor
+ <c>&lt;&lt;E_1:Size_1/TSL_1, ..., E_k:Size_k/TSL_k>></c>,
where each <c>Size_i</c> is an expression and each
<c>TSL_i</c> is a type specificer list, then Rep(E) =
<c>{bin,LINE,[{bin_element,LINE,Rep(E_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(E_k),Rep(Size_k),Rep(TSL_k)}]}</c>.
@@ -386,16 +387,17 @@
<item>If Q is a generator <c>P &lt;- E</c>, where <c>P</c> is
a pattern and <c>E</c> is an expression, then
Rep(Q) = <c>{generate,LINE,Rep(P),Rep(E)}</c>.</item>
- <item>If Q is a generator <c>P &lt;= E</c>, where <c>P</c> is
+ <item>If Q is a bit string generator
+ <c>P &lt;= E</c>, where <c>P</c> is
a pattern and <c>E</c> is an expression, then
Rep(Q) = <c>{b_generate,LINE,Rep(P),Rep(E)}</c>.</item>
</list>
</section>
<section>
- <title>Binary Element Type Specifiers</title>
- <p>A type specifier list TSL for a binary element is a sequence of type
- specifiers <c>TS_1 - ... - TS_k</c>, and
+ <title>Bit String Element Type Specifiers</title>
+ <p>A type specifier list TSL for a bit string element is a sequence
+ of type specifiers <c>TS_1 - ... - TS_k</c>, and
Rep(TSL) = <c>[Rep(TS_1), ..., Rep(TS_k)]</c>.</p>
<list type="bulleted">
<item>If TS is a type specifier <c>A</c>, where <c>A</c> is an atom,
@@ -473,7 +475,7 @@
<p>A guard test <c>Gt</c> is one of the following alternatives:</p>
<list type="bulleted">
<item>If Gt is an atomic literal <c>L</c>, then Rep(Gt) = Rep(L).</item>
- <item>If Gt is a binary constructor
+ <item>If Gt is a bit string constructor
<c>&lt;&lt;Gt_1:Size_1/TSL_1, ..., Gt_k:Size_k/TSL_k>></c>,
where each <c>Size_i</c> is a guard test and each
<c>TSL_i</c> is a type specificer list, then
@@ -540,7 +542,7 @@
<c>{ann_type,LINE,[Rep(A),Rep(T_0)]}</c>.</item>
<item>If T is an atom or integer literal L, then Rep(T) = Rep(L).
</item>
- <item>If T is a bitstring type <c>&lt;&lt;_:M,_:_*N>></c>,
+ <item>If T is a bit string type <c>&lt;&lt;_:M,_:_*N>></c>,
where <c>M</c> and <c>N</c> are singleton integer types, then Rep(T) =
<c>{type,LINE,binary,[Rep(M),Rep(N)]}</c>.</item>
<item>If T is the empty list type <c>[]</c>, then Rep(T) =
diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml
index 28fcc8f7af..7f61804bea 100644
--- a/erts/doc/src/epmd.xml
+++ b/erts/doc/src/epmd.xml
@@ -37,7 +37,7 @@
<comsummary>
<p>Erlang Port Mapper Daemon</p>
<taglist>
- <tag><c><![CDATA[epmd [-d|-debug] [DbgExtra...] [-port No] [-daemon] [-relaxed_command_check]]]></c></tag>
+ <tag><c><![CDATA[epmd [-d|-debug] [DbgExtra...] [-address Addresses] [-port No] [-daemon] [-relaxed_command_check]]]></c></tag>
<item>
<p>Starts the port mapper daemon</p>
</item>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index 1c4a0056a7..096af096dc 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -387,6 +387,28 @@
<p>Replaces the path specified in the boot script. See
<seealso marker="sasl:script">script(4)</seealso>.</p>
</item>
+ <tag><c><![CDATA[-proto_dist Proto]]></c></tag>
+ <item>
+ <p>Specify a protocol for Erlang distribution.</p>
+ <taglist>
+ <tag><c>inet_tcp</c></tag>
+ <item>
+ <p>TCP over IPv4 (the default)</p>
+ </item>
+ <tag><c>inet_tls</c></tag>
+ <item>
+ <p>distribution over TLS/SSL</p>
+ </item>
+ <tag><c>inet6_tcp</c></tag>
+ <item>
+ <p>TCP over IPv6</p>
+ </item>
+ </taglist>
+ <p>For example, to start up IPv6 distributed nodes:</p>
+<pre>
+% <input>erl -name [email protected] -proto_dist inet6_tcp</input>
+</pre>
+ </item>
<tag><c><![CDATA[-remsh Node]]></c></tag>
<item>
<p>Starts Erlang with a remote shell connected to <c><![CDATA[Node]]></c>.</p>
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index be0e406b9c..1e95634d1b 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -524,6 +524,18 @@ typedef struct {
<p>Note that <c>ErlNifBinary</c> is a semi-opaque type and you are
only allowed to read fields <c>size</c> and <c>data</c>.</p>
</item>
+
+ <tag><marker id="ErlNifBinaryToTerm"/>ErlNifBinaryToTerm</tag>
+ <item>
+ <p>An enumeration of the options that can be given to
+ <seealso marker="#enif_binary_to_term">enif_binary_to_term</seealso>.
+ For default behavior, use the value <c>0</c>.</p>
+ <taglist>
+ <tag><c>ERL_NIF_BIN2TERM_SAFE</c></tag>
+ <item><p>Use this option when receiving data from untrusted sources.</p></item>
+ </taglist>
+ </item>
+
<tag><marker id="ErlNifPid"/>ErlNifPid</tag>
<item>
<p><c>ErlNifPid</c> is a process identifier (pid). In contrast to
@@ -532,6 +544,14 @@ typedef struct {
<seealso marker="#ErlNifEnv">environment</seealso>. <c>ErlNifPid</c>
is an opaque type.</p>
</item>
+ <tag><marker id="ErlNifPort"/>ErlNifPort</tag>
+ <item>
+ <p><c>ErlNifPort</c> is a port identifier. In contrast to
+ port id terms (instances of <c>ERL_NIF_TERM</c>), <c>ErlNifPort</c>'s are self
+ contained and not bound to any
+ <seealso marker="#ErlNifEnv">environment</seealso>. <c>ErlNifPort</c>
+ is an opaque type.</p>
+ </item>
<tag><marker id="ErlNifResourceType"/>ErlNifResourceType</tag>
<item>
@@ -591,6 +611,21 @@ typedef enum {
</taglist>
</item>
+ <tag><marker id="ErlNifUniqueInteger"/>ErlNifUniqueInteger</tag>
+ <item>
+ <p>An enumeration of the properties that can be requested from
+ <seealso marker="#enif_make_unique_integer">enif_unique_integer</seealso>.
+ For default properties, use the value <c>0</c>.</p>
+ <taglist>
+ <tag><c>ERL_NIF_UNIQUE_POSITIVE</c></tag>
+ <item><p>Return only positive integers</p></item>
+ <tag><c>ERL_NIF_UNIQUE_MONOTONIC</c></tag>
+ <item><p>Return only
+ <seealso marker="time_correction#Strictly_Monotonically_Increasing">strictly
+ monotonically increasing</seealso> integer corresponding to creation time</p></item>
+ </taglist>
+ </item>
+
</taglist>
</section>
@@ -632,6 +667,25 @@ typedef enum {
have been allocated with <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>.
</p></desc>
</func>
+ <func><name><ret>size_t</ret><nametext>enif_binary_to_term(ErlNifEnv *env, const unsigned char* data, size_t size, ERL_NIF_TERM *term, ErlNifBinaryToTerm opts)</nametext></name>
+ <fsummary>Create a term from the external format</fsummary>
+ <desc>
+ <p>Create a term that is the result of decoding the binary data
+ at <c>data</c>, which must be encoded according to the Erlang external term format.
+ No more than <c>size</c> bytes are read from <c>data</c>. Argument <c>opts</c>
+ correspond to the second argument to <seealso marker="erlang#binary_to_term-2">
+ <c>erlang:binary_to_term/2</c></seealso>, and must be either <c>0</c> or
+ <c>ERL_NIF_BIN2TERM_SAFE</c>.</p>
+ <p>On success, store the resulting term at <c>*term</c> and return
+ the actual number of bytes read. Return zero if decoding fails or if <c>opts</c>
+ is invalid.</p>
+ <p>See also:
+ <seealso marker="#ErlNifBinaryToTerm"><c>ErlNifBinaryToTerm</c></seealso>,
+ <seealso marker="erlang#binary_to_term-2"><c>erlang:binary_to_term/2</c></seealso> and
+ <seealso marker="#enif_term_to_binary"><c>enif_term_to_binary</c></seealso>.
+ </p>
+ </desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)</nametext></name>
<fsummary>Compare two terms</fsummary>
<desc><p>Return an integer less than, equal to, or greater than
@@ -689,7 +743,48 @@ typedef enum {
a number of repeated NIF-calls without the need to create threads.
See also the <seealso marker="#WARNING">warning</seealso> text at the beginning of this document.</p>
</desc>
+
</func>
+
+ <func>
+ <name><ret>ErlNifTime</ret><nametext>enif_convert_time_unit(ErlNifTime val, ErlNifTimeUnit from, ErlNifTimeUnit to)</nametext></name>
+ <fsummary>Convert time unit of a time value</fsummary>
+ <desc>
+ <marker id="enif_convert_time_unit"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>val</c></tag>
+ <item>Value to convert time unit for.</item>
+ <tag><c>from</c></tag>
+ <item>Time unit of <c>val</c>.</item>
+ <tag><c>to</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>Converts the <c>val</c> value of time unit <c>from</c> to
+ the corresponding value of time unit <c>to</c>. The result is
+ rounded using the floor function.</p>
+ <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
+ time unit argument.</p>
+ <p>See also:
+ <seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso> and
+ <seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_cpu_time(ErlNifEnv *)</nametext></name>
+ <fsummary></fsummary>
+ <desc>
+ <p>Returns the CPU time in the same format as <seealso marker="erlang#timestamp-0">erlang:timestamp()</seealso>.
+ The CPU time is the time the current logical cpu has spent executing since
+ some arbitrary point in the past.
+ If the OS does not support fetching of this value <c>enif_cpu_time</c>
+ invokes <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.
+ </p>
+ </desc>
+ </func>
+
<func><name><ret>int</ret><nametext>enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2)</nametext></name>
<fsummary></fsummary>
<desc><p>Same as <seealso marker="erl_driver#erl_drv_equal_tids">erl_drv_equal_tids</seealso>.
@@ -744,6 +839,12 @@ typedef enum {
pid variable <c>*pid</c> from it and return true. Otherwise return false.
No check if the process is alive is done.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_get_local_port(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPort* port_id)</nametext></name>
+ <fsummary>Read an local port term</fsummary>
+ <desc><p>If <c>term</c> identifies a node local port, initialize the
+ port variable <c>*port_id</c> from it and return true. Otherwise return false.
+ No check if the port is alive is done.</p></desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_get_list_cell(ErlNifEnv* env, ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail)</nametext></name>
<fsummary>Get head and tail from a list</fsummary>
<desc><p>Set <c>*head</c> and <c>*tail</c> from
@@ -912,6 +1013,17 @@ typedef enum {
<fsummary>Determine if a term is a port</fsummary>
<desc><p>Return true if <c>term</c> is a port.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_is_port_alive(ErlNifEnv* env, ErlNifPort *port_id)</nametext></name>
+ <fsummary>Determine if a local port is alive or not.</fsummary>
+ <desc><p>Return true if <c>port_id</c> is currently alive.</p>
+ <p>This function can only be used in a from a NIF-calling thread.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_process_alive(ErlNifEnv* env, ErlNifPid *pid)</nametext></name>
+ <fsummary>Determine if a local process is alive or not.</fsummary>
+ <desc><p>Return true if <c>pid</c> is currently alive.</p>
+ <p>This function is only thread-safe when the emulator with SMP support is used.
+ It can only be used in a non-SMP emulator from a NIF-calling thread.</p></desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
<fsummary>Determine if a term is a reference</fsummary>
<desc><p>Return true if <c>term</c> is a reference.</p></desc>
@@ -961,7 +1073,7 @@ typedef enum {
<seealso marker="#enif_is_exception">enif_is_exception</seealso>, but
not to any other NIF API function.</p>
<p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso>
- and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso>
+ and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso>.
</p>
<note><p>In earlier versions (older than erts-7.0, OTP 18) the return value
from <c>enif_make_badarg</c> had to be returned from the NIF. This
@@ -1195,6 +1307,23 @@ typedef enum {
<fsummary>Create an unsigned integer term</fsummary>
<desc><p>Create an integer term from an unsigned 64-bit integer.</p></desc>
</func>
+ <func>
+ <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_unique_integer(ErlNifEnv *env, ErlNifUniqueInteger properties)</nametext></name>
+ <fsummary></fsummary>
+ <desc>
+ <p>Returns a unique integer with the same properties as given by <seealso marker="erlang#unique_integer-1">erlang:unique_integer/1</seealso>.</p>
+ <p><c>env</c> is the environment to create the integer in.</p>
+ <p>
+ <c>ERL_NIF_UNIQUE_POSITIVE</c> and <c>ERL_NIF_UNIQUE_MONOTONIC</c> can
+ be passed as the second argument to change the properties of the
+ integer returned. It is possible to combine them by or:ing the
+ two values together.
+ </p>
+ <p>See also:
+ <seealso marker="#ErlNifUniqueInteger"><c>ErlNifUniqueInteger</c></seealso>.
+ </p>
+ </desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ulong(ErlNifEnv* env, unsigned long i)</nametext></name>
<fsummary>Create an integer term from an unsigned long int</fsummary>
<desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc>
@@ -1265,6 +1394,33 @@ enif_map_iterator_destroy(env, &amp;iter);
or false if the iterator is positioned at the head (before the first
entry).</p></desc>
</func>
+
+ <func>
+ <name><ret>ErlNifTime</ret><nametext>enif_monotonic_time(ErlNifTimeUnit time_unit)</nametext></name>
+ <fsummary>Get Erlang Monotonic Time</fsummary>
+ <desc>
+ <marker id="enif_monotonic_time"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>time_unit</c></tag>
+ <item>Time unit of returned value.</item>
+ </taglist>
+ <p>
+ Returns the current
+ <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
+ monotonic time</seealso>. Note that it is not uncommon with
+ negative values.
+ </p>
+ <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
+ time unit argument, or if called from a thread that is not a
+ scheduler thread.</p>
+ <p>See also:
+ <seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso> and
+ <seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso>.
+ </p>
+ </desc>
+ </func>
+
<func><name><ret>ErlNifMutex *</ret><nametext>enif_mutex_create(char *name)</nametext></name>
<fsummary></fsummary>
<desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_create">erl_drv_mutex_create</seealso>.
@@ -1290,6 +1446,11 @@ enif_map_iterator_destroy(env, &amp;iter);
<desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_unlock">erl_drv_mutex_unlock</seealso>.
</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_now_time(ErlNifEnv *env)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Retuns an <seealso marker="erlang#now-0">erlang:now()</seealso> timestamp.
+ The enif_now_time function is <em>deprecated</em>.</p></desc>
+ </func>
<func><name><ret>ErlNifResourceType *</ret><nametext>enif_open_resource_type(ErlNifEnv* env,
const char* module_str, const char* name,
ErlNifResourceDtor* dtor, ErlNifResourceFlags flags, ErlNifResourceFlags* tried)</nametext></name>
@@ -1319,6 +1480,35 @@ enif_map_iterator_destroy(env, &amp;iter);
and <seealso marker="#upgrade">upgrade</seealso>.</p>
</desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_port_command(ErlNifEnv* env, const ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg)</nametext></name>
+ <fsummary>Send a port_command to to_port</fsummary>
+ <desc>
+ <p>This function works the same as <seealso marker="erlang#port_command-2">erlang:port_command/2</seealso>
+ except that it is always completely asynchronous. This call may return false
+ if it detects that the port is already dead, otherwise it will return true.
+ </p>
+ <taglist>
+ <tag><c>env</c></tag>
+ <item>The environment of the calling process. May not be NULL.</item>
+ <tag><c>*to_port</c></tag>
+ <item>The port id of the receiving port. The port id should refer to a
+ port on the local node.</item>
+ <tag><c>msg_env</c></tag>
+ <item>The environment of the message term. Can be a process
+ independent environment allocated with
+ <seealso marker="#enif_alloc_env">enif_alloc_env</seealso> or NULL.</item>
+ <tag><c>msg</c></tag>
+ <item>The message term to send. The same limitations apply as on the
+ payload to <seealso marker="erlang#port_command-2">erlang:port_command/2</seealso>.</item>
+ </taglist>
+ <p>Using a <c>msg_env</c> of NULL is an optimization which groups together
+ calls to <c>enif_alloc_env</c>, <c>enif_make_copy</c>, <c>enif_port_command</c>
+ and <c>enif_free_env</c> into one call. This optimization is only usefull
+ when a majority of the terms are to be copied from <c>env</c> to the <c>msg_env</c>.</p>
+ <p>The call may return false if it detects that the command failed for some reason. Otherwise true is returned.</p>
+ <p>See also: <seealso marker="#enif_get_local_port"><c>enif_get_local_port</c></seealso>.</p>
+ </desc>
+ </func>
<func><name><ret>void *</ret><nametext>enif_priv_data(ErlNifEnv* env)</nametext></name>
<fsummary>Get the private data of a NIF library</fsummary>
<desc><p>Return the pointer to the private data that was set by <c>load</c>,
@@ -1453,6 +1643,8 @@ enif_map_iterator_destroy(env, &amp;iter);
of cleared for reuse with <seealso marker="#enif_clear_env">enif_clear_env</seealso>.</p>
<p>This function is only thread-safe when the emulator with SMP support is used.
It can only be used in a non-SMP emulator from a NIF-calling thread.</p>
+ <note><p>Passing <c>msg_env</c> as <c>NULL</c> is only supported since
+ erts-8.0 (OTP 19).</p></note>
</desc>
</func>
<func><name><ret>unsigned</ret><nametext>enif_sizeof_resource(void* obj)</nametext></name>
@@ -1466,6 +1658,18 @@ enif_map_iterator_destroy(env, &amp;iter);
<desc><p>Same as <seealso marker="erl_driver#driver_system_info">driver_system_info</seealso>.
</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_term_to_binary(ErlNifEnv *env, ERL_NIF_TERM term, ErlNifBinary *bin)</nametext></name>
+ <fsummary>Convert a term to the external format</fsummary>
+ <desc>
+ <p>Allocates a new binary with <seealso marker="#enif_alloc_binary">enif_alloc_binary</seealso>
+ and stores the result of encoding <c>term</c> according to the Erlang external term format.</p>
+ <p>Returns true on success or false if allocation failed.</p>
+ <p>See also:
+ <seealso marker="erlang#term_to_binary-1"><c>erlang:term_to_binary/1</c></seealso> and
+ <seealso marker="#enif_binary_to_term"><c>enif_binary_to_term</c></seealso>.
+ </p>
+ </desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_thread_create(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts)</nametext></name>
<fsummary></fsummary>
<desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_create">erl_drv_thread_create</seealso>.
@@ -1496,54 +1700,6 @@ enif_map_iterator_destroy(env, &amp;iter);
<desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_self">erl_drv_thread_self</seealso>.
</p></desc>
</func>
- <func><name><ret>int</ret><nametext>enif_tsd_key_create(char *name, ErlNifTSDKey *key)</nametext></name>
- <fsummary></fsummary>
- <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_create">erl_drv_tsd_key_create</seealso>.
- </p></desc>
- </func>
- <func><name><ret>void</ret><nametext>enif_tsd_key_destroy(ErlNifTSDKey key)</nametext></name>
- <fsummary></fsummary>
- <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_destroy">erl_drv_tsd_key_destroy</seealso>.
- </p></desc>
- </func>
- <func><name><ret>void *</ret><nametext>enif_tsd_get(ErlNifTSDKey key)</nametext></name>
- <fsummary></fsummary>
- <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_get">erl_drv_tsd_get</seealso>.
- </p></desc>
- </func>
- <func><name><ret>void</ret><nametext>enif_tsd_set(ErlNifTSDKey key, void *data)</nametext></name>
- <fsummary></fsummary>
- <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_set">erl_drv_tsd_set</seealso>.
- </p></desc>
- </func>
-
-
- <func>
- <name><ret>ErlNifTime</ret><nametext>enif_monotonic_time(ErlNifTimeUnit time_unit)</nametext></name>
- <fsummary>Get Erlang Monotonic Time</fsummary>
- <desc>
- <marker id="enif_monotonic_time"></marker>
- <p>Arguments:</p>
- <taglist>
- <tag><c>time_unit</c></tag>
- <item>Time unit of returned value.</item>
- </taglist>
- <p>
- Returns
- <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang
- monotonic time</seealso>. Note that it is not uncommon with
- negative values.
- </p>
- <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
- time unit argument, or if called from a thread that is not a
- scheduler thread.</p>
- <p>See also:</p>
- <list>
- <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item>
- <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item>
- </list>
- </desc>
- </func>
<func>
<name><ret>ErlNifTime</ret><nametext>enif_time_offset(ErlNifTimeUnit time_unit)</nametext></name>
@@ -1563,41 +1719,33 @@ enif_map_iterator_destroy(env, &amp;iter);
<p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
time unit argument, or if called from a thread that is not a
scheduler thread.</p>
- <p>See also:</p>
- <list>
- <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item>
- <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item>
- </list>
+ <p>See also:
+ <seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso> and
+ <seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso>.
+ </p>
</desc>
</func>
- <func>
- <name><ret>ErlNifTime</ret><nametext>enif_convert_time_unit(ErlNifTime val, ErlNifTimeUnit from, ErlNifTimeUnit to)</nametext></name>
- <fsummary>Convert time unit of a time value</fsummary>
- <desc>
- <marker id="enif_convert_time_unit"></marker>
- <p>Arguments:</p>
- <taglist>
- <tag><c>val</c></tag>
- <item>Value to convert time unit for.</item>
- <tag><c>from</c></tag>
- <item>Time unit of <c>val</c>.</item>
- <tag><c>to</c></tag>
- <item>Time unit of returned value.</item>
- </taglist>
- <p>Converts the <c>val</c> value of time unit <c>from</c> to
- the corresponding value of time unit <c>to</c>. The result is
- rounded using the floor function.</p>
- <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid
- time unit argument.</p>
- <p>See also:</p>
- <list>
- <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item>
- <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item>
- </list>
- </desc>
+ <func><name><ret>int</ret><nametext>enif_tsd_key_create(char *name, ErlNifTSDKey *key)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_create">erl_drv_tsd_key_create</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_tsd_key_destroy(ErlNifTSDKey key)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_destroy">erl_drv_tsd_key_destroy</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void *</ret><nametext>enif_tsd_get(ErlNifTSDKey key)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_get">erl_drv_tsd_get</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_tsd_set(ErlNifTSDKey key, void *data)</nametext></name>
+ <fsummary></fsummary>
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_set">erl_drv_tsd_set</seealso>.
+ </p></desc>
</func>
-
</funcs>
<section>
<title>SEE ALSO</title>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 803da382ed..350a8506f5 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -1811,7 +1811,8 @@ os_prompt% </pre>
</item>
</taglist>
<note><p>On many platforms, the OS supports only status
- codes 0-255.</p></note>
+ codes 0-255. A too large status code will be truncated by clearing
+ the high bits.</p></note>
<p>For integer <c><anno>Status</anno></c>, the Erlang runtime system
closes all ports and allows async threads to finish their
operations before exiting. To exit without such flushing, use
@@ -6468,32 +6469,44 @@ ok
<p><marker id="system_flag_multi_scheduling"></marker>
If multi-scheduling is enabled, more than one scheduler
thread is used by the emulator. Multi-scheduling can be
- blocked. When multi-scheduling is blocked, only
- one scheduler thread schedules Erlang processes.</p>
+ blocked in two different ways. Either all schedulers but
+ one is blocked, or all <em>normal</em> schedulers but
+ one is blocked. When only normal schedulers are blocked
+ dirty schedulers are free to continue to schedule
+ processes.</p>
<p>If <c><anno>BlockState</anno> =:= block</c>, multi-scheduling is
- blocked. If <c><anno>BlockState</anno> =:= unblock</c> and no one
+ blocked. That is, one and only one scheduler thread will
+ execute. If <c><anno>BlockState</anno> =:= unblock</c> and no one
else blocks multi-scheduling, and this process has
blocked only once, multi-scheduling is unblocked.</p>
- <p>One process can block multi-scheduling multiple times.
- If a process has blocked multiple times, it must
- unblock exactly as many times as it has blocked before it
- has released its multi-scheduling block. If a process that
- has blocked multi-scheduling exits, it releases its
- blocking of multi-scheduling.</p>
+ <p>If <c><anno>BlockState</anno> =:= block_normal</c>, normal
+ multi-scheduling is blocked. That is, only one normal scheduler
+ thread will execute, but multiple dirty schedulers may execute.
+ If <c><anno>BlockState</anno> =:= unblock_normal</c> and no one
+ else blocks normal multi-scheduling, and this process has
+ blocked only once, normal multi-scheduling is unblocked.</p>
+ <p>One process can block multi-scheduling as well as normal
+ multi-scheduling multiple times. If a process has blocked
+ multiple times, it must unblock exactly as many times as it
+ has blocked before it has released its multi-scheduling
+ block. If a process that has blocked multi-scheduling or normal
+ multi scheduling exits, it automatically releases its blocking
+ of multi-scheduling and normal multi-scheduling.</p>
<p>The return values are <c>disabled</c>, <c>blocked</c>,
- or <c>enabled</c>. The returned value describes the
- state just after the call to
+ <c>blocked_normal</c>, or <c>enabled</c>. The returned value
+ describes the state just after the call to
<c>erlang:system_flag(multi_scheduling, <anno>BlockState</anno>)</c>
has been made. For information about the return values, see
<seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>.</p>
- <note><p>Blocking of multi-scheduling is normally not needed.
- If you feel that you need to block multi-scheduling,
- consider it a few more times again. Blocking multi-scheduling
- is only to be used as a last resort, as it is most likely
- a <em>very inefficient</em> way to solve the problem.</p>
+ <note><p>Blocking of multi-scheduling and normal multi-scheduling
+ is normally not needed. If you feel that you need to use these
+ features, consider it a few more times again. Blocking
+ multi-scheduling is only to be used as a last resort, as it is
+ most likely a <em>very inefficient</em> way to solve the problem.</p>
</note>
<p>See also
<seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ <seealso marker="#system_info_normal_multi_scheduling_blockers">erlang:system_info(normal_multi_scheduling_blockers)</seealso>,
<seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</desc>
@@ -7328,6 +7341,16 @@ ok
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></marker></tag>
+ <item>
+ <p>Returns the default value of the <c>message_queue_data</c>
+ process flag which is either <c>off_heap</c>, <c>on_heap</c>, or <c>mixed</c>.
+ This default is set by the <c>erl</c> command line argument
+ <seealso marker="erl#+xmqd"><c>+xmqd</c></seealso>. For more information on the
+ <c>message_queue_data</c> process flag, see documentation of
+ <seealso marker="#process_flag_message_queue_data"><c>process_flag(message_queue_data,
+ MQD)</c></seealso>.</p>
+ </item>
<tag><c>min_bin_vheap_size</c></tag>
<item>
<p>Returns <c>{min_bin_vheap_size,
@@ -7347,7 +7370,8 @@ ok
<tag><c>multi_scheduling</c></tag>
<item>
<marker id="system_info_multi_scheduling"></marker>
- <p>Returns <c>disabled</c>, <c>blocked</c>, or <c>enabled</c>:</p>
+ <p>Returns <c>disabled</c>, <c>blocked</c>, <c>blocked_normal</c>,
+ or <c>enabled</c>:</p>
<taglist>
<tag><c>disabled</c></tag>
<item>
@@ -7358,14 +7382,22 @@ ok
<tag><c>blocked</c></tag>
<item>
<p>The emulator has more than one scheduler thread,
- but all scheduler threads except one are blocked,
- that is, only one scheduler thread schedules
+ but all scheduler threads except one are blocked.
+ That is, only one scheduler thread schedules
Erlang processes and executes Erlang code.</p>
</item>
+ <tag><c>blocked_normal</c></tag>
+ <item>
+ <p>The emulator has more than one scheduler thread,
+ but all normal scheduler threads except one are
+ blocked. Note that dirty schedulers are not
+ blocked, and may schedule Erlang processes and
+ execute native code.</p>
+ </item>
<tag><c>enabled</c></tag>
<item>
<p>The emulator has more than one scheduler thread,
- and no scheduler threads are blocked, that is,
+ and no scheduler threads are blocked. That is,
all available scheduler threads schedule
Erlang processes and execute Erlang code.</p>
</item>
@@ -7373,6 +7405,7 @@ ok
<p>See also
<seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
<seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>,
+ <seealso marker="#system_info_normal_multi_scheduling_blockers">erlang:system_info(normal_multi_scheduling_blockers)</seealso>,
and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
@@ -7389,6 +7422,8 @@ ok
<p>See also
<seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
<seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ <seealso marker="#system_info_normal_multi_scheduling_blockers">erlang:system_info(normal_multi_scheduling_blockers)</seealso>,
+
and
<seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
@@ -7398,15 +7433,23 @@ ok
used by the runtime system. It is on the form
"&lt;major ver&gt;.&lt;minor ver&gt;".</p>
</item>
- <tag><marker id="system_info_message_queue_data"><c>message_queue_data</c></marker></tag>
+ <tag><c>normal_multi_scheduling_blockers</c></tag>
<item>
- <p>Returns the default value of the <c>message_queue_data</c>
- process flag which is either <c>off_heap</c>, <c>on_heap</c>, or <c>mixed</c>.
- This default is set by the <c>erl</c> command line argument
- <seealso marker="erl#+xmqd"><c>+xmqd</c></seealso>. For more information on the
- <c>message_queue_data</c> process flag, see documentation of
- <seealso marker="#process_flag_message_queue_data"><c>process_flag(message_queue_data,
- MQD)</c></seealso>.</p>
+ <marker id="system_info_normal_multi_scheduling_blockers"></marker>
+ <p>Returns a list of <c><anno>Pid</anno></c>s when
+ normal multi-scheduling is blocked (i.e. all normal schedulers
+ but one is blocked), otherwise the empty list is returned.
+ The <c><anno>Pid</anno></c>s in the list represent all the
+ processes currently blocking normal multi-scheduling.
+ A <c><anno>Pid</anno></c> occurs only once in the list, even if
+ the corresponding process has blocked multiple times.</p>
+ <p>See also
+ <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>,
+
+ and
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
</item>
<tag><marker id="system_info_otp_release"><c>otp_release</c></marker></tag>
<item>
@@ -7649,6 +7692,7 @@ ok
<seealso marker="#system_info_scheduler_id">erlang:system_info(scheduler_id)</seealso>,
<seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
<seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ <seealso marker="#system_info_normal_multi_scheduling_blockers">erlang:system_info(normal_multi_scheduling_blockers)</seealso>
and
<seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>.</p>
</item>
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 15b78ffa10..0965f9b49c 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -52,6 +52,8 @@
<item>Allocator used for ETS data.</item>
<tag><c>driver_alloc</c></tag>
<item>Allocator used for driver data.</item>
+ <tag><c>literal_alloc</c></tag>
+ <item>Allocator used for constant terms in Erlang code.</item>
<tag><c>sl_alloc</c></tag>
<item>Allocator used for memory blocks that are expected to be
short-lived.</item>
@@ -77,7 +79,7 @@
instead of creating new segments. This in order to reduce
the number of system calls made.</item>
</taglist>
- <p><c>sys_alloc</c> is always enabled and
+ <p><c>sys_alloc</c> and <c>literal_alloc</c> are always enabled and
cannot be disabled. <c>mseg_alloc</c> is always enabled if it is
available and an allocator that uses it is enabled. All other
allocators can be <seealso marker="#M_e">enabled or disabled</seealso>.
@@ -246,6 +248,7 @@
the currently present allocators:</p>
<list type="bulleted">
<item><c>B: binary_alloc</c></item>
+ <item><c>I: literal_alloc</c></item>
<item><c>D: std_alloc</c></item>
<item><c>E: ets_alloc</c></item>
<item><c>F: fix_alloc</c></item>
@@ -563,6 +566,16 @@
set to <c>false</c>, <c>sys_alloc</c> carriers will never be
created by allocators using the <c>alloc_util</c> framework.</item>
</taglist>
+ <p>The following flag is special for <c>literal_alloc</c>:</p>
+ <taglist>
+ <tag><marker id="MIscs"/><c><![CDATA[+MIscs <size in MB>]]></c></tag>
+ <item>
+ <c>literal_alloc</c> super carrier size (in MB). The amount of
+ <em>virtual</em> address space reserved for literal terms in
+ Erlang code on 64-bit architectures. The default is 1024 (1GB)
+ and is usually sufficient. The flag is ignored on 32-bit
+ architectures.</item>
+ </taglist>
<p>Instrumentation flags:</p>
<taglist>
<tag><marker id="Mim"/><c>+Mim true|false</c></tag>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index a726cc7b97..7ccddf4ff0 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -32,6 +32,257 @@
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 7.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>process_info(Pid, last_calls)</c> did not work for
+ <c>Pid /= self()</c>.</p>
+ <p>
+ Own Id: OTP-13418</p>
+ </item>
+ <item>
+ <p>
+ Make sure to create a crash dump when running out of
+ memory. This was accidentally removed in the erts-7.3
+ release.</p>
+ <p>
+ Own Id: OTP-13419</p>
+ </item>
+ <item>
+ <p>
+ Schedulers could be woken by a premature timeout on
+ Linux. This premature wakeup was however harmless.</p>
+ <p>
+ Own Id: OTP-13420</p>
+ </item>
+ <item>
+ <p>
+ A process communicating with a port via one of the
+ <c>erlang:port_*</c> BIFs could potentially end up in an
+ inconsistent state if the port terminated during the
+ communication. When this occurred the process could later
+ block in a <c>receive</c> even though it had messages
+ matching in its message queue.</p>
+ <p>
+ This bug was introduced in erts version 5.10 (OTP R16A).</p>
+ <p>
+ Own Id: OTP-13424 Aux Id: OTP-10336 </p>
+ </item>
+ <item>
+ <p>
+ The reference count of a process structure could under
+ rare circumstances be erroneously managed. When this
+ happened invalid memory accesses occurred.</p>
+ <p>
+ Own Id: OTP-13446</p>
+ </item>
+ <item>
+ <p>
+ Fix race between <c>process_flag(trap_exit,true)</c> and
+ a received exit signal.</p>
+ <p>
+ A process could terminate due to exit signal even though
+ <c>process_flag(trap_exit,true)</c> had returned. A very
+ specific timing between call to <c>process_flag/2</c> and
+ exit signal from another scheduler was required for this
+ to happen.</p>
+ <p>
+ Own Id: OTP-13452</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The '-path' flag to 'erl' has been documented. This flag
+ replaces the path specified in the boot script. It has
+ always existed, but was earlier only documented in SASL
+ (script).</p>
+ <p>
+ Own Id: OTP-13060</p>
+ </item>
+ <item>
+ <p>
+ The <c>call_time</c> tracing functionality internally
+ used a time based on OS system time in order to measure
+ call time which could cause erroneous results if OS
+ system time was changed during tracing.</p>
+ <p>
+ This functionality now use Erlang monotonic time in order
+ to measure time. Besides fixing the erroneous results due
+ to OS system time being used, the results are often also
+ better since Erlang monotonic time often has better
+ accuracy and precision.</p>
+ <p>
+ Own Id: OTP-13216</p>
+ </item>
+ <item>
+ <p>
+ Fix behaviour of -delay_write command line switch of
+ epmd, which is used for debugging - in some cases epmd
+ was sleeping twice the requested amount of time.</p>
+ <p>
+ Own Id: OTP-13220</p>
+ </item>
+ <item>
+ <p>
+ Fix race between timeout and exit signal that could cause
+ a process to ignore the exit signal and continue
+ execution. Bug exist since OTP 18.0.</p>
+ <p>
+ Own Id: OTP-13245</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in <c>erlang:halt/1,2</c> for large exit status
+ values, causing either <c>badarg</c> (on 32-bit) or exit
+ with a crash dump and/or core dump (on 64-bit). Make
+ <c>erlang:halt/1,2</c> tolerate any non negative integer
+ as exit status and truncate high order bits if the OS
+ does not support it.</p>
+ <p>
+ Own Id: OTP-13251 Aux Id: ERL-49 </p>
+ </item>
+ <item>
+ <p>
+ <seealso
+ marker="kernel:gen_tcp#accept/2"><c>gen_tcp:accept/2</c></seealso>
+ was not <seealso
+ marker="erts:time_correction#Time_Warp_Safe_Code">time
+ warp safe</seealso>. This since it used the same time as
+ returned by <seealso
+ marker="erts:erlang#now/0"><c>erlang:now/0</c></seealso>
+ when calculating timeout. This has now been fixed.</p>
+ <p>
+ Own Id: OTP-13254 Aux Id: OTP-11997, OTP-13222 </p>
+ </item>
+ <item>
+ <p>
+ Fix faulty error handling when writing to a compressed
+ file.</p>
+ <p>
+ Own Id: OTP-13270</p>
+ </item>
+ <item>
+ <p>
+ Fix sendfile usage for large files on FreeBSD</p>
+ <p>
+ Own Id: OTP-13271</p>
+ </item>
+ <item>
+ <p>
+ Fix bug that could cause
+ <c>process_info(P,current_location)</c> to crash emulator
+ for hipe compiled modules.</p>
+ <p>
+ Own Id: OTP-13282 Aux Id: ERL-79 </p>
+ </item>
+ <item>
+ <p>
+ Out of memory errors have been changed to cause an exit
+ instead of abort.</p>
+ <p>
+ Own Id: OTP-13292</p>
+ </item>
+ <item>
+ <p>
+ When calling <c>garbage_collect/[1,2]</c> or
+ <c>check_process_code/[2,3]</c> from a process with a
+ higher priority than the priority of the process operated
+ on, the run queues could end up in an inconsistent state.
+ This bug has now been fixed.</p>
+ <p>
+ Own Id: OTP-13298 Aux Id: OTP-11388 </p>
+ </item>
+ <item>
+ <p>
+ A workaround for an issue with older gcc versions (less
+ than 5) and inline assembly on 32-bit x86 caused an
+ emulator crash when it had been compiled with a newer gcc
+ version. An improved <c>configure</c> test, run when
+ building OTP, now detects whether the workaround should
+ be used or not.</p>
+ <p>
+ Own Id: OTP-13326 Aux Id: ERL-80 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Introduced new statistics functionality in order to
+ more efficiently retrieve information about run able and
+ active processes and ports. For more information see:</p>
+ <list> <item><seealso
+ marker="erlang#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso></item>
+ <item><seealso
+ marker="erlang#statistics_run_queue_lengths"><c>statistics(run_queue_lengths)</c></seealso></item>
+ <item><seealso
+ marker="erlang#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso></item>
+ <item><seealso
+ marker="erlang#statistics_active_tasks"><c>statistics(active_tasks)</c></seealso></item>
+ </list>
+ <p>
+ Own Id: OTP-13201</p>
+ </item>
+ <item>
+ <p>
+ Time warp safety improvements.</p>
+ <p>
+ Introduced the options <c>monotonic_timestamp</c>, and
+ <c>strict_monotonic_timestamp</c> to the trace,
+ sequential trace, and system profile functionality. This
+ since the already existing <c>timestamp</c> option is not
+ time warp safe.</p>
+ <p>
+ Introduced the option <c>safe_fixed_monotonic_time</c> to
+ <c>ets:info/2</c> and <c>dets:info/2</c>. This since the
+ already existing <c>safe_fixed</c> option is not time
+ warp safe.</p>
+ <p>
+ Own Id: OTP-13222 Aux Id: OTP-11997 </p>
+ </item>
+ <item>
+ <p>
+ Fix a register race where down nodes goes undetected in
+ epmd</p>
+ <p>
+ Own Id: OTP-13301</p>
+ </item>
+ <item>
+ <p>
+ Improved the gcc inline assembly implementing double word
+ atomic compare and exchange on x86/x86_64 so that it also
+ can be used when compiling with clang.</p>
+ <p>
+ Own Id: OTP-13336</p>
+ </item>
+ <item>
+ <p>
+ An optimization preventing a long wait for a scheduler
+ thread looking up information about a process executing
+ on another scheduler thread had unintentionally been lost
+ in erts-5.10 (OTP R16A). This optimization has now been
+ reintroduced.</p>
+ <p>
+ Own Id: OTP-13365 Aux Id: OTP-9892 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 7.2.1</title>
<section><title>Fixed Bugs and Malfunctions</title>