diff options
Diffstat (limited to 'erts/doc/src')
-rw-r--r-- | erts/doc/src/Makefile | 8 | ||||
-rw-r--r-- | erts/doc/src/absform.xml | 55 | ||||
-rw-r--r-- | erts/doc/src/alt_disco.xml | 93 | ||||
-rw-r--r-- | erts/doc/src/alt_dist.xml | 737 | ||||
-rw-r--r-- | erts/doc/src/driver_entry.xml | 7 | ||||
-rw-r--r-- | erts/doc/src/erl.xml | 166 | ||||
-rw-r--r-- | erts/doc/src/erl_dist_protocol.xml | 71 | ||||
-rw-r--r-- | erts/doc/src/erl_driver.xml | 28 | ||||
-rw-r--r-- | erts/doc/src/erl_nif.xml | 147 | ||||
-rw-r--r-- | erts/doc/src/erlang.xml | 2229 | ||||
-rw-r--r-- | erts/doc/src/erlc.xml | 10 | ||||
-rw-r--r-- | erts/doc/src/erts_alloc.xml | 60 | ||||
-rw-r--r-- | erts/doc/src/match_spec.xml | 33 | ||||
-rw-r--r-- | erts/doc/src/notes.xml | 1034 | ||||
-rw-r--r-- | erts/doc/src/part.xml | 3 | ||||
-rw-r--r-- | erts/doc/src/run_erl.xml | 2 |
16 files changed, 3646 insertions, 1037 deletions
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index 18c5490d7b..21aa3db864 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2017. All Rights Reserved. +# Copyright Ericsson AB 1997-2018. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -74,6 +74,7 @@ XML_CHAPTER_FILES = \ match_spec.xml \ crash_dump.xml \ alt_dist.xml \ + alt_disco.xml \ driver.xml \ absform.xml \ inet_cfg.xml \ @@ -148,6 +149,7 @@ debug opt: clean: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN1DIR)/* rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) @@ -155,7 +157,7 @@ clean: rm -f errs core *~ $(SPECDIR)/specs_%.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + $(gen_verbose)escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ -o$(dir $@) -module $(patsubst $(SPECDIR)/specs_%.xml,%,$@) # ---------------------------------------------------- @@ -171,6 +173,8 @@ release_docs_spec: docs "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(ERL_TOP)/erts/example/time_compat.erl \ "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(ERL_TOP)/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl \ + "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml index e49c8c32e9..f29bb7b8f9 100644 --- a/erts/doc/src/absform.xml +++ b/erts/doc/src/absform.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2001</year><year>2017</year> + <year>2001</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -407,9 +407,8 @@ </item> <item> <p>If E is a map creation <c>#{A_1, ..., A_k}</c>, - where each <c>A_i</c> is an association <c>E_i_1 => E_i_2</c> - or <c>E_i_1 := E_i_2</c>, then Rep(E) = - <c>{map,LINE,[Rep(A_1), ..., Rep(A_k)]}</c>. + where each <c>A_i</c> is an association <c>E_i_1 => E_i_2</c>, + then Rep(E) = <c>{map,LINE,[Rep(A_1), ..., Rep(A_k)]}</c>. For Rep(A), see below.</p> </item> <item> @@ -614,26 +613,58 @@ <item> <p>If C is a catch clause <c>P -> B</c>, where <c>P</c> is a pattern and <c>B</c> is a body, then - Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}</c>.</p> + Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}</c>, + that is, a catch clause with an explicit exception class + <c>throw</c> and with or without an explicit stacktrace + variable <c>_</c> cannot be distinguished from a catch clause + without an explicit exception class and without an explicit + stacktrace variable.</p> </item> <item> <p>If C is a catch clause <c>X : P -> B</c>, where <c>X</c> is an atomic literal or a variable pattern, <c>P</c> is a pattern, and <c>B</c> is a body, then - Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],[],Rep(B)}</c>.</p> + Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],[],Rep(B)}</c>, + that is, a catch clause with an explicit exception class and + with an explicit stacktrace variable <c>_</c> cannot be + distinguished from a catch clause with an explicit exception + class and without an explicit stacktrace variable.</p> + </item> + <item> + <p>If C is a catch clause <c>X : P : S -> B</c>, + where <c>X</c> is an atomic literal or a variable pattern, + <c>P</c> is a pattern, <c>S</c> is a variable, and <c>B</c> + is a body, then + Rep(C) = <c>{clause,LINE,[Rep({X,P,S})],[],Rep(B)}</c>.</p> </item> <item> <p>If C is a catch clause <c>P when Gs -> B</c>, where <c>P</c> is a pattern, <c>Gs</c> is a guard sequence, and <c>B</c> is a body, then - Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}</c>.</p> + Rep(C) = <c>{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}</c>, + that is, a catch clause with an explicit exception class + <c>throw</c> and with or without an explicit stacktrace + variable <c>_</c> cannot be distinguished from a catch clause + without an explicit exception class and without an explicit + stacktrace variable.</p> </item> <item> <p>If C is a catch clause <c>X : P when Gs -> B</c>, where <c>X</c> is an atomic literal or a variable pattern, <c>P</c> is a pattern, <c>Gs</c> is a guard sequence, and <c>B</c> is a body, then - Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}</c>.</p> + Rep(C) = <c>{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}</c>, + that is, a catch clause with an explicit exception class and + with an explicit stacktrace variable <c>_</c> cannot be + distinguished from a catch clause with an explicit exception + class and without an explicit stacktrace variable.</p> + </item> + <item> + <p>If C is a catch clause <c>X : P : S when Gs -> B</c>, + where <c>X</c> is an atomic literal or a variable pattern, + <c>P</c> is a pattern, <c>Gs</c> is a guard sequence, + <c>S</c> is a variable, and <c>B</c> is a body, then + Rep(C) = <c>{clause,LINE,[Rep({X,P,S})],Rep(Gs),Rep(B)}</c>.</p> </item> <item> <p>If C is a function clause <c>( Ps ) -> B</c>, @@ -699,9 +730,8 @@ </item> <item> <p>If Gt is a map creation <c>#{A_1, ..., A_k}</c>, - where each <c>A_i</c> is an association <c>Gt_i_1 => Gt_i_2</c> - or <c>Gt_i_1 := Gt_i_2</c>, then Rep(Gt) = - <c>{map,LINE,[Rep(A_1), ..., Rep(A_k)]}</c>. + where each <c>A_i</c> is an association <c>Gt_i_1 => Gt_i_2</c>, + then Rep(Gt) = <c>{map,LINE,[Rep(A_1), ..., Rep(A_k)]}</c>. For Rep(A), see above.</p> </item> <item> @@ -771,7 +801,8 @@ <c>{ann_type,LINE,[Rep(A),Rep(T_0)]}</c>.</p> </item> <item> - <p>If T is an atom or integer literal L, then Rep(T) = Rep(L).</p> + <p>If T is an atom, a character, or an integer literal L, + then Rep(T) = Rep(L).</p> </item> <item> <p>If T is a bitstring type <c><<_:M,_:_*N>></c>, diff --git a/erts/doc/src/alt_disco.xml b/erts/doc/src/alt_disco.xml new file mode 100644 index 0000000000..d04221b9b3 --- /dev/null +++ b/erts/doc/src/alt_disco.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2018</year><year>2018</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>How to Implement an Alternative Service Discovery for Erlang Distribution + </title> + <prepared>Timmo Verlaan</prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date>2018-04-25</date> + <rev>PA1</rev> + <file>alt_disco.xml</file> + </header> + <p> + This section describes how to implement an alternative discovery mechanism + for Erlang distribution. Discovery is normally done using DNS and the + Erlang Port Mapper Daemon (EPMD) for port discovery. + </p> + + <note><p> + Support for alternative service discovery mechanisms was added in Erlang/OTP + 21. + </p></note> + + + <section> + <title>Introduction</title> + <p>To implement your own service discovery module you have to write your own + EPMD module. The <seealso marker="kernel:erl_epmd">EPMD module</seealso> is + responsible for providing the location of another node. The distribution + modules (<c>inet_tcp_dist</c>/<c>inet_tls_dist</c>) call the EPMD module to + get the IP address and port of the other node. The EPMD module that is part + of Erlang/OTP will resolve the hostname using DNS and uses the EPMD unix + process to get the port of another node. The EPMD unix process does this by + connecting to the other node on a well-known port, port 4369.</p> + </section> + + <section> + <title>Discovery module</title> + <p>The discovery module needs to implement the same API as the regular + <seealso marker="kernel:erl_epmd">EPMD module</seealso>. However, instead of + communicating with EPMD you can connect to any service to find out + connection details of other nodes. A discovery module is enabled + by setting <seealso marker="erts:erl#epmd_module">-epmd_module</seealso> + when starting erlang. The discovery module must implement the following + callbacks:</p> + + <taglist> + <tag><seealso marker="kernel:erl_epmd#start_link/0">start_link/0</seealso></tag> + <item>Start any processes needed by the discovery module.</item> + <tag><seealso marker="kernel:erl_epmd#names/1">names/1</seealso></tag> + <item>Return node names held by the registrar for the given host.</item> + <tag><seealso marker="kernel:erl_epmd#register_node/2">register_node/2</seealso></tag> + <item>Register the given node name with the registrar.</item> + <tag><seealso marker="kernel:erl_epmd#port_please/3">port_please/3</seealso></tag> + <item>Return the distribution port used by the given node.</item> + </taglist> + + <p>The discovery module may implement the following callback:</p> + + <taglist> + <tag><seealso marker="kernel:erl_epmd#address_please/3">address_please/3</seealso></tag> + <item><p>Return the address of the given node. + If not implemented, <seealso marker="kernel:inet#gethostbyname/1"> + inet:gethostbyname/1</seealso> will be used instead</p> + <p>This callback may also return the port of the given node. In that case + <seealso marker="kernel:erl_epmd#port_please/3">port_please/3</seealso> + may be omitted.</p></item> + </taglist> + </section> +</chapter> diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml index be969a8267..e6245130fc 100644 --- a/erts/doc/src/alt_dist.xml +++ b/erts/doc/src/alt_dist.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2016</year> + <year>2000</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -47,23 +47,30 @@ runs on. The reason the C code is not made portable, is simply readability.</p> - <note> - <p>This section was written a long time ago. Most of it is still - valid, but some things have changed since then. - Most notably is the driver interface. Some updates have been made - to the documentation of the driver presented here, - but more can be done and is planned for the future. - The reader is encouraged to read the - <seealso marker="erl_driver"><c>erl_driver</c></seealso> and - <seealso marker="driver_entry"><c>driver_entry</c></seealso> - documentation also.</p> - </note> - <section> <title>Introduction</title> <p>To implement a new carrier for the Erlang distribution, the main steps are as follows.</p> + <note><p> + As of ERTS version 10.0 support for distribution controller + processes has been introduced. That is, the traffic over a + distribution channel can be managed by a process instead of + only by a port. This makes it possible to implement large + parts of the logic in Erlang code, and you perhaps do not + even need a new driver for the protocol. One example could + be Erlang distribution over UDP using <c>gen_udp</c> (your + Erlang code will of course have to take care of retranspissions, + etc in this example). That is, depending on what you want + to do you perhaps do not need to implement a driver at all + and can then skip the driver related sections below. + The <c>gen_tcp_dist</c> example described in the + <seealso marker="#distribution_module">Distribution + Module</seealso> section utilize distribution controller + processes and can be worth having a look at if you want to + use distribution controller processes. + </p></note> + <section> <title>Writing an Erlang Driver</title> <p>First, the protocol must be available to the Erlang machine, which @@ -152,7 +159,711 @@ </section> <section> + <marker id="distribution_module"/> + <title>Distribution Module</title> + <p> + The distribution module expose an API that <c>net_kernel</c> call + in order to manage connections to other nodes. The module name + should have the suffix <c>_dist</c>. + </p> + <p> + The module needs to create some kind of listening entity (process + or port) and an acceptor process that accepts incoming connections + using the listening entity. For each connection, the module at least + needs to create one connection supervisor process, which also is + responsible for the handshake when setting up the connection, and + a distribution controller (process or port) responsible for + transport of data over the connection. The distribution controller + and the connection supervisor process should be linked together + so both of them are cleaned up when the connection is taken down. + </p> + <p> + Note that there need to be exactly one distribution controller + per connection. A process or port can only be distribution + controller for one connection. The registration as distribution + controller cannot be undone. It will stick until the distribution + controller terminates. The distribution controller should not + ignore exit signals. It is allowed to trap exits, but it should + then voluntarily terminate when an exit signal is received. + </p> + <p> + An example implementation of a distribution module can be found + in + <url href="gen_tcp_dist.erl">$ERL_TOP/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl</url>. + It implements the distribution over TCP/IP using the <c>gen_tcp</c> + API with distribution controllers implemented by processes. This + instead of using port distribution controllers as the ordinary TCP/IP + distribution uses. + </p> + + <section> + <marker id="distribution_module_exported_callback_functions"/> + <title>Exported Callback Functions</title> + + <p> + The following functions are mandatory: + </p> + <taglist> + <tag><marker id="listen"/><c>listen(Name) -></c><br/> <c>{ok, {Listen, Address, Creation}} | {error, Error} </c></tag> + <item> + <p> + <c>listen/1</c> is called once in order to listen for incoming + connection requests. The call is made when the distribution is brought + up. The argument <c>Name</c> is the part of the node name before + the <c>@</c> sign in the full node name. It can be either an atom or a + string. + </p> + <p> + The return value consists of a <c>Listen</c> handle (which is + later passed to the <seealso marker="#accept"><c>accept/1</c></seealso> + callback), <c>Address</c> which is a <c>#net_address{}</c> record + with information about the address for the node (the + <c>#net_address{}</c> record is defined in + <c>kernel/include/net_address.hrl</c>), and <c>Creation</c> which + (currently) is an integer <c>1</c>, <c>2</c>, or <c>3</c>. + </p> + <p> + If <seealso marker="erts:epmd"><c>epmd</c></seealso> is to be used + for node discovery, you typically want to use the (unfortunately + undocumented) <c>erl_epmd</c> module (part of the <c>kernel</c> + application) in order to register the listen port with <c>epmd</c> + and retrieve <c>Creation</c> to use. + </p> + </item> + + <tag><marker id="accept"/><c>accept(Listen) -></c><br/> <c>AcceptorPid</c></tag> + <item> + <p> + <c>accept/1</c> should spawn a process that accepts connections. This + process should preferably execute on <c>max</c> priority. The process + identifier of this process should be returned. + </p> + <p> + The <c>Listen</c> argument will be the same as the <c>Listen</c> handle + part of the return value of the + <seealso marker="#listen"><c>listen/1</c></seealso> callback above. + <c>accept/1</c> is called only once when the distribution protocol is + started. + </p> + <p> + The caller of this function is a representative for <c>net_kernel</c> + (this may or may not be the process registered as <c>net_kernel</c>) + and is in this document identified as <c>Kernel</c>. + When a connection has been accepted by the acceptor process, it needs + to inform <c>Kernel</c> about the accepted connection. This is done by + passing a message on the form: + </p> + <code type="none"><![CDATA[Kernel ! {accept, AcceptorPid, DistController, Family, Proto}]]></code> + <p> + <c>DistController</c> is either the process or port identifier + of the distribution controller for the connection. The + distribution controller should be created by the acceptor + processes when a new connection is accepted. Its job is to + dispatch traffic on the connection. + </p> + <c>Kernel</c> responds with one of the following messages: + <taglist> + <tag><c>{Kernel, controller, SupervisorPid}</c></tag> + <item> + <p> + The request was accepted and <c>SupervisorPid</c> is the + process identifier of the connection supervisor process + (which is created in the + <seealso marker="#accept_connection"><c>accept_connection/5</c></seealso> + callback). + </p> + </item> + <tag><c>{Kernel, unsupported_protocol}</c></tag> + <item> + <p> + The request was rejected. This is a fatal error. The acceptor + process should terminate. + </p> + </item> + </taglist> + <p> + When an accept sequence has been completed the acceptor process + is expected to continue accepting further requests. + </p> + </item> + + <tag><marker id="accept_connection"/><c>accept_connection(AcceptorPid, DistCtrl, MyNode, Allowed, SetupTime) -></c><br/> <c>ConnectionSupervisorPid</c></tag> + <item> + <p> + <c>accept_connection/5</c> should spawn a process that will + perform the Erlang distribution handshake for the connection. + If the handshake successfully completes it should continue to + function as a connection supervisor. This process + should preferably execute on <c>max</c> priority. + </p> + <p>The arguments:</p> + <taglist> + <tag><c>AcceptorPid</c></tag> + <item> + <p> + Process identifier of the process created by the + <seealso marker="#accept"><c>accept/1</c></seealso> + callback. + </p> + </item> + <tag><c>DistCtrl</c></tag> + <item> + <p>The identifier of the distribution controller identifier + created by the acceptor process. To be passed along to + <c>dist_util:handshake_other_started(HsData)</c>. + </p> + </item> + <tag><c>MyNode</c></tag> + <item> + <p> + Node name of this node. To be passed along to + <c>dist_util:handshake_other_started(HsData)</c>. + </p> + </item> + <tag><c>Allowed</c></tag> + <item> + <p> + To be passed along to + <c>dist_util:handshake_other_started(HsData)</c>. + </p> + </item> + <tag><c>SetupTime</c></tag> + <item> + <p> + Time used for creating a setup timer by a + call to <c>dist_util:start_timer(SetupTime)</c>. + The timer should be passed along to + <c>dist_util:handshake_other_started(HsData)</c>. + </p> + </item> + </taglist> + <p> + The created process should provide callbacks and other + information needed for the handshake in a + <seealso marker="#hs_data_record"><c>#hs_data{}</c></seealso> + record and call <c>dist_util:handshake_other_started(HsData)</c> + with this record. + </p> + <p> + <c>dist_util:handshake_other_started(HsData)</c> will perform + the handshake and if the handshake successfully completes this + process will then continue in a connection supervisor loop + as long as the connection is up. + </p> + </item> + + <tag><marker id="setup"/><c>setup(Node, Type, MyNode, LongOrShortNames, SetupTime) -></c><br/> <c>ConnectionSupervisorPid</c></tag> + <item> + <p> + <c>setup/5</c> should spawn a process that connects to + <c>Node</c>. When connection has been established it should + perform the Erlang distribution handshake for the connection. + If the handshake successfully completes it should continue to + function as a connection supervisor. This process + should preferably execute on <c>max</c> priority. + </p> + <p>The arguments:</p> + <taglist> + <tag><c>Node</c></tag> + <item> + <p> + Node name of remote node. To be passed along to + <c>dist_util:handshake_we_started(HsData)</c>. + </p> + </item> + <tag><c>Type</c></tag> + <item> + <p> + Connection type. To be passed along to + <c>dist_util:handshake_we_started(HsData)</c>. + </p> + </item> + <tag><c>MyNode</c></tag> + <item> + <p> + Node name of this node. To be passed along to + <c>dist_util:handshake_we_started(HsData)</c>. + </p> + </item> + <tag><c>LongOrShortNames</c></tag> + <item> + <p> + Either the atom <c>longnames</c> or + the atom <c>shortnames</c> indicating + whether long or short names is used. + </p> + </item> + <tag><c>SetupTime</c></tag> + <item> + <p> + Time used for creating a setup timer by a + call to <c>dist_util:start_timer(SetupTime)</c>. + The timer should be passed along to + <c>dist_util:handshake_we_started(HsData)</c>. + </p> + </item> + </taglist> + <p> + The caller of this function is a representative for <c>net_kernel</c> + (this may or may not be the process registered as <c>net_kernel</c>) + and is in this document identified as <c>Kernel</c>. + </p> + <p> + This function should, besides spawning the connection supervisor, + also create a distribution controller. The distribution + controller is either a process or a port which is responsible + for dispatching traffic. + </p> + <p> + The created process should provide callbacks and other + information needed for the handshake in a + <seealso marker="#hs_data_record"><c>#hs_data{}</c></seealso> + record and call <c>dist_util:handshake_we_started(HsData)</c> + with this record. + </p> + <p> + <c>dist_util:handshake_we_started(HsData)</c> will perform + the handshake and the handshake successfully completes this + process will then continue in a connection supervisor loop + as long as the connection is up. + </p> + </item> + + <tag><marker id="close"/><c>close(Listen) -></c><br/> <c>void()</c></tag> + + <item><p> + Called in order to close the <c>Listen</c> handle + that originally was passed from the + <seealso marker="#listen"><c>listen/1</c></seealso> callback. + </p></item> + + <tag><marker id="select"/><c>select(NodeName) -></c><br/> <c>boolean()</c></tag> + <item> + <p>Return <c>true</c> if the host name part + of the <c>NodeName</c> is valid for use + with this protocol; otherwise, <c>false</c>. + </p> + </item> + + </taglist> + + <p> + There are also two optional functions that may be + exported: + </p> + <taglist> + <tag><marker id="select"/><c>setopts(Listen, Opts) -></c><br/> <c>ok | {error, Error}</c></tag> + <item> + <p> + The argument <c>Listen</c> is the handle originally passed + from the + <seealso marker="#listen"><c>listen/1</c></seealso> callback. + The argument <c>Opts</c> is a list of options to set on future + connections. + </p> + </item> + + <tag><marker id="select"/><c>getopts(Listen, Opts) -></c><br/> <c>{ok, OptionValues} | {error, Error}</c></tag> + <item> + <p> + The argument <c>Listen</c> is the handle originally passed + from the + <seealso marker="#listen"><c>listen/1</c></seealso> callback. + The argument <c>Opts</c> is a list of options to read for future + connections. + </p> + </item> + </taglist> + + </section> + <section> + <marker id="hs_data_record"/> + <title>The #hs_data{} Record</title> + <p> + The <c>dist_util:handshake_we_started/1</c> and + <c>dist_util:handshake_other_started/1</c> functions + takes a <c>#hs_data{}</c> record as argument. There + are quite a lot of fields in this record that you + need to set. The record is defined in + <c>kernel/include/dist_util.hrl</c>. Not documented + fields should not be set, i.e., should be left as + <c>undefined</c>. + </p> + <p> + The following <c>#hs_data{}</c> record fields need + to be set unless otherwise stated:</p> + <taglist> + <tag><marker id="hs_data_kernel_pid"/><c>kernel_pid</c></tag> + <item> + <p> + Process identifier of the <c>Kernel</c> process. That is, + the process that called either + <seealso marker="#setup"><c>setup/5</c></seealso> or + <seealso marker="#accept_connection"><c>accept_connection/5</c></seealso>. + </p> + </item> + + <tag><marker id="hs_data_other_node"/><c>other_node</c></tag> + <item> + <p>Name of the other node. This field is only + mandatory when this node initiates the connection. + That is, when connection is set up via + <seealso marker="#setup"><c>setup/5</c></seealso>. + </p> + </item> + + <tag><marker id="hs_data_this_node"/><c>this_node</c></tag> + <item> + <p> + The node name of this node. + </p> + </item> + + <tag><marker id="hs_data_socket"/><c>socket</c></tag> + <item> + <p> + The identifier of the distribution controller. + </p> + </item> + + <tag><marker id="hs_data_timer"/><c>timer</c></tag> + <item> + <p> + The timer created using <c>dist_util:start_timer/1</c>. + </p> + </item> + + <tag><marker id="hs_data_allowed"/><c>allowed</c></tag> + <item> + <p>Information passed as <c>Allowed</c> to + <c>accept_connection/5</c>. This field is only + mandatory when the remote node initiated the + connection. That is, when the connection is set + up via + <seealso marker="#accept_connection"><c>accept_connection/5</c></seealso>. + </p> + </item> + + <tag><marker id="hs_data_f_send"/><c>f_send</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr, Data) -> ok | {error, Error}]]></code> + <p> + where <c>DistCtrlr</c> is the identifier of + the distribution controller and <c>Data</c> + is io data to pass to the other side. + </p> + <p>Only used during handshake phase.</p> + </item> + + <tag><marker id="hs_data_f_recv"/><c>f_recv</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr, Length) -> {ok, Packet} | {error, Reason}]]></code> + <p> + where <c>DistCtrlr</c> is the identifier of the distribution + controller. + If <c>Length</c> is <c>0</c>, all available bytes should be + returned. If <c>Length > 0</c>, exactly <c>Length</c> bytes + should be returned, or an error; possibly discarding less + than <c>Length</c> bytes of data when the connection is + closed from the other side. + It is used for passive receive of data from the + other end. + </p> + <p>Only used during handshake phase.</p> + </item> + + <tag><marker id="hs_data_f_setopts_pre_nodeup"/><c>f_setopts_pre_nodeup</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr) -> ok | {error, Error}]]></code> + <p> + where <c>DistCtrlr</c> is the identifier of + the distribution controller. Called just + before the distribution channel is taken up + for normal traffic. + </p> + <p>Only used during handshake phase.</p> + </item> + + <tag><marker id="hs_data_f_setopts_post_nodeup"/><c>f_setopts_post_nodeup</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr) -> ok | {error, Error}]]></code> + <p> + where <c>DistCtrlr</c> is the identifier of + the distribution controller. Called just + after distribution channel has been taken + up for normal traffic. + </p> + <p>Only used during handshake phase.</p> + </item> + + <tag><marker id="hs_data_f_getll"/><c>f_getll</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr) -> ID]]></code> + <p> + where <c>DistCtrlr</c> is the identifier of + the distribution controller and <c>ID</c> is + the identifier of the low level entity that + handles the connection (often <c>DistCtrlr</c> + itself). + </p> + <p>Only used during handshake phase.</p> + </item> + + <tag><marker id="hs_data_f_address"/><c>f_address</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr, Node) -> NetAddress]]></code> + <p> + where <c>DistCtrlr</c> is the identifier of + the distribution controller, <c>Node</c> + is the node name of the node on the other end, + and <c>NetAddress</c> is a <c>#net_address{}</c> + record with information about the address + for the <c>Node</c> on the other end of the + connection. The <c>#net_address{}</c> record + is defined in + <c>kernel/include/net_address.hrl</c>. + </p> + <p>Only used during handshake phase.</p> + </item> + + <tag><marker id="hs_data_mf_tick"/><c>mf_tick</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr) -> void()]]></code> + <p> + where <c>DistCtrlr</c> is the identifier + of the distribution controller. This + function should send information over + the connection that is not interpreted + by the other end while increasing the + statistics of received packets on the + other end. This is usually implemented by + sending an empty packet. + </p> + <note><p> + It is of vital importance that this operation + does not block the caller for a long time. + This since it is called from the connection + supervisor. + </p></note> + <p>Used when connection is up.</p> + </item> + + <tag><marker id="hs_data_mf_getstat"/><c>mf_getstat</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr) -> {ok, Received, Sent, PendSend}]]></code> + <p> + where <c>DistCtrlr</c> is the identifier + of the distribution controller, <c>Received</c> + is received packets, <c>Sent</c> is + sent packets, and <c>PendSend</c> is + amount of packets in queue to be sent + or a <c>boolean()</c> indicating whether + there are packets in queue to be sent. + </p> + <note><p> + It is of vital importance that this operation + does not block the caller for a long time. + This since it is called from the connection + supervisor. + </p></note> + <p>Used when connection is up.</p> + </item> + + <tag><marker id="hs_data_request_type"/><c>request_type</c></tag> + <item> + <p> + The request <c>Type</c> as passed to + <seealso marker="#setup"><c>setup/5</c></seealso>. + This is only mandatory when the connection has + been initiated by this node. That is, the connection + is set up via <c>setup/5</c>. + </p> + </item> + + <tag><marker id="hs_data_mf_setopts"/><c>mf_setopts</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrl, Opts) -> ok | {error, Error}]]></code> + <p> + where <c>DistCtrlr</c> is the identifier + of the distribution controller and <c>Opts</c> + is a list of options to set on the connection. + </p> + <p>This function is optional. Used when connection is up.</p> + </item> + + <tag><marker id="hs_data_mf_getopts"/><c>mf_getopts</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrl, Opts) -> {ok, OptionValues} | {error, Error}]]></code> + <p> + where <c>DistCtrlr</c> is the identifier + of the distribution controller and <c>Opts</c> + is a list of options to read for the connection. + </p> + <p>This function is optional. Used when connection is up.</p> + </item> + + <tag><marker id="hs_data_f_handshake_complete"/><c>f_handshake_complete</c></tag> + <item> + <p> + A fun with the following signature: + </p> + <code type="none"><![CDATA[fun (DistCtrlr, Node, DHandle) -> void()]]></code> + <p> + where <c>DistCtrlr</c> is the identifier + of the distribution controller, <c>Node</c> is + the node name of the node connected at the other + end, and <c>DHandle</c> is a distribution handle + needed by a distribution controller process when + calling the following BIFs: + </p> + <list> + <item><p><seealso marker="erts:erlang#dist_ctrl_get_data/1"><c>erlang:dist_ctrl_get_data/1</c></seealso></p></item> + <item><p><seealso marker="erts:erlang#dist_ctrl_get_data_notification/1"><c>erlang:dist_ctrl_get_data_notification/1</c></seealso></p></item> + <item><p><seealso marker="erts:erlang#dist_ctrl_input_handler/2"><c>erlang:dist_ctrl_input_handler/2</c></seealso></p></item> + <item><p><seealso marker="erts:erlang#dist_ctrl_put_data/2"><c>erlang:dist_ctrl_put_data/2</c></seealso></p></item> + </list> + <p> + This function is called when the handshake has + completed and the distribution channel is up. + The distribution controller can begin dispatching + traffic over the channel. This function is optional. + </p> + <p>Only used during handshake phase.</p> + </item> + + <tag><marker id="hs_data_add_flags"/><c>add_flags</c></tag> + <item> + <p> + <seealso marker="erl_dist_protocol#dflags">Distribution flags</seealso> + to add to the connection. Currently all (non obsolete) flags will + automatically be enabled. + </p> + <p> + This flag field is optional. + </p> + </item> + + <tag><marker id="hs_data_reject_flags"/><c>reject_flags</c></tag> + <item> + <p> + <seealso marker="erl_dist_protocol#dflags">Distribution flags</seealso> + to reject. Currently the following distribution flags can be rejected: + </p> + <taglist> + <tag><c>DFLAG_DIST_HDR_ATOM_CACHE</c></tag> + <item>Do not use atom cache over this connection.</item> + </taglist> + <p>Use function <c>dist_util:strict_order_flags/0</c> to get all flags + for features that require strict order delivery.</p> + <p> + This flag field is optional. + </p> + </item> + + <tag><marker id="hs_data_require_flags"/><c>require_flags</c></tag> + <item> + <p> + Require these <seealso marker="erl_dist_protocol#dflags">distribution + flags</seealso> to be used. The connection will be aborted during the + handshake if the other end does not use them. + </p> + <p> + This flag field is optional. + </p> + </item> + + </taglist> + </section> + + <section> + <marker id="distribution_data_delivery"/> + <title>Distribution Data Delivery</title> + <p> + When using the default configuration, the data to pass + over a connection needs to be delivered as is + to the node on the receiving end in the <em>exact same + order</em>, with no loss of data what so ever, as sent + from the sending node. + </p> + <p> + The data delivery order can be relaxed by disabling + features that require strict ordering. This is done by + passing the + <seealso marker="erl_dist_protocol#dflags">distribution flags</seealso> + returned by <c>dist_util:strict_order_flags/0</c> in the + <seealso marker="alt_dist#hs_data_reject_flags"><c>reject_flags</c></seealso> + field of the <seealso marker="#hs_data_record"><c>#hs_data{}</c></seealso> + record used when setting up the connection. When relaxed + ordering is used, only the order of signals with the same + sender/receiver pair has to be preserved. + However, note that disabling the features that require + strict ordering may have a negative impact on performance, + throughput, and/or latency. + </p> + </section> + + <section> + <marker id="enable_your_distribution_module"/> + <title>Enable Your Distribution Module</title> + + <p>For <c>net_kernel</c> to find out which distribution module to use, + the <c>erl</c> command-line argument <c>-proto_dist</c> is used. It + is followed by one or more distribution module names, with suffix + "_dist" removed. That is, <c>gen_tcp_dist</c> as a distribution module + is specified as <c>-proto_dist gen_tcp</c>.</p> + + <p>If no <c>epmd</c> (TCP port mapper daemon) is used, also command-line + option <c>-no_epmd</c> is to be specified, which makes + Erlang skip the <c>epmd</c> startup, both as an OS process and as an + Erlang ditto.</p> + </section> + + </section> + + <section> <title>The Driver</title> + + <note> + <p>This section was written a long time ago. Most of it is still + valid, but some things have changed since then. Some updates have + been made to the documentation of the driver presented here, + but more can be done and is planned for the future. + The reader is encouraged to read the + <seealso marker="erl_driver"><c>erl_driver</c></seealso> and + <seealso marker="driver_entry"><c>driver_entry</c></seealso> + documentation also.</p> + </note> + <p>Although Erlang drivers in general can be beyond the scope of this section, a brief introduction seems to be in place.</p> diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml index 2421e0a8d9..fd7d6223f6 100644 --- a/erts/doc/src/driver_entry.xml +++ b/erts/doc/src/driver_entry.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2001</year><year>2016</year> + <year>2001</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -196,10 +196,7 @@ typedef struct erl_drv_entry { char **rbuf, ErlDrvSizeT rlen, unsigned int *flags); /* Works mostly like 'control', a synchronous call into the driver */ - void (*event)(ErlDrvData drv_data, ErlDrvEvent event, - ErlDrvEventData event_data); - /* Called when an event selected by - driver_event() has occurred */ + void* unused_event_callback; int extended_marker; /* ERL_DRV_EXTENDED_MARKER */ int major_version; /* ERL_DRV_EXTENDED_MAJOR_VERSION */ int minor_version; /* ERL_DRV_EXTENDED_MINOR_VERSION */ diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 638e88ca31..05a9895687 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1996</year><year>2017</year> + <year>1996</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -360,11 +360,12 @@ </item> <tag><c><![CDATA[-mode interactive | embedded]]></c></tag> <item> - <p>Indicates if the system is to load code dynamically - (<c><![CDATA[interactive]]></c>), or if all code is to be loaded - during system initialization (<c><![CDATA[embedded]]></c>); see - <seealso marker="kernel:code"><c>code(3)</c></seealso>. - Defaults to <c><![CDATA[interactive]]></c>.</p> + <p>Modules are auto loaded when they are first referenced if the + runtime system runs in <c><![CDATA[interactive]]></c> mode, which is + the default. In <c><![CDATA[embedded]]></c> mode modules are not auto + loaded. The latter is recommended when the boot script preloads all + modules, as conventionally happens in OTP releases. See + <seealso marker="kernel:code"><c>code(3)</c></seealso></p>. </item> <tag><c><![CDATA[-name Name]]></c></tag> <item> @@ -538,20 +539,6 @@ <p>Note that a distributed node will fail to start if epmd is not running.</p> </item> - <tag><marker id="smp"/><c><![CDATA[-smp [enable|auto|disable]]]></c></tag> - <item> - <p><c>-smp enable</c> and <c>-smp</c> start the Erlang runtime - system with SMP support enabled. This can fail if no runtime - system with SMP support is available. <c>-smp auto</c> starts - the Erlang runtime system with SMP support enabled if it is - available and more than one logical processor is detected. - <c>-smp disable</c> starts a runtime system without SMP support. - The runtime system without SMP support is deprecated and will - be removed in a future major release.</p> - <note> - <p>See also flag<seealso marker="#+S"><c>+S</c></seealso>.</p> - </note> - </item> <tag><c><![CDATA[-version]]></c> (emulator flag)</tag> <item> <p>Makes the emulator print its version number. The same @@ -585,7 +572,7 @@ <tag><marker id="async_thread_pool_size"/><c><![CDATA[+A size]]></c></tag> <item> <p>Sets the number of threads in async thread pool. Valid range - is 0-1024. Defaults to 10 if thread support is available.</p> + is 0-1024. Defaults to 1.</p> </item> <tag><c><![CDATA[+B [c | d | i]]]></c></tag> <item> @@ -644,14 +631,16 @@ of process heaps is destroyed by the crash dump generation.</p> <p>Option <c>+d</c> instructs the emulator to produce only a core dump and no crash dump if an internal error is detected.</p> - <p>Calling <seealso marker="erlang:halt/1"> + <p>Calling <seealso marker="erlang#halt/1"> <c>erlang:halt/1</c></seealso> with a string argument still produces a crash dump. On Unix systems, sending an emulator process a <c>SIGUSR1</c> signal also forces a crash dump.</p> </item> <tag><marker id="+e"/><c><![CDATA[+e Number]]></c></tag> <item> - <p>Sets the maximum number of ETS tables.</p> + <p>Sets the maximum number of ETS tables. This limit is + <seealso marker="stdlib:ets#max_ets_tables">partially obsolete</seealso>. + </p> </item> <tag><c><![CDATA[+ec]]></c></tag> <item> @@ -776,13 +765,40 @@ <seealso marker="erlang#process_flag_message_queue_data"> <c>process_flag(message_queue_data, MQD)</c></seealso>.</p> </item> - <tag><c><![CDATA[+K true | false]]></c></tag> + <tag><marker id="+IOp"/><c>+IOp PollSets</c></tag> + <item> + <p>Sets the number of IO pollsets to use when polling for I/O. + This option is only used on platforms that support concurrent + updates of a pollset, otherwise the same number of pollsets + are used as IO poll threads. + The default is 1. + </p> + </item> + <tag><marker id="+IOt"/><c>+IOt PollThreads</c></tag> + <item> + <p>Sets the number of IO poll threads to use when polling for I/O. + The maximum number of poll threads allowed is 1024. The default is 1. + </p> + <p>A good way to check if more IO poll threads are needed is to use + <seealso marker="runtime_tools:msacc">microstate accounting</seealso> + and see what the load of the IO poll thread is. If it is high it could + be a good idea to add more threads.</p> + </item> + <tag><marker id="+IOPp"/><c>+IOPp PollSetsPercentage</c></tag> + <item> + <p>Similar to <seealso marker="#+IOp"><c>+IOp</c></seealso> but uses + percentages to set the number of IO pollsets to create, based on the + number of poll threads configured. If both <c>+IOPp</c> and <c>+IOp</c> + are used, <c>+IOPp</c> is ignored. + </p> + </item> + <tag><marker id="+IOPt"/><c>+IOPt PollThreadsPercentage</c></tag> <item> - <p>Enables or disables the kernel poll functionality if supported by - the emulator. Defaults to <c><![CDATA[false]]></c> (disabled). - If the emulator does not support kernel poll, and flag - <c><![CDATA[+K]]></c> is passed to the emulator, a warning is - issued at startup.</p> + <p>Similar to <seealso marker="#+IOt"><c>+IOt</c></seealso> but uses + percentages to set the number of IO poll threads to create, based on + the number of schedulers configured. If both <c>+IOPt</c> and + <c>+IOt</c> are used, <c>+IOPt</c> is ignored. + </p> </item> <tag><c><![CDATA[+l]]></c></tag> <item> @@ -902,7 +918,7 @@ <c><![CDATA[+S Schedulers:SchedulerOnline]]></c></tag> <item> <p>Sets the number of scheduler threads to create and scheduler threads - to set online when SMP support has been enabled. The maximum for both + to set online. The maximum for both values is 1024. If the Erlang runtime system is able to determine the number of logical processors configured and logical processors available, <c>Schedulers</c> defaults to logical processors @@ -920,8 +936,6 @@ <p>Specifying value <c>0</c> for <c>Schedulers</c> or <c>SchedulersOnline</c> resets the number of scheduler threads or scheduler threads online, respectively, to its default value.</p> - <p>This option is ignored if the emulator does not have SMP support - enabled (see flag <seealso marker="#smp"><c>-smp</c></seealso>).</p> </item> <tag><marker id="+SP"/><c><![CDATA[+SP SchedulersPercentage:SchedulersOnlinePercentage]]></c></tag> @@ -929,8 +943,8 @@ <p>Similar to <seealso marker="#+S"><c>+S</c></seealso> but uses percentages to set the number of scheduler threads to create, based on logical processors configured, and scheduler threads to set online, - based on logical processors available, when SMP support has been - enabled. Specified values must be > 0. For example, + based on logical processors available. + Specified values must be > 0. For example, <c>+SP 50:25</c> sets the number of scheduler threads to 50% of the logical processors configured, and the number of scheduler threads online to 25% of the logical processors available. @@ -945,15 +959,13 @@ and 8 logical cores available, the combination of the options <c>+S 4:4 +SP 50:25</c> (in either order) results in 2 scheduler threads (50% of 4) and 1 scheduler thread online (25% of 4).</p> - <p>This option is ignored if the emulator does not have SMP support - enabled (see flag <seealso marker="#smp"><c>-smp</c></seealso>).</p> </item> <tag><marker id="+SDcpu"/><c><![CDATA[+SDcpu DirtyCPUSchedulers:DirtyCPUSchedulersOnline]]></c></tag> <item> <p>Sets the number of dirty CPU scheduler threads to create and dirty - CPU scheduler threads to set online when threading support has been - enabled. The maximum for both values is 1024, and each value is + CPU scheduler threads to set online. + The maximum for both values is 1024, and each value is further limited by the settings for normal schedulers:</p> <list type="bulleted"> <item>The number of dirty CPU scheduler threads created cannot exceed @@ -977,16 +989,14 @@ executing on ordinary schedulers. If the amount of dirty CPU schedulers was allowed to be unlimited, dirty CPU bound jobs would potentially starve normal jobs.</p> - <p>This option is ignored if the emulator does not have threading - support enabled.</p> </item> <tag><marker id="+SDPcpu"/><c><![CDATA[+SDPcpu DirtyCPUSchedulersPercentage:DirtyCPUSchedulersOnlinePercentage]]></c></tag> <item> <p>Similar to <seealso marker="#+SDcpu"><c>+SDcpu</c></seealso> but uses percentages to set the number of dirty CPU scheduler threads to - create and the number of dirty CPU scheduler threads to set online - when threading support has been enabled. Specified values must be + create and the number of dirty CPU scheduler threads to set online. + Specified values must be > 0. For example, <c>+SDPcpu 50:25</c> sets the number of dirty CPU scheduler threads to 50% of the logical processors configured and the number of dirty CPU scheduler threads online to 25% of the @@ -1003,13 +1013,11 @@ the combination of the options <c>+SDcpu 4:4 +SDPcpu 50:25</c> (in either order) results in 2 dirty CPU scheduler threads (50% of 4) and 1 dirty CPU scheduler thread online (25% of 4).</p> - <p>This option is ignored if the emulator does not have threading - support enabled.</p> </item> <tag><marker id="+SDio"/><c><![CDATA[+SDio DirtyIOSchedulers]]></c></tag> <item> - <p>Sets the number of dirty I/O scheduler threads to create when - threading support has been enabled. Valid range is 0-1024. By + <p>Sets the number of dirty I/O scheduler threads to create. + Valid range is 0-1024. By default, the number of dirty I/O scheduler threads created is 10, same as the default number of threads in the <seealso marker="#async_thread_pool_size">async thread pool</seealso>.</p> @@ -1019,8 +1027,6 @@ expected to execute on dirty I/O schedulers. If the user should schedule CPU bound jobs on dirty I/O schedulers, these jobs might starve ordinary jobs executing on ordinary schedulers.</p> - <p>This option is ignored if the emulator does not have threading - support enabled.</p> </item> <tag><c><![CDATA[+sFlag Value]]></c></tag> <item> @@ -1151,6 +1157,26 @@ without prior notice.</p> </note> </item> + <tag><marker id="+sbwtdcpu"/> + <c>+sbwtdcpu none|very_short|short|medium|long|very_long</c></tag> + <item> + <p>As <seealso marker="#+sbwt"><c>+sbwt</c></seealso> but affects + dirty CPU schedulers. Defaults to <c>short</c>.</p> + <note> + <p>This flag can be removed or changed at any time + without prior notice.</p> + </note> + </item> + <tag><marker id="+sbwtdio"/> + <c>+sbwtdio none|very_short|short|medium|long|very_long</c></tag> + <item> + <p>As <seealso marker="#+sbwt"><c>+sbwt</c></seealso> but affects + dirty IO schedulers. Defaults to <c>short</c>.</p> + <note> + <p>This flag can be removed or changed at any time + without prior notice.</p> + </note> + </item> <tag><marker id="+scl"/><c>+scl true|false</c></tag> <item> <p>Enables or disables scheduler compaction of load. By default @@ -1297,25 +1323,6 @@ <seealso marker="erlang#system_info_cpu_topology"> <c>erlang:system_info(cpu_topology)</c></seealso>.</p> </item> - <tag><marker id="+secio"/><c>+secio true|false</c></tag> - <item> - <p>Enables or disables eager check I/O scheduling. Defaults - to <c>true</c>. The default was changed from <c>false</c> - as from ERTS 7.0. The behavior before this - flag was introduced corresponds to <c>+secio false</c>.</p> - <p>The flag effects when schedulers will check for I/O - operations possible to execute, and when such I/O operations - will execute. As the parameter name implies, - schedulers are more eager to check for I/O when - <c>true</c> is passed. This, however, also implies that - execution of outstanding I/O operation is not - prioritized to the same extent as when <c>false</c> is - passed.</p> - <p><seealso marker="erlang#system_info_eager_check_io"> - <c>erlang:system_info(eager_check_io)</c></seealso> - returns the value of this parameter used when starting - the virtual machine.</p> - </item> <tag><marker id="+sfwi"/><c>+sfwi Interval</c></tag> <item> <p>Sets scheduler-forced wakeup interval. All run queues are @@ -1435,6 +1442,26 @@ notice.</p> </note> </item> + <tag><marker id="+swtdcpu"/> + <c>+swtdcpu very_low|low|medium|high|very_high</c></tag> + <item> + <p>As <seealso marker="#+swt"><c>+swt</c></seealso> but + affects dirty CPU schedulers. Defaults to <c>medium</c>.</p> + <note> + <p>This flag can be removed or changed at any time + without prior notice.</p> + </note> + </item> + <tag><marker id="+swtdio"/> + <c>+swtdio very_low|low|medium|high|very_high</c></tag> + <item> + <p>As <seealso marker="#+swt"><c>+swt</c></seealso> but affects + dirty IO schedulers. Defaults to <c>medium</c>.</p> + <note> + <p>This flag can be removed or changed at any time + without prior notice.</p> + </note> + </item> </taglist> </item> <tag><marker id="+t"/><c><![CDATA[+t size]]></c></tag> @@ -1657,9 +1684,7 @@ <tag>The <c>.erlang</c> startup file</tag> <item> <p>When Erlang/OTP is started, the system searches for a file named - <c>.erlang</c> in the directory where Erlang/OTP is started. If not - found, the user's home directory is searched for an <c>.erlang</c> - file.</p> + <c>.erlang</c> in the user's home directory.</p> <p>If an <c>.erlang</c> file is found, it is assumed to contain valid Erlang expressions. These expressions are evaluated as if they were input to the shell.</p> @@ -1711,4 +1736,3 @@ code:load_abs("..../user_default"). ]]></code> <seealso marker="tools:make"><c>make(3)</c></seealso></p> </section> </comref> - diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml index 610351db6c..c90c8f9521 100644 --- a/erts/doc/src/erl_dist_protocol.xml +++ b/erts/doc/src/erl_dist_protocol.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2017</year> + <year>2018</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -829,7 +829,30 @@ DiB == gen_digest(ChA, ICA)? <item> <p>The node understand UTF-8 encoded atoms.</p> </item> + <tag><c>-define(DFLAG_MAP_TAG, 16#20000).</c></tag> + <item> + <p>The node understand the map tag.</p> + </item> + <tag><c>-define(DFLAG_BIG_CREATION, 16#40000).</c></tag> + <item> + <p>The node understand big node creation.</p> + </item> + <tag><c>-define(DFLAG_SEND_SENDER, 16#80000).</c></tag> + <item> + <p> + Use the <c>SEND_SENDER</c> + <seealso marker="#control_message">control message</seealso> + instead of the <c>SEND</c> control message and use the + <c>SEND_SENDER_TT</c> control message instead + of the <c>SEND_TT</c> control message. + </p> + </item> </taglist> + <p> + There is also function <c>dist_util:strict_order_flags/0</c> + returning all flags (bitwise or:ed together) corresponding to features + that require strict ordering of data over distribution channels. + </p> </section> </section> @@ -922,6 +945,7 @@ DiB == gen_digest(ChA, ICA)? </item> </taglist> + <marker id="control_message"/> <p>The <c>ControlMessage</c> is a tuple, where the first element indicates which distributed operation it encodes:</p> @@ -1028,4 +1052,49 @@ DiB == gen_digest(ChA, ICA)? </item> </taglist> </section> + + <section> + <title>New Ctrlmessages for Erlang/OTP 21</title> + <taglist> + <tag><c>SEND_SENDER</c></tag> + <item> + <p><c>{22, FromPid, ToPid}</c></p> + <p>Followed by <c>Message</c>.</p> + <p> + This control messages replace the <c>SEND</c> control + message and will be sent when the distribution flag + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_SEND_SENDER</c></seealso> + has been negotiated in the connection setup handshake. + </p> + <note><p> + Messages encoded before the connection has + been set up may still use the <c>SEND</c> control + message. However, once a <c>SEND_SENDER</c> or <c>SEND_SENDER_TT</c> + control message has been sent, no more <c>SEND</c> + control messages will be sent in the same direction + on the connection. + </p></note> + </item> + <tag><c>SEND_SENDER_TT</c></tag> + <item> + <p><c>{23, FromPid, ToPid, TraceToken}</c></p> + <p>Followed by <c>Message</c>.</p> + <p> + This control messages replace the <c>SEND_TT</c> control + message and will be sent when the distribution flag + <seealso marker="erl_dist_protocol#dflags"><c>DFLAG_SEND_SENDER</c></seealso> + has been negotiated in the connection setup handshake. + </p> + <note><p> + Messages encoded before the connection has + been set up may still use the <c>SEND_TT</c> control + message. However, once a <c>SEND_SENDER</c> or <c>SEND_SENDER_TT</c> + control message has been sent, no more <c>SEND_TT</c> + control messages will be sent in the same direction + on the connection. + </p></note> + </item> + </taglist> + </section> + </chapter> diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index 5705100ab2..7055889e4a 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2001</year><year>2017</year> + <year>2001</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -157,7 +157,7 @@ </note> <p>Most functions in this API are <em>not</em> thread-safe, that is, - they <em>cannot</em> be called from any thread. Functions + they <em>cannot</em> be called from arbitrary threads. Functions that are not documented as thread-safe can only be called from driver callbacks or function calls descending from a driver callback call. Notice that driver callbacks can be called from @@ -429,7 +429,7 @@ <taglist> <tag>Return types for driver callbacks</tag> <item> - <p>Rrewrite driver callback + <p>Rewrite driver callback <seealso marker="driver_entry#control"><c>control</c></seealso> to use return type <c>ErlDrvSSizeT</c> instead of <c>int</c>.</p> <p>Rewrite driver callback @@ -841,7 +841,7 @@ int suggested_stack_size;</code> <p>Thread options structure passed to <seealso marker="#erl_drv_thread_create"> <c>erl_drv_thread_create</c></seealso>. - The following fields exists:</p> + The following field exists:</p> <taglist> <tag><c>suggested_stack_size</c></tag> <item>A suggestion, in kilowords, on how large a stack to use. @@ -2304,8 +2304,13 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> buffer is too small, a value > <c>0</c> is returned and <c>*value_size</c> has been set to the buffer size needed.</p> <warning> - <p>Do <em>not</em> use libc's <c>getenv</c> or similar C library - interfaces from a driver.</p> + <p>This function reads the emulated environment used by + <seealso marker="os:getenv/1"><c>os:getenv/1</c></seealso> and not + the environment used by libc's <c>getenv(3)</c> or similar. Drivers + that <em>require</em> that these are in sync will need to do so + themselves, but keep in mind that they are segregated for a reason; + <c>getenv(3)</c> and its friends are <em>not thread-safe</em> and + may cause unrelated code to misbehave or crash the emulator.</p> </warning> <p>This function is thread-safe.</p> </desc> @@ -2650,8 +2655,13 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] environment variable is removed.</p> </note> <warning> - <p>Do <em>not</em> use libc's <c>putenv</c> or similar C library - interfaces from a driver.</p> + <p>This function modifies the emulated environment used by + <seealso marker="os:putenv/2"><c>os:putenv/2</c></seealso> and not + the environment used by libc's <c>putenv(3)</c> or similar. Drivers + that <em>require</em> that these are in sync will need to do so + themselves, but keep in mind that they are segregated for a reason; + <c>putenv(3)</c> and its friends are <em>not thread-safe</em> and + may cause unrelated code to misbehave or crash the emulator.</p> </warning> <p>This function is thread-safe.</p> </desc> @@ -3210,6 +3220,6 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] <seealso marker="erlang"><c>erlang(3)</c></seealso>, <seealso marker="kernel:erl_ddll"><c>erl_ddll(3)</c></seealso>, section <seealso marker="alt_dist">How to Implement an Alternative - Carrier for the Erlang Distribution></seealso> in the User's Guide</p> + Carrier for the Erlang Distribution</seealso> in the User's Guide</p> </section> </cref> diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index b9c2e70b57..a20b8ee884 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2001</year><year>2017</year> + <year>2001</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -194,7 +194,7 @@ ok <p>Binaries are sequences of whole bytes. Bitstrings with an arbitrary bit length have no support yet.</p> </item> - <tag>Resource objects</tag> + <tag><marker id="resource_objects"/>Resource objects</tag> <item> <p>The use of resource objects is a safe way to return pointers to native data structures from a NIF. A resource object is @@ -367,6 +367,8 @@ return term;</code> <c>enif_ioq_deq()</c></seealso></item> <item><seealso marker="#enif_ioq_peek"> <c>enif_ioq_peek()</c></seealso></item> + <item><seealso marker="#enif_ioq_peek_head"> + <c>enif_ioq_peek_head()</c></seealso></item> <item><seealso marker="#enif_inspect_iovec"> <c>enif_inspect_iovec()</c></seealso></item> <item><seealso marker="#enif_free_iovec"> @@ -538,7 +540,7 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, have to wait for a very long time. Blocking multi-scheduling, that is, calling <seealso marker="erlang#system_flag_multi_scheduling"> <c>erlang:system_flag(multi_scheduling, block)</c></seealso>, can - also take a very long time to complete. This becaue all ongoing + also take a very long time to complete. This is because all ongoing dirty operations on all dirty schedulers must complete before the block operation can complete.</p> <p>Many operations communicating with a process executing a @@ -588,7 +590,7 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, <c>unload</c> is called to release the library. All are described individually below.</p> <p>The fourth argument <c>NULL</c> is ignored. It - was earlier used for the deprectated <c>reload</c> callback + was earlier used for the deprecated <c>reload</c> callback which is no longer supported since OTP 20.</p> <p>If compiling a NIF for static inclusion through <c>--enable-static-nifs</c>, you must define <c>STATIC_ERLANG_NIF</c> @@ -807,7 +809,7 @@ typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj);</code> <tag><marker id="ErlNifResourceDown"/><c>ErlNifResourceDown</c></tag> <item> <code type="none"> -typedef void ErlNifResourceDown(ErlNifEnv* env, void* obj, const ErlNifPid* pid, const ErlNifMonitor* mon);</code> +typedef void ErlNifResourceDown(ErlNifEnv* env, void* obj, ErlNifPid* pid, ErlNifMonitor* mon);</code> <p>The function prototype of a resource down function, called on the behalf of <seealso marker="#enif_monitor_process"> enif_monitor_process</seealso>. <c>obj</c> is the resource, <c>pid</c> @@ -873,7 +875,7 @@ typedef enum { <item> <p>An enumeration of the properties that can be requested from <seealso marker="#enif_make_unique_integer"> - <c>enif_unique_integer</c></seealso>. + <c>enif_make_unique_integer</c></seealso>. For default properties, use value <c>0</c>.</p> <taglist> <tag><c>ERL_NIF_UNIQUE_POSITIVE</c></tag> @@ -972,6 +974,10 @@ typedef struct { <seealso marker="#enif_make_binary"><c>enif_make_binary</c></seealso>. An allocated (and owned) <c>ErlNifBinary</c> can be kept between NIF calls.</p> + <p>If you do not need to reallocate or keep the data alive across NIF + calls, consider using <seealso marker="#enif_make_new_binary"> + <c>enif_make_new_binary</c></seealso> instead as it will allocate + small binaries on the process heap when possible.</p> <p>Returns <c>true</c> on success, or <c>false</c> if allocation fails.</p> </desc> @@ -1098,6 +1104,16 @@ typedef struct { </func> <func> + <name><ret>char*</ret> + <nametext>enif_cond_name(ErlNifCond* cnd)</nametext></name> + <fsummary></fsummary> + <desc> + <p>Same as <seealso marker="erl_driver#erl_drv_cond_name"> + <c>erl_drv_cond_name</c></seealso>.</p> + </desc> + </func> + + <func> <name><ret>void</ret> <nametext>enif_cond_signal(ErlNifCond *cnd)</nametext></name> <fsummary></fsummary> @@ -1230,6 +1246,19 @@ typedef struct { </func> <func> + <name><ret>int</ret><nametext>enif_fprintf(FILE *stream, const char *format, ...)</nametext></name> + <fsummary>Format strings and Erlang terms.</fsummary> + <desc> + <p>Similar to <c>fprintf</c> but this format string also accepts + <c>"%T"</c>, which formats Erlang terms of type + <seealso marker="#ERL_NIF_TERM"><c>ERL_NIF_TERM</c></seealso>.</p> + <p>This function is primarily intenden for debugging purpose. It is not + recommended to print very large terms with <c>%T</c>. The function may + change <c>errno</c>, even if successful.</p> + </desc> + </func> + + <func> <name><ret>void</ret><nametext>enif_free(void* ptr)</nametext></name> <fsummary>Free dynamic memory.</fsummary> <desc> @@ -1264,7 +1293,7 @@ typedef struct { ErlNifIOVec *iovec = NULL; size_t max_elements = 128; ERL_NIF_TERM tail; -if (!enif_inspect_iovec(NULL, max_elements, term, &tail, iovec)) +if (!enif_inspect_iovec(NULL, max_elements, term, &tail, &iovec)) return 0; // Do things with the iovec @@ -1683,8 +1712,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); <fsummary>Peek inside the IO Queue</fsummary> <desc> <p>Get the I/O queue as a pointer to an array of <c>SysIOVec</c>s. - It also returns the number of elements in <c>iovlen</c>. - This is the only way to get data out of the queue.</p> + It also returns the number of elements in <c>iovlen</c>.</p> <p>Nothing is removed from the queue by this function, that must be done with <seealso marker="#enif_ioq_deq"><c>enif_ioq_deq</c></seealso>.</p> <p>The returned array is suitable to use with the Unix system @@ -1693,6 +1721,21 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> + <name><ret>int</ret> + <nametext>enif_ioq_peek_head(ErlNifEnv *env, ErlNifIOQueue *q, size_t *size, ERL_NIF_TERM *bin_term)</nametext></name> + <fsummary>Peek the head of the IO Queue.</fsummary> + <desc> + <p>Get the head of the IO Queue as a binary term.</p> + <p>If <c>size</c> is not <c>NULL</c>, the size of the head is placed + there.</p> + <p>Nothing is removed from the queue by this function, that must be done + with <seealso marker="#enif_ioq_deq"><c>enif_ioq_deq</c></seealso>.</p> + <p>Returns <c>true</c> on success, or <c>false</c> if the queue is + empty.</p> + </desc> + </func> + + <func> <name><ret>size_t</ret> <nametext>enif_ioq_size(ErlNifIOQueue *q)</nametext></name> <fsummary>Get the current size of the IO Queue</fsummary> @@ -2143,6 +2186,20 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); </func> <func> + <name><ret>int</ret> + <nametext>enif_make_map_from_arrays(ErlNifEnv* env, ERL_NIF_TERM keys[], + ERL_NIF_TERM values[], size_t cnt, ERL_NIF_TERM *map_out)</nametext></name> + <fsummary>Make map term from the given keys and values.</fsummary> + <desc> + <p>Makes a map term from the given keys and values.</p> + <p>If successful, this function sets <c>*map_out</c> to the new map and + returns <c>true</c>. Returns <c>false</c> there are any duplicate + keys.</p> + <p>All keys and values must belong to <c>env</c>.</p> + </desc> + </func> + + <func> <name><ret>unsigned char *</ret><nametext>enif_make_new_binary(ErlNifEnv* env, size_t size, ERL_NIF_TERM* termp)</nametext></name> <fsummary>Allocate and create a new binary term.</fsummary> @@ -2216,7 +2273,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); <seealso marker="#enif_get_resource"><c>enif_get_resource</c></seealso>.</p> </item> <item> - <p>A resoure term can be serialized with <c>term_to_binary</c> and later + <p>A resource term can be serialized with <c>term_to_binary</c> and later be fully recreated if the resource object is still alive when <c>binary_to_term</c> is called. A <em>stale</em> resource term will be returned from <c>binary_to_term</c> if the resource object has @@ -2596,6 +2653,16 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> + <name><ret>char*</ret> + <nametext>enif_mutex_name(ErlNifMutex* mtx)</nametext></name> + <fsummary></fsummary> + <desc> + <p>Same as <seealso marker="erl_driver#erl_drv_mutex_name"> + <c>erl_drv_mutex_name</c></seealso>.</p> + </desc> + </func> + + <func> <name><ret>int</ret> <nametext>enif_mutex_trylock(ErlNifMutex *mtx)</nametext></name> <fsummary></fsummary> @@ -2840,6 +2907,16 @@ enif_map_iterator_destroy(env, &iter);</code> </func> <func> + <name><ret>char*</ret> + <nametext>enif_rwlock_name(ErlNifRWLock* rwlck)</nametext></name> + <fsummary></fsummary> + <desc> + <p>Same as <seealso marker="erl_driver#erl_drv_rwlock_name"> + <c>erl_drv_rwlock_name</c></seealso>.</p> + </desc> + </func> + + <func> <name><ret>void</ret> <nametext>enif_rwlock_rlock(ErlNifRWLock *rwlck)</nametext></name> <fsummary></fsummary> @@ -2960,7 +3037,7 @@ enif_map_iterator_destroy(env, &iter);</code> <p>Argument <c>mode</c> describes the type of events to wait for. It can be <c>ERL_NIF_SELECT_READ</c>, <c>ERL_NIF_SELECT_WRITE</c> or a bitwise OR combination to wait for both. It can also be <c>ERL_NIF_SELECT_STOP</c> - which is described further below. When a read or write event is triggerred, + which is described further below. When a read or write event is triggered, a notification message like this is sent to the process identified by <c>pid</c>:</p> <code type="none">{select, Obj, Ref, ready_input | ready_output}</code> @@ -3011,7 +3088,7 @@ enif_map_iterator_destroy(env, &iter);</code> <item>The stop callback was scheduled to run on some other thread or later by this thread.</item> </taglist> - <p>Returns a negative value if the call failed where the follwing bits can be set:</p> + <p>Returns a negative value if the call failed where the following bits can be set:</p> <taglist> <tag><c>ERL_NIF_SELECT_INVALID_EVENT</c></tag> <item>Argument <c>event</c> is not a valid OS event object.</item> @@ -3019,9 +3096,9 @@ enif_map_iterator_destroy(env, &iter);</code> <item>The system call failed to add the event object to the poll set.</item> </taglist> <note> - <p>Use bitwise AND to test for specific bits in the return vaue. + <p>Use bitwise AND to test for specific bits in the return value. New significant bits may be added in future releases to give more detailed - information for both failed and successful calls. Do NOT use equallity tests + information for both failed and successful calls. Do NOT use equality tests like <c>==</c>, as that may cause your application to stop working.</p> <p>Example:</p> <code type="none"> @@ -3086,7 +3163,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { <c>enif_free_env</c></seealso> of cleared for reuse with <seealso marker="#enif_clear_env"><c>enif_clear_env</c></seealso>.</p> <p>If <c>msg_env</c> is set to <c>NULL</c>, the <c>msg</c> term is - copied and the original term and its environemt is still valid after + copied and the original term and its environment is still valid after the call.</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 @@ -3115,7 +3192,11 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { <fsummary>Format strings and Erlang terms.</fsummary> <desc> <p>Similar to <c>snprintf</c> but this format string also accepts - <c>"%T"</c>, which formats Erlang terms.</p> + <c>"%T"</c>, which formats Erlang terms of type + <seealso marker="#ERL_NIF_TERM"><c>ERL_NIF_TERM</c></seealso>.</p> + <p>This function is primarily intenden for debugging purpose. It is not + recommended to print very large terms with <c>%T</c>. The function may + change <c>errno</c>, even if successful.</p> </desc> </func> @@ -3179,6 +3260,16 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { </func> <func> + <name><ret>char*</ret> + <nametext>enif_thread_name(ErlNifTid tid)</nametext></name> + <fsummary>Thread name</fsummary> + <desc> + <p>Same as <seealso marker="erl_driver#erl_drv_thread_name"> + <c>erl_drv_thread_name</c></seealso>.</p> + </desc> + </func> + + <func> <name><ret>ErlNifThreadOpts *</ret> <nametext>enif_thread_opts_create(char *name)</nametext></name> <fsummary></fsummary> @@ -3296,6 +3387,30 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { <func> <name><ret>int</ret> + <nametext>enif_vfprintf(FILE *stream, const char *format, va_list ap) + </nametext></name> + <fsummary>Format strings and Erlang terms.</fsummary> + <desc> + <p>Equivalent to <seealso marker="#enif_fprintf"><c>enif_fprintf</c></seealso> + except that its called with a <c>va_list</c> instead of a variable number of + arguments.</p> + </desc> + </func> + + <func> + <name><ret>int</ret> + <nametext>enif_vsnprintf(char *str, size_t size, const char *format, va_list ap) + </nametext></name> + <fsummary>Format strings and Erlang terms.</fsummary> + <desc> + <p>Equivalent to <seealso marker="#enif_snprintf"><c>enif_snprintf</c></seealso> + except that its called with a <c>va_list</c> instead of a variable number of + arguments.</p> + </desc> + </func> + + <func> + <name><ret>int</ret> <nametext>enif_whereis_pid(ErlNifEnv *env, ERL_NIF_TERM name, ErlNifPid *pid)</nametext></name> <fsummary>Looks up a process by its registered name.</fsummary> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 3ed0f59b7d..8e014c3010 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2017</year> + <year>1996</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -36,8 +36,8 @@ in this module. Some of the BIFs are viewed more or less as part of the Erlang programming language and are <em>auto-imported</em>. Thus, it is not necessary to specify the - module name. For example, the calls <c>atom_to_list(Erlang)</c> - and <c>erlang:atom_to_list(Erlang)</c> are identical.</p> + module name. For example, the calls <c>atom_to_list(erlang)</c> + and <c>erlang:atom_to_list(erlang)</c> are identical.</p> <p>Auto-imported BIFs are listed without module prefix. BIFs listed with module prefix are not auto-imported.</p> @@ -53,14 +53,14 @@ <datatypes> <datatype> - <name>ext_binary()</name> + <name name="ext_binary"/> <desc> <p>A binary data object, structured according to the Erlang external term format.</p> </desc> </datatype> <datatype> - <name>iovec()</name> + <name name="iovec"/> <desc> <p>A list of binaries. This datatype is useful to use together with <seealso marker="erl_nif#enif_inspect_iovec"> @@ -189,6 +189,23 @@ </taglist> </desc> </datatype> + + <datatype> + <name name="dist_handle"></name> + <desc> + <p>An opaque handle identifing a distribution channel.</p> + </desc> + </datatype> + + <datatype> + <name name="nif_resource"></name> + <desc> + <p>An opaque handle identifing a + <seealso marker="erl_nif#resource_objects">NIF resource object + </seealso>.</p> + </desc> + </datatype> + </datatypes> <funcs> @@ -196,10 +213,6 @@ <name name="abs" arity="1" clause_i="1"/> <name name="abs" arity="1" clause_i="2"/> <fsummary>Arithmetical absolute value.</fsummary> - <type> - <v>Float = float()</v> - <v>Int = integer()</v> - </type> <desc> <p>Returns an integer or float that is the arithmetical absolute value of <c><anno>Float</anno></c> or @@ -549,9 +562,7 @@ hello <name name="binary_to_term" arity="2"/> <fsummary>Decode an Erlang external term format binary.</fsummary> <desc> - <p>As <c>binary_to_term/1</c>, but takes options that affect decoding - of the binary.</p> - <p>Option:</p> + <p>As <c>binary_to_term/1</c>, but takes these options:</p> <taglist> <tag><c>safe</c></tag> <item> @@ -567,18 +578,31 @@ hello creation of new external function references. None of those resources are garbage collected, so unchecked creation of them can exhaust available memory.</p> - </item> - </taglist> - <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe - data is decoded.</p> <pre> -> <input>binary_to_term(<<131,100,0,5,104,101,108,108,111>>, [safe]).</input> +> <input>binary_to_term(<<131,100,0,5,"hello">>, [safe]).</input> ** exception error: bad argument > <input>hello.</input> hello -> <input>binary_to_term(<<131,100,0,5,104,101,108,108,111>>, [safe]).</input> +> <input>binary_to_term(<<131,100,0,5,"hello">>, [safe]).</input> hello </pre> + </item> + <tag><c>used</c></tag> + <item> + <p>Changes the return value to <c>{Term, Used}</c> where <c>Used</c> + is the number of bytes actually read from <c>Binary</c>.</p> + <pre> +> <input>Input = <<131,100,0,5,"hello","world">>.</input> +<<131,100,0,5,104,101,108,108,111,119,111,114,108,100>> +> <input>{Term, Used} = binary_to_term(Input, [used]).</input> +{hello, 9} +> <input>split_binary(Input, Used).</input> +{<<131,100,0,5,104,101,108,108,111>>, <<"world">>} +</pre> + </item> + </taglist> + <p>Failure: <c>badarg</c> if <c>safe</c> is specified and unsafe + data is decoded.</p> <p>See also <seealso marker="#term_to_binary/1"><c>term_to_binary/1</c></seealso>, <seealso marker="#binary_to_term/1"> @@ -1233,6 +1257,141 @@ end</code> </func> <func> + <name name="dist_ctrl_get_data" arity="1"/> + <fsummary>Get distribution channel data to pass to another node.</fsummary> + <desc> + <p> + Get distribution channel data from the local node that is + to be passed to the remote node. The distribution channel + is identified by <c><anno>DHandle</anno></c>. If no data + is available, the atom <c>none</c> is returned. One + can request to be informed by a message when more + data is available by calling + <seealso marker="erlang#dist_ctrl_get_data_notification/1"><c>erlang:dist_ctrl_get_data_notification(DHandle)</c></seealso>. + </p> + <note><p> + Only the process registered as distribution + controller for the distribution channel identified by + <c><anno>DHandle</anno></c> is allowed to call this + function. + </p></note> + <p> + This function is used when implementing an alternative + distribution carrier using processes as distribution + controllers. <c><anno>DHandle</anno></c> is retrived + via the callback + <seealso marker="erts:alt_dist#hs_data_f_handshake_complete"><c>f_handshake_complete</c></seealso>. + More information can be found in the documentation of + <seealso marker="erts:alt_dist#distribution_module">ERTS + User's Guide ➜ How to implement an Alternative Carrier + for the Erlang Distribution ➜ Distribution Module</seealso>. + </p> + </desc> + </func> + + <func> + <name name="dist_ctrl_get_data_notification" arity="1"/> + <fsummary>Request notification about available outgoing distribution channel data.</fsummary> + <desc> + <p> + Request notification when more data is available to + fetch using + <seealso marker="erlang#dist_ctrl_get_data/1"><c>erlang:dist_ctrl_get_data(DHandle)</c></seealso> + for the distribution channel identified by + <c><anno>DHandle</anno></c>. When more data is present, + the caller will be sent the message <c>dist_data</c>. + Once a <c>dist_data</c> messages has been sent, no + more <c>dist_data</c> messages will be sent until + the <c>dist_ctrl_get_data_notification/1</c> function has been called + again. + </p> + <note><p> + Only the process registered as distribution + controller for the distribution channel identified by + <c><anno>DHandle</anno></c> is allowed to call this + function. + </p></note> + <p> + This function is used when implementing an alternative + distribution carrier using processes as distribution + controllers. <c><anno>DHandle</anno></c> is retrived + via the callback + <seealso marker="erts:alt_dist#hs_data_f_handshake_complete"><c>f_handshake_complete</c></seealso>. + More information can be found in the documentation of + <seealso marker="erts:alt_dist#distribution_module">ERTS + User's Guide ➜ How to implement an Alternative Carrier + for the Erlang Distribution ➜ Distribution Module</seealso>. + </p> + </desc> + </func> + + <func> + <name name="dist_ctrl_input_handler" arity="2"/> + <fsummary>Register distribution channel input handler process.</fsummary> + <desc> + <p> + Register an alternate input handler process for the + distribution channel identified by <c><anno>DHandle</anno></c>. + Once this function has been called, <c><anno>InputHandler</anno></c> + is the only process allowed to call + <seealso marker="erlang#dist_ctrl_put_data/2"><c>erlang:dist_ctrl_put_data(DHandle, Data)</c></seealso> + with the <c><anno>DHandle</anno></c> identifing this distribution + channel. + </p> + <note><p> + Only the process registered as distribution + controller for the distribution channel identified by + <c><anno>DHandle</anno></c> is allowed to call this + function. + </p></note> + <p> + This function is used when implementing an alternative + distribution carrier using processes as distribution + controllers. <c><anno>DHandle</anno></c> is retrived + via the callback + <seealso marker="erts:alt_dist#hs_data_f_handshake_complete"><c>f_handshake_complete</c></seealso>. + More information can be found in the documentation of + <seealso marker="erts:alt_dist#distribution_module">ERTS + User's Guide ➜ How to implement an Alternative Carrier + for the Erlang Distribution ➜ Distribution Module</seealso>. + </p> + </desc> + </func> + + <func> + <name name="dist_ctrl_put_data" arity="2"/> + <fsummary>Pass data into the VM from a distribution channel.</fsummary> + <desc> + <p> + Deliver distribution channel data from a remote node to the + local node. + </p> + <note><p> + Only the process registered as distribution + controller for the distribution channel identified by + <c><anno>DHandle</anno></c> is allowed to call this + function unless an alternate input handler process + has been registered using + <seealso marker="erlang#dist_ctrl_input_handler/2"><c>erlang:dist_ctrl_input_handler(DHandle, InputHandler)</c></seealso>. + If an alternate input handler has been registered, only + the registered input handler process is allowed to call + this function. + </p></note> + <p> + This function is used when implementing an alternative + distribution carrier using processes as distribution + controllers. <c><anno>DHandle</anno></c> is retrived + via the callback + <seealso marker="erts:alt_dist#hs_data_f_handshake_complete"><c>f_handshake_complete</c></seealso>. + More information can be found in the documentation of + <seealso marker="erts:alt_dist#distribution_module">ERTS + User's Guide ➜ How to implement an Alternative Carrier + for the Erlang Distribution ➜ Distribution Module</seealso>. + </p> + </desc> + </func> + + <func> <name name="element" arity="2"/> <fsummary>Return the Nth element of a tuple.</fsummary> <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc> @@ -1290,11 +1449,14 @@ b</pre> the process to terminate, it has no return value. Example:</p> <pre> > <input>catch error(foobar).</input> -{'EXIT',{foobar,[{erl_eval,do_apply,5}, - {erl_eval,expr,5}, - {shell,exprs,6}, - {shell,eval_exprs,6}, - {shell,eval_loop,3}]}}</pre> +{'EXIT',{foobar,[{shell,apply_fun,3, + [{file,"shell.erl"},{line,906}]}, + {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,677}]}, + {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,430}]}, + {shell,exprs,7,[{file,"shell.erl"},{line,687}]}, + {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]}, + {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}} +</pre> </desc> </func> @@ -1831,39 +1993,26 @@ 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>) 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, - depending on the exception.</p> - <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> + <warning><p><c>erlang:get_stacktrace/0</c> is deprecated and will stop working + in a future release.</p></warning> + <p>Instead of using <c>erlang:get_stacktrace/0</c> to retrieve + the call stack back-trace, use the following syntax:</p> <pre> try Expr catch - C:R -> - {C,R,erlang:get_stacktrace()} + Class:Reason:Stacktrace -> + {Class,Reason,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><c>erlang:get_stacktrace/0</c> retrieves 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, depending on the exception.</p> + <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>The stacktrace is the same data as operator <c>catch</c> returns, for example:</p> <pre> @@ -1886,6 +2035,18 @@ helper() -> where the exception occurred or the function was called. </item> </taglist> + <warning><p>Developers should rely on stacktrace entries only for + debugging purposes.</p> + <p>The VM performs tail call optimization, which + does not add new entries to the stacktrace, and also limits stacktraces + to a certain depth. Furthermore, compiler options, optimizations and + future changes may add or remove stacktrace entries, causing any code + that expects the stacktrace to be in a certain order or contain specific + items to fail.</p> + <p>The only exception to this rule is <c>error:undef</c> which + guarantees to include the <anno>Module</anno>, <anno>Function</anno> and <anno>Arity</anno> + of the attempted function as the first stacktrace entry.</p> + </warning> <p>See also <seealso marker="#error/1"><c>error/1</c></seealso> and <seealso marker="#error/2"><c>error/2</c></seealso>.</p> @@ -1916,8 +2077,15 @@ helper() -> Typically, this is used when a process started from a certain shell is to have another group leader than <c>init</c>.</p> + <p>The group leader should be rarely changed in + applications with a supervision tree, because OTP + assumes the group leader of their processes is + their application master.</p> <p>See also - <seealso marker="#group_leader/0"><c>group_leader/0</c></seealso>.</p> + <seealso marker="#group_leader/0"><c>group_leader/0</c></seealso> + and <seealso marker="doc/design_principles:applications#stopping">OTP + design principles</seealso> related to starting and stopping + applications.</p> </desc> </func> @@ -2280,6 +2448,26 @@ os_prompt%</pre> </func> <func> + <name name="is_map_key" arity="2"/> + <fsummary></fsummary> + <desc> + <p>Returns <c>true</c> if map <c><anno>Map</anno></c> contains + <c><anno>Key</anno></c> and returns <c>false</c> if it does not + contain the <c><anno>Key</anno></c>.</p> + <p>The call fails with a <c>{badmap,Map}</c> exception if + <c><anno>Map</anno></c> is not a map.</p> + <p><em>Example:</em></p> + <code type="none"> +> Map = #{"42" => value}. +#{"42" => value} +> is_map_key("42",Map). +true +> is_map_key(value,Map). +false</code> + </desc> + </func> + + <func> <name name="is_number" arity="1"/> <fsummary>Check whether a term is a number.</fsummary> <desc> @@ -2813,6 +3001,25 @@ os_prompt%</pre> </func> <func> + <name name="map_get" arity="2" /> + <fsummary>Extract a value from a map</fsummary> + <desc> + <p>Returns value <c><anno>Value</anno></c> associated with + <c><anno>Key</anno></c> if <c><anno>Map</anno></c> contains + <c><anno>Key</anno></c>.</p> + <p>The call fails with a <c>{badmap,Map}</c> exception if + <c><anno>Map</anno></c> is not a map, or with a <c>{badkey,Key}</c> + exception if no value is associated with <c><anno>Key</anno></c>.</p> + <p><em>Example:</em></p> + <code type="none"> +> Key = 1337, + Map = #{42 => value_two,1337 => "value one","a" => 1}, + map_get(Key,Map). +"value one"</code> + </desc> + </func> + + <func> <name name="map_size" arity="1"/> <fsummary>Return the size of a map.</fsummary> <desc> @@ -3195,25 +3402,6 @@ RealSystem = system + MissedSystem</code> monitored process resides). </p></item> </taglist> - <p>If an attempt is made to monitor a process on an older node - (where remote process monitoring is not implemented or - where remote process monitoring by registered name is not - implemented), the call fails with <c>badarg</c>.</p> - <note> - <p>The format of the <c>'DOWN'</c> message changed in ERTS - 5.2 (Erlang/OTP R9B) for monitoring - <em>by registered name</em>. Element <c>Object</c> of - the <c>'DOWN'</c> message could in earlier versions - sometimes be the process identifier of the monitored process and sometimes - be the registered name. Now element <c>Object</c> is - always a tuple consisting of the registered name and - the node name. Processes on new nodes (ERTS 5.2 - or higher versions) always get <c>'DOWN'</c> messages on - the new format even if they are monitoring processes on old - nodes. Processes on old nodes always get <c>'DOWN'</c> - messages on the old format.</p> - </note> - <taglist> <tag>Monitoring a <marker id="monitor_process"/><c>process</c></tag> <item> @@ -3221,7 +3409,19 @@ RealSystem = system + MissedSystem</code> process identified by <c><anno>Item</anno></c>, which can be a <c>pid()</c> (local or remote), an atom <c>RegisteredName</c> or a tuple <c>{RegisteredName, Node}</c> for a registered process, - located elsewhere.</p> + located elsewhere.</p> + + <note><p>Before ERTS 10.0 (OTP 21.0), monitoring a process could fail with + <c>badarg</c> if the monitored process resided on a primitive node + (such as erl_interface or jinterface), where remote process monitoring + is not implemented.</p> + <p>Now, such a call to <c>monitor</c> will instead succeed and a + monitor is created. But the monitor will only supervise the + connection. That is, a <c>{'DOWN', _, process, _, noconnection}</c> is + the only message that may be received, as the primitive node have no + way of reporting the status of the monitored process.</p> + </note> + </item> <tag>Monitoring a <marker id="monitor_port"/><c>port</c></tag> @@ -3581,13 +3781,6 @@ RealSystem = system + MissedSystem</code> If found, that driver is started. A driver runs in the Erlang work space, which means that it is linked with the Erlang runtime system.</p> - <p>When starting external programs on Solaris, the system - call <c>vfork</c> is used in preference to <c>fork</c> - for performance reasons, although it has a history of - being less robust. If there are problems using - <c>vfork</c>, setting environment variable - <c>ERL_NO_VFORK</c> to any value causes <c>fork</c> - to be used instead.</p> <p>For external programs, <c>PATH</c> is searched (or an equivalent method is used to find programs, depending on the OS). This is done by invoking @@ -3686,6 +3879,12 @@ RealSystem = system + MissedSystem</code> </item> <tag><c>{env, <anno>Env</anno>}</c></tag> <item> + <p> + Types:<br/> + <c><anno>Name</anno> = </c><seealso marker="kernel:os#type-env_var_name"><c>os:env_var_name()</c></seealso><br/> + <c><anno>Val</anno> = </c><seealso marker="kernel:os#type-env_var_value"><c>os:env_var_value()</c></seealso><c> | false</c><br/> + <c>Env = [{<anno>Name</anno>, <anno>Val</anno>}]</c> + </p> <p>Only valid for <c>{spawn, <anno>Command</anno>}</c>, and <c>{spawn_executable, <anno>FileName</anno>}</c>. The environment of the started process is extended using @@ -3700,7 +3899,13 @@ RealSystem = system + MissedSystem</code> exception is <c><anno>Val</anno></c> being the atom <c>false</c> (in analogy with <seealso marker="kernel:os#getenv/1"><c>os:getenv/1</c></seealso>, - which removes the environment variable.</p> + which removes the environment variable. + </p> + <p> + For information about encoding requirements, see documentation + of the types for <c><anno>Name</anno></c> and + <c><anno>Val</anno></c>. + </p> </item> <tag><c>{args, [ string() | binary() ]}</c></tag> <item> @@ -4326,7 +4531,6 @@ RealSystem = system + MissedSystem</code> <desc> <p><c><anno>Locking</anno></c> is one of the following:</p> <list type="bulleted"> - <item><c>false</c> (emulator without SMP support)</item> <item><c>port_level</c> (port-specific locking)</item> <item><c>driver_level</c> (driver-specific locking)</item> </list> @@ -4567,11 +4771,11 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="3"/> + <name name="process_flag" arity="2" clause_i="3" + anchor="process_flag_min_heap_size"/> <fsummary>Set process flag min_heap_size for the calling process. </fsummary> <desc> - <marker id="process_flag_min_heap_size"/> <p>Changes the minimum heap size for the calling process.</p> <p>Returns the old value of the flag.</p> </desc> @@ -4589,12 +4793,12 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="5"/> + <name name="process_flag" arity="2" clause_i="5" + anchor="process_flag_max_heap_size"/> <fsummary>Set process flag max_heap_size for the calling process. </fsummary> <type name="max_heap_size"/> <desc> - <marker id="process_flag_max_heap_size"/> <p>This flag sets the maximum heap size for the calling process. If <c><anno>MaxHeapSize</anno></c> is an integer, the system default values for <c>kill</c> and <c>error_logger</c> are used. @@ -4637,11 +4841,11 @@ RealSystem = system + MissedSystem</code> </item> <tag><c>error_logger</c></tag> <item> - <p>When set to <c>true</c>, the runtime system sends a - message to the current <seealso marker="kernel:error_logger"> - <c>error_logger</c></seealso> + <p>When set to <c>true</c>, the runtime system logs an + error event via <seealso marker="kernel:logger"> + <c>logger</c></seealso>, containing details about the process when the maximum - heap size is reached. One <c>error_logger</c> report is sent + heap size is reached. One log event is sent each time the limit is reached.</p> <p>If <c>error_logger</c> is not defined in the map, the system default is used. The default system default is <c>true</c>. @@ -4655,7 +4859,7 @@ RealSystem = system + MissedSystem</code> amount of memory that is used during the garbage collection. When contemplating using this option, it is recommended to first run it in production with <c>kill</c> set to <c>false</c> and inspect - the <c>error_logger</c> reports to see what the normal peak sizes + the log events to see what the normal peak sizes of the processes in the system is and then tune the value accordingly. </p> @@ -4663,12 +4867,12 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="6"/> + <name name="process_flag" arity="2" clause_i="6" + anchor="process_flag_message_queue_data"/> <fsummary>Set process flag message_queue_data for the calling process. </fsummary> <type name="message_queue_data"/> <desc> - <marker id="process_flag_message_queue_data"/> <p>This flag determines how messages in the message queue are stored, as follows:</p> <taglist> @@ -4705,11 +4909,12 @@ RealSystem = system + MissedSystem</code> </func> <func> - <name name="process_flag" arity="2" clause_i="7"/> + <name name="process_flag" arity="2" clause_i="7" + anchor="process_flag_priority"/> <fsummary>Set process flag priority for the calling process.</fsummary> <type name="priority_level"/> <desc> - <p><marker id="process_flag_priority"></marker> + <p> Sets the process priority. <c><anno>Level</anno></c> is an atom. Four priority levels exist: <c>low</c>, <c>normal</c>, <c>high</c>, and <c>max</c>. Default @@ -4730,8 +4935,8 @@ RealSystem = system + MissedSystem</code> selected for execution. Notice however that this does <em>not</em> mean that no processes on priority <c>low</c> or <c>normal</c> can run when processes - are running on priority <c>high</c>. On the runtime - system with SMP support, more processes can be running + are running on priority <c>high</c>. When using multiple + schedulers, more processes can be running in parallel than processes on priority <c>high</c>. That is, a <c>low</c> and a <c>high</c> priority process can execute at the same time.</p> @@ -4746,10 +4951,8 @@ RealSystem = system + MissedSystem</code> execution.</p> <note> <p>Do not depend on the scheduling - to remain exactly as it is today. Scheduling, at least on - the runtime system with SMP support, is likely to be - changed in a future release to use available - processor cores better.</p> + to remain exactly as it is today. Scheduling is likely to be + changed in a future release to use available processor cores better.</p> </note> <p>There is <em>no</em> automatic mechanism for avoiding priority inversion, such as priority inheritance @@ -4881,7 +5084,6 @@ RealSystem = system + MissedSystem</code> <item><c>initial_call</c></item> <item><c>status</c></item> <item><c>message_queue_len</c></item> - <item><c>messages</c></item> <item><c>links</c></item> <item><c>dictionary</c></item> <item><c>trap_exit</c></item> @@ -5095,10 +5297,10 @@ RealSystem = system + MissedSystem</code> <p><c><anno>MinBinVHeapSize</anno></c> is the minimum binary virtual heap size for the process.</p> </item> - <tag><c>{monitored_by, <anno>Pids</anno>}</c></tag> + <tag><c>{monitored_by, <anno>MonitoredBy</anno>}</c></tag> <item> - <p>A list of process identifiers monitoring the process (with - <c>monitor/2</c>).</p> + <p>A list of identifiers for all the processes, ports and NIF + resources, that are monitoring the process.</p> </item> <tag><c>{monitors, <anno>Monitors</anno>}</c></tag> <item> @@ -5541,11 +5743,17 @@ true</pre> <type name="dst"/> <desc> <p>Sends a message and returns <c><anno>Msg</anno></c>. This - is the same as <c><anno>Dest</anno> ! <anno>Msg</anno></c>.</p> + is the same as using the <seealso marker="doc/reference_manual:expressions#send"> + send operator</seealso>: + <c><anno>Dest</anno> ! <anno>Msg</anno></c>.</p> <p><c><anno>Dest</anno></c> can be a remote or local process identifier, a (local) port, a locally registered name, or a tuple <c>{<anno>RegName</anno>, <anno>Node</anno>}</c> - for a registered name at another node.</p> + for a registered name at another node.</p> + <p>The function fails with a <c>badarg</c> run-time error if + <c><anno>Dest</anno></c> is an atom name, but this name is not + registered. This is the only case when <c>send</c> fails for an + unreachable destination <c><anno>Dest</anno></c> (of correct type).</p> </desc> </func> @@ -5964,7 +6172,7 @@ true</pre> <p>Monitors the new process (like <seealso marker="#monitor/2"><c>monitor/2</c></seealso> does).</p> </item> - <tag><c>{priority, <anno>Level</anno></c></tag> + <tag><c>{priority, <anno>Level</anno>}</c></tag> <item> <p>Sets the priority of the new process. Equivalent to executing <seealso marker="#process_flag_priority"> @@ -6190,10 +6398,10 @@ true</pre> </func> <func> - <name name="statistics" arity="1" clause_i="1"/> + <name name="statistics" arity="1" clause_i="1" + anchor="statistics_active_tasks"/> <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> @@ -6205,10 +6413,10 @@ true</pre> </func> <func> - <name name="statistics" arity="1" clause_i="2"/> + <name name="statistics" arity="1" clause_i="2" + anchor="statistics_active_tasks_all"/> <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 schedulers. That is, the number of processes and @@ -6256,17 +6464,16 @@ true</pre> </func> <func> - <name name="statistics" arity="1" clause_i="4"/> + <name name="statistics" arity="1" clause_i="4" + anchor="statistics_exact_reductions"/> <fsummary>Information about exact reductions.</fsummary> <desc> - <marker id="statistics_exact_reductions"></marker> <p>Returns the number of exact reductions.</p> <note> <p><c>statistics(exact_reductions)</c> is a more expensive operation than <seealso marker="#statistics_reductions"> - statistics(reductions)</seealso>, - especially on an Erlang machine with SMP support.</p> + statistics(reductions)</seealso>.</p> </note> </desc> </func> @@ -6295,10 +6502,10 @@ true</pre> </func> <func> - <name name="statistics" arity="1" clause_i="7"/> + <name name="statistics" arity="1" clause_i="7" + anchor="statistics_microstate_accounting"/> <fsummary>Information about microstate accounting.</fsummary> <desc> - <marker id="statistics_microstate_accounting"></marker> <p>Microstate accounting can be used to measure how much time the Erlang runtime system spends doing various tasks. It is designed to be as lightweight as possible, but some overhead exists when this @@ -6343,17 +6550,24 @@ lists:map( <p><c><anno>MSAcc_Thread_Type</anno></c>s:</p> <taglist> <tag><c>scheduler</c></tag> - <item>The main execution threads that do most of the work.</item> + <item>The main execution threads that do most of the work. See + <seealso marker="erts:erl#+S">erl +S</seealso> for more details.</item> <tag><c>dirty_cpu_scheduler</c></tag> - <item>The threads for long running cpu intensive work.</item> + <item>The threads for long running cpu intensive work. See + <seealso marker="erts:erl#+SDcpu">erl +SDcpu</seealso> for more details.</item> <tag><c>dirty_io_scheduler</c></tag> - <item>The threads for long running I/O work.</item> + <item>The threads for long running I/O work. See + <seealso marker="erts:erl#+SDio">erl +SDio</seealso> for more details.</item> <tag><c>async</c></tag> <item>Async threads are used by various linked-in drivers (mainly the - file drivers) do offload non-CPU intensive work.</item> + file drivers) do offload non-CPU intensive work. See + <seealso marker="erts:erl#+async_thread_pool_size">erl +A</seealso> for more details.</item> <tag><c>aux</c></tag> <item>Takes care of any work that is not specifically assigned to a scheduler.</item> + <tag><c>poll</c></tag> + <item>Does the IO polling for the emulator. See + <seealso marker="erts:erl#+IOt">erl +IOt</seealso> for more details.</item> </taglist> <p>The following <c><anno>MSAcc_Thread_State</anno></c>s are available. All states are exclusive, meaning that a thread cannot be in two @@ -6431,10 +6645,10 @@ lists:map( </func> <func> - <name name="statistics" arity="1" clause_i="8"/> + <name name="statistics" arity="1" clause_i="8" + anchor="statistics_reductions"/> <fsummary>Information about reductions.</fsummary> <desc> - <marker id="statistics_reductions"></marker> <p>Returns information about reductions, for example:</p> <pre> > <input>statistics(reductions).</input> @@ -6450,9 +6664,10 @@ lists:map( </func> <func> - <name name="statistics" arity="1" clause_i="9"/> + <name name="statistics" arity="1" clause_i="9" + anchor="statistics_run_queue"/> <fsummary>Information about the run-queues.</fsummary> - <desc><marker id="statistics_run_queue"></marker> + <desc> <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 normal run-queues. Dirty run queues are not part of the @@ -6466,9 +6681,10 @@ lists:map( </func> <func> - <name name="statistics" arity="1" clause_i="10"/> + <name name="statistics" arity="1" clause_i="10" + anchor="statistics_run_queue_lengths"/> <fsummary>Information about the run-queue lengths.</fsummary> - <desc><marker id="statistics_run_queue_lengths"></marker> + <desc> <p>Returns the same as <seealso marker="#statistics_run_queue_lengths_all"> <c>statistics(run_queue_lengths_all)</c></seealso> @@ -6480,9 +6696,10 @@ lists:map( </func> <func> - <name name="statistics" arity="1" clause_i="11"/> + <name name="statistics" arity="1" clause_i="11" + anchor="statistics_run_queue_lengths_all"/> <fsummary>Information about the run-queue lengths.</fsummary> - <desc><marker id="statistics_run_queue_lengths_all"></marker> + <desc> <p>Returns a list where each element represents the amount of processes and ports ready to run for each run queue. Values for normal run queues are located first in the @@ -6540,10 +6757,10 @@ lists:map( </func> <func> - <name name="statistics" arity="1" clause_i="13"/> + <name name="statistics" arity="1" clause_i="13" + anchor="statistics_scheduler_wall_time"/> <fsummary>Information about each schedulers work time.</fsummary> <desc> - <marker id="statistics_scheduler_wall_time"></marker> <p>Returns a list of tuples with <c>{<anno>SchedulerId</anno>, <anno>ActiveTime</anno>, <anno>TotalTime</anno>}</c>, where @@ -6585,17 +6802,20 @@ lists:map( 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> + <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 =< <anno>SchedulerId</anno> =< - </c><seealso marker="#system_info_schedulers"><c>erlang:system_info(schedulers)</c></seealso>. + </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) < <anno>SchedulerId</anno> =< erlang:system_info(schedulers) + - </c><seealso marker="#system_info_dirty_cpu_schedulers"><c>erlang:system_info(dirty_cpu_schedulers)</c></seealso>. + </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 @@ -6650,8 +6870,8 @@ ok 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> + 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 @@ -6661,23 +6881,26 @@ ok </func> <func> - <name name="statistics" arity="1" clause_i="14"/> + <name name="statistics" arity="1" clause_i="14" + anchor="statistics_scheduler_wall_time_all"/> <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> + <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> < + </c><seealso marker="#system_info_dirty_cpu_schedulers"> + <c>erlang:system_info(dirty_cpu_schedulers)</c></seealso><c> < <anno>SchedulerId</anno> =< 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> + </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, @@ -6686,9 +6909,10 @@ ok </desc> </func> <func> - <name name="statistics" arity="1" clause_i="15"/> + <name name="statistics" arity="1" clause_i="15" + anchor="statistics_total_active_tasks"/> <fsummary>Information about active processes and ports.</fsummary> - <desc><marker id="statistics_total_active_tasks"></marker> + <desc> <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> @@ -6696,9 +6920,10 @@ ok </func> <func> - <name name="statistics" arity="1" clause_i="16"/> + <name name="statistics" arity="1" clause_i="16" + anchor="statistics_total_active_tasks_all"/> <fsummary>Information about active processes and ports.</fsummary> - <desc><marker id="statistics_total_active_tasks_all"></marker> + <desc> <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> @@ -6706,9 +6931,10 @@ ok </func> <func> - <name name="statistics" arity="1" clause_i="17"/> + <name name="statistics" arity="1" clause_i="17" + anchor="statistics_total_run_queue_lengths"/> <fsummary>Information about the run-queue lengths.</fsummary> - <desc><marker id="statistics_total_run_queue_lengths"></marker> + <desc> <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> @@ -6716,9 +6942,10 @@ ok </func> <func> - <name name="statistics" arity="1" clause_i="18"/> + <name name="statistics" arity="1" clause_i="18" + anchor="statistics_total_run_queue_lengths_all"/> <fsummary>Information about the run-queue lengths.</fsummary> - <desc><marker id="statistics_total_run_queue_lengths_all"></marker> + <desc> <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> @@ -6787,10 +7014,47 @@ ok from other events in the system. It is only guaranteed that <c><anno>Suspendee</anno></c> <em>eventually</em> suspends (unless it - is resumed). If option <c>asynchronous</c> has <em>not</em> + is resumed). If no <c>asynchronous</c> options has been passed, the caller of <c>erlang:suspend_process/2</c> is blocked until <c><anno>Suspendee</anno></c> has suspended.</p> </item> + <tag><c>{asynchronous, ReplyTag}</c></tag> + <item> + <p>A suspend request is sent to the process identified by + <c><anno>Suspendee</anno></c>. When the suspend request + has been processed, a reply message is sent to the caller + of this function. The reply is on the form <c>{ReplyTag, + State}</c> where <c>State</c> is either:</p> + <taglist> + <tag><c>exited</c></tag> + <item> + <p> + <c><anno>Suspendee</anno></c> has exited. + </p> + </item> + <tag><c>suspended</c></tag> + <item> + <p> + <c><anno>Suspendee</anno></c> is now suspended. + </p> + </item> + <tag><c>not_suspended</c></tag> + <item> + <p> + <c><anno>Suspendee</anno></c> is not suspended. + This can only happen when the process that + issued this request, have called + <c>resume_process(<anno>Suspendee</anno>)</c> + before getting the reply. + </p> + </item> + </taglist> + <p> + Appart from the reply message, the <c>{asynchronous, + ReplyTag}</c> option behaves exactly the same as the + <c>asynchronous</c> option without reply tag. + </p> + </item> <tag><c>unless_suspending</c></tag> <item> <p>The process identified by <c><anno>Suspendee</anno></c> is @@ -6814,6 +7078,13 @@ ok <warning> <p>This BIF is intended for debugging only.</p> </warning> + <warning> + <p>You can easily create deadlocks if processes suspends + each other (directly or in circles). In ERTS versions prior + to ERTS version 10.0, the runtime system prevented such + deadlocks, but this prevention has now been removed due + to performance reasons.</p> + </warning> <p>Failures:</p> <taglist> <tag><c>badarg</c></tag> @@ -6866,7 +7137,8 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="2"/> + <name name="system_flag" arity="2" clause_i="2" + anchor="system_flag_cpu_topology"/> <fsummary>Set system flag <c>cpu_topology</c>.</fsummary> <type name="cpu_topology"/> <type name="level_entry"/> @@ -6875,7 +7147,7 @@ ok <type name="info_list"/> <desc> <warning> - <p><marker id="system_flag_cpu_topology"></marker> + <p> <em>This argument is deprecated.</em> Instead of using this argument, use command-line argument <seealso marker="erts:erl#+sct"><c>+sct</c></seealso> in @@ -6913,10 +7185,11 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="3"/> + <name name="system_flag" arity="2" clause_i="3" + anchor="system_flag_dirty_cpu_schedulers_online"/> <fsummary>Set system_flag_dirty_cpu_schedulers_online.</fsummary> <desc> - <p><marker id="system_flag_dirty_cpu_schedulers_online"></marker> + <p> Sets the number of dirty CPU schedulers online. Range is <c><![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]></c>, where <c>N</c> is the smallest of the return values of @@ -6977,10 +7250,11 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="6"/> + <name name="system_flag" arity="2" clause_i="6" + anchor="system_flag_microstate_accounting"/> <fsummary>Set system flag microstate_accounting.</fsummary> <desc> - <p><marker id="system_flag_microstate_accounting"></marker> + <p> Turns on/off microstate accounting measurements. When passing reset, all counters are reset to 0.</p> <p>For more information see @@ -7022,28 +7296,29 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="9"/> + <name name="system_flag" arity="2" clause_i="9" + anchor="system_flag_max_heap_size"/> <fsummary>Set system flag max_heap_size.</fsummary> <type name="max_heap_size"/> <desc> - <marker id="system_flag_max_heap_size"></marker> <p> Sets the default maximum heap size settings for processes. The size is specified in words. The new <c>max_heap_size</c> effects only processes spawned efter the change has been made. <c>max_heap_size</c> can be set for individual processes using <seealso marker="#spawn_opt/4"><c>spawn_opt/2,3,4</c></seealso> or - <seealso marker="#process_flag_message_queue_data"> + <seealso marker="#process_flag_max_heap_size"> <c>process_flag/2</c></seealso>.</p> <p>Returns the old value of the flag.</p> </desc> </func> <func> - <name name="system_flag" arity="2" clause_i="10"/> + <name name="system_flag" arity="2" clause_i="10" + anchor="system_flag_multi_scheduling"/> <fsummary>Set system flag multi_scheduling.</fsummary> <desc> - <p><marker id="system_flag_multi_scheduling"></marker> + <p> If multi-scheduling is enabled, more than one scheduler thread is used by the emulator. Multi-scheduling can be blocked in two different ways. Either all schedulers but @@ -7095,12 +7370,13 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="11"/> + <name name="system_flag" arity="2" clause_i="11" + anchor="system_flag_scheduler_bind_type"/> <fsummary>Set system flag scheduler_bind_type.</fsummary> <type name="scheduler_bind_type"/> <desc> <warning> - <p><marker id="system_flag_scheduler_bind_type"></marker> + <p> <em>This argument is deprecated.</em> Instead of using this argument, use command-line argument <seealso marker="erts:erl#+sbt"><c>+sbt</c></seealso> in @@ -7115,7 +7391,7 @@ ok <note><p>If a scheduler fails to bind, this is often silently ignored, as it is not always possible to verify valid logical processor identifiers. If an error is reported, - it is reported to <c>error_logger</c>. To verify that the + an error event is logged. To verify that the schedulers have bound as requested, call <seealso marker="#system_info_scheduler_bindings"> <c>erlang:system_info(scheduler_bindings)</c></seealso>.</p> @@ -7221,10 +7497,11 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="12"/> + <name name="system_flag" arity="2" clause_i="12" + anchor="system_flag_scheduler_wall_time"/> <fsummary>Set system flag scheduler_wall_time.</fsummary> <desc> - <p><marker id="system_flag_scheduler_wall_time"></marker> + <p> Turns on or off scheduler wall time measurements.</p> <p>For more information, see <seealso marker="#statistics_scheduler_wall_time"> @@ -7233,10 +7510,11 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="13"/> + <name name="system_flag" arity="2" clause_i="13" + anchor="system_flag_schedulers_online"/> <fsummary>Set system flag schedulers_online.</fsummary> <desc> - <p><marker id="system_flag_schedulers_online"></marker> + <p> Sets the number of schedulers online. Range is <c><![CDATA[1 <= SchedulersOnline <= erlang:system_info(schedulers)]]></c>.</p> @@ -7275,10 +7553,11 @@ ok </func> <func> - <name name="system_flag" arity="2" clause_i="15"/> + <name name="system_flag" arity="2" clause_i="15" + anchor="system_flag_time_offset"/> <fsummary>Finalize the time offset.</fsummary> <desc> - <p><marker id="system_flag_time_offset"></marker> + <p> Finalizes the <seealso marker="#time_offset/0">time offset</seealso> when <seealso marker="time_correction#Single_Time_Warp_Mode">single time warp mode</seealso> is used. If another time warp mode @@ -7304,11 +7583,145 @@ ok </func> <func> - <name name="system_info" arity="1" clause_i="1"/> - <name name="system_info" arity="1" clause_i="2"/> - <name name="system_info" arity="1" clause_i="3"/> - <name name="system_info" arity="1" clause_i="4"/> - <name name="system_info" arity="1" clause_i="5"/> + <name name="system_info" arity="1" clause_i="76"/> + <fsummary>System info overview.</fsummary> + <desc> + <p>Returns information about the current system. + The documentation of this function is broken into the following + sections in order to make it easier to navigate.</p> + <taglist> + <tag><seealso marker="#system_info_allocator"> + <c>Memory Allocation</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_allocated_areas"><c>allocated_areas</c></seealso>, + <seealso marker="#system_info_allocator"><c>allocator</c></seealso>, + <seealso marker="#system_info_alloc_util_allocators"><c>alloc_util_allocators</c></seealso>, + <seealso marker="#system_info_allocator_sizes"><c>allocator_sizes</c></seealso>, + <seealso marker="#system_info_elib_malloc"><c>elib_malloc</c></seealso> + </p> + </item> + <tag><seealso marker="#system_info_cpu_topology"> + <c>CPU Topology</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_cpu_topology"><c>cpu_topology</c></seealso>, + <seealso marker="#system_info_logical_processors"><c>logical_processors</c></seealso>, + <seealso marker="#system_info_update_cpu_info"><c>update_cpu_info</c></seealso> + </p> + </item> + <tag><seealso marker="#system_info_process"> + <c>Process Information</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_fullsweep_after"><c>fullsweep_after</c></seealso>, + <seealso marker="#system_info_garbage_collection"><c>garbage_collection</c></seealso>, + <seealso marker="#system_info_heap_sizes"><c>heap_sizes</c></seealso>, + <seealso marker="#system_info_heap_type"><c>heap_type</c></seealso>, + <seealso marker="#system_info_max_heap_size"><c>max_heap_size</c></seealso>, + <seealso marker="#system_info_message_queue_data"><c>message_queue_data</c></seealso>, + <seealso marker="#system_info_min_heap_size"><c>min_heap_size</c></seealso>, + <seealso marker="#system_info_min_bin_vheap_size"><c>min_bin_vheap_size</c></seealso>, + <seealso marker="#system_info_procs"><c>procs</c></seealso> + </p> + </item> + <tag><seealso marker="#system_info_limits"> + <c>System Limits</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_atom_count"><c>atom_count</c></seealso>, + <seealso marker="#system_info_atom_limit"><c>atom_limit</c></seealso>, + <seealso marker="#system_info_ets_count"><c>ets_count</c></seealso>, + <seealso marker="#system_info_ets_limit"><c>ets_limit</c></seealso>, + <seealso marker="#system_info_port_count"><c>port_count</c></seealso>, + <seealso marker="#system_info_port_limit"><c>port_limit</c></seealso>, + <seealso marker="#system_info_process_count"><c>process_count</c></seealso>, + <seealso marker="#system_info_process_limit"><c>process_limit</c></seealso> + </p> + </item> + <tag><seealso marker="#system_info_time"> + <c>System Time</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_end_time"><c>end_time</c></seealso>, + <seealso marker="#system_info_os_monotonic_time_source"><c>os_monotonic_time_source</c></seealso>, + <seealso marker="#system_info_os_system_time_source"><c>os_system_time_source</c></seealso>, + <seealso marker="#system_info_start_time"><c>start_time</c></seealso>, + <seealso marker="#system_info_time_correction"><c>time_correction</c></seealso>, + <seealso marker="#system_info_time_offset"><c>time_offset</c></seealso>, + <seealso marker="#system_info_time_warp_mode"><c>time_warp_mode</c></seealso>, + <seealso marker="#system_info_tolerant_timeofday"><c>tolerant_timeofday</c></seealso> + </p> + </item> + <tag><seealso marker="#system_info_scheduler"> + <c>Scheduler Information</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_dirty_cpu_schedulers"><c>dirty_cpu_schedulers</c></seealso>, + <seealso marker="#system_info_dirty_cpu_schedulers_online"><c>dirty_cpu_schedulers_online</c></seealso>, + <seealso marker="#system_info_dirty_io_schedulers"><c>dirty_io_schedulers</c></seealso>, + <seealso marker="#system_info_multi_scheduling"><c>multi_scheduling</c></seealso>, + <seealso marker="#system_info_multi_scheduling_blockers"><c>multi_scheduling_blockers</c></seealso>, + <seealso marker="#system_info_normal_multi_scheduling_blockers"><c>normal_multi_scheduling_blockers</c></seealso>, + <seealso marker="#system_info_scheduler_bind_type"><c>scheduler_bind_type</c></seealso>, + <seealso marker="#system_info_scheduler_bindings"><c>scheduler_bindings</c></seealso>, + <seealso marker="#system_info_scheduler_id"><c>scheduler_id</c></seealso>, + <seealso marker="#system_info_schedulers"><c>schedulers</c></seealso>, + <seealso marker="#system_info_smp_support"><c>smp_support</c></seealso>, + <seealso marker="#system_info_threads"><c>threads</c></seealso>, + <seealso marker="#system_info_thread_pool_size"><c>thread_pool_size</c></seealso> + </p> + </item> + <tag><seealso marker="#system_info_dist"> + <c>Distribution Information</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_creation"><c>creation</c></seealso>, + <seealso marker="#system_info_delayed_node_table_gc"><c>delayed_node_table_gc</c></seealso>, + <seealso marker="#system_info_dist"><c>dist</c></seealso>, + <seealso marker="#system_info_dist_buf_busy_limit"><c>dist_buf_busy_limit</c></seealso>, + <seealso marker="#system_info_dist_ctrl"><c>dist_ctrl</c></seealso> + </p> + </item> + <tag><seealso marker="#system_info_misc"> + <c>System Information</c></seealso></tag> + <item> + <p> + <seealso marker="#system_info_build_type"><c>build_type</c></seealso>, + <seealso marker="#system_info_c_compiler_used"><c>c_compiler_used</c></seealso>, + <seealso marker="#system_info_check_io"><c>check_io</c></seealso>, + <seealso marker="#system_info_compat_rel"><c>compat_rel</c></seealso>, + <seealso marker="#system_info_debug_compiled"><c>debug_compiled</c></seealso>, + <seealso marker="#system_info_driver_version"><c>driver_version</c></seealso>, + <seealso marker="#system_info_dynamic_trace"><c>dynamic_trace</c></seealso>, + <seealso marker="#system_info_dynamic_trace_probes"><c>dynamic_trace_probes</c></seealso>, + <seealso marker="#system_info_info"><c>info</c></seealso>, + <seealso marker="#system_info_kernel_poll"><c>kernel_poll</c></seealso>, + <seealso marker="#system_info_loaded"><c>loaded</c></seealso>, + <seealso marker="#system_info_machine"><c>machine</c></seealso>, + <seealso marker="#system_info_modified_timing_level"><c>modified_timing_level</c></seealso>, + <seealso marker="#system_info_nif_version"><c>nif_version</c></seealso>, + <seealso marker="#system_info_otp_release"><c>otp_release</c></seealso>, + <seealso marker="#system_info_port_parallelism"><c>port_parallelism</c></seealso>, + <seealso marker="#system_info_system_version"><c>system_version</c></seealso>, + <seealso marker="#system_info_system_architecture"><c>system_architecture</c></seealso>, + <seealso marker="#system_info_trace_control_word"><c>trace_control_word</c></seealso>, + <seealso marker="#system_info_version"><c>version</c></seealso>, + <seealso marker="#system_info_wordsize"><c>wordsize</c></seealso> + </p> + </item> + </taglist> + </desc> + </func> + + <func> + <name name="system_info" arity="1" clause_i="1" + anchor="system_info_allocator"/> <!-- allocated_areas --> + <name name="system_info" arity="1" clause_i="2"/> <!-- allocator --> + <name name="system_info" arity="1" clause_i="3"/> <!-- {allocator, _} --> + <name name="system_info" arity="1" clause_i="4"/> <!-- alloc_util_allocators --> + <name name="system_info" arity="1" clause_i="5"/> <!-- {allocator_sizes, _} --> + <name name="system_info" arity="1" clause_i="27"/> <!-- elib_malloc --> <fsummary>Information about the system allocators.</fsummary> <type variable="Allocator" name_i="2"/> <type variable="Version" name_i="2"/> @@ -7317,12 +7730,13 @@ ok <type variable="Alloc" name_i="3"/> <desc> <marker id="system_info_allocator_tags"></marker> - <p>Returns various information about the allocators of the - current system (emulator) as specified by + <p>Returns various information about the memory allocators + of the current system (emulator) as specified by <c><anno>Item</anno></c>:</p> <marker id="system_info_allocated_areas"></marker> <taglist> - <tag><c>allocated_areas</c></tag> + <tag><marker id="system_info_allocated_areas"/> + <c>allocated_areas</c></tag> <item> <p>Returns a list of tuples with information about miscellaneous allocated memory areas.</p> @@ -7344,9 +7758,9 @@ ok <seealso marker="#memory/0"> <c>erlang:memory/0,1</c></seealso>.</p> </item> - <tag><c>allocator</c></tag> + <tag><marker id="system_info_allocator"/> + <c>allocator</c></tag> <item> - <marker id="system_info_allocator"></marker> <p>Returns <c>{<anno>Allocator</anno>, <anno>Version</anno>, <anno>Features</anno>, <anno>Settings</anno></c>, where:</p> <list type="bulleted"> @@ -7379,19 +7793,9 @@ ok <seealso marker="erts:erts_alloc#flags"> <c>erts_alloc(3)</c></seealso>.</p> </item> - <tag><c>alloc_util_allocators</c></tag> - <item> - <marker id="system_info_alloc_util_allocators"></marker> - <p>Returns a list of the names of all allocators using - the ERTS internal <c>alloc_util</c> framework - as atoms. For more information, see section - <seealso marker="erts:erts_alloc#alloc_util">The - alloc_util framework</seealso> - in <c>erts_alloc(3)</c>.</p> - </item> - <tag><c>{allocator, <anno>Alloc</anno>}</c></tag> + <tag><marker id="system_info_allocator_tuple"></marker> + <c>{allocator, <anno>Alloc</anno>}</c></tag> <item> - <marker id="system_info_allocator_tuple"></marker> <p>Returns information about the specified allocator. As from ERTS 5.6.1, the return value is a list of <c>{instance, InstanceNo, InstanceInfo}</c> tuples, @@ -7436,9 +7840,19 @@ ok values. The first value is the memory pool size and the second value is the used memory size.</p> </item> - <tag><c>{allocator_sizes, <anno>Alloc</anno>}</c></tag> + <tag><marker id="system_info_alloc_util_allocators"/> + <c>alloc_util_allocators</c></tag> + <item> + <p>Returns a list of the names of all allocators using + the ERTS internal <c>alloc_util</c> framework + as atoms. For more information, see section + <seealso marker="erts:erts_alloc#alloc_util">The + alloc_util framework</seealso> + in <c>erts_alloc(3)</c>.</p> + </item> + <tag><marker id="system_info_allocator_sizes"/> + <c>{allocator_sizes, <anno>Alloc</anno>}</c></tag> <item> - <marker id="system_info_allocator_sizes"></marker> <p>Returns various size information for the specified allocator. The information returned is a subset of the information returned by @@ -7446,13 +7860,23 @@ ok <c>erlang:system_info({allocator, <anno>Alloc</anno>})</c></seealso>.</p> </item> + <tag><marker id="system_info_elib_malloc"/> + <c>elib_malloc</c></tag> + <item> + <p>This option will be removed in a future release. + The return value will always be <c>false</c>, as the + <c>elib_malloc</c> allocator has been removed.</p> + </item> </taglist> </desc> </func> <func> - <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="12" + anchor="system_info_cpu_topology"/> <!-- cpu_topology --> + <name name="system_info" arity="1" clause_i="13"/> <!-- {cpu_topology, _} --> + <name name="system_info" arity="1" clause_i="38"/> <!-- logical_processors --> + <name name="system_info" arity="1" clause_i="73"/> <!-- update_cpu_info --> <fsummary>Information about the CPU topology of the system.</fsummary> <type name="cpu_topology"/> <type name="level_entry"/> @@ -7479,12 +7903,12 @@ ok </type_desc> <desc> <marker id="system_info_cpu_topology_tags"></marker> - <marker id="system_info_cpu_topology"></marker> <p>Returns various information about the CPU topology of the current system (emulator) as specified by <c><anno>Item</anno></c>:</p> <taglist> - <tag><c>cpu_topology</c></tag> + <tag><marker id="system_info_cpu_topology"/> + <c>cpu_topology</c></tag> <item> <p>Returns the <c><anno>CpuTopology</anno></c> currently used by the emulator. The CPU topology is used when binding schedulers @@ -7547,31 +7971,89 @@ ok <seealso marker="#system_info_cpu_topology"> <c>cpu_topology</c></seealso>.</p> </item> + <tag><marker id="system_info_logical_processors"/> + <c>logical_processors</c></tag> + <item> + <p>Returns the detected number of logical processors configured + in the system. The return value is either an integer, or + the atom <c>unknown</c> if the emulator cannot + detect the configured logical processors.</p> + </item> + <tag><marker id="system_info_logical_processors_available"/> + <c>logical_processors_available</c></tag> + <item> + <p>Returns the detected number of logical processors available + to the Erlang runtime system. The return value is either an + integer, or the atom <c>unknown</c> if the emulator + cannot detect the available logical processors. The number + of available logical processors is less than or equal to + the number of <seealso marker="#system_info_logical_processors_online"> + logical processors online</seealso>.</p> + </item> + <tag><marker id="system_info_logical_processors_online"/> + <c>logical_processors_online</c></tag> + <item> + <p>Returns the detected number of logical processors online on + the system. The return value is either an integer, + or the atom <c>unknown</c> if the emulator cannot + detect logical processors online. The number of logical + processors online is less than or equal to the number of + <seealso marker="#system_info_logical_processors">logical processors + configured</seealso>.</p> + </item> + <tag><marker id="system_info_update_cpu_info"/> + <c>update_cpu_info</c></tag> + <item> + <p>The runtime system rereads the CPU information available + and updates its internally stored information about the + <seealso marker="#system_info_cpu_topology_detected">detected + CPU topology</seealso> and the number of logical processors + <seealso marker="#system_info_logical_processors">configured</seealso>, + <seealso marker="#system_info_logical_processors_online">online</seealso>, + and <seealso marker="#system_info_logical_processors_available"> + available</seealso>.</p> + <p>If the CPU information has changed since the last time + it was read, the atom <c>changed</c> is returned, otherwise + the atom <c>unchanged</c>. If the CPU information has changed, + you probably want to + <seealso marker="#system_flag_schedulers_online">adjust the + number of schedulers online</seealso>. You typically want + to have as many schedulers online as + <seealso marker="#system_info_logical_processors_available">logical + processors available</seealso>.</p> + </item> </taglist> </desc> </func> <func> - <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"/> + <name name="system_info" arity="1" clause_i="31" + anchor="system_info_process"/> <!-- fullsweep_after --> + <name name="system_info" arity="1" clause_i="32"/> <!-- garbage_collection --> + <name name="system_info" arity="1" clause_i="33"/> <!-- heap_sizes --> + <name name="system_info" arity="1" clause_i="34"/> <!-- heap_type --> + <name name="system_info" arity="1" clause_i="40"/> <!-- max_heap_size --> + <name name="system_info" arity="1" clause_i="41"/> <!-- message_queue_data --> + <name name="system_info" arity="1" clause_i="42"/> <!-- min_heap_size --> + <name name="system_info" arity="1" clause_i="43"/> <!-- min_bin_vheap_size --> + <name name="system_info" arity="1" clause_i="57"/> <!-- procs --> <fsummary>Information about the default process heap settings.</fsummary> <type name="message_queue_data"/> <type name="max_heap_size"/> <desc> + <marker id="system_info_process_tags"/> <p>Returns information about the default process heap settings:</p> <taglist> - <tag><c>fullsweep_after</c></tag> + <tag><marker id="system_info_fullsweep_after"/> + <c>fullsweep_after</c></tag> <item> <p>Returns <c>{fullsweep_after, integer() >= 0}</c>, which is the <c>fullsweep_after</c> garbage collection setting used by default. For more information, see <c>garbage_collection</c> described below.</p> </item> - <tag><c>garbage_collection</c></tag> + <tag><marker id="system_info_garbage_collection"/> + <c>garbage_collection</c></tag> <item> <p>Returns a list describing the default garbage collection settings. A process spawned on the local node by a @@ -7584,7 +8066,30 @@ ok can spawn a process that does not use the default settings.</p> </item> - <tag><c>max_heap_size</c></tag> + <tag><marker id="system_info_heap_sizes"/> + <c>heap_sizes</c></tag> + <item> + <p>Returns a list of integers representing valid heap sizes + in words. All Erlang heaps are sized from sizes in this + list.</p> + </item> + <tag><marker id="system_info_heap_type"/> + <c>heap_type</c></tag> + <item> + <p>Returns the heap type used by the current emulator. One + heap type exists:</p> + <taglist> + <tag><c>private</c></tag> + <item> + Each process has a heap reserved for its use and no + references between heaps of different processes are + allowed. Messages passed between processes are copied + between heaps. + </item> + </taglist> + </item> + <tag><marker id="system_info_max_heap_size"/> + <c>max_heap_size</c></tag> <item> <p>Returns <c>{max_heap_size, <anno>MaxHeapSize</anno>}</c>, where <c><anno>MaxHeapSize</anno></c> is the current @@ -7612,173 +8117,366 @@ 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> + <tag><marker id="system_info_min_heap_size"/> + <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> + <tag><marker id="system_info_min_bin_vheap_size"/> + <c>min_bin_vheap_size</c></tag> <item> <p>Returns <c>{min_bin_vheap_size, <anno>MinBinVHeapSize</anno>}</c>, where <c><anno>MinBinVHeapSize</anno></c> is the current system-wide minimum binary virtual heap size for spawned processes.</p> </item> + <tag><marker id="system_info_procs"/> + <c>procs</c></tag> + <item> + <p>Returns a binary containing a string of process and port + information formatted as in Erlang crash dumps. For more + information, see section <seealso marker="erts:crash_dump"> + How to interpret the Erlang crash dumps</seealso> + in the User's Guide.</p> + </item> </taglist> </desc> </func> <func> - <name name="system_info" arity="1" clause_i="6"/> - <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="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"/> - <name name="system_info" arity="1" clause_i="17"/> - <name name="system_info" arity="1" clause_i="18"/> - <name name="system_info" arity="1" clause_i="19"/> - <name name="system_info" arity="1" clause_i="20"/> - <name name="system_info" arity="1" clause_i="21"/> - <name name="system_info" arity="1" clause_i="22"/> - <name name="system_info" arity="1" clause_i="23"/> - <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="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="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"/> - <name name="system_info" arity="1" clause_i="45"/> - <name name="system_info" arity="1" clause_i="46"/> - <name name="system_info" arity="1" clause_i="47"/> - <name name="system_info" arity="1" clause_i="48"/> - <name name="system_info" arity="1" clause_i="49"/> - <name name="system_info" arity="1" clause_i="50"/> - <name name="system_info" arity="1" clause_i="51"/> - <name name="system_info" arity="1" clause_i="52"/> - <name name="system_info" arity="1" clause_i="53"/> - <name name="system_info" arity="1" clause_i="54"/> - <name name="system_info" arity="1" clause_i="55"/> - <name name="system_info" arity="1" clause_i="56"/> - <name name="system_info" arity="1" clause_i="57"/> - <name name="system_info" arity="1" clause_i="58"/> - <name name="system_info" arity="1" clause_i="59"/> - <name name="system_info" arity="1" clause_i="60"/> - <name name="system_info" arity="1" clause_i="61"/> - <name name="system_info" arity="1" clause_i="62"/> - <name name="system_info" arity="1" clause_i="63"/> - <name name="system_info" arity="1" clause_i="64"/> - <name name="system_info" arity="1" clause_i="65"/> - <name name="system_info" arity="1" clause_i="66"/> - <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> + <name name="system_info" arity="1" clause_i="6" anchor="system_info_limits"/> <!-- atom_count --> + <name name="system_info" arity="1" clause_i="7"/> <!-- atom_limit --> + <name name="system_info" arity="1" clause_i="29"/> <!-- ets_count --> + <name name="system_info" arity="1" clause_i="30"/> <!-- ets_limit --> + <name name="system_info" arity="1" clause_i="53"/> <!-- port_count --> + <name name="system_info" arity="1" clause_i="54"/> <!-- port_limit --> + <name name="system_info" arity="1" clause_i="55"/> <!-- process_count --> + <name name="system_info" arity="1" clause_i="56"/> <!-- process_limit --> + <fsummary>Information about various system limits.</fsummary> <desc> - <p>Returns various information about the current system - (emulator) as specified by <c><anno>Item</anno></c>:</p> + <marker id="system_info_limits"/> + <p>Returns information about the current system + (emulator) limits as specified by <c><anno>Item</anno></c>:</p> <taglist> - <tag><c>atom_count</c></tag> + <tag><marker id="system_info_atom_count"/> + <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> + local node. The value is given as an integer.</p> </item> - <tag><c>atom_limit</c></tag> + <tag><marker id="system_info_atom_limit"/> + <c>atom_limit</c></tag> <item> - <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>. + 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> + <tag><marker id="system_info_ets_count"/> + <c>ets_count</c></tag> <item> - <p>Returns an atom describing the build type of the runtime - system. This is normally the atom <c>opt</c> for optimized. - Other possible return values are <c>debug</c>, <c>purify</c>, - <c>quantify</c>, <c>purecov</c>, <c>gcov</c>, <c>valgrind</c>, - <c>gprof</c>, and <c>lcnt</c>. Possible return values - can be added or removed at any time without prior notice.</p> + <p>Returns the number of ETS tables currently existing at the + local node.</p> </item> - <tag><c>c_compiler_used</c></tag> + <tag><marker id="system_info_ets_limit"/> + <c>ets_limit</c></tag> <item> - <p>Returns a two-tuple describing the C compiler used when - compiling the runtime system. The first element is an - atom describing the name of the compiler, or <c>undefined</c> - if unknown. The second element is a term describing the - version of the compiler, or <c>undefined</c> if unknown.</p> + <p>Returns the limit for number of ETS tables. This limit is + <seealso marker="stdlib:ets#max_ets_tables">partially obsolete</seealso> + and number of tables are only limited by available memory.</p> </item> - <tag><c>check_io</c></tag> + <tag><marker id="system_info_port_count"/><c>port_count</c></tag> <item> - <p>Returns a list containing miscellaneous information - about the emulators internal I/O checking. Notice that - the content of the returned list can vary between - platforms and over time. It is only guaranteed - that a list is returned.</p> + <p>Returns the number of ports currently existing at the + local node. The value is given as an integer. This is + the same value as returned by + <c>length(erlang:ports())</c>, but more efficient.</p> </item> - <tag><c>compat_rel</c></tag> + <tag><marker id="system_info_port_limit"/> + <c>port_limit</c></tag> <item> - <p>Returns the compatibility mode of the local node as - an integer. The integer returned represents the - Erlang/OTP release that the current emulator has been - set to be backward compatible with. The compatibility - mode can be configured at startup by using command-line flag - <seealso marker="erts:erl#compat_rel"><c>+R</c></seealso> in - <c>erl(1)</c>.</p> + <p>Returns the maximum number of simultaneously existing + ports at the local node as an integer. This limit can be + configured at startup by using command-line flag + <seealso marker="erl#+Q"><c>+Q</c></seealso> in <c>erl(1)</c>.</p> </item> - <tag><c>cpu_topology</c></tag> + <tag><marker id="system_info_process_count"/> + <c>process_count</c></tag> <item> - <p>See <seealso - marker="#system_info_cpu_topology_tags">above</seealso>.</p> + <p>Returns the number of processes currently existing at the + local node. The value is given as an integer. This is + the same value as returned by + <c>length(processes())</c>, but more efficient.</p> </item> - <tag><c>creation</c></tag> + <tag><marker id="system_info_process_limit"/> + <c>process_limit</c></tag> <item> - <p>Returns the creation of the local node as an integer. - The creation is changed when a node is restarted. The - creation of a node is stored in process identifiers, port - identifiers, and references. This makes it (to some - extent) possible to distinguish between identifiers from - different incarnations of a node. The valid - creations are integers in the range 1..3, but this will - probably change in a future release. If the node is not - alive, <c>0</c> is returned.</p> + <p>Returns the maximum number of simultaneously existing + processes at the local node. The value is given as an + integer. This limit can be configured at startup by using + command-line flag <seealso marker="erl#+P"><c>+P</c></seealso> + in <c>erl(1)</c>.</p> + </item> + </taglist> + </desc> + </func> + + <func> + <name name="system_info" arity="1" clause_i="26" + anchor="system_info_time"/> <!-- end_time --> + <name name="system_info" arity="1" clause_i="50"/> <!-- os_monotonic_time_source --> + <name name="system_info" arity="1" clause_i="51"/> <!-- os_system_time_source --> + <name name="system_info" arity="1" clause_i="63"/> <!-- start_time --> + <name name="system_info" arity="1" clause_i="68"/> <!-- time_correction --> + <name name="system_info" arity="1" clause_i="69"/> <!-- time_offset --> + <name name="system_info" arity="1" clause_i="70"/> <!-- time_warp_mode --> + <name name="system_info" arity="1" clause_i="71"/> <!-- tolerant_timeofday --> + <fsummary>Information about system time.</fsummary> + <desc> + <marker id="system_info_time_tags"/> + <p>Returns information about the current system + (emulator) time as specified by <c><anno>Item</anno></c>:</p> + <taglist> + <tag><marker id="system_info_end_time"/><c>end_time</c></tag> + <item> + <p>The last <seealso marker="#monotonic_time/0">Erlang monotonic + time</seealso> in <c>native</c> + <seealso marker="#type_time_unit">time unit</seealso> that + can be represented internally in the current Erlang runtime system + instance. The time between the + <seealso marker="#system_info_start_time">start time</seealso> and + the end time is at least a quarter of a millennium.</p> </item> - <tag><c>debug_compiled</c></tag> + <tag><marker id="system_info_os_monotonic_time_source"/> + <c>os_monotonic_time_source</c></tag> <item> - <p>Returns <c>true</c> if the emulator has been - debug-compiled, otherwise <c>false</c>.</p> + <p>Returns a list containing information about the source of + <seealso marker="erts:time_correction#OS_Monotonic_Time">OS + monotonic time</seealso> that is used by the runtime system.</p> + <p>If <c>[]</c> is returned, no OS monotonic time is + available. The list contains two-tuples with <c>Key</c>s + as first element, and <c>Value</c>s as second element. The + order of these tuples is undefined. The following + tuples can be part of the list, but more tuples can be + introduced in the future:</p> + <taglist> + <tag><c>{function, Function}</c></tag> + <item><p><c>Function</c> is the name of the function + used. This tuple always exists if OS monotonic time is + available to the runtime system.</p> + </item> + <tag><c>{clock_id, ClockId}</c></tag> + <item><p>This tuple only exists if <c>Function</c> + can be used with different clocks. <c>ClockId</c> + corresponds to the clock identifier used when calling + <c>Function</c>.</p> + </item> + <tag><c>{resolution, OsMonotonicTimeResolution}</c></tag> + <item><p>Highest possible + <seealso marker="time_correction#Time_Resolution"> + resolution</seealso> + of current OS monotonic time source as parts per + second. If no resolution information can be retrieved + from the OS, <c>OsMonotonicTimeResolution</c> is + set to the resolution of the time unit of + <c>Function</c>s return value. That is, the actual + resolution can be lower than + <c>OsMonotonicTimeResolution</c>. Notice that + the resolution does not say anything about the + <seealso marker="time_correction#Time_Accuracy"> + accuracy</seealso> or whether the + <seealso marker="time_correction#Time_Precision"> + precision</seealso> aligns with the resolution. You do, + however, know that the precision is not better than + <c>OsMonotonicTimeResolution</c>.</p> + </item> + <tag><c>{extended, Extended}</c></tag> + <item><p><c>Extended</c> equals <c>yes</c> if + the range of time values has been extended; + otherwise <c>Extended</c> equals <c>no</c>. The + range must be extended if <c>Function</c> + returns values that wrap fast. This typically + is the case when the return value is a 32-bit value.</p> + </item> + <tag><c>{parallel, Parallel}</c></tag> + <item><p><c>Parallel</c> equals <c>yes</c> if + <c>Function</c> is called in parallel from multiple + threads. If it is not called in parallel, because + calls must be serialized, <c>Parallel</c> equals + <c>no</c>.</p> + </item> + <tag><c>{time, OsMonotonicTime}</c></tag> + <item><p><c>OsMonotonicTime</c> equals current OS + monotonic time in <c>native</c> + <seealso marker="#type_time_unit">time unit</seealso>.</p> + </item> + </taglist> </item> - <tag><c>delayed_node_table_gc</c></tag> + <tag><marker id="system_info_os_system_time_source"/> + <c>os_system_time_source</c></tag> <item> - <marker id="system_info_delayed_node_table_gc"></marker> - <p>Returns the amount of time in seconds garbage collection - of an entry in a node table is delayed. This limit can be set - on startup by passing command-line flag - <seealso marker="erts:erl#+zdntgc"><c>+zdntgc</c></seealso> - to <c>erl(1)</c>. For more information, see the documentation of - the command-line flag.</p> + <p>Returns a list containing information about the source of + <seealso marker="erts:time_correction#OS_System_Time">OS + system time</seealso> that is used by the runtime system.</p> + <p>The list contains two-tuples with <c>Key</c>s + as first element, and <c>Value</c>s as second element. The + order if these tuples is undefined. The following + tuples can be part of the list, but more tuples can be + introduced in the future:</p> + <taglist> + <tag><c>{function, Function}</c></tag> + <item><p><c>Function</c> is the name of the funcion used.</p> + </item> + <tag><c>{clock_id, ClockId}</c></tag> + <item><p>Exists only if <c>Function</c> + can be used with different clocks. <c>ClockId</c> + corresponds to the clock identifier used when calling + <c>Function</c>.</p> + </item> + <tag><c>{resolution, OsSystemTimeResolution}</c></tag> + <item><p>Highest possible + <seealso marker="time_correction#Time_Resolution"> + resolution</seealso> + of current OS system time source as parts per + second. If no resolution information can be retrieved + from the OS, <c>OsSystemTimeResolution</c> is + set to the resolution of the time unit of + <c>Function</c>s return value. That is, the actual + resolution can be lower than + <c>OsSystemTimeResolution</c>. Notice that + the resolution does not say anything about the + <seealso marker="time_correction#Time_Accuracy"> + accuracy</seealso> or whether the + <seealso marker="time_correction#Time_Precision"> + precision</seealso> do align with the resolution. You do, + however, know that the precision is not better than + <c>OsSystemTimeResolution</c>.</p> + </item> + <tag><c>{parallel, Parallel}</c></tag> + <item><p><c>Parallel</c> equals <c>yes</c> if + <c>Function</c> is called in parallel from multiple + threads. If it is not called in parallel, because + calls needs to be serialized, <c>Parallel</c> equals + <c>no</c>.</p> + </item> + <tag><c>{time, OsSystemTime}</c></tag> + <item><p><c>OsSystemTime</c> equals current OS + system time in <c>native</c> + <seealso marker="#type_time_unit">time unit</seealso>.</p> + </item> + </taglist> + </item> + <tag><marker id="system_info_start_time"/><c>start_time</c></tag> + <item> + <p>The <seealso marker="#monotonic_time/0">Erlang monotonic + time</seealso> in <c>native</c> + <seealso marker="#type_time_unit">time unit</seealso> at the + time when current Erlang runtime system instance started.</p> + <p>See also <seealso marker="#system_info_end_time"> + <c>erlang:system_info(end_time)</c></seealso>.</p> + </item> + <tag><marker id="system_info_time_correction"/> + <c>time_correction</c></tag> + <item> + <p>Returns a boolean value indicating whether + <seealso marker="time_correction#Time_Correction"> + time correction</seealso> is enabled or not.</p> + </item> + <tag><marker id="system_info_time_offset"/> + <c>time_offset</c></tag> + <item> + <p>Returns the state of the time offset:</p> + <taglist> + <tag><c>preliminary</c></tag> + <item> + <p>The time offset is preliminary, and will be changed + and finalized later. The preliminary time offset + is used during the preliminary phase of the + <seealso marker="time_correction#Single_Time_Warp_Mode"> + single time warp mode</seealso>.</p> + </item> + <tag><c>final</c></tag> + <item> + <p>The time offset is final. This either because + <seealso marker="time_correction#No_Time_Warp_Mode"> + no time warp mode</seealso> is used, or because the time + offset have been finalized when + <seealso marker="time_correction#Single_Time_Warp_Mode"> + single time warp mode</seealso> is used.</p> + </item> + <tag><c>volatile</c></tag> + <item> + <p>The time offset is volatile. That is, it can + change at any time. This is because + <seealso marker="time_correction#Multi_Time_Warp_Mode"> + multi-time warp mode</seealso> is used.</p> + </item> + </taglist> + </item> + <tag><marker id="system_info_time_warp_mode"/> + <c>time_warp_mode</c></tag> + <item> + <p>Returns a value identifying the + <seealso marker="time_correction#Time_Warp_Modes"> + time warp mode</seealso> that is used:</p> + <taglist> + <tag><c>no_time_warp</c></tag> + <item>The <seealso marker="time_correction#No_Time_Warp_Mode"> + no time warp mode</seealso> is used. + </item> + <tag><c>single_time_warp</c></tag> + <item>The <seealso marker="time_correction#Single_Time_Warp_Mode"> + single time warp mode</seealso> is used. + </item> + <tag><c>multi_time_warp</c></tag> + <item>The <seealso marker="time_correction#Multi_Time_Warp_Mode"> + multi-time warp mode</seealso> is used. + </item> + </taglist> + </item> + <tag><marker id="system_info_tolerant_timeofday"/> + <c>tolerant_timeofday</c></tag> + <item> + <p>Returns whether a pre ERTS 7.0 backwards compatible + compensation for sudden changes of system time is <c>enabled</c> + or <c>disabled</c>. Such compensation is <c>enabled</c> when the + <seealso marker="#system_info_time_offset">time offset</seealso> + is <c>final</c>, and + <seealso marker="#system_info_time_correction"> + time correction</seealso> is enabled.</p> </item> - <tag><c>dirty_cpu_schedulers</c></tag> + </taglist> + </desc> + </func> + + <func> + <name name="system_info" arity="1" clause_i="17" + anchor="system_info_scheduler"/> <!-- dirty_cpu_schedulers --> + <name name="system_info" arity="1" clause_i="18"/> <!-- dirty_cpu_schedulers_online --> + <name name="system_info" arity="1" clause_i="19"/> <!-- dirty_io_schedulers --> + <name name="system_info" arity="1" clause_i="45"/> <!-- multi_scheduling --> + <name name="system_info" arity="1" clause_i="46"/> <!-- multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="49"/> <!-- normal_multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="58"/> <!-- scheduler_bind_type --> + <name name="system_info" arity="1" clause_i="59"/> <!-- scheduler_bindings --> + <name name="system_info" arity="1" clause_i="60"/> <!-- scheduler_id --> + <name name="system_info" arity="1" clause_i="61"/> <!-- schedulers --> + <name name="system_info" arity="1" clause_i="62"/> <!-- smp_support --> + <name name="system_info" arity="1" clause_i="66"/> <!-- threads --> + <name name="system_info" arity="1" clause_i="67"/> <!-- thread_pool_size --> + <fsummary>Information about system schedulers.</fsummary> + <desc> + <marker id="system_info_scheduler_tags"/> + <p>Returns information about schedulers, scheduling and threads in the + current system as specified by <c><anno>Item</anno></c>:</p> + <taglist> + <tag><marker id="system_info_dirty_cpu_schedulers"/> + <c>dirty_cpu_schedulers</c></tag> <item> - <marker id="system_info_dirty_cpu_schedulers"></marker> <p>Returns the number of dirty CPU scheduler threads used by the emulator. Dirty CPU schedulers execute CPU-bound native functions, such as NIFs, linked-in driver code, @@ -7809,9 +8507,9 @@ ok <c>erlang:system_flag(schedulers_online, SchedulersOnline)</c></seealso>.</p> </item> - <tag><c>dirty_cpu_schedulers_online</c></tag> + <tag><marker id="system_info_dirty_cpu_schedulers_online"/> + <c>dirty_cpu_schedulers_online</c></tag> <item> - <marker id="system_info_dirty_cpu_schedulers_online"></marker> <p>Returns the number of dirty CPU schedulers online. The return value satisfies <c><![CDATA[1 <= DirtyCPUSchedulersOnline <= N]]></c>, @@ -7833,9 +8531,9 @@ ok <c>erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</c></seealso>.</p> </item> - <tag><c>dirty_io_schedulers</c></tag> + <tag><marker id="system_info_dirty_io_schedulers"/> + <c>dirty_io_schedulers</c></tag> <item> - <marker id="system_info_dirty_io_schedulers"></marker> <p>Returns the number of dirty I/O schedulers as an integer. Dirty I/O schedulers execute I/O-bound native functions, such as NIFs and linked-in driver code, which cannot be @@ -7852,195 +8550,14 @@ ok <c>erlang:system_flag(dirty_cpu_schedulers_online, DirtyCPUSchedulersOnline)</c></seealso>.</p> </item> - <tag><c>dist</c></tag> - <item> - <p>Returns a binary containing a string of distribution - information formatted as in Erlang crash dumps. For more - information, see section <seealso marker="erts:crash_dump"> - How to interpret the Erlang crash dumps</seealso> - in the User's Guide.</p> - </item> - <tag><c>dist_buf_busy_limit</c></tag> - <item> - <marker id="system_info_dist_buf_busy_limit"></marker> - <p>Returns the value of the distribution buffer busy limit - in bytes. This limit can be set at startup by passing - command-line flag - <seealso marker="erts:erl#+zdbbl"><c>+zdbbl</c></seealso> - to <c>erl(1)</c>.</p> - </item> - <tag><c>dist_ctrl</c></tag> - <item> - <p>Returns a list of tuples - <c>{<anno>Node</anno>, <anno>ControllingEntity</anno>}</c>, - one entry for each connected remote node. - <c><anno>Node</anno></c> is the node name - and <c><anno>ControllingEntity</anno></c> is the port or process - identifier responsible for the communication to that node. - More specifically, <c><anno>ControllingEntity</anno></c> for - nodes connected through TCP/IP (the normal case) is the socket - used in communication with the specific node.</p> - </item> - <tag><c>driver_version</c></tag> - <item> - <p>Returns a string containing the Erlang driver version - used by the runtime system. It has the form - <seealso marker="erts:erl_driver#version_management"> - "<major ver>.<minor ver>"</seealso>.</p> - </item> - <tag><c>dynamic_trace</c></tag> - <item> - <p>Returns an atom describing the dynamic trace framework - compiled into the virtual machine. It can be - <c>dtrace</c>, <c>systemtap</c>, or <c>none</c>. For a - commercial or standard build, it is always <c>none</c>. - The other return values indicate a custom configuration - (for example, <c>./configure --with-dynamic-trace=dtrace</c>). - For more information about dynamic tracing, see - <seealso marker="runtime_tools:dyntrace"> - <c>dyntrace(3)</c></seealso> manual page and the - <c>README.dtrace</c>/<c>README.systemtap</c> files in the - Erlang source code top directory.</p> - </item> - <tag><c>dynamic_trace_probes</c></tag> - <item> - <p>Returns a <c>boolean()</c> indicating if dynamic trace - probes (<c>dtrace</c> or <c>systemtap</c>) are built into - the emulator. This can only be <c>true</c> if the virtual - machine was built for dynamic tracing (that is, - <c>system_info(dynamic_trace)</c> returns - <c>dtrace</c> or <c>systemtap</c>).</p> - </item> - <tag><marker id="system_info_end_time"/><c>end_time</c></tag> - <item> - <p>The last <seealso marker="#monotonic_time/0">Erlang monotonic - time</seealso> in <c>native</c> - <seealso marker="#type_time_unit">time unit</seealso> that - can be represented internally in the current Erlang runtime system - instance. The time between the - <seealso marker="#system_info_start_time">start time</seealso> and - the end time is at least a quarter of a millennium.</p> - </item> - <tag><c>elib_malloc</c></tag> - <item> - <p>This option will be removed in a future release. - The return value will always be <c>false</c>, as the - <c>elib_malloc</c> allocator has been removed.</p> - </item> - <tag><marker id="system_info_eager_check_io"/> - <c>eager_check_io</c></tag> - <item> - <p>Returns the value of command-line flag - <seealso marker="erl#+secio"><c>+secio</c></seealso> in - <c>erl(1)</c>, which is either <c>true</c> or <c>false</c>. - For information about the different values, see the - documentation of the command-line flag.</p> - </item> - <tag><c>ets_limit</c></tag> - <item> - <p>Returns the maximum number of ETS tables allowed. This - limit can be increased at startup by passing - command-line flag - <seealso marker="erts:erl#+e"><c>+e</c></seealso> to - <c>erl(1)</c> or by setting environment variable - <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang - runtime system.</p> - </item> - <tag><c>heap_sizes</c></tag> - <item> - <p>Returns a list of integers representing valid heap sizes - in words. All Erlang heaps are sized from sizes in this - list.</p> - </item> - <tag><c>heap_type</c></tag> - <item> - <p>Returns the heap type used by the current emulator. One - heap type exists:</p> - <taglist> - <tag><c>private</c></tag> - <item> - Each process has a heap reserved for its use and no - references between heaps of different processes are - allowed. Messages passed between processes are copied - between heaps. - </item> - </taglist> - </item> - <tag><c>info</c></tag> - <item> - <p>Returns a binary containing a string of miscellaneous - system information formatted as in Erlang crash dumps. - For more information, see section - <seealso marker="erts:crash_dump"> - How to interpret the Erlang crash dumps</seealso> - in the User's Guide.</p> - </item> - <tag><c>kernel_poll</c></tag> - <item> - <p>Returns <c>true</c> if the emulator uses some kind of - kernel-poll implementation, otherwise <c>false</c>.</p> - </item> - <tag><c>loaded</c></tag> - <item> - <p>Returns a binary containing a string of loaded module - information formatted as in Erlang crash dumps. For more - information, see section - <seealso marker="erts:crash_dump">How to interpret the Erlang - crash dumps</seealso> in the User's Guide.</p> - </item> - <tag><c>logical_processors</c></tag> - <item> - <marker id="logical_processors"></marker> - <p>Returns the detected number of logical processors configured - in the system. The return value is either an integer, or - the atom <c>unknown</c> if the emulator cannot - detect the configured logical processors.</p> - </item> - <tag><c>logical_processors_available</c></tag> - <item> - <marker id="logical_processors_available"></marker> - <p>Returns the detected number of logical processors available - to the Erlang runtime system. The return value is either an - integer, or the atom <c>unknown</c> if the emulator - cannot detect the available logical processors. The number - of available logical processors is less than or equal to - the number of <seealso marker="#logical_processors_online"> - logical processors online</seealso>.</p> - </item> - <tag><c>logical_processors_online</c></tag> - <item> - <marker id="logical_processors_online"></marker> - <p>Returns the detected number of logical processors online on - the system. The return value is either an integer, - or the atom <c>unknown</c> if the emulator cannot - detect logical processors online. The number of logical - processors online is less than or equal to the number of - <seealso marker="#logical_processors">logical processors - configured</seealso>.</p> - </item> - <tag><c>machine</c></tag> + <tag><marker id="system_info_multi_scheduling"/> + <c>multi_scheduling</c></tag> <item> - <p>Returns a string containing the Erlang machine name.</p> - </item> - <tag><c>modified_timing_level</c></tag> - <item> - <p>Returns the modified timing-level (an integer) if - modified timing is enabled, otherwise <c>undefined</c>. - For more information about modified timing, see - command-line flag - <seealso marker="erts:erl#+T"><c>+T</c></seealso> - in <c>erl(1)</c></p> - </item> - <tag><c>multi_scheduling</c></tag> - <item> - <marker id="system_info_multi_scheduling"></marker> <p>Returns one of the following:</p> <taglist> <tag><c>disabled</c></tag> <item> - <p>The emulator has only one scheduler thread. The - emulator does not have SMP support, or have been - started with only one scheduler thread.</p> + <p>The emulator has been started with only one scheduler thread.</p> </item> <tag><c>blocked</c></tag> <item> @@ -8075,9 +8592,9 @@ ok and <seealso marker="#system_info_schedulers"> <c>erlang:system_info(schedulers)</c></seealso>.</p> </item> - <tag><c>multi_scheduling_blockers</c></tag> + <tag><marker id="system_info_multi_scheduling_blockers"/> + <c>multi_scheduling_blockers</c></tag> <item> - <marker id="system_info_multi_scheduling_blockers"></marker> <p>Returns a list of <c><anno>Pid</anno></c>s when multi-scheduling is blocked, otherwise the empty list is returned. The <c><anno>Pid</anno></c>s in the list @@ -8095,15 +8612,9 @@ ok and <seealso marker="#system_info_schedulers"> <c>erlang:system_info(schedulers)</c></seealso>.</p> </item> - <tag><c>nif_version</c></tag> - <item> - <p>Returns a string containing the version of the Erlang NIF - interface used by the runtime system. It is on the form - "<major ver>.<minor ver>".</p> - </item> - <tag><c>normal_multi_scheduling_blockers</c></tag> + <tag><marker id="system_info_normal_multi_scheduling_blockers"/> + <c>normal_multi_scheduling_blockers</c></tag> <item> - <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 (that is, all normal schedulers but one is blocked), otherwise the empty list is returned. @@ -8121,192 +8632,9 @@ ok and <seealso marker="#system_info_schedulers"> <c>erlang:system_info(schedulers)</c></seealso>.</p> </item> - <tag><marker id="system_info_otp_release"/> - <c>otp_release</c></tag> - <item> - <marker id="system_info_otp_release"></marker> - <p>Returns a string containing the OTP release number of the - OTP release that the currently executing ERTS application - is part of.</p> - <p>As from Erlang/OTP 17, the OTP release number corresponds to - the major OTP version number. No - <c>erlang:system_info()</c> argument gives the exact OTP - version. This is because the exact OTP version in the general case - is difficult to determine. For more information, see the - description of versions in - <seealso marker="doc/system_principles:versions"> - System principles</seealso> in System Documentation.</p> - </item> - <tag><marker id="system_info_os_monotonic_time_source"/> - <c>os_monotonic_time_source</c></tag> - <item> - <p>Returns a list containing information about the source of - <seealso marker="erts:time_correction#OS_Monotonic_Time">OS - monotonic time</seealso> that is used by the runtime system.</p> - <p>If <c>[]</c> is returned, no OS monotonic time is - available. The list contains two-tuples with <c>Key</c>s - as first element, and <c>Value</c>s as second element. The - order of these tuples is undefined. The following - tuples can be part of the list, but more tuples can be - introduced in the future:</p> - <taglist> - <tag><c>{function, Function}</c></tag> - <item><p><c>Function</c> is the name of the function - used. This tuple always exists if OS monotonic time is - available to the runtime system.</p> - </item> - <tag><c>{clock_id, ClockId}</c></tag> - <item><p>This tuple only exists if <c>Function</c> - can be used with different clocks. <c>ClockId</c> - corresponds to the clock identifier used when calling - <c>Function</c>.</p> - </item> - <tag><c>{resolution, OsMonotonicTimeResolution}</c></tag> - <item><p>Highest possible - <seealso marker="time_correction#Time_Resolution"> - resolution</seealso> - of current OS monotonic time source as parts per - second. If no resolution information can be retrieved - from the OS, <c>OsMonotonicTimeResolution</c> is - set to the resolution of the time unit of - <c>Function</c>s return value. That is, the actual - resolution can be lower than - <c>OsMonotonicTimeResolution</c>. Notice that - the resolution does not say anything about the - <seealso marker="time_correction#Time_Accuracy"> - accuracy</seealso> or whether the - <seealso marker="time_correction#Time_Precision"> - precision</seealso> aligns with the resolution. You do, - however, know that the precision is not better than - <c>OsMonotonicTimeResolution</c>.</p> - </item> - <tag><c>{extended, Extended}</c></tag> - <item><p><c>Extended</c> equals <c>yes</c> if - the range of time values has been extended; - otherwise <c>Extended</c> equals <c>no</c>. The - range must be extended if <c>Function</c> - returns values that wrap fast. This typically - is the case when the return value is a 32-bit value.</p> - </item> - <tag><c>{parallel, Parallel}</c></tag> - <item><p><c>Parallel</c> equals <c>yes</c> if - <c>Function</c> is called in parallel from multiple - threads. If it is not called in parallel, because - calls must be serialized, <c>Parallel</c> equals - <c>no</c>.</p> - </item> - <tag><c>{time, OsMonotonicTime}</c></tag> - <item><p><c>OsMonotonicTime</c> equals current OS - monotonic time in <c>native</c> - <seealso marker="#type_time_unit">time unit</seealso>.</p> - </item> - </taglist> - </item> - <tag><marker id="system_info_os_system_time_source"/> - <c>os_system_time_source</c></tag> - <item> - <p>Returns a list containing information about the source of - <seealso marker="erts:time_correction#OS_System_Time">OS - system time</seealso> that is used by the runtime system.</p> - <p>The list contains two-tuples with <c>Key</c>s - as first element, and <c>Value</c>s as second element. The - order if these tuples is undefined. The following - tuples can be part of the list, but more tuples can be - introduced in the future:</p> - <taglist> - <tag><c>{function, Function}</c></tag> - <item><p><c>Function</c> is the name of the funcion used.</p> - </item> - <tag><c>{clock_id, ClockId}</c></tag> - <item><p>Exists only if <c>Function</c> - can be used with different clocks. <c>ClockId</c> - corresponds to the clock identifier used when calling - <c>Function</c>.</p> - </item> - <tag><c>{resolution, OsSystemTimeResolution}</c></tag> - <item><p>Highest possible - <seealso marker="time_correction#Time_Resolution"> - resolution</seealso> - of current OS system time source as parts per - second. If no resolution information can be retrieved - from the OS, <c>OsSystemTimeResolution</c> is - set to the resolution of the time unit of - <c>Function</c>s return value. That is, the actual - resolution can be lower than - <c>OsSystemTimeResolution</c>. Notice that - the resolution does not say anything about the - <seealso marker="time_correction#Time_Accuracy"> - accuracy</seealso> or whether the - <seealso marker="time_correction#Time_Precision"> - precision</seealso> do align with the resolution. You do, - however, know that the precision is not better than - <c>OsSystemTimeResolution</c>.</p> - </item> - <tag><c>{parallel, Parallel}</c></tag> - <item><p><c>Parallel</c> equals <c>yes</c> if - <c>Function</c> is called in parallel from multiple - threads. If it is not called in parallel, because - calls needs to be serialized, <c>Parallel</c> equals - <c>no</c>.</p> - </item> - <tag><c>{time, OsSystemTime}</c></tag> - <item><p><c>OsSystemTime</c> equals current OS - system time in <c>native</c> - <seealso marker="#type_time_unit">time unit</seealso>.</p> - </item> - </taglist> - </item> - <tag><c>port_parallelism</c></tag> - <item> - <marker id="system_info_port_parallelism"></marker> - <p>Returns the default port parallelism scheduling hint used. - For more information, see command-line argument - <seealso marker="erl#+spp"><c>+spp</c></seealso> - in <c>erl(1)</c>.</p> - </item> - <tag><marker id="system_info_port_count"/><c>port_count</c></tag> - <item> - <p>Returns the number of ports currently existing at the - local node. The value is given as an integer. This is - the same value as returned by - <c>length(erlang:ports())</c>, but more efficient.</p> - </item> - <tag><c>port_limit</c></tag> - <item> - <marker id="system_info_port_limit"></marker> - <p>Returns the maximum number of simultaneously existing - ports at the local node as an integer. This limit can be - configured at startup by using command-line flag - <seealso marker="erl#+Q"><c>+Q</c></seealso> in <c>erl(1)</c>.</p> - </item> - <tag><marker id="system_info_process_count"/> - <c>process_count</c></tag> + <tag><marker id="system_info_scheduler_bind_type"/> + <c>scheduler_bind_type</c></tag> <item> - <p>Returns the number of processes currently existing at the - local node. The value is given as an integer. This is - the same value as returned by - <c>length(processes())</c>, but more efficient.</p> - </item> - <tag><c>process_limit</c></tag> - <item> - <marker id="system_info_process_limit"></marker> - <p>Returns the maximum number of simultaneously existing - processes at the local node. The value is given as an - integer. This limit can be configured at startup by using - command-line flag <seealso marker="erl#+P"><c>+P</c></seealso> - in <c>erl(1)</c>.</p> - </item> - <tag><c>procs</c></tag> - <item> - <p>Returns a binary containing a string of process and port - information formatted as in Erlang crash dumps. For more - information, see section <seealso marker="erts:crash_dump"> - How to interpret the Erlang crash dumps</seealso> - in the User's Guide.</p> - </item> - <tag><c>scheduler_bind_type</c></tag> - <item> - <marker id="system_info_scheduler_bind_type"></marker> <p>Returns information about how the user has requested schedulers to be bound or not bound.</p> <p>Notice that although a user has requested @@ -8320,9 +8648,9 @@ ok <seealso marker="#system_info_scheduler_bindings"> <c>erlang:system_info(scheduler_bindings)</c></seealso>.</p> </item> - <tag><c>scheduler_bindings</c></tag> + <tag><marker id="system_info_scheduler_bindings"/> + <c>scheduler_bindings</c></tag> <item> - <marker id="system_info_scheduler_bindings"></marker> <p>Returns information about the currently used scheduler bindings.</p> <p>A tuple of a size equal to @@ -8346,9 +8674,9 @@ ok <seealso marker="#system_info_schedulers_online"> <c>erlang:system_info(schedulers_online)</c></seealso>.</p> </item> - <tag><c>scheduler_id</c></tag> + <tag><marker id="system_info_scheduler_id"/> + <c>scheduler_id</c></tag> <item> - <marker id="system_info_scheduler_id"></marker> <p>Returns the scheduler ID (<c>SchedulerId</c>) of the scheduler thread that the calling process is executing on. <c><anno>SchedulerId</anno></c> is a positive integer, @@ -8358,9 +8686,9 @@ ok <seealso marker="#system_info_schedulers"> <c>erlang:system_info(schedulers)</c></seealso>.</p> </item> - <tag><c>schedulers</c></tag> + <tag><marker id="system_info_schedulers"/> + <c>schedulers</c></tag> <item> - <marker id="system_info_schedulers"></marker> <p>Returns the number of scheduler threads used by the emulator. Scheduler threads online schedules Erlang processes and Erlang ports, and execute Erlang code @@ -8387,9 +8715,9 @@ ok <c>erlang:system_info(multi_scheduling_blockers)</c></seealso>. </p> </item> - <tag><c>schedulers_online</c></tag> + <tag><marker id="system_info_schedulers_online"/> + <c>schedulers_online</c></tag> <item> - <marker id="system_info_schedulers_online"></marker> <p>Returns the number of schedulers online. The scheduler identifiers of schedulers online satisfy the relationship <c><![CDATA[1 <= SchedulerId <= @@ -8401,36 +8729,18 @@ ok <c>erlang:system_flag(schedulers_online, SchedulersOnline)</c></seealso>.</p> </item> - <tag><c>smp_support</c></tag> - <item> - <p>Returns <c>true</c> if the emulator has been compiled - with SMP support, otherwise <c>false</c> is returned.</p> - </item> - <tag><marker id="system_info_start_time"/><c>start_time</c></tag> - <item> - <p>The <seealso marker="#monotonic_time/0">Erlang monotonic - time</seealso> in <c>native</c> - <seealso marker="#type_time_unit">time unit</seealso> at the - time when current Erlang runtime system instance started.</p> - <p>See also <seealso marker="#system_info_end_time"> - <c>erlang:system_info(end_time)</c></seealso>.</p> - </item> - <tag><c>system_version</c></tag> + <tag><marker id="system_info_smp_support"/> + <c>smp_support</c></tag> <item> - <p>Returns a string containing version number and - some important properties, such as the number of schedulers.</p> + <p>Returns <c>true</c>.</p> </item> - <tag><c>system_architecture</c></tag> + <tag><marker id="system_info_threads"/> + <c>threads</c></tag> <item> - <p>Returns a string containing the processor and OS - architecture the emulator is built for.</p> + <p>Returns <c>true</c>.</p> </item> - <tag><c>threads</c></tag> - <item> - <p>Returns <c>true</c> if the emulator has been compiled - with thread support, otherwise <c>false</c> is returned.</p> - </item> - <tag><c>thread_pool_size</c></tag> + <tag><marker id="system_info_thread_pool_size"/> + <c>thread_pool_size</c></tag> <item> <marker id="system_info_thread_pool_size"></marker> <p>Returns the number of async threads in the async thread @@ -8439,111 +8749,342 @@ ok <c>erl_driver:driver_async()</c></seealso>). The value is given as an integer.</p> </item> - <tag><c>time_correction</c></tag> + </taglist> + </desc> + </func> + + <func> + <name name="system_info" arity="1" clause_i="14" + anchor="system_info_dist"/> <!-- creation --> + <name name="system_info" arity="1" clause_i="16"/> <!-- delayed_node_table_gc --> + <name name="system_info" arity="1" clause_i="20"/> <!-- dist --> + <name name="system_info" arity="1" clause_i="21"/> <!-- dist_buf_busy_limit --> + <name name="system_info" arity="1" clause_i="22"/> <!-- dist_ctrl --> + <fsummary>Information about erlang distribution.</fsummary> + <desc> + <marker id="system_info_dist_tags"/> + <p>Returns information about Erlang Distribution in the + current system as specified by <c><anno>Item</anno></c>:</p> + <taglist> + <tag><marker id="system_info_creation"/> + <c>creation</c></tag> <item> - <marker id="system_info_time_correction"></marker> - <p>Returns a boolean value indicating whether - <seealso marker="time_correction#Time_Correction"> - time correction</seealso> is enabled or not.</p> + <p>Returns the creation of the local node as an integer. + The creation is changed when a node is restarted. The + creation of a node is stored in process identifiers, port + identifiers, and references. This makes it (to some + extent) possible to distinguish between identifiers from + different incarnations of a node. The valid + creations are integers in the range 1..3, but this will + probably change in a future release. If the node is not + alive, <c>0</c> is returned.</p> </item> - <tag><c>time_offset</c></tag> + <tag><marker id="system_info_delayed_node_table_gc"/> + <c>delayed_node_table_gc</c></tag> <item> - <marker id="system_info_time_offset"></marker> - <p>Returns the state of the time offset:</p> - <taglist> - <tag><c>preliminary</c></tag> - <item> - <p>The time offset is preliminary, and will be changed - and finalized later. The preliminary time offset - is used during the preliminary phase of the - <seealso marker="time_correction#Single_Time_Warp_Mode"> - single time warp mode</seealso>.</p> - </item> - <tag><c>final</c></tag> - <item> - <p>The time offset is final. This either because - <seealso marker="time_correction#No_Time_Warp_Mode"> - no time warp mode</seealso> is used, or because the time - offset have been finalized when - <seealso marker="time_correction#Single_Time_Warp_Mode"> - single time warp mode</seealso> is used.</p> - </item> - <tag><c>volatile</c></tag> - <item> - <p>The time offset is volatile. That is, it can - change at any time. This is because - <seealso marker="time_correction#Multi_Time_Warp_Mode"> - multi-time warp mode</seealso> is used.</p> - </item> - </taglist> + <p>Returns the amount of time in seconds garbage collection + of an entry in a node table is delayed. This limit can be set + on startup by passing command-line flag + <seealso marker="erts:erl#+zdntgc"><c>+zdntgc</c></seealso> + to <c>erl(1)</c>. For more information, see the documentation of + the command-line flag.</p> </item> - <tag><marker id="system_info_time_warp_mode"/> - <c>time_warp_mode</c></tag> + <tag><marker id="system_info_dist"/> + <c>dist</c></tag> <item> - <p>Returns a value identifying the - <seealso marker="time_correction#Time_Warp_Modes"> - time warp mode</seealso> that is used:</p> - <taglist> - <tag><c>no_time_warp</c></tag> - <item>The <seealso marker="time_correction#No_Time_Warp_Mode"> - no time warp mode</seealso> is used. - </item> - <tag><c>single_time_warp</c></tag> - <item>The <seealso marker="time_correction#Single_Time_Warp_Mode"> - single time warp mode</seealso> is used. - </item> - <tag><c>multi_time_warp</c></tag> - <item>The <seealso marker="time_correction#Multi_Time_Warp_Mode"> - multi-time warp mode</seealso> is used. - </item> - </taglist> + <p>Returns a binary containing a string of distribution + information formatted as in Erlang crash dumps. For more + information, see section <seealso marker="erts:crash_dump"> + How to interpret the Erlang crash dumps</seealso> + in the User's Guide.</p> </item> - <tag><c>tolerant_timeofday</c></tag> + <tag><marker id="system_info_dist_buf_busy_limit"/> + <c>dist_buf_busy_limit</c></tag> <item> - <marker id="system_info_tolerant_timeofday"></marker> - <p>Returns whether a pre ERTS 7.0 backwards compatible - compensation for sudden changes of system time is <c>enabled</c> - or <c>disabled</c>. Such compensation is <c>enabled</c> when the - <seealso marker="#system_info_time_offset">time offset</seealso> - is <c>final</c>, and - <seealso marker="#system_info_time_correction"> - time correction</seealso> is enabled.</p> + <p>Returns the value of the distribution buffer busy limit + in bytes. This limit can be set at startup by passing + command-line flag + <seealso marker="erts:erl#+zdbbl"><c>+zdbbl</c></seealso> + to <c>erl(1)</c>.</p> + </item> + <tag><marker id="system_info_dist_ctrl"/> + <c>dist_ctrl</c></tag> + <item> + <p>Returns a list of tuples + <c>{<anno>Node</anno>, <anno>ControllingEntity</anno>}</c>, + one entry for each connected remote node. + <c><anno>Node</anno></c> is the node name + and <c><anno>ControllingEntity</anno></c> is the port or process + identifier responsible for the communication to that node. + More specifically, <c><anno>ControllingEntity</anno></c> for + nodes connected through TCP/IP (the normal case) is the socket + used in communication with the specific node.</p> + </item> + </taglist> + </desc> + </func> + + <func> + <!-- <name name="system_info" arity="1" clause_i="1"/> allocated_areas --> + <!-- <name name="system_info" arity="1" clause_i="2"/> allocated --> + <!-- <name name="system_info" arity="1" clause_i="3"/> {allocator, _} --> + <!-- <name name="system_info" arity="1" clause_i="4"/> alloc_util_allocators --> + <!-- <name name="system_info" arity="1" clause_i="5"/> {allocator_sizes, _} --> + <!-- <name name="system_info" arity="1" clause_i="6"/> atom_count --> + <!-- <name name="system_info" arity="1" clause_i="7"/> atom_limit --> + <name name="system_info" arity="1" clause_i="8" + anchor="system_info_misc"/> <!-- build_type --> + <name name="system_info" arity="1" clause_i="9"/> <!-- c_compiler_used --> + <name name="system_info" arity="1" clause_i="10"/> <!-- check_io --> + <name name="system_info" arity="1" clause_i="11"/> <!-- compat_rel --> + <!-- <name name="system_info" arity="1" clause_i="12"/> cpu_topology --> + <!-- <name name="system_info" arity="1" clause_i="13"/> {cpu_topology, _} --> + <!-- <name name="system_info" arity="1" clause_i="14"/> creation --> + <name name="system_info" arity="1" clause_i="15"/> <!-- debug_compiled --> + <!-- <name name="system_info" arity="1" clause_i="16"/> delayed_node_table_gc --> + <!-- <name name="system_info" arity="1" clause_i="17"/> dirty_cpu_schedulers --> + <!-- <name name="system_info" arity="1" clause_i="18"/> dirty_cpu_schedulers_online --> + <!-- <name name="system_info" arity="1" clause_i="19"/> dirty_io_schedulers --> + <!-- <name name="system_info" arity="1" clause_i="20"/> dist --> + <!-- <name name="system_info" arity="1" clause_i="21"/> dist_buf_busy_limit --> + <!-- <name name="system_info" arity="1" clause_i="22"/> dist_ctrl --> + <name name="system_info" arity="1" clause_i="23"/> <!-- driver_version --> + <name name="system_info" arity="1" clause_i="24"/> <!-- dynamic_trace --> + <name name="system_info" arity="1" clause_i="25"/> <!-- dynamic_trace_probes --> + <!-- <name name="system_info" arity="1" clause_i="26"/> end_time --> + <!-- <name name="system_info" arity="1" clause_i="27"/> elib_malloc --> + <!-- <name name="system_info" arity="1" clause_i="28"/> eager_check_io, removed --> + <!-- <name name="system_info" arity="1" clause_i="29"/> ets_count --> + <!-- <name name="system_info" arity="1" clause_i="30"/> ets_limit --> + <!-- <name name="system_info" arity="1" clause_i="31"/> fullsweep_after --> + <!-- <name name="system_info" arity="1" clause_i="32"/> garbage_collection --> + <!-- <name name="system_info" arity="1" clause_i="33"/> heap_sizes --> + <!-- <name name="system_info" arity="1" clause_i="34"/> heap_type --> + <name name="system_info" arity="1" clause_i="35"/> <!-- info --> + <name name="system_info" arity="1" clause_i="36"/> <!-- kernel_poll --> + <name name="system_info" arity="1" clause_i="37"/> <!-- loaded --> + <!-- <name name="system_info" arity="1" clause_i="38"/> logical_processors --> + <name name="system_info" arity="1" clause_i="39"/> <!-- machine --> + <!-- <name name="system_info" arity="1" clause_i="40"/> max_heap_size --> + <!-- <name name="system_info" arity="1" clause_i="41"/> message_queue_data --> + <!-- <name name="system_info" arity="1" clause_i="42"/> min_heap_size --> + <!-- <name name="system_info" arity="1" clause_i="43"/> min_bin_vheap_size --> + <name name="system_info" arity="1" clause_i="44"/> <!-- modified_timing_level --> + <!-- <name name="system_info" arity="1" clause_i="45"/> multi_scheduling --> + <!-- <name name="system_info" arity="1" clause_i="46"/> multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="47"/> <!-- nif_version --> + <!-- n<name name="system_info" arity="1" clause_i="48"/> ormal_multi_scheduling_blockers --> + <name name="system_info" arity="1" clause_i="49"/> <!-- otp_release --> + <!-- <name name="system_info" arity="1" clause_i="50"/> os_monotonic_time_source --> + <!-- <name name="system_info" arity="1" clause_i="51"/> os_system_time_source --> + <name name="system_info" arity="1" clause_i="52"/> <!-- port_parallelism --> + <!-- <name name="system_info" arity="1" clause_i="53"/> port_count --> + <!-- <name name="system_info" arity="1" clause_i="54"/> port_limit --> + <!-- <name name="system_info" arity="1" clause_i="55"/> process_count --> + <!-- <name name="system_info" arity="1" clause_i="56"/> process_limit --> + <!-- <name name="system_info" arity="1" clause_i="57"/> procs --> + <!-- <name name="system_info" arity="1" clause_i="58"/> scheduler_bind_type --> + <!-- <name name="system_info" arity="1" clause_i="59"/> scheduler_bindings --> + <!-- <name name="system_info" arity="1" clause_i="60"/> scheduler_id --> + <!-- <name name="system_info" arity="1" clause_i="61"/> schedulers --> + <!-- <name name="system_info" arity="1" clause_i="62"/> smp_support --> + <!-- <name name="system_info" arity="1" clause_i="63"/> start_time --> + <name name="system_info" arity="1" clause_i="64"/> <!-- system_version --> + <name name="system_info" arity="1" clause_i="65"/> <!-- system_architecture --> + <!-- <name name="system_info" arity="1" clause_i="66"/> threads --> + <!-- <name name="system_info" arity="1" clause_i="67"/> thread_pool_size --> + <!-- <name name="system_info" arity="1" clause_i="68"/> time_correction --> + <!-- <name name="system_info" arity="1" clause_i="69"/> time_offset --> + <!-- <name name="system_info" arity="1" clause_i="70"/> time_warp_mode --> + <!-- <name name="system_info" arity="1" clause_i="71"/> tolerant_timeofday --> + <name name="system_info" arity="1" clause_i="72"/> <!-- trace_control_word --> + <!-- <name name="system_info" arity="1" clause_i="73"/> update_cpu_info --> + <name name="system_info" arity="1" clause_i="74"/> <!-- version --> + <name name="system_info" arity="1" clause_i="75"/> <!-- wordsize --> + <!-- <name name="system_info" arity="1" clause_i="76"/> overview --> + <fsummary>Information about the system.</fsummary> + <desc> + <marker id="system_info_misc_tags"/> + <p>Returns various information about the current system + (emulator) as specified by <c><anno>Item</anno></c>:</p> + <taglist> + <tag><marker id="system_info_build_type"/> + <c>build_type</c></tag> + <item> + <p>Returns an atom describing the build type of the runtime + system. This is normally the atom <c>opt</c> for optimized. + Other possible return values are <c>debug</c>, <c>purify</c>, + <c>quantify</c>, <c>purecov</c>, <c>gcov</c>, <c>valgrind</c>, + <c>gprof</c>, and <c>lcnt</c>. Possible return values + can be added or removed at any time without prior notice.</p> + </item> + <tag><marker id="system_info_c_compiler_used"/> + <c>c_compiler_used</c></tag> + <item> + <p>Returns a two-tuple describing the C compiler used when + compiling the runtime system. The first element is an + atom describing the name of the compiler, or <c>undefined</c> + if unknown. The second element is a term describing the + version of the compiler, or <c>undefined</c> if unknown.</p> + </item> + <tag><marker id="system_info_check_io"/> + <c>check_io</c></tag> + <item> + <p>Returns a list containing miscellaneous information + about the emulators internal I/O checking. Notice that + the content of the returned list can vary between + platforms and over time. It is only guaranteed + that a list is returned.</p> + </item> + <tag><marker id="system_info_compat_rel"/> + <c>compat_rel</c></tag> + <item> + <p>Returns the compatibility mode of the local node as + an integer. The integer returned represents the + Erlang/OTP release that the current emulator has been + set to be backward compatible with. The compatibility + mode can be configured at startup by using command-line flag + <seealso marker="erts:erl#compat_rel"><c>+R</c></seealso> in + <c>erl(1)</c>.</p> + </item> + <tag><marker id="system_info_debug_compiled"/> + <c>debug_compiled</c></tag> + <item> + <p>Returns <c>true</c> if the emulator has been + debug-compiled, otherwise <c>false</c>.</p> + </item> + <tag><marker id="system_info_driver_version"/> + <c>driver_version</c></tag> + <item> + <p>Returns a string containing the Erlang driver version + used by the runtime system. It has the form + <seealso marker="erts:erl_driver#version_management"> + "<major ver>.<minor ver>"</seealso>.</p> + </item> + <tag><marker id="system_info_dynamic_trace"/> + <c>dynamic_trace</c></tag> + <item> + <p>Returns an atom describing the dynamic trace framework + compiled into the virtual machine. It can be + <c>dtrace</c>, <c>systemtap</c>, or <c>none</c>. For a + commercial or standard build, it is always <c>none</c>. + The other return values indicate a custom configuration + (for example, <c>./configure --with-dynamic-trace=dtrace</c>). + For more information about dynamic tracing, see + <seealso marker="runtime_tools:dyntrace"> + <c>dyntrace(3)</c></seealso> manual page and the + <c>README.dtrace</c>/<c>README.systemtap</c> files in the + Erlang source code top directory.</p> + </item> + <tag><marker id="system_info_dynamic_trace_probes"/> + <c>dynamic_trace_probes</c></tag> + <item> + <p>Returns a <c>boolean()</c> indicating if dynamic trace + probes (<c>dtrace</c> or <c>systemtap</c>) are built into + the emulator. This can only be <c>true</c> if the virtual + machine was built for dynamic tracing (that is, + <c>system_info(dynamic_trace)</c> returns + <c>dtrace</c> or <c>systemtap</c>).</p> + </item> + <tag><marker id="system_info_info"/> + <c>info</c></tag> + <item> + <p>Returns a binary containing a string of miscellaneous + system information formatted as in Erlang crash dumps. + For more information, see section + <seealso marker="erts:crash_dump"> + How to interpret the Erlang crash dumps</seealso> + in the User's Guide.</p> + </item> + <tag><marker id="system_info_kernel_poll"/> + <c>kernel_poll</c></tag> + <item> + <p>Returns <c>true</c> if the emulator uses some kind of + kernel-poll implementation, otherwise <c>false</c>.</p> + </item> + <tag><marker id="system_info_loaded"/> + <c>loaded</c></tag> + <item> + <p>Returns a binary containing a string of loaded module + information formatted as in Erlang crash dumps. For more + information, see section + <seealso marker="erts:crash_dump">How to interpret the Erlang + crash dumps</seealso> in the User's Guide.</p> + </item> + <tag><marker id="system_info_machine"/> + <c>machine</c></tag> + <item> + <p>Returns a string containing the Erlang machine name.</p> + </item> + <tag><marker id="system_info_modified_timing_level"/> + <c>modified_timing_level</c></tag> + <item> + <p>Returns the modified timing-level (an integer) if + modified timing is enabled, otherwise <c>undefined</c>. + For more information about modified timing, see + command-line flag + <seealso marker="erts:erl#+T"><c>+T</c></seealso> + in <c>erl(1)</c></p> + </item> + <tag><marker id="system_info_nif_version"/> + <c>nif_version</c></tag> + <item> + <p>Returns a string containing the version of the Erlang NIF + interface used by the runtime system. It is on the form + "<major ver>.<minor ver>".</p> + </item> + <tag><marker id="system_info_otp_release"/> + <c>otp_release</c></tag> + <item> + <marker id="system_info_otp_release"></marker> + <p>Returns a string containing the OTP release number of the + OTP release that the currently executing ERTS application + is part of.</p> + <p>As from Erlang/OTP 17, the OTP release number corresponds to + the major OTP version number. No + <c>erlang:system_info()</c> argument gives the exact OTP + version. This is because the exact OTP version in the general case + is difficult to determine. For more information, see the + description of versions in + <seealso marker="doc/system_principles:versions"> + System principles</seealso> in System Documentation.</p> </item> - <tag><c>trace_control_word</c></tag> + <tag><marker id="system_info_port_parallelism"/> + <c>port_parallelism</c></tag> + <item> + <p>Returns the default port parallelism scheduling hint used. + For more information, see command-line argument + <seealso marker="erl#+spp"><c>+spp</c></seealso> + in <c>erl(1)</c>.</p> + </item> + <tag><marker id="system_info_system_version"/> + <c>system_version</c></tag> + <item> + <p>Returns a string containing version number and + some important properties, such as the number of schedulers.</p> + </item> + <tag><marker id="system_info_system_architecture"/> + <c>system_architecture</c></tag> + <item> + <p>Returns a string containing the processor and OS + architecture the emulator is built for.</p> + </item> + <tag><marker id="system_info_trace_control_word"/> + <c>trace_control_word</c></tag> <item> <p>Returns the value of the node trace control word. For more information, see function <c>get_tcw</c> in section <seealso marker="erts:match_spec#get_tcw"> Match Specifications in Erlang</seealso> in the User's Guide.</p> </item> - <tag><c>update_cpu_info</c></tag> + <tag><marker id="system_info_version"/> + <c>version</c></tag> <item> - <marker id="update_cpu_info"></marker> - <p>The runtime system rereads the CPU information available - and updates its internally stored information about the - <seealso marker="#system_info_cpu_topology_detected">detected - CPU topology</seealso> and the number of logical processors - <seealso marker="#logical_processors">configured</seealso>, - <seealso marker="#logical_processors_online">online</seealso>, - and <seealso marker="#logical_processors_available"> - available</seealso>.</p> - <p>If the CPU information has changed since the last time - it was read, the atom <c>changed</c> is returned, otherwise - the atom <c>unchanged</c>. If the CPU information has changed, - you probably want to - <seealso marker="#system_flag_schedulers_online">adjust the - number of schedulers online</seealso>. You typically want - to have as many schedulers online as - <seealso marker="#logical_processors_available">logical - processors available</seealso>.</p> - </item> - <tag><c>version</c></tag> - <item> - <marker id="system_info_version"></marker> <p>Returns a string containing the version number of the emulator.</p> </item> - <tag><c>wordsize</c></tag> + <tag><marker id="system_info_wordsize"/> + <c>wordsize</c></tag> <item> <p>Same as <c>{wordsize, internal}</c>.</p> </item> @@ -8565,13 +9106,6 @@ ok 64-bit architecture, 8 is returned.</p> </item> </taglist> - <note> - <p>Argument <c>scheduler</c> has changed name to - <c>scheduler_id</c> to avoid mix up with argument - <c>schedulers</c>. Argument <c>scheduler</c> was - introduced in ERTS 5.5 and renamed in - ERTS 5.5.1.</p> - </note> </desc> </func> @@ -10551,9 +11085,9 @@ true</pre> <c>receive after 1 -> ok end</c>, except that <c>yield()</c> is faster.</p> <warning> - <p>There is seldom or never any need to use this BIF, - especially in the SMP emulator, as other processes have a - chance to run in another scheduler thread anyway. + <p>There is seldom or never any need to use this BIF + as other processes have a chance to run in another scheduler + thread anyway. Using this BIF without a thorough grasp of how the scheduler works can cause performance degradation.</p> </warning> @@ -10561,4 +11095,3 @@ true</pre> </func> </funcs> </erlref> - diff --git a/erts/doc/src/erlc.xml b/erts/doc/src/erlc.xml index 7355be488b..be9b4e8d97 100644 --- a/erts/doc/src/erlc.xml +++ b/erts/doc/src/erlc.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1997</year><year>2016</year> + <year>1997</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -143,6 +143,14 @@ <p>Produces a Makefile rule to track header dependencies. The rule is sent to <c>stdout</c>. No object file is produced.</p> </item> + + <tag><c>-MMD</c></tag> + <item> + <p>Generate dependencies as a side-effect. The object file + will be produced as normal. This option overrides the + option <c><![CDATA[-M]]></c>.</p> + </item> + <tag><c>-MF <Makefile></c></tag> <item> <p>As option <c><![CDATA[-M]]></c>, except that the diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml index ce8d75f350..a094217959 100644 --- a/erts/doc/src/erts_alloc.xml +++ b/erts/doc/src/erts_alloc.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2002</year><year>2017</year> + <year>2002</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -68,8 +68,7 @@ fixed size data types.</item> <tag><c>exec_alloc</c></tag> <item>Allocator used by the <seealso marker="hipe:HiPE_app"><c>HiPE</c></seealso> - application for native executable code on specific architectures - (x86_64).</item> + application for native executable code.</item> <tag><c>std_alloc</c></tag> <item>Allocator used for most memory blocks not allocated through any of the other allocators described above.</item> @@ -87,9 +86,9 @@ the number of system calls made.</item> </taglist> - <p><c>sys_alloc</c> and <c>literal_alloc</c> are always enabled and - cannot be disabled. <c>exec_alloc</c> is only available if it is needed - and cannot be disabled. <c>mseg_alloc</c> is always enabled if it is + <p><c>sys_alloc</c>, <c>literal_alloc</c> and <c>temp_alloc</c> are always + enabled and cannot be disabled. <c>exec_alloc</c> is only available if it + is needed 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>. By default all allocators are enabled. @@ -560,6 +559,20 @@ than this threshold, otherwise the carrier is shrunk. See also <seealso marker="#M_rsbcst"><c>rsbcst</c></seealso>.</p> </item> + <tag><marker id="M_atags"/><c><![CDATA[+M<S>atags true|false]]></c></tag> + <item> + <p>Adds a small tag to each allocated block that contains basic + information about what it is and who allocated it. Use the + <seealso marker="tools:instrument"><c>instrument</c></seealso> + module to inspect this information.</p> + + <p>The runtime overhead is one word per allocation when enabled. This + may change at any time in the future.</p> + + <p>The default is <c>true</c> for <c>binary_alloc</c> and + <c>driver_alloc</c>, and <c>false</c> for the other allocator + types.</p> + </item> <tag><marker id="M_e"/><c><![CDATA[+M<S>e true|false]]></c></tag> <item> <p>Enables allocator <c><![CDATA[<S>]]></c>.</p> @@ -723,37 +736,14 @@ </section> <section> - <title>Special Flag for exec_alloc</title> - <taglist> - <tag><marker id="MXscs"/><c><![CDATA[+MXscs <size in MB>]]></c></tag> - <item> - <p><c>exec_alloc</c> super carrier size (in MB). The amount of - <em>virtual</em> address space reserved for native executable code - used by the <seealso marker="hipe:HiPE_app"><c>HiPE</c></seealso> application - on specific architectures (x86_64). Defaults to <c>512</c>.</p> - </item> - </taglist> - </section> - - <section> <title>Instrumentation Flags</title> <taglist> - <tag><marker id="Mim"/><c>+Mim true|false</c></tag> - <item> - <p>A map over current allocations is kept by the emulator. - The allocation map can be retrieved through module - <seealso marker="tools:instrument"> - <c>instrument(3)</c></seealso>. <c>+Mim true</c> - implies <c>+Mis true</c>. <c>+Mim true</c> is the same as flag - <seealso marker="erl#instr"><c>-instr</c></seealso> in - <c>erl(1)</c>.</p> - </item> - <tag><marker id="Mis"/><c>+Mis true|false</c></tag> - <item> - <p>Status over allocated memory is kept by the emulator. - The allocation status can be retrieved through module - <seealso marker="tools:instrument"> - <c>instrument(3)</c></seealso>.</p> + <tag><c>+M<S>atags</c></tag> + <item> + <p>Adds a small tag to each allocated block that contains basic + information about what it is and who allocated it. See + <seealso marker="#M_atags"><c>+M<S>atags</c></seealso> for a + more complete description.</p> </item> <tag><marker id="Mit"/><c>+Mit X</c></tag> <item> diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml index 2a14f1e47b..5cd6dc1750 100644 --- a/erts/doc/src/match_spec.xml +++ b/erts/doc/src/match_spec.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1999</year><year>2016</year> + <year>1999</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -86,12 +86,12 @@ <c><![CDATA[is_list]]></c> | <c><![CDATA[is_number]]></c> | <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> | <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> | - <c><![CDATA[is_map]]></c> | <c><![CDATA[is_binary]]></c> | - <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> | - <c><![CDATA[is_seq_trace]]></c> | <c><![CDATA['and']]></c> | - <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> | - <c><![CDATA['xor']]></c> | <c><![CDATA['andalso']]></c> | - <c><![CDATA['orelse']]></c> + <c><![CDATA[is_map]]></c> | <c><![CDATA[is_map_key]]></c> | + <c><![CDATA[is_binary]]></c> | <c><![CDATA[is_function]]></c> | + <c><![CDATA[is_record]]></c> | <c><![CDATA[is_seq_trace]]></c> | + <c><![CDATA['and']]></c> | <c><![CDATA['or']]></c> | + <c><![CDATA['not']]></c> | <c><![CDATA['xor']]></c> | + <c><![CDATA['andalso']]></c> | <c><![CDATA['orelse']]></c> </item> <item>ConditionExpression ::= ExprMatchVariable | { GuardFunction } | { GuardFunction, ConditionExpression, ... } | TermConstruct @@ -110,7 +110,8 @@ </item> <item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> | <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> | - <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> | + <c><![CDATA[length]]></c> | <c><![CDATA[map_get]]></c> | + <c><![CDATA[map_size]]></c> | <c><![CDATA[node]]></c> | <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> | <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | @@ -167,9 +168,9 @@ <c><![CDATA[is_list]]></c> | <c><![CDATA[is_number]]></c> | <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> | <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> | - <c><![CDATA[is_map]]></c> | <c><![CDATA[is_binary]]></c> | - <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> | - <c><![CDATA[is_seq_trace]]></c> | <c><![CDATA['and']]></c> | + <c><![CDATA[is_map]]></c> | <c><![CDATA[map_is_key]]></c> | + <c><![CDATA[is_binary]]></c> | <c><![CDATA[is_function]]></c> | + <c><![CDATA[is_record]]></c> | <c><![CDATA['and']]></c> | <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> | <c><![CDATA['xor']]></c> | <c><![CDATA['andalso']]></c> | <c><![CDATA['orelse']]></c> @@ -190,7 +191,8 @@ </item> <item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> | <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> | - <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> | + <c><![CDATA[length]]></c> | <c><![CDATA[map_get]]></c> | + <c><![CDATA[map_size]]></c> | <c><![CDATA[node]]></c> | <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> | <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | @@ -202,8 +204,7 @@ <c><![CDATA['>=']]></c> | <c><![CDATA['<']]></c> | <c><![CDATA['=<']]></c> | <c><![CDATA['=:=']]></c> | <c><![CDATA['==']]></c> | <c><![CDATA['=/=']]></c> | - <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> | - <c><![CDATA[get_tcw]]></c> + <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> </item> <item>MatchBody ::= [ ConditionExpression, ... ] </item> @@ -405,7 +406,8 @@ <c><![CDATA[tracer]]></c>.</p> <p>If a tracer is specified in both lists, the tracer in the enable list takes precedence. If no tracer is specified, the same - tracer as the process executing the match specification is used.</p> + tracer as the process executing the match specification is used (not the meta tracer). + If that process doesn't have tracer either, then trace flags are ignored.</p> <p>When using a <seealso marker="erl_tracer">tracer module</seealso>, the module must be loaded before the match specification is executed. If it is not loaded, the match fails.</p> @@ -866,4 +868,3 @@ can be useful for testing complicated ETS matches.</p> </section> </chapter> - diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 4913b0f204..f1f5831cec 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2004</year><year>2017</year> + <year>2004</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,6 +31,1030 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 10.0.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a bug that prevented the <c>noshell</c> option + from working correctly on Mac OS X and BSD.</p> + <p> + Own Id: OTP-15169</p> + </item> + <item> + <p>Fixed a crash when matching directly against a literal + map using a single key that had been saved on the + stack.</p> + <p> + Own Id: OTP-15184</p> + </item> + <item> + <p>Fix node crash when passing a bad time option to + <c>file:read_file_info/2</c>.</p> + <p> + Own Id: OTP-15196</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a scheduler bug that caused normal schedulers to + run dirty code.</p> + <p> + Own Id: OTP-15154</p> + </item> + <item> + <p> + Fixed a bug in <c>erlang:trace_info/2</c> which caused + the emulator to crash when a bad argument was passed. The + bug was introduced in ERTS version 10.0.</p> + <p> + Own Id: OTP-15183 Aux Id: ERL-670 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a rare bug that could cause processes to be + scheduled after they had been freed.</p> + <p> + Own Id: OTP-15067 Aux Id: ERL-573 </p> + </item> + <item> + <p>Fixed a race condition in the inet driver that could + cause receive to hang when the emulator was compiled with + gcc 8.</p> + <p> + Own Id: OTP-15158 Aux Id: ERL-654 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The keys used in <c>os:getenv</c> and <c>os:putenv</c> + are case-insensitive again on Windows.</p> + <p> + Own Id: OTP-15147 Aux Id: ERL-644 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 10.0</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The type specifications for <c>file:posix/0</c> and + <c>inet:posix/0</c> have been updated according to which + errors file and socket operations should be able to + return.</p> + <p> + Own Id: OTP-14019 Aux Id: ERL-550 </p> + </item> + <item> + <p> + Fix error printout from run_erl and a bug that could + cause unintended fds to be leaked into the started + program.</p> + <p> + Own Id: OTP-14537 Aux Id: PR1529 </p> + </item> + <item> + <p> File operations used to accept <seealso + marker="kernel:file#type-name_all">filenames</seealso> + containing null characters (integer value zero). This + caused the name to be truncated and in some cases + arguments to primitive operations to be mixed up. + Filenames containing null characters inside the filename + are now <em>rejected</em> and will cause primitive file + operations to fail. </p> <p> Also environment variable + operations used to accept <seealso + marker="kernel:os#type-env_var_name">names</seealso> and + <seealso + marker="kernel:os#type-env_var_value">values</seealso> of + environment variables containing null characters (integer + value zero). This caused operations to silently produce + erroneous results. Environment variable names and values + containing null characters inside the name or value are + now <em>rejected</em> and will cause environment variable + operations to fail. </p> <p>Primitive environment + variable operations also used to accept the <c>$=</c> + character in environment variable names causing various + problems. <c>$=</c> characters in environment variable + names are now also <em>rejected</em>. </p> <p>Also + <seealso + marker="kernel:os#cmd/1"><c>os:cmd/1</c></seealso> now + reject null characters inside its <seealso + marker="kernel:os#type-os_command">command</seealso>. + </p> <p><seealso + marker="erts:erlang#open_port/2"><c>erlang:open_port/2</c></seealso> + will also reject null characters inside the port name + from now on.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14543 Aux Id: ERL-370 </p> + </item> + <item> + <p> + Fix bugs related to the bookkeeping of microstate + accounting states.</p> + <p> + Own Id: OTP-14652</p> + </item> + <item> + <p><c>os:putenv</c> and <c>os:getenv</c> no longer access + the process environment directly and instead work on a + thread-safe emulation. The only observable difference is + that it's <em>not</em> kept in sync with libc + <c>getenv(3)</c> / <c>putenv(3)</c>, so those who relied + on that behavior in drivers or NIFs will need to add + manual synchronization.</p> <p>On Windows this means that + you can no longer resolve DLL dependencies by modifying + the <c>PATH</c> just before loading the driver/NIF. To + make this less of a problem, the emulator now adds the + target DLL's folder to the DLL search path.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14666</p> + </item> + <item> + <p>Corrected <c>erlang:is_builtin(erlang, M, F)</c> to + return <c>true</c> for <c>apply/2</c> and + <c>yield/0</c>.</p> + <p> + Own Id: OTP-14713 Aux Id: ERL-500 </p> + </item> + <item> + <p>Fixed a bug where the PATH environment variable wasn't + updated correctly on a release downgrade, effectively + keeping the PATH of the new release.</p> + <p> + Own Id: OTP-14719</p> + </item> + <item> + <p>A receive optimization that avoids scanning the entire + message queue when receiving a message containing a + freshly created reference could in rare circumstances + (involving recursive calls to the functions that does the + receive) cause the receive to hang. This has been + corrected.</p> + <p> + Own Id: OTP-14782 Aux Id: ERL-511 </p> + </item> + <item> + <p> + Fix building of Erlang/OTP on platforms which have small + data area with short addressing. For example the + PowerPC/RTEMS platform.</p> + <p> + Own Id: OTP-14909 Aux Id: PR-1692 </p> + </item> + <item> + <p>Fixed a crash when <c>enif_make_binary</c> is called + with a binary produced by <c>enif_inspect_binary</c> in a + different environment.</p> + <p> + Own Id: OTP-14931</p> + </item> + <item> + <p>Fixed a crash when <c>enif_make_binary</c> is called + more than once with a binary that had previously been + added to an <c>enif_ioq</c>.</p> + <p> + Own Id: OTP-14932</p> + </item> + <item> + <p> + The erl_child_setup program now ignores SIGTERM signals.</p> + <p> + Own Id: OTP-14943 Aux Id: ERL-576 </p> + </item> + <item> + <p> + Force 64-bit alignment on pre-allocators on architectures + which needs it.</p> + <p> + Own Id: OTP-14977</p> + </item> + <item> + <p> + Fixed a bug where dirty scheduler picked up non-dirty + work.</p> + <p> + Own Id: OTP-14978</p> + </item> + <item> + <p> + Calls to <c>gen_tcp:send/2</c> on closed sockets now + returns <c>{error, closed}</c> instead of + <c>{error,enotconn}</c>.</p> + <p> + Own Id: OTP-15001</p> + </item> + <item> + <p> + <c>erlang:monotonic_time/1</c> failed with <c>badarg</c> + when passing the <c>perf_counter</c> time unit as + argument.</p> + <p> + Own Id: OTP-15008</p> + </item> + <item> + <p> + Fix bug where rapid <c>init:restart()</c> calls would + sometimes crash because a code load request leaked in + between the restarts.</p> + <p> + Own Id: OTP-15013</p> + </item> + <item> + <p> + Improve <c>float_to_list(F, [{decimals,D}])</c> to closer + conform with <c>io_lib:format("~.*f", [D,F])</c>.</p> + <p> + There are however, still cases when <c>float_to_list</c> + does not produce the exact same result as + <c>io_lib:format</c>, especially for large values + <c>F</c> and/or many decimals <c>D</c>.</p> + <p> + Own Id: OTP-15015 Aux Id: OTP-14890 </p> + </item> + <item> + <p>Fixed a deadlock that would occur on certain + allocators when a reallocation failed with <c>+ramv</c> + enabled.</p> + <p> + Own Id: OTP-15024</p> + </item> + <item> + <p> + Fix bug that made it impossible to use an erl_tracer as + the seq_trace trace receiver.</p> + <p> + Own Id: OTP-15029</p> + </item> + <item> + <p> + Fix bug where a large (> 1 GB) emulator generated error + logger message would cause the emulator to crash.</p> + <p> + Own Id: OTP-15032</p> + </item> + <item> + <p>The emulator will no longer crash when reading the + file information of an ordinary file that has an NTFS + reparse point, such as files stored in a OneDrive-mapped + folder.</p> + <p> + Own Id: OTP-15062 Aux Id: ERL-615 </p> + </item> + <item> + <p> + Fixed bug in <c>enif_binary_to_term</c> which could cause + memory corruption for immediate terms (atoms, small + integers, pids, ports, empty lists).</p> + <p> + Own Id: OTP-15080</p> + </item> + <item> + <p> + Fixed bug in <c>erlang:system_profile/2</c> that could + cause superfluous <c>{profile,_,active,_,_}</c> messages + for terminating processes.</p> + <p> + Own Id: OTP-15085</p> + </item> + <item> + <p> + On OSs with per thread CPU time support, change + <c>cpu_timestamp</c> in <seealso + marker="erlang#trace/3">erlang:trace/3</seealso> to use + it instead of per process CPU time. This makes this + option useable on such OSs when running multiple + schedulers.</p> + <p> + Own Id: OTP-15090</p> + </item> + <item> + <p> + Fix segfault in abort_signal_task which could happen if a + port terminated while there were outstanding port tasks + that were not signals, for example a + ready_input/ready_output event.</p> + <p> + Own Id: OTP-15108 Aux Id: ERL-621 </p> + </item> + <item> + <p> + Fixed bug in <c>ets</c> that could cause VM crash if + process A terminates after fixating a table and process B + deletes the table at "the same time". The table fixation + could be done with <c>ets:safe_fixtable</c> or if process + A terminates in the middle of a long running + <c>select</c> or <c>match</c> call.</p> + <p> + Own Id: OTP-15109</p> + </item> + <item> + <p>Owner and group changes through + <c>file:write_file_info</c>, <c>file:change_owner</c>, + and <c>file:change_group</c> will no longer report + success on permission errors.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15118</p> + </item> + <item> + <p> + Fix a bug error reporting from escripts on windows where + the error message would get garbled.</p> + <p> + Own Id: OTP-15119 Aux Id: PR-1826 </p> + </item> + <item> + <p> + Fix segfault when a process is interally re-scheduled + while being traced for in out events. This bug was + introduced in erts-8.0 (OTP-19.0).</p> + <p> + Own Id: OTP-15125</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>It is now possible to open device files and FIFOs with + <c>file:open/2</c>.</p> + <p> + Own Id: OTP-11462</p> + </item> + <item> + <p> + The <c>erlang:system_flag(scheduler_wall_time,Bool)</c> + call is now reference counted and will be turned off if + the (last) process that started the performance + statistics dies. Thus it is no longer possible to start + the statistics with <c>rpc:call(Node, erlang, + system_flag, [scheduler_wall_time, true])</c> since it + will be turned off directly afterwards when the rpc + process dies.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-11694</p> + </item> + <item> + <p>A new logging API is added to Erlang/OTP, see the + <seealso + marker="kernel:logger"><c>logger(3)</c></seealso> manual + page, and section <seealso + marker="kernel:logger_chapter">Logging</seealso> in the + Kernel User's Guide.</p> + <p>Calls to <c>error_logger</c> are automatically + redirected to the new API, and legacy error logger event + handlers can still be used. It is, however, recommended + to use the Logger API directly when writing new code.</p> + <p>Notice the following potential incompatibilities:</p> + <list> <item><p>Kernel configuration parameters + <c>error_logger</c> still works, but is overruled if the + default handler's output destination is configured with + Kernel configuration parameter <c>logger</c>.</p> <p>In + general, parameters for configuring error logger are + overwritten by new parameters for configuring + Logger.</p></item> <item><p>The concept of SASL error + logging is deprecated, meaning that by default the SASL + application does not affect which log events are + logged.</p> <p>By default, supervisor reports and crash + reports are logged by the default Logger handler started + by Kernel, and end up at the same destination (terminal + or file) as other standard log event from Erlang/OTP.</p> + <p>Progress reports are not logged by default, but can be + enabled by setting the primary log level to info, for + example with the Kernel configuration parameter + <c>logger_level</c>.</p> <p>To obtain backwards + compatibility with the SASL error logging functionality + from earlier releases, set Kernel configuration parameter + <c>logger_sasl_compatible</c> to <c>true</c>. This + prevents the default Logger handler from logging any + supervisor-, crash-, or progress reports. Instead, SASL + adds a separate Logger handler during application start, + which takes care of these log events. The SASL + configuration parameters <c>sasl_error_logger</c> and + <c>sasl_errlog_type</c> specify the destination (terminal + or file) and severity level to log for these + events.</p></item></list> + <p> + Since Logger is new in Erlang/OTP 21.0, we do reserve the + right to introduce changes to the Logger API and + functionality in patches following this release. These + changes might or might not be backwards compatible with + the initial version.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-13295</p> + </item> + <item> + <p> + <c>gen_sctp:connect_init/4</c> or rather connect in + <c>inet_drv.c</c> for SCTP has been fixed to not check + the write file descriptor for writeability after a + connect, since for SCTP (SOCK_SEQPACKET) that property + does not seem to be any kind of indicator for when a + connect has finished. This fixes connects that the OS + returned as "in progress" that was misinterpreted by + <c>gen_sctp:connect_init</c> as failed.</p> + <p> + Own Id: OTP-13760 Aux Id: PR-1592 </p> + </item> + <item> + <p>The file driver has been rewritten as a NIF, + decreasing the latency of file operations. Notable + incompatibilities are:</p> <list> <item><p>The + <c>use_threads</c> option for <c>file:sendfile/5</c> no + longer has any effect; we either use non-blocking + <c>sendfile(2)</c> or fall back to <c>file:read</c> + + <c>gen_tcp:send</c>. </p></item> <item><p>The + file-specific DTrace probes have been removed. The same + effect can be achieved with normal tracing together with + the <c>nif__entry</c>/<c>nif__return</c> probes to track + scheduling.</p></item> </list> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14256</p> + </item> + <item> + <p>The I/O polling functionality of erts has been + re-written to better make use of the OSs polling + mechanisms. This change means that erts will now always + prefer to use a kernel-polling mechanism if possible. + Also all of the I/O polling has been moved to dedicated + threads instead of being placed in the scheduler + loops.</p> <p>As a result of this, the <c>erl</c> options + <c>+K</c> and <c>+secio</c> have been removed. It is + still possible to disable kernel-poll, but it has to be + done at compile time through the configure option + <c>--disable-kernel-poll</c>.</p> <p>The new <c>erl</c> + options <seealso marker="erl#+IOt"><c>+IOt</c></seealso> + and <seealso marker="erl#+IOp"><c>+IOp</c></seealso> can + be used to change how many IO poll threads and poll sets + that erts should use. See their respective documentation + for more details.</p> + <p> + Own Id: OTP-14346</p> + </item> + <item> + <p>Truly asynchronous auto-connect. Earlier, when + <c>erlang:send</c> was aimed toward an unconnected node, + the function would not return until the connection setup + had completed (or failed). Now the function returns + directly after the message has been enqueued and the + connection setup started.</p> + <p>The same applies to all distributed operations that + may trigger auto-connect, i.e. <c>'!'</c>, <c>send</c>, + <c>link</c>, <c>monitor</c>, <c>monitor_node</c>, + <c>exit/2</c> and <c>group_leader</c>.</p> + <p>The interface for all these functions are unchanged as + they do not return connection failures. The only + exception is <c>erlang:monitor</c> where a <em>possible + incompatibility</em> is introduced: An attempt to monitor + a process on a primitive node (such as erl_interface or + jinterface), where remote process monitoring is not + implemented, will no longer fail with <c>badarg</c> + exception. Instead a monitor will be created, but it will + only supervise the connection to the node.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14370</p> + </item> + <item> + <p>Changed the default behaviour of <c>.erlang</c> + loading: <c>.erlang</c> is no longer loaded from the + current directory. <c>c:erlangrc(PathList)</c> can be + used to search and load an <c>.erlang</c> file from user + specified directories.</p> <p><c>escript</c>, + <c>erlc</c>, <c>dialyzer</c> and <c>typer</c> no longer + load an <c>.erlang</c> at all.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14439</p> + </item> + <item> + <p> + New functionality for implementation of alternative + carriers for the Erlang distribution has been introduced. + This mainly consists of support for usage of distribution + controller processes (previously only ports could be used + as distribution controllers). For more information see + <seealso marker="erts:alt_dist#distribution_module">ERTS + User's Guide ➜ How to implement an Alternative Carrier + for the Erlang Distribution ➜ Distribution + Module</seealso>.</p> + <p> + Own Id: OTP-14459</p> + </item> + <item> + <p> + Add support for the lcc compiler and in extension the + Elbrus 2000 platform.</p> + <p> + Own Id: OTP-14492</p> + </item> + <item> + <p>Support for "tuple calls" have been removed from the + run-time system. Tuple calls was an undocumented and + unsupported feature which allowed the module argument for + an apply operation to be a tuple: <c>Var = dict:new(), + Var:size()</c>. This "feature" frequently caused + confusion, especially when such call failed. The + stacktrace would point out functions that don't exist in + the source code.</p> + <p>For legacy code that need to use parameterized modules + or tuple calls for some other reason, there is a new + compiler option called <c>tuple_calls</c>. When this + option is given, the compiler will generate extra code + that emulates the old behavior for calls where the module + is a variable.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14497</p> + </item> + <item> + <p>Creation of small maps with literal keys has been + optimized to be faster and potentially use less memory. + The keys are combined into a literal key tuple which is + put into the literal pool. The key tuple can be shared + between many instances of maps having the same keys.</p> + <p> + Own Id: OTP-14502</p> + </item> + <item> + <p> + When an exception is thrown, include the arguments of the + call in the stacktrace for BIFs <c>band</c>, <c>bor</c>, + <c>bsl</c>, <c>bsr</c>, <c>bxor</c>, <c>div</c>, + <c>rem</c> and the operators <c>+</c>, <c>-</c>, <c>*</c> + and <c>/</c>.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14508</p> + </item> + <item> + <p> + The non-smp emulators have been removed. This means that + the configure options <c>--disable-threads</c> and + <c>--enable-plain-emulator</c> have been removed and + configure will now refuse to build Erlang/OTP on + platforms without thread support.</p> + <p> + In order to achieve a similar setup as the non-smp + emulator, it is possible to start Erlang/OTP with the + <c>+S 1</c> option.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14518</p> + </item> + <item> + <p>Modules that use floating point constants compiled + with R15 or earlier will need to be re-compiled before + they can be loaded.</p> + <p> + Own Id: OTP-14575</p> + </item> + <item> + <p> + Implementation of true asynchronous signaling between + processes in order to improve scalability. Signals + affected include exit, monitor, demonitor, monitor + triggered, link, unlink, and group leader.</p> + <p> + Own Id: OTP-14589</p> + </item> + <item> + <p> + Added a PGO (profile guided optimization) pass to the + build step of erts. This can be disabled by passing + --disable-pgo to configure.</p> + <p> + Own Id: OTP-14604</p> + </item> + <item> + <p> + Improved the performance of <c>binary:split</c> and + <c>binary:match</c>.</p> + <p> + Own Id: OTP-14610 Aux Id: PR-1480 </p> + </item> + <item> + <p> + It is not longer possible to disable dirty schedulers + when building erlang.</p> + <p> + Own Id: OTP-14613</p> + </item> + <item> + <p>Loaded BEAM code in a 64-bit system requires less + memory because of better packing of operands for + instructions.</p> + <p>These memory savings were achieved by major + improvements to the <c>beam_makeops</c> scripts used when + building the run time system and BEAM compiler. There is + also new for documentation for <c>beam_makeops</c> that + describes how new BEAM instructions and loader + transformations can be implemented. The documentation is + found in here in a source directory or git repository: + erts/emulator/internal_doc/beam_makeops.md. An online + version can be found here: + https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/beam_makeops.md</p> + <p> + Own Id: OTP-14626</p> + </item> + <item> + <p><c>file:read_file</c> has been changed to read the + content of files that report a size of 0 even when data + can be read from them. An example of such a file is + <c>/proc/cpuinfo</c> on Linux.</p> + <p> + Own Id: OTP-14637 Aux Id: ERL-327 PR-1524 </p> + </item> + <item> + <p> + It is no longer possible to disable the <c>temp_alloc</c> + allocator. Disabling it caused serious performance + degradations and was never what was wanted.</p> + <p> + Own Id: OTP-14651</p> + </item> + <item> + <p>The reduction cost of sending messages is now + constant. It will no longer scale according to the length + of the receiving process' message queue.</p> + <p> + Own Id: OTP-14667</p> + </item> + <item> + <p> + Improved loading of modules with <c>-on_load</c> + directive, to no longer block all schedulers when the + load operation is completed.</p> + <p> + Own Id: OTP-14680</p> + </item> + <item> + <p> + On platforms with real-time signals available, SIGRTMIN+1 + is now used as the internal scheduler suspend signal + instead of SIGUSR2.</p> + <p> + Own Id: OTP-14682</p> + </item> + <item> + <p>When the value returned from a '<c>catch</c>' + expression is ignored, no stacktrace will be built if an + exception is caught. That will save time and produce less + garbage. There are also some minor optimizations of + '<c>try</c>/<c>catch</c>' both in the compiler and + run-time system.</p> + <p> + Own Id: OTP-14683</p> + </item> + <item> + <p>The guarantees and non-guarantees of + <c>erlang:get_stacktrace/0</c> are now documented.</p> + <p> + Own Id: OTP-14687</p> + </item> + <item> + <p>There is a new syntax in '<c>try/catch</c>' for + retrieving the stacktrace without calling + '<c>erlang:get_stacktrace/0</c>'. See the reference + manual for a description of the new syntax. The + '<c>erlang:get_stacktrace/0</c>' BIF is now + deprecated.</p> + <p> + Own Id: OTP-14692</p> + </item> + <item> + <p> + New 'used' option for <c>binary_to_term/2</c> that will + also return number of bytes actually read from the + binary. This enables easy access to any extra data in the + binary located directly after the returned term.</p> + <p> + Own Id: OTP-14780</p> + </item> + <item> + <p> + Added more statistics for + <c>erlang:system_info({allocator,A})</c> in the + <c>mbcs_pool</c> section.</p> + <p> + Own Id: OTP-14795 Aux Id: ERL-88 </p> + </item> + <item> + <p>Added <c>enif_ioq_peek_head</c> to retrieve Erlang + terms from NIF IO queues without having to resort to + copying.</p> + <p> + Own Id: OTP-14797</p> + </item> + <item> + <p>There is a new option '<c>makedep_side_effect</c>' for + the compiler and <c>-MMD</c> for '<c>erlc</c>' that + generates dependencies and continues to compile as + normal.</p> + <p> + Own Id: OTP-14830</p> + </item> + <item> + <p>Added <c>ets:whereis/1</c> for retrieving the table + identifier of a named table.</p> + <p> + Own Id: OTP-14884</p> + </item> + <item> + <p><c>seq_trace</c> labels may now be any erlang + term.</p> + <p> + Own Id: OTP-14899</p> + </item> + <item> + <p> + Optimized the common case of <c>monitor</c> followed by + <c>send</c> to the same local process. The monitor signal + is now delayed in order to be piggybacked with the sent + message and thereby only get one lock operation on the + message queue of the receiver. A delayed monitor signal + is flushed if no <c>send</c> has been done at the latest + when the process is scheduled out.</p> + <p> + Own Id: OTP-14901</p> + </item> + <item> + <p> + Make hipe compiled code work on x86_64 (amd64) with OS + security feature PIE, where executable code can be loaded + into a random location. Old behavior, if hipe was + enabled, was to disable PIE build options for the VM.</p> + <p> + Own Id: OTP-14903</p> + </item> + <item> + <p>The number of driver async threads will now default to + 1 as the standard drivers do not use them anymore. Users + that changed this value to tweak the file driver should + replace <c>+A</c> with <c>+SDio</c> since it now uses + dirty IO schedulers instead of async threads.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14928</p> + </item> + <item> + <p> + Optimize <c>==</c> and <c>/=</c> for binaries with + different sizes to be constant in time instead of + proportional to the size of their common prefix.</p> + <p> + Own Id: OTP-14934 Aux Id: PR-1708 </p> + </item> + <item> + <p> + Refactorings making some internal process flags available + for other usage.</p> + <p> + Own Id: OTP-14948</p> + </item> + <item> + <p> + Removed need for HiPE to allocate native executable + memory in low 2GB address space on x86_64. Command line + option <c>+MXscs</c> is thereby obsolete and ignored.</p> + <p> + Own Id: OTP-14951</p> + </item> + <item> + <p>Added <c>enif_make_map_from_arrays</c> for creating a + populated map, analogous to + <c>enif_make_list_from_array</c>.</p> + <p> + Own Id: OTP-14954</p> + </item> + <item> + <p>Added configuration switches for busy-wait and wake up + thresholds for dirty schedulers, and changing these + settings for normal schedulers will no longer affect + dirty schedulers. </p> <p>Refer to the documentation for + details. The new switches are <seealso + marker="erl#+sbwtdcpu">+sbwtdcpu</seealso>, <seealso + marker="erl#+sbwtdio">+sbwtdio</seealso>, <seealso + marker="erl#+swtdcpu">+swtdcpu</seealso>, and <seealso + marker="erl#+swtdio">+swtdio</seealso>.</p> <p>The + default busy wait threshold for dirty scheduler threads + has also been lowered to <c>short</c>.</p> + <p> + Own Id: OTP-14959</p> + </item> + <item> + <p> + The list of "taints" now also includes dynamic loaded + drivers in addition to NIF libraries. Statically linked + drivers and NIF libraries that are part of erts are not + included. The "taints" are returned by + <c>system_info(taints)</c> and printed in the header of + <c>erl_crash.dump</c> files.</p> + <p> + Own Id: OTP-14960</p> + </item> + <item> + <p>Added <c>instrument:allocations</c> and + <c>instrument:carriers</c> for retrieving information + about memory utilization and fragmentation.</p> + <p>The old <c>instrument</c> interface has been removed, + as have the related options <c>+Mim</c> and + <c>+Mis</c>.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14961</p> + </item> + <item> + <p>The process suspend functionality used by the <seealso + marker="erlang#suspend_process/2">erlang:suspend_process/2</seealso> + BIF has been reimplemented using the newly introduced + true asynchronous signaling between processes. This + mainly to reduce memory usage in the process control + block of all processes, but also in order to simplify the + implementation.</p> <warning> <p>You can easily create + deadlocks if processes suspends each other (directly or + in circles). In ERTS versions prior to ERTS version 10.0, + the runtime system prevented such deadlocks, but this + prevention has now been removed due to performance + reasons.</p> </warning> <p>Other ERTS internal + functionality that used the previous process suspend + functionality have also been reimplemented to use + asynchronous signaling instead.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14964 Aux Id: OTP-14589 </p> + </item> + <item> + <p>Added the <c>nifs</c> option to + <c>?MODULE:module_info/1</c> for listing a module's + installed NIF functions.</p> + <p> + Own Id: OTP-14965</p> + </item> + <item> + <p> + New implementation of <c>erlang:process_info/[1,2]</c>.</p> + <p> + In the general case when inspecting another process, the + new implementation sends an asynchronous process-info + request signal to the other process and waits for the + result instead of locking the other process and reading + the result directly. In some special cases where no + conflicts occur, signal order wont be violated, and the + amount of data requested is guaranteed to be small, the + inspected process may be inspected directly.</p> + <p> + Appropriate amount of reductions are now also bumped when + inspecting a process.</p> + <p> + Own Id: OTP-14966</p> + </item> + <item> + <p> + Removed process start time from crash dump in order to + save memory in process control block.</p> + <p> + Own Id: OTP-14975 Aux Id: PR-1597 </p> + </item> + <item> + <p> + Optimize <c>erlang:put/2</c> when updating existing key + with a new immediate value (atom, small integer, pid, + port).</p> + <p> + Own Id: OTP-14976</p> + </item> + <item> + <p> + <c>erlang:process_info/1</c> has been changed to no + longer include <c>messages</c> by default. Instead + <c>erlang:process_info/2</c> should be used.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14986 Aux Id: PR-1745 </p> + </item> + <item> + <p> + New <c>erlang:system_info(ets_count)</c> to get total + number of ets tables existing at the local node.</p> + <p> + Own Id: OTP-14987</p> + </item> + <item> + <p> + New NIF functions: <c>enif_mutex_name</c>, + <c>enif_cond_name</c>, <c>enif_rwlock_name</c>, + <c>enif_thread_name</c>, <c>enif_vfprintf</c>, + <c>enif_vsnprintf</c>.</p> + <p> + Own Id: OTP-14994</p> + </item> + <item> + <p>When <c>erlang:system_flag(backtrace_depth, 0)</c> has + been called, all exceptions will now contain the entry + for <em>one</em> function (despite the zero). It used to + be that a hand-made stack backtrace passed to + <c>erlang:raise/3</c> would be be truncated to an empty + list.</p> + <p> + Own Id: OTP-15026</p> + </item> + <item> + <p> + Fixed bug for named <c>ets</c> tables which could cause + unexpected results from matchspec iteration functions + (<c>ets:select*</c> and <c>ets:match*</c>) if the table + was deleted and recreated with the same name during the + iteration. The iteration could incorrectly continue + through the recreated table. The expected correct + behavior is now for the iteration call to fail with a + <c>badarg</c> exception if the table is deleted before + the iteration has completed.</p> + <p> + Own Id: OTP-15031</p> + </item> + <item> + <p>Two new guards BIFs operating on maps have been added: + <c>map_get/2</c> and <c>is_map_key/2</c>. They do the + same as <c>maps:get/2</c> and <c>maps:is_key/2</c>, + respectively, except that they are allowed to be used in + guards.</p> + <p> + Own Id: OTP-15037 Aux Id: PR-1784, PR-1802 </p> + </item> + <item> + <p> + Release run-queue lock while cleaning up terminated dirty + process.</p> + <p> + Own Id: OTP-15081</p> + </item> + <item> + <p>The callback module passed as <c>-epmd_module</c> to + erl has been expanded to be able to do name and port + resolving.</p> <p>Documentation has also been added in + the <seealso + marker="kernel:erl_epmd"><c>erl_epmd</c></seealso> + reference manual and ERTS User's Guide <seealso + marker="erts:alt_disco">How to Implement an Alternative + Service Discovery for Erlang Distribution</seealso>.</p> + <p> + Own Id: OTP-15086 Aux Id: PR-1694 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 9.3.3.3</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -4451,8 +5475,7 @@ <p>The previously introduced "eager check I/O" feature is now enabled by default.</p> <p>Eager check I/O can be disabled using the <c>erl</c> - command line argument: <seealso - marker="erl#+secio"><c>+secio false</c></seealso></p> + command line argument: <c>+secio false</c></p> <p>Characteristics impact compared to previous default:</p> <list> <item>Lower latency and smoother management of externally triggered I/O operations.</item> @@ -5233,8 +6256,7 @@ prioritized to the same extent as when eager check I/O is disabled.</p> <p>Eager check I/O can be enabled using the <c>erl</c> - command line argument: <seealso - marker="erl#+secio"><c>+secio true</c></seealso></p> + command line argument: <c>+secio true</c></p> <p>Characteristics impact when enabled:</p> <list> <item>Lower latency and smoother management of externally triggered I/O operations.</item> <item>A slightly reduced @@ -11228,7 +12250,7 @@ <c>update_cpu_info</c> will make the runtime system reread and update the internally stored CPU information. For more information see the documentation of <seealso - marker="erlang#update_cpu_info">erlang:system_info(update_cpu_info)</seealso>.</p> + marker="erlang#system_info_update_cpu_info">erlang:system_info(update_cpu_info)</seealso>.</p> <p> The CPU topology is now automatically detected on Windows systems with less than 33 logical processors. The runtime diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml index d583b873a0..05e9a24af8 100644 --- a/erts/doc/src/part.xml +++ b/erts/doc/src/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2016</year> + <year>1996</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -37,6 +37,7 @@ <xi:include href="match_spec.xml"/> <xi:include href="crash_dump.xml"/> <xi:include href="alt_dist.xml"/> + <xi:include href="alt_disco.xml"/> <xi:include href="absform.xml"/> <xi:include href="tty.xml"/> <xi:include href="driver.xml"/> diff --git a/erts/doc/src/run_erl.xml b/erts/doc/src/run_erl.xml index e4c1b943c4..fa36457489 100644 --- a/erts/doc/src/run_erl.xml +++ b/erts/doc/src/run_erl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1999</year><year>2016</year> + <year>1999</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> |