aboutsummaryrefslogtreecommitdiffstats
path: root/erts/doc
diff options
context:
space:
mode:
Diffstat (limited to 'erts/doc')
-rw-r--r--erts/doc/Makefile36
-rw-r--r--erts/doc/html/.gitignore0
-rw-r--r--erts/doc/man1/.gitignore0
-rw-r--r--erts/doc/man3/.gitignore0
-rw-r--r--erts/doc/pdf/.gitignore0
-rw-r--r--erts/doc/src/Makefile153
-rw-r--r--erts/doc/src/absform.xml444
-rw-r--r--erts/doc/src/alt_dist.xml1099
-rw-r--r--erts/doc/src/book.xml49
-rw-r--r--erts/doc/src/crash_dump.xml518
-rw-r--r--erts/doc/src/driver.xml812
-rw-r--r--erts/doc/src/driver_entry.xml453
-rw-r--r--erts/doc/src/epmd.xml120
-rw-r--r--erts/doc/src/erl.xml928
-rw-r--r--erts/doc/src/erl_dist_protocol.xml802
-rw-r--r--erts/doc/src/erl_driver.xml2465
-rw-r--r--erts/doc/src/erl_ext_dist.xml1014
-rwxr-xr-xerts/doc/src/erl_ext_fig.gifbin0 -> 3834 bytes
-rw-r--r--erts/doc/src/erl_ext_fig.ps153
-rw-r--r--erts/doc/src/erl_fix_alloc.fig104
-rw-r--r--erts/doc/src/erl_fix_alloc.gifbin0 -> 5638 bytes
-rw-r--r--erts/doc/src/erl_fix_alloc.ps646
-rw-r--r--erts/doc/src/erl_nif.xml351
-rw-r--r--erts/doc/src/erl_prim_loader.xml251
-rw-r--r--erts/doc/src/erl_set_memory_block.xml172
-rw-r--r--erts/doc/src/erlang.xml6920
-rw-r--r--erts/doc/src/erlc.xml256
-rw-r--r--erts/doc/src/erlsrv.xml405
-rw-r--r--erts/doc/src/erts_alloc.xml554
-rw-r--r--erts/doc/src/escript.xml232
-rw-r--r--erts/doc/src/fascicules.xml18
-rw-r--r--erts/doc/src/inet_cfg.xml397
-rw-r--r--erts/doc/src/init.xml384
-rw-r--r--erts/doc/src/make.dep32
-rw-r--r--erts/doc/src/match_spec.xml564
-rw-r--r--erts/doc/src/notes.xml5439
-rw-r--r--erts/doc/src/notes_history.xml503
-rw-r--r--erts/doc/src/part.xml44
-rw-r--r--erts/doc/src/part_notes.xml37
-rw-r--r--erts/doc/src/part_notes_history.xml35
-rw-r--r--erts/doc/src/ref_man.xml60
-rw-r--r--erts/doc/src/run_erl.xml155
-rw-r--r--erts/doc/src/start.xml64
-rw-r--r--erts/doc/src/start_erl.xml126
-rw-r--r--erts/doc/src/tty.xml137
-rw-r--r--erts/doc/src/werl.xml88
-rw-r--r--erts/doc/src/zlib.xml606
47 files changed, 27626 insertions, 0 deletions
diff --git a/erts/doc/Makefile b/erts/doc/Makefile
new file mode 100644
index 0000000000..8ea3793d90
--- /dev/null
+++ b/erts/doc/Makefile
@@ -0,0 +1,36 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1996-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+#
+# Default Rules
+#
+OTP_MAKE_ROOT=/home/super/otp/otp_make
+include $(OTP_MAKE_ROOT)/otp.mk
+
+#
+# Macros
+#
+SUB_DIRECTORIES = src
+
+SPECIAL_TARGETS =
+
+#
+# Default Subdir Targets
+#
+include $(OTP_MAKE_ROOT)/otp_subdir.mk
diff --git a/erts/doc/html/.gitignore b/erts/doc/html/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/erts/doc/html/.gitignore
diff --git a/erts/doc/man1/.gitignore b/erts/doc/man1/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/erts/doc/man1/.gitignore
diff --git a/erts/doc/man3/.gitignore b/erts/doc/man3/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/erts/doc/man3/.gitignore
diff --git a/erts/doc/pdf/.gitignore b/erts/doc/pdf/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/erts/doc/pdf/.gitignore
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile
new file mode 100644
index 0000000000..3dfefa2001
--- /dev/null
+++ b/erts/doc/src/Makefile
@@ -0,0 +1,153 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+APPLICATION=erts
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/$(APPLICATION)-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+XML_APPLICATION_FILES = ref_man.xml
+XML_REF1_FILES = epmd.xml \
+ erl.xml \
+ erlc.xml \
+ escript.xml \
+ werl.xml \
+ erlsrv.xml \
+ start_erl.xml \
+ run_erl.xml \
+ start.xml
+
+XML_REF3_FILES = \
+ driver_entry.xml \
+ erl_set_memory_block.xml \
+ erl_driver.xml \
+ erl_prim_loader.xml \
+ erlang.xml \
+ erts_alloc.xml \
+ init.xml \
+ zlib.xml
+
+XML_PART_FILES = \
+ part.xml \
+ part_notes.xml \
+ part_notes_history.xml
+
+XML_CHAPTER_FILES = \
+ tty.xml \
+ match_spec.xml \
+ crash_dump.xml \
+ alt_dist.xml \
+ driver.xml \
+ absform.xml \
+ inet_cfg.xml \
+ erl_ext_dist.xml \
+ erl_dist_protocol.xml \
+ notes.xml \
+ notes_history.xml
+
+TOPDOCDIR=../../../doc
+
+BOOK_FILES = book.xml
+
+GIF_FILES = \
+ erl_ext_fig.gif
+
+XML_FILES = \
+ $(BOOK_FILES) $(XML_CHAPTER_FILES) \
+ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF1_FILES) $(XML_APPLICATION_FILES)
+
+# ----------------------------------------------------
+
+HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
+ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
+
+INFO_FILE = ../../info
+INFO_FILE_SRC = ../../info.src
+
+MAN1_FILES = $(XML_REF1_FILES:%.xml=$(MAN1DIR)/%.1)
+MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
+
+HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
+
+TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+XML_FLAGS +=
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+$(HTMLDIR)/%.gif: %.gif
+ $(INSTALL_DATA) $< $@
+
+docs: pdf html man $(INFO_FILE)
+
+$(TOP_PDF_FILE): $(XML_FILES)
+
+pdf: $(TOP_PDF_FILE)
+
+html: gifs $(HTML_REF_MAN_FILE)
+
+man: $(MAN1_FILES) $(MAN3_FILES)
+
+gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+
+$(INFO_FILE): $(INFO_FILE_SRC) ../../vsn.mk
+ sed -e 's;%RELEASE%;$(SYSTEM_VSN);' $(INFO_FILE_SRC) > $(INFO_FILE)
+
+
+debug opt:
+
+clean:
+ rm -rf $(HTMLDIR)/*
+ rm -f $(MAN1DIR)/*
+ rm -f $(MAN3DIR)/*
+ rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f errs core *~
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_docs_spec: docs
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(HTMLDIR)/* \
+ $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
+ $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man1
+ $(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1
+
+release_spec:
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml
new file mode 100644
index 0000000000..4c84412dd6
--- /dev/null
+++ b/erts/doc/src/absform.xml
@@ -0,0 +1,444 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>The Abstract Format</title>
+ <prepared>Arndt Jonasson</prepared>
+ <responsible>Kenneth Lundin</responsible>
+ <docno>1</docno>
+ <approved>Jultomten</approved>
+ <checked></checked>
+ <date>00-12-01</date>
+ <rev>A</rev>
+ <file>absform.xml</file>
+ </header>
+ <p></p>
+ <p>This document describes the standard representation of parse trees for Erlang
+ programs as Erlang terms. This representation is known as the <em>abstract format</em>.
+ Functions dealing with such parse trees are <c><![CDATA[compile:forms/[1,2]]]></c>
+ and functions in the modules
+ <c><![CDATA[epp]]></c>,
+ <c><![CDATA[erl_eval]]></c>,
+ <c><![CDATA[erl_lint]]></c>,
+ <c><![CDATA[erl_pp]]></c>,
+ <c><![CDATA[erl_parse]]></c>,
+ and
+ <c><![CDATA[io]]></c>.
+ They are also used as input and output for parse transforms (see the module
+ <c><![CDATA[compile]]></c>).</p>
+ <p>We use the function <c><![CDATA[Rep]]></c> to denote the mapping from an Erlang source
+ construct <c><![CDATA[C]]></c> to its abstract format representation <c><![CDATA[R]]></c>, and write
+ <c><![CDATA[R = Rep(C)]]></c>.
+ </p>
+ <p>The word <c><![CDATA[LINE]]></c> below represents an integer, and denotes the
+ number of the line in the source file where the construction occurred.
+ Several instances of <c><![CDATA[LINE]]></c> in the same construction may denote
+ different lines.</p>
+ <p>Since operators are not terms in their own right, when operators are
+ mentioned below, the representation of an operator should be taken to
+ be the atom with a printname consisting of the same characters as the
+ operator.
+ </p>
+
+ <section>
+ <title>Module declarations and forms</title>
+ <p>A module declaration consists of a sequence of forms that are either
+ function declarations or attributes.</p>
+ <list type="bulleted">
+ <item>If D is a module declaration consisting of the forms
+ <c><![CDATA[F_1]]></c>, ..., <c><![CDATA[F_k]]></c>, then
+ Rep(D) = <c><![CDATA[[Rep(F_1), ..., Rep(F_k)]]]></c>.</item>
+ <item>If F is an attribute <c><![CDATA[-module(Mod)]]></c>, then
+ Rep(F) = <c><![CDATA[{attribute,LINE,module,Mod}]]></c>.</item>
+ <item>If F is an attribute <c><![CDATA[-export([Fun_1/A_1, ..., Fun_k/A_k])]]></c>, then
+ Rep(F) = <c><![CDATA[{attribute,LINE,export,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}]]></c>.</item>
+ <item>If F is an attribute <c><![CDATA[-import(Mod,[Fun_1/A_1, ..., Fun_k/A_k])]]></c>, then
+ Rep(F) = <c><![CDATA[{attribute,LINE,import,{Mod,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}}]]></c>.</item>
+ <item>If F is an attribute <c><![CDATA[-compile(Options)]]></c>, then
+ Rep(F) = <c><![CDATA[{attribute,LINE,compile,Options}]]></c>.</item>
+ <item>If F is an attribute <c><![CDATA[-file(File,Line)]]></c>, then
+ Rep(F) = <c><![CDATA[{attribute,LINE,file,{File,Line}}]]></c>.</item>
+ <item>If F is a record declaration <c><![CDATA[-record(Name,{V_1, ..., V_k})]]></c>, then
+ Rep(F) =
+ <c><![CDATA[{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}]]></c>. For Rep(V), see below.</item>
+ <item>If F is a wild attribute <c><![CDATA[-A(T)]]></c>, then
+ Rep(F) = <c><![CDATA[{attribute,LINE,A,T}]]></c>.
+ <br></br></item>
+ <item>If F is a function declaration <c><![CDATA[Name Fc_1 ; ... ; Name Fc_k]]></c>,
+ where each <c><![CDATA[Fc_i]]></c> is a function clause with a
+ pattern sequence of the same length <c><![CDATA[Arity]]></c>, then
+ Rep(F) = <c><![CDATA[{function,LINE,Name,Arity,[Rep(Fc_1), ...,Rep(Fc_k)]}]]></c>.</item>
+ </list>
+
+ <section>
+ <title>Record fields</title>
+ <p>Each field in a record declaration may have an optional
+ explicit default initializer expression</p>
+ <list type="bulleted">
+ <item>If V is <c><![CDATA[A]]></c>, then
+ Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A)}]]></c>.</item>
+ <item>If V is <c><![CDATA[A = E]]></c>, then
+ Rep(V) = <c><![CDATA[{record_field,LINE,Rep(A),Rep(E)}]]></c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Representation of parse errors and end of file</title>
+ <p>In addition to the representations of forms, the list that represents
+ a module declaration (as returned by functions in <c><![CDATA[erl_parse]]></c> and
+ <c><![CDATA[epp]]></c>) may contain tuples <c><![CDATA[{error,E}]]></c> and <c><![CDATA[{warning,W}]]></c>, denoting
+ syntactically incorrect forms and warnings, and <c><![CDATA[{eof,LINE}]]></c>, denoting an end
+ of stream encountered before a complete form had been parsed.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Atomic literals</title>
+ <p>There are five kinds of atomic literals, which are represented in the
+ same way in patterns, expressions and guards:</p>
+ <list type="bulleted">
+ <item>If L is an integer or character literal, then
+ Rep(L) = <c><![CDATA[{integer,LINE,L}]]></c>.</item>
+ <item>If L is a float literal, then
+ Rep(L) = <c><![CDATA[{float,LINE,L}]]></c>.</item>
+ <item>If L is a string literal consisting of the characters
+ <c><![CDATA[C_1]]></c>, ..., <c><![CDATA[C_k]]></c>, then
+ Rep(L) = <c><![CDATA[{string,LINE,[C_1, ..., C_k]}]]></c>.</item>
+ <item>If L is an atom literal, then
+ Rep(L) = <c><![CDATA[{atom,LINE,L}]]></c>.</item>
+ </list>
+ <p>Note that negative integer and float literals do not occur as such; they are
+ parsed as an application of the unary negation operator.</p>
+ </section>
+
+ <section>
+ <title>Patterns</title>
+ <p>If <c><![CDATA[Ps]]></c> is a sequence of patterns <c><![CDATA[P_1, ..., P_k]]></c>, then
+ Rep(Ps) = <c><![CDATA[[Rep(P_1), ..., Rep(P_k)]]]></c>. Such sequences occur as the
+ list of arguments to a function or fun.</p>
+ <p>Individual patterns are represented as follows:</p>
+ <list type="bulleted">
+ <item>If P is an atomic literal L, then Rep(P) = Rep(L).</item>
+ <item>If P is a compound pattern <c><![CDATA[P_1 = P_2]]></c>, then
+ Rep(P) = <c><![CDATA[{match,LINE,Rep(P_1),Rep(P_2)}]]></c>.</item>
+ <item>If P is a variable pattern <c><![CDATA[V]]></c>, then
+ Rep(P) = <c><![CDATA[{var,LINE,A}]]></c>,
+ where A is an atom with a printname consisting of the same characters as
+ <c><![CDATA[V]]></c>.</item>
+ <item>If P is a universal pattern <c><![CDATA[_]]></c>, then
+ Rep(P) = <c><![CDATA[{var,LINE,'_'}]]></c>.</item>
+ <item>If P is a tuple pattern <c><![CDATA[{P_1, ..., P_k}]]></c>, then
+ Rep(P) = <c><![CDATA[{tuple,LINE,[Rep(P_1), ..., Rep(P_k)]}]]></c>.</item>
+ <item>If P is a nil pattern <c><![CDATA[[]]]></c>, then
+ Rep(P) = <c><![CDATA[{nil,LINE}]]></c>.</item>
+ <item>If P is a cons pattern <c><![CDATA[[P_h | P_t]]]></c>, then
+ Rep(P) = <c><![CDATA[{cons,LINE,Rep(P_h),Rep(P_t)}]]></c>.</item>
+ <item>If E is a binary pattern <c><![CDATA[<<P_1:Size_1/TSL_1, ..., P_k:Size_k/TSL_k>>]]></c>, then
+ Rep(E) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(P_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(P_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ For Rep(TSL), see below.
+ An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
+ (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
+ <item>If P is <c><![CDATA[P_1 Op P_2]]></c>, where <c><![CDATA[Op]]></c> is a binary operator (this
+ is either an occurrence of <c><![CDATA[++]]></c> applied to a literal string or character
+ list, or an occurrence of an expression that can be evaluated to a number
+ at compile time),
+ then Rep(P) = <c><![CDATA[{op,LINE,Op,Rep(P_1),Rep(P_2)}]]></c>.</item>
+ <item>If P is <c><![CDATA[Op P_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator (this is an
+ occurrence of an expression that can be evaluated to a number at compile
+ time), then Rep(P) = <c><![CDATA[{op,LINE,Op,Rep(P_0)}]]></c>.</item>
+ <item>If P is a record pattern <c><![CDATA[#Name{Field_1=P_1, ..., Field_k=P_k}]]></c>,
+ then Rep(P) =
+ <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(P_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(P_k)}]}]]></c>.</item>
+ <item>If P is <c><![CDATA[#Name.Field]]></c>, then
+ Rep(P) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
+ <item>If P is <c><![CDATA[( P_0 )]]></c>, then
+ Rep(P) = <c><![CDATA[Rep(P_0)]]></c>,
+ i.e., patterns cannot be distinguished from their bodies.</item>
+ </list>
+ <p>Note that every pattern has the same source form as some expression, and is
+ represented the same way as the corresponding expression.</p>
+ </section>
+
+ <section>
+ <title>Expressions</title>
+ <p>A body B is a sequence of expressions <c><![CDATA[E_1, ..., E_k]]></c>, and
+ Rep(B) = <c><![CDATA[[Rep(E_1), ..., Rep(E_k)]]]></c>.</p>
+ <p>An expression E is one of the following alternatives:</p>
+ <list type="bulleted">
+ <item>If P is an atomic literal <c><![CDATA[L]]></c>, then
+ Rep(P) = Rep(L).</item>
+ <item>If E is <c><![CDATA[P = E_0]]></c>, then
+ Rep(E) = <c><![CDATA[{match,LINE,Rep(P),Rep(E_0)}]]></c>.</item>
+ <item>If E is a variable <c><![CDATA[V]]></c>, then
+ Rep(E) = <c><![CDATA[{var,LINE,A}]]></c>,
+ where <c><![CDATA[A]]></c> is an atom with a printname consisting of the same
+ characters as <c><![CDATA[V]]></c>.</item>
+ <item>If E is a tuple skeleton <c><![CDATA[{E_1, ..., E_k}]]></c>, then
+ Rep(E) = <c><![CDATA[{tuple,LINE,[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
+ <item>If E is <c><![CDATA[[]]]></c>, then
+ Rep(E) = <c><![CDATA[{nil,LINE}]]></c>.</item>
+ <item>If E is a cons skeleton <c><![CDATA[[E_h | E_t]]]></c>, then
+ Rep(E) = <c><![CDATA[{cons,LINE,Rep(E_h),Rep(E_t)}]]></c>.</item>
+ <item>If E is a binary constructor <c><![CDATA[<<V_1:Size_1/TSL_1, ..., V_k:Size_k/TSL_k>>]]></c>, then
+ Rep(E) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(V_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(V_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ For Rep(TSL), see below.
+ An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
+ (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
+ <item>If E is <c><![CDATA[E_1 Op E_2]]></c>, where <c><![CDATA[Op]]></c> is a binary operator,
+ then Rep(E) = <c><![CDATA[{op,LINE,Op,Rep(E_1),Rep(E_2)}]]></c>.</item>
+ <item>If E is <c><![CDATA[Op E_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator, then
+ Rep(E) = <c><![CDATA[{op,LINE,Op,Rep(E_0)}]]></c>.</item>
+ <item>If E is <c><![CDATA[#Name{Field_1=E_1, ..., Field_k=E_k}]]></c>, then
+ Rep(E) =
+ <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}]]></c>.</item>
+ <item>If E is <c><![CDATA[E_0#Name{Field_1=E_1, ..., Field_k=E_k}]]></c>, then
+ Rep(E) =
+ <c><![CDATA[{record,LINE,Rep(E_0),Name, [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}]]></c>.</item>
+ <item>If E is <c><![CDATA[#Name.Field]]></c>, then
+ Rep(E) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
+ <item>If E is <c><![CDATA[E_0#Name.Field]]></c>, then
+ Rep(E) = <c><![CDATA[{record_field,LINE,Rep(E_0),Name,Rep(Field)}]]></c>.</item>
+ <item>If E is <c><![CDATA[catch E_0]]></c>, then
+ Rep(E) = <c><![CDATA[{'catch',LINE,Rep(E_0)}]]></c>.</item>
+ <item>If E is <c><![CDATA[E_0(E_1, ..., E_k)]]></c>, then
+ Rep(E) = <c><![CDATA[{call,LINE,Rep(E_0),[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
+ <item>If E is <c><![CDATA[E_m:E_0(E_1, ..., E_k)]]></c>, then
+ Rep(E) =
+ <c><![CDATA[{call,LINE,{remote,LINE,Rep(E_m),Rep(E_0)},[Rep(E_1), ..., Rep(E_k)]}]]></c>.</item>
+ <item>If E is a list comprehension <c><![CDATA[[E_0 || W_1, ..., W_k]]]></c>,
+ where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
+ Rep(E) = <c><![CDATA[{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
+ below.</item>
+ <item>If E is a binary comprehension <c><![CDATA[<<E_0 || W_1, ..., W_k>>]]></c>,
+ where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
+ Rep(E) = <c><![CDATA[{bc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}]]></c>. For Rep(W), see
+ below.</item>
+ <item>If E is <c><![CDATA[begin B end]]></c>, where <c><![CDATA[B]]></c> is a body, then
+ Rep(E) = <c><![CDATA[{block,LINE,Rep(B)}]]></c>.</item>
+ <item>If E is <c><![CDATA[if Ic_1 ; ... ; Ic_k end]]></c>,
+ where each <c><![CDATA[Ic_i]]></c> is an if clause then
+ Rep(E) =
+ <c><![CDATA[{'if',LINE,[Rep(Ic_1), ..., Rep(Ic_k)]}]]></c>.</item>
+ <item>If E is <c><![CDATA[case E_0 of Cc_1 ; ... ; Cc_k end]]></c>,
+ where <c><![CDATA[E_0]]></c> is an expression and each <c><![CDATA[Cc_i]]></c> is a
+ case clause then
+ Rep(E) =
+ <c><![CDATA[{'case',LINE,Rep(E_0),[Rep(Cc_1), ..., Rep(Cc_k)]}]]></c>.</item>
+ <item>If E is <c><![CDATA[try B catch Tc_1 ; ... ; Tc_k end]]></c>,
+ where <c><![CDATA[B]]></c> is a body and each <c><![CDATA[Tc_i]]></c> is a catch clause then
+ Rep(E) =
+ <c><![CDATA[{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],[]}]]></c>.</item>
+ <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n end]]></c>,
+ where <c><![CDATA[B]]></c> is a body,
+ each <c><![CDATA[Cc_i]]></c> is a case clause and
+ each <c><![CDATA[Tc_j]]></c> is a catch clause then
+ Rep(E) =
+ <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],[]}]]></c>.</item>
+ <item>If E is <c><![CDATA[try B after A end]]></c>,
+ where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are bodies then
+ Rep(E) =
+ <c><![CDATA[{'try',LINE,Rep(B),[],[],Rep(A)}]]></c>.</item>
+ <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k after A end]]></c>,
+ where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are a bodies and
+ each <c><![CDATA[Cc_i]]></c> is a case clause then
+ Rep(E) =
+ <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[],Rep(A)}]]></c>.</item>
+ <item>If E is <c><![CDATA[try B catch Tc_1 ; ... ; Tc_k after A end]]></c>,
+ where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are bodies and
+ each <c><![CDATA[Tc_i]]></c> is a catch clause then
+ Rep(E) =
+ <c><![CDATA[{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],Rep(A)}]]></c>.</item>
+ <item>If E is <c><![CDATA[try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n after A end]]></c>,
+ where <c><![CDATA[B]]></c> and <c><![CDATA[A]]></c> are a bodies,
+ each <c><![CDATA[Cc_i]]></c> is a case clause and
+ each <c><![CDATA[Tc_j]]></c> is a catch clause then
+ Rep(E) =
+ <c><![CDATA[{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],Rep(A)}]]></c>.</item>
+ <item>If E is <c><![CDATA[receive Cc_1 ; ... ; Cc_k end]]></c>,
+ where each <c><![CDATA[Cc_i]]></c> is a case clause then
+ Rep(E) =
+ <c><![CDATA[{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)]}]]></c>.</item>
+ <item>If E is <c><![CDATA[receive Cc_1 ; ... ; Cc_k after E_0 -> B_t end]]></c>,
+ where each <c><![CDATA[Cc_i]]></c> is a case clause,
+ <c><![CDATA[E_0]]></c> is an expression and <c><![CDATA[B_t]]></c> is a body, then
+ Rep(E) =
+ <c><![CDATA[{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)],Rep(E_0),Rep(B_t)}]]></c>.</item>
+ <item>If E is <c><![CDATA[fun Name / Arity]]></c>, then
+ Rep(E) = <c><![CDATA[{'fun',LINE,{function,Name,Arity}}]]></c>.</item>
+ <item>If E is <c><![CDATA[fun Module:Name/Arity]]></c>, then
+ Rep(E) = <c><![CDATA[{'fun',LINE,{function,Module,Name,Arity}}]]></c>.</item>
+ <item>If E is <c><![CDATA[fun Fc_1 ; ... ; Fc_k end]]></c>
+ where each <c><![CDATA[Fc_i]]></c> is a function clause then Rep(E) =
+ <c><![CDATA[{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}]]></c>.</item>
+ <item>If E is <c><![CDATA[query [E_0 || W_1, ..., W_k] end]]></c>,
+ where each <c><![CDATA[W_i]]></c> is a generator or a filter, then
+ Rep(E) = <c><![CDATA[{'query',LINE,{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}}]]></c>.
+ For Rep(W), see below.</item>
+ <item>If E is <c><![CDATA[E_0.Field]]></c>, a Mnesia record access
+ inside a query, then
+ Rep(E) = <c><![CDATA[{record_field,LINE,Rep(E_0),Rep(Field)}]]></c>.</item>
+ <item>If E is <c><![CDATA[( E_0 )]]></c>, then
+ Rep(E) = <c><![CDATA[Rep(E_0)]]></c>,
+ i.e., parenthesized expressions cannot be distinguished from their bodies.</item>
+ </list>
+
+ <section>
+ <title>Generators and filters</title>
+ <p>When W is a generator or a filter (in the body of a list or binary comprehension), then:</p>
+ <list type="bulleted">
+ <item>If W is a generator <c><![CDATA[P <- E]]></c>, where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[E]]></c>
+ is an expression, then
+ Rep(W) = <c><![CDATA[{generate,LINE,Rep(P),Rep(E)}]]></c>.</item>
+ <item>If W is a generator <c><![CDATA[P <= E]]></c>, where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[E]]></c>
+ is an expression, then
+ Rep(W) = <c><![CDATA[{b_generate,LINE,Rep(P),Rep(E)}]]></c>.</item>
+ <item>If W is a filter <c><![CDATA[E]]></c>, which is an expression, then
+ Rep(W) = <c><![CDATA[Rep(E)]]></c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Binary element type specifiers</title>
+ <p>A type specifier list TSL for a binary element is a sequence of type
+ specifiers <c><![CDATA[TS_1 - ... - TS_k]]></c>.
+ Rep(TSL) = <c><![CDATA[[Rep(TS_1), ..., Rep(TS_k)]]]></c>.</p>
+ <p>When TS is a type specifier for a binary element, then:</p>
+ <list type="bulleted">
+ <item>If TS is an atom <c><![CDATA[A]]></c>, Rep(TS) = <c><![CDATA[A]]></c>.</item>
+ <item>If TS is a couple <c><![CDATA[A:Value]]></c> where <c><![CDATA[A]]></c> is an atom and <c><![CDATA[Value]]></c>
+ is an integer, Rep(TS) = <c><![CDATA[{A, Value}]]></c>.</item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Clauses</title>
+ <p>There are function clauses, if clauses, case clauses
+ and catch clauses.</p>
+ <p>A clause <c><![CDATA[C]]></c> is one of the following alternatives:</p>
+ <list type="bulleted">
+ <item>If C is a function clause <c><![CDATA[( Ps ) -> B]]></c>
+ where <c><![CDATA[Ps]]></c> is a pattern sequence and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,Rep(Ps),[],Rep(B)}]]></c>.</item>
+ <item>If C is a function clause <c><![CDATA[( Ps ) when Gs -> B]]></c>
+ where <c><![CDATA[Ps]]></c> is a pattern sequence,
+ <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,Rep(Ps),Rep(Gs),Rep(B)}]]></c>.</item>
+ <item>If C is an if clause <c><![CDATA[Gs -> B]]></c>
+ where <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,[],Rep(Gs),Rep(B)}]]></c>.</item>
+ <item>If C is a case clause <c><![CDATA[P -> B]]></c>
+ where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,[Rep(P)],[],Rep(B)}]]></c>.</item>
+ <item>If C is a case clause <c><![CDATA[P when Gs -> B]]></c>
+ where <c><![CDATA[P]]></c> is a pattern,
+ <c><![CDATA[Gs]]></c> is a guard sequence and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,[Rep(P)],Rep(Gs),Rep(B)}]]></c>.</item>
+ <item>If C is a catch clause <c><![CDATA[P -> B]]></c>
+ where <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}]]></c>.</item>
+ <item>If C is a catch clause <c><![CDATA[X : P -> B]]></c>
+ where <c><![CDATA[X]]></c> is an atomic literal or a variable pattern,
+ <c><![CDATA[P]]></c> is a pattern and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,[Rep({X,P,_})],[],Rep(B)}]]></c>.</item>
+ <item>If C is a catch clause <c><![CDATA[P when Gs -> B]]></c>
+ where <c><![CDATA[P]]></c> is a pattern, <c><![CDATA[Gs]]></c> is a guard sequence
+ and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}]]></c>.</item>
+ <item>If C is a catch clause <c><![CDATA[X : P when Gs -> B]]></c>
+ where <c><![CDATA[X]]></c> is an atomic literal or a variable pattern,
+ <c><![CDATA[P]]></c> is a pattern, <c><![CDATA[Gs]]></c> is a guard sequence
+ and <c><![CDATA[B]]></c> is a body, then
+ Rep(C) = <c><![CDATA[{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}]]></c>.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Guards</title>
+ <p>A guard sequence Gs is a sequence of guards <c><![CDATA[G_1; ...; G_k]]></c>, and
+ Rep(Gs) = <c><![CDATA[[Rep(G_1), ..., Rep(G_k)]]]></c>. If the guard sequence is
+ empty, Rep(Gs) = <c><![CDATA[[]]]></c>.</p>
+ <p>A guard G is a nonempty sequence of guard tests <c><![CDATA[Gt_1, ..., Gt_k]]></c>, and
+ Rep(G) = <c><![CDATA[[Rep(Gt_1), ..., Rep(Gt_k)]]]></c>.</p>
+ <p>A guard test <c><![CDATA[Gt]]></c> is one of the following alternatives:</p>
+ <list type="bulleted">
+ <item>If Gt is an atomic literal L, then Rep(Gt) = Rep(L).</item>
+ <item>If Gt is a variable pattern <c><![CDATA[V]]></c>, then
+ Rep(Gt) = <c><![CDATA[{var,LINE,A}]]></c>,
+ where A is an atom with a printname consisting of the same characters as
+ <c><![CDATA[V]]></c>.</item>
+ <item>If Gt is a tuple skeleton <c><![CDATA[{Gt_1, ..., Gt_k}]]></c>, then
+ Rep(Gt) = <c><![CDATA[{tuple,LINE,[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[[]]]></c>, then
+ Rep(Gt) = <c><![CDATA[{nil,LINE}]]></c>.</item>
+ <item>If Gt is a cons skeleton <c><![CDATA[[Gt_h | Gt_t]]]></c>, then
+ Rep(Gt) = <c><![CDATA[{cons,LINE,Rep(Gt_h),Rep(Gt_t)}]]></c>.</item>
+ <item>If Gt is a binary constructor <c><![CDATA[<<Gt_1:Size_1/TSL_1, ..., Gt_k:Size_k/TSL_k>>]]></c>, then
+ Rep(Gt) = <c><![CDATA[{bin,LINE,[{bin_element,LINE,Rep(Gt_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(Gt_k),Rep(Size_k),Rep(TSL_k)}]}]]></c>.
+ For Rep(TSL), see above.
+ An omitted <c><![CDATA[Size]]></c> is represented by <c><![CDATA[default]]></c>. An omitted <c><![CDATA[TSL]]></c>
+ (type specifier list) is represented by <c><![CDATA[default]]></c>.</item>
+ <item>If Gt is <c><![CDATA[Gt_1 Op Gt_2]]></c>, where <c><![CDATA[Op]]></c>
+ is a binary operator, then Rep(Gt) = <c><![CDATA[{op,LINE,Op,Rep(Gt_1),Rep(Gt_2)}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[Op Gt_0]]></c>, where <c><![CDATA[Op]]></c> is a unary operator, then
+ Rep(Gt) = <c><![CDATA[{op,LINE,Op,Rep(Gt_0)}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[#Name{Field_1=Gt_1, ..., Field_k=Gt_k}]]></c>, then
+ Rep(E) =
+ <c><![CDATA[{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(Gt_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(Gt_k)}]}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[#Name.Field]]></c>, then
+ Rep(Gt) = <c><![CDATA[{record_index,LINE,Name,Rep(Field)}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[Gt_0#Name.Field]]></c>, then
+ Rep(Gt) = <c><![CDATA[{record_field,LINE,Rep(Gt_0),Name,Rep(Field)}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[A(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A]]></c> is an atom, then
+ Rep(Gt) = <c><![CDATA[{call,LINE,Rep(A),[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[A_m:A(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A_m]]></c> is
+ the atom <c><![CDATA[erlang]]></c> and <c><![CDATA[A]]></c> is an atom or an operator, then
+ Rep(Gt) = <c><![CDATA[{call,LINE,{remote,LINE,Rep(A_m),Rep(A)},[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[{A_m,A}(Gt_1, ..., Gt_k)]]></c>, where <c><![CDATA[A_m]]></c> is
+ the atom <c><![CDATA[erlang]]></c> and <c><![CDATA[A]]></c> is an atom or an operator, then
+ Rep(Gt) = <c><![CDATA[{call,LINE,Rep({A_m,A}),[Rep(Gt_1), ..., Rep(Gt_k)]}]]></c>.</item>
+ <item>If Gt is <c><![CDATA[( Gt_0 )]]></c>, then
+ Rep(Gt) = <c><![CDATA[Rep(Gt_0)]]></c>,
+ i.e., parenthesized guard tests cannot be distinguished from their bodies.</item>
+ </list>
+ <p>Note that every guard test has the same source form as some expression,
+ and is represented the same way as the corresponding expression.</p>
+ </section>
+
+ <section>
+ <title>The abstract format after preprocessing</title>
+ <p>The compilation option <c><![CDATA[debug_info]]></c> can be given to the
+ compiler to have the abstract code stored in
+ the <c><![CDATA[abstract_code]]></c> chunk in the BEAM file
+ (for debugging purposes).</p>
+ <p>In OTP R9C and later, the <c><![CDATA[abstract_code]]></c> chunk will
+ contain</p>
+ <p><c><![CDATA[{raw_abstract_v1,AbstractCode}]]></c></p>
+ <p>where <c><![CDATA[AbstractCode]]></c> is the abstract code as described
+ in this document.</p>
+ <p>In releases of OTP prior to R9C, the abstract code after some more
+ processing was stored in the BEAM file. The first element of the
+ tuple would be either <c><![CDATA[abstract_v1]]></c> (R7B) or <c><![CDATA[abstract_v2]]></c>
+ (R8B).</p>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
new file mode 100644
index 0000000000..9a68b3cf40
--- /dev/null
+++ b/erts/doc/src/alt_dist.xml
@@ -0,0 +1,1099 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>How to implement an alternative carrier for the Erlang distribution</title>
+ <prepared>Patrik Nyblom</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2000-10-17</date>
+ <rev>PA2</rev>
+ <file>alt_dist.xml</file>
+ </header>
+ <p>This document describes how one can implement ones own carrier
+ protocol for the Erlang distribution. The distribution is normally
+ carried by the TCP/IP protocol. What's explained here is the method for
+ replacing TCP/IP with another protocol. </p>
+ <p>The document is a step by step explanation of the <c><![CDATA[uds_dist]]></c> example
+ application (seated in the kernel applications <c><![CDATA[examples]]></c> directory).
+ The <c><![CDATA[uds_dist]]></c> application implements distribution over Unix domain
+ sockets and is written for the Sun Solaris 2 operating environment. The
+ mechanisms are however general and applies to any operating system Erlang
+ runs on. The reason the C code is not made portable, is simply readability.</p>
+ <note><p>This document was written a long time ago. Most of it is still
+ valid, but some things have changed since it was first written.
+ Most notably the driver interface. There have been some updates
+ to the documentation of the driver presented in this documentation,
+ but more could be done and are planned for the future. The
+ reader is encouraged to also read the
+ <seealso marker="erl_driver">erl_driver</seealso>, and the
+ <seealso marker="erl_driver">driver_entry</seealso> documentation.
+ </p></note>
+
+ <section>
+ <title>Introduction</title>
+ <p>To implement a new carrier for the Erlang distribution, one must first
+ make the protocol available to the Erlang machine, which involves writing
+ an Erlang driver. There is no way one can use a port program,
+ there <em>has</em> to
+ be an Erlang driver. Erlang drivers can either be statically
+ linked
+ to the emulator, which can be an alternative when using the open source
+ distribution of Erlang, or dynamically loaded into the Erlang machines
+ address space, which is the only alternative if a precompiled version of
+ Erlang is to be used. </p>
+ <p>Writing an Erlang driver is by no means easy. The driver is written
+ as a couple of call-back functions called by the Erlang emulator when
+ data is sent to the driver or the driver has any data available on a file
+ descriptor. As the driver call-back routines execute in the main
+ thread of the Erlang machine, the call-back functions can perform
+ no blocking activity whatsoever. The call-backs should only set up
+ file descriptors for waiting and/or read/write available data. All
+ I/O has to be non blocking. Driver call-backs are however executed
+ in sequence, why a global state can safely be updated within the
+ routines. </p>
+ <p>When the driver is implemented, one would preferably write an
+ Erlang interface for the driver to be able to test the
+ functionality of the driver separately. This interface can then
+ be used by the distribution module which will cover the details of
+ the protocol from the <c><![CDATA[net_kernel]]></c>. The easiest path is to
+ mimic the <c><![CDATA[inet]]></c> and <c><![CDATA[inet_tcp]]></c> interfaces, but a lot of
+ functionality in those modules need not be implemented. In the
+ example application, only a few of the usual interfaces are
+ implemented, and they are much simplified.</p>
+ <p>When the protocol is available to Erlang through a driver and an
+ Erlang interface module, a distribution module can be
+ written. The distribution module is a module with well defined
+ call-backs, much like a <c><![CDATA[gen_server]]></c> (there is no compiler support
+ for checking the call-backs though). The details of finding other
+ nodes (i.e. talking to epmd or something similar), creating a
+ listen port (or similar), connecting to other nodes and performing
+ the handshakes/cookie verification are all implemented by this
+ module. There is however a utility module, <c><![CDATA[dist_util]]></c>, that
+ will do most of the hard work of handling handshakes, cookies,
+ timers and ticking. Using <c><![CDATA[dist_util]]></c> makes implementing a
+ distribution module much easier and that's what we are doing in
+ the example application.</p>
+ <p>The last step is to create boot scripts to make the protocol
+ implementation available at boot time. The implementation can be
+ debugged by starting the distribution when all of the system is
+ running, but in a real system the distribution should start very
+ early, why a boot-script and some command line parameters are
+ necessary. This last step also implies that the Erlang code in the
+ interface and distribution modules is written in such a way that
+ it can be run in the startup phase. Most notably there can be no
+ calls to the <c><![CDATA[application]]></c> module or to any modules not
+ loaded at boot-time (i.e. only <c><![CDATA[kernel]]></c>, <c><![CDATA[stdlib]]></c> and the
+ application itself can be used).</p>
+ </section>
+
+ <section>
+ <title>The driver</title>
+ <p>Although Erlang drivers in general may be beyond the scope of this
+ document, a brief introduction seems to be in place.</p>
+
+ <section>
+ <title>Drivers in general</title>
+ <p>An Erlang driver is a native code module written in C (or
+ assembler) which serves as an interface for some special operating
+ system service. This is a general mechanism that is used
+ throughout the Erlang emulator for all kinds of I/O. An Erlang
+ driver can be dynamically linked (or loaded) to the Erlang
+ emulator at runtime by using the <c><![CDATA[erl_ddll]]></c> Erlang
+ module. Some of the drivers in OTP are however statically linked
+ to the runtime system, but that's more an optimization than a
+ necessity.</p>
+ <p>The driver data-types and the functions available to the driver
+ writer are defined in the header file <c><![CDATA[erl_driver.h]]></c> (there
+ is also an deprecated version called <c><![CDATA[driver.h]]></c>, don't use
+ that one.) seated in Erlang's include directory (and in
+ $ERL_TOP/erts/emulator/beam in the source code
+ distribution). Refer to that file for function prototypes etc.</p>
+ <p>When writing a driver to make a communications protocol available
+ to Erlang, one should know just about everything worth knowing
+ about that particular protocol. All operation has to be non
+ blocking and all possible situations should be accounted for in
+ the driver. A non stable driver will affect and/or crash the
+ whole Erlang runtime system, which is seldom what's wanted. </p>
+ <p>The emulator calls the driver in the following situations:</p>
+ <list type="bulleted">
+ <item>When the driver is loaded. This call-back has to have a
+ special name and will inform the emulator of what call-backs should
+ be used by returning a pointer to a <c><![CDATA[ErlDrvEntry]]></c> struct,
+ which should be properly filled in (see below).</item>
+ <item>When a port to the driver is opened (by a <c><![CDATA[open_port]]></c>
+ call from Erlang). This routine should set up internal data
+ structures and return an opaque data entity of the type
+ <c><![CDATA[ErlDrvData]]></c>, which is a data-type large enough to hold a
+ pointer. The pointer returned by this function will be the first
+ argument to all other call-backs concerning this particular
+ port. It is usually called the port handle. The emulator only
+ stores the handle and does never try to interpret it, why it can
+ be virtually anything (well anything not larger than a pointer
+ that is) and can point to anything if it is a pointer. Usually
+ this pointer will refer to a structure holding information about
+ the particular port, as i t does in our example.</item>
+ <item>When an Erlang process sends data to the port. The data will
+ arrive as a buffer of bytes, the interpretation is not defined,
+ but is up to the implementor. This call-back returns nothing to the
+ caller, answers are sent to the caller as messages (using a
+ routine called <c><![CDATA[driver_output]]></c> available to all
+ drivers). There is also a way to talk in a synchronous way to
+ drivers, described below. There can be an additional call-back
+ function for handling data that is fragmented (sent in a deep
+ io-list). That interface will get the data in a form suitable for
+ Unix <c><![CDATA[writev]]></c> rather than in a single buffer. There is no
+ need for a distribution driver to implement such a call-back, so
+ we wont.</item>
+ <item>When a file descriptor is signaled for input. This call-back
+ is called when the emulator detects input on a file descriptor
+ which the driver has marked for monitoring by using the interface
+ <c><![CDATA[driver_select]]></c>. The mechanism of driver select makes it
+ possible to read non blocking from file descriptors by calling
+ <c><![CDATA[driver_select]]></c> when reading is needed and then do the actual
+ reading in this call-back (when reading is actually possible). The
+ typical scenario is that <c><![CDATA[driver_select]]></c> is called when an
+ Erlang process orders a read operation, and that this routine
+ sends the answer when data is available on the file descriptor.</item>
+ <item>When a file descriptor is signaled for output. This call-back
+ is called in a similar way as the previous, but when writing to a
+ file descriptor is possible. The usual scenario is that Erlang
+ orders writing on a file descriptor and that the driver calls
+ <c><![CDATA[driver_select]]></c>. When the descriptor is ready for output,
+ this call-back is called an the driver can try to send the
+ output. There may of course be queuing involved in such
+ operations, and there are some convenient queue routines available
+ to the driver writer to use in such situations.</item>
+ <item>When a port is closed, either by an Erlang process or by the
+ driver calling one of the <c><![CDATA[driver_failure_XXX]]></c> routines. This
+ routine should clean up everything connected to one particular
+ port. Note that when other call-backs call a
+ <c><![CDATA[driver_failure_XXX]]></c> routine, this routine will be
+ immediately called and the call-back routine issuing the error can
+ make no more use of the data structures for the port, as this
+ routine surely has freed all associated data and closed all file
+ descriptors. If the queue utility available to driver writes is
+ used, this routine will however <em>not</em> be called until the
+ queue is empty.</item>
+ <item>When an Erlang process calls <c>erlang:port_control/3</c>,
+ which is a synchronous interface to drivers. The control interface
+ is used to set driver options, change states of ports etc. We'll
+ use this interface quite a lot in our example.</item>
+ <item>When a timer expires. The driver can set timers with the
+ function <c><![CDATA[driver_set_timer]]></c>. When such timers expire, a
+ specific call-back function is called. We will not use timers in
+ our example.</item>
+ <item>When the whole driver is unloaded. Every resource allocated
+ by the driver should be freed.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>The distribution driver's data structures</title>
+ <p>The driver used for Erlang distribution should implement a
+ reliable, order maintaining, variable length packet oriented
+ protocol. All error correction, re-sending and such need to be
+ implemented in the driver or by the underlying communications
+ protocol. If the protocol is stream oriented (as is the case with
+ both TCP/IP and our streamed Unix domain sockets), some mechanism
+ for packaging is needed. We will use the simple method of having a
+ header of four bytes containing the length of the package in a big
+ endian 32 bit integer (as Unix domain sockets only can be used
+ between processes on the same machine, we actually don't need to
+ code the integer in some special endianess, but I'll do it anyway
+ because in most situation you do need to do it. Unix domain
+ sockets are reliable and order maintaining, so we don't need to
+ implement resends and such in our driver.</p>
+ <p>Lets start writing our example Unix domain sockets driver by
+ declaring prototypes and filling in a static ErlDrvEntry
+ structure.</p>
+ <code type="none"><![CDATA[
+( 1) #include <stdio.h>
+( 2) #include <stdlib.h>
+( 3) #include <string.h>
+( 4) #include <unistd.h>
+( 5) #include <errno.h>
+( 6) #include <sys/types.h>
+( 7) #include <sys/stat.h>
+( 8) #include <sys/socket.h>
+( 9) #include <sys/un.h>
+(10) #include <fcntl.h>
+
+(11) #define HAVE_UIO_H
+(12) #include "erl_driver.h"
+
+(13) /*
+(14) ** Interface routines
+(15) */
+(16) static ErlDrvData uds_start(ErlDrvPort port, char *buff);
+(17) static void uds_stop(ErlDrvData handle);
+(18) static void uds_command(ErlDrvData handle, char *buff, int bufflen);
+(19) static void uds_input(ErlDrvData handle, ErlDrvEvent event);
+(20) static void uds_output(ErlDrvData handle, ErlDrvEvent event);
+(21) static void uds_finish(void);
+(22) static int uds_control(ErlDrvData handle, unsigned int command,
+(23) char* buf, int count, char** res, int res_size);
+
+(24) /* The driver entry */
+(25) static ErlDrvEntry uds_driver_entry = {
+(26) NULL, /* init, N/A */
+(27) uds_start, /* start, called when port is opened */
+(28) uds_stop, /* stop, called when port is closed */
+(29) uds_command, /* output, called when erlang has sent */
+(30) uds_input, /* ready_input, called when input
+(31) descriptor ready */
+(32) uds_output, /* ready_output, called when output
+(33) descriptor ready */
+(34) "uds_drv", /* char *driver_name, the argument
+(35) to open_port */
+(36) uds_finish, /* finish, called when unloaded */
+(37) NULL, /* void * that is not used (BC) */
+(38) uds_control, /* control, port_control callback */
+(39) NULL, /* timeout, called on timeouts */
+(40) NULL, /* outputv, vector output interface */
+(41) NULL, /* ready_async callback */
+(42) NULL, /* flush callback */
+(43) NULL, /* call callback */
+(44) NULL, /* event callback */
+(45) ERL_DRV_EXTENDED_MARKER, /* Extended driver interface marker */
+(46) ERL_DRV_EXTENDED_MAJOR_VERSION, /* Major version number */
+(47) ERL_DRV_EXTENDED_MINOR_VERSION, /* Minor version number */
+(48) ERL_DRV_FLAG_SOFT_BUSY, /* Driver flags. Soft busy flag is
+(49) required for distribution drivers */
+(50) NULL, /* Reserved for internal use */
+(51) NULL, /* process_exit callback */
+(52) NULL /* stop_select callback */
+(53) };]]></code>
+ <p>On line 1 to 10 we have included the OS headers needed for our
+ driver. As this driver is written for Solaris, we know that the
+ header <c><![CDATA[uio.h]]></c> exists, why we can define the preprocessor
+ variable <c><![CDATA[HAVE_UIO_H]]></c> before we include <c><![CDATA[erl_driver.h]]></c>
+ at line 12. The definition of <c><![CDATA[HAVE_UIO_H]]></c> will make the
+ I/O vectors used in Erlang's driver queues to correspond to the
+ operating systems ditto, which is very convenient.</p>
+ <p>The different call-back functions are declared ("forward
+ declarations") on line 16 to 23.</p>
+ <p>The driver structure is similar for statically linked in
+ drivers and dynamically loaded. However some of the fields
+ should be left empty (i.e. initialized to NULL) in the
+ different types of drivers. The first field (the <c><![CDATA[init]]></c>
+ function pointer) is always left blank in a dynamically loaded
+ driver, which can be seen on line 26. The NULL on line 37
+ should always be there, the field is no longer used and is
+ retained for backward compatibility. We use no timers in this
+ driver, why no call-back for timers is needed. The <c>outputv</c> field
+ (line 40) can be used to implement an interface similar to
+ Unix <c><![CDATA[writev]]></c> for output. The Erlang runtime
+ system could previously not use <c>outputv</c> for the
+ distribution, but since erts version 5.7.2 it can.
+ Since this driver was written before erts version 5.7.2 it does
+ not use the <c>outputv</c> callback. Using the <c>outputv</c>
+ callback is preferred since it reduces copying of data. (We
+ will however use scatter/gather I/O internally in the driver).</p>
+ <p>As of erts version 5.5.3 the driver interface was extended with
+ version control and the possibility to pass capability information.
+ Capability flags are present at line 48. As of erts version 5.7.4
+ the
+ <seealso marker="driver_entry#driver_flags">ERL_DRV_FLAG_SOFT_BUSY</seealso>
+ flag is required for drivers that are to be used by the distribution.
+ The soft busy flag implies that the driver is capable of handling
+ calls to the <c>output</c> and <c>outputv</c> callbacks even though
+ it has marked itself as busy. This has always been a requirement
+ on drivers used by the distribution, but there have previously not
+ been any capability information available about this. For more
+ information see
+ <seealso marker="erl_driver#set_busy_port">set_busy_port()</seealso>).
+</p>
+ <p>This driver was written before the runtime system had SMP support.
+ The driver will still function in the runtime system with SMP support,
+ but performance will suffer from lock contention on the driver lock
+ used for the driver. This can be alleviated by reviewing and perhaps
+ rewriting the code so that each instance of the driver safely can
+ execute in parallel. When instances safely can execute in parallel it
+ is safe to enable instance specific locking on the driver. This is done
+ by passing
+ <seealso marker="driver_entry#driver_flags">ERL_DRV_FLAG_USE_PORT_LOCKING</seealso>
+ as a driver flag. This is left as an exercise for the reader.</p>
+ <p>Our defined call-backs thus are:</p>
+ <list type="bulleted">
+ <item>uds_start, which shall initiate data for a port. We wont
+ create any actual sockets here, just initialize data structures.</item>
+ <item>uds_stop, the function called when a port is closed.</item>
+ <item>uds_command, which will handle messages from Erlang. The
+ messages can either be plain data to be sent or more subtle
+ instructions to the driver. We will use this function mostly for
+ data pumping.</item>
+ <item>uds_input, this is the call-back which is called when we have
+ something to read from a socket.</item>
+ <item>uds_output, this is the function called when we can write to a
+ socket.</item>
+ <item>uds_finish, which is called when the driver is unloaded. A
+ distribution driver will actually (or hopefully) never be unloaded,
+ but we include this for completeness. Being able to clean up after
+ oneself is always a good thing.</item>
+ <item>uds_control, the <c>erlang:port_control/2</c> call-back, which
+ will be used a lot in this implementation.</item>
+ </list>
+ <p>The ports implemented by this driver will operate in two major
+ modes, which i will call the <em>command</em> and <em>data</em>
+ modes. In command mode, only passive reading and writing (like
+ gen_tcp:recv/gen_tcp:send) can be
+ done, and this is the mode the port will be in during the
+ distribution handshake. When the connection is up, the port will
+ be switched to data mode and all data will be immediately read and
+ passed further to the Erlang emulator. In data mode, no data
+ arriving to the uds_command will be interpreted, but just packaged
+ and sent out on the socket. The uds_control call-back will do the
+ switching between those two modes.</p>
+ <p>While the <c><![CDATA[net_kernel]]></c> informs different subsystems that the
+ connection is coming up, the port should accept data to send, but
+ not receive any data, to avoid that data arrives from another node
+ before every kernel subsystem is prepared to handle it. We have a
+ third mode for this intermediate stage, lets call it the
+ <em>intermediate</em> mode.</p>
+ <p>Lets define an enum for the different types of ports we have:</p>
+ <code type="none"><![CDATA[
+( 1) typedef enum {
+( 2) portTypeUnknown, /* An uninitialized port */
+( 3) portTypeListener, /* A listening port/socket */
+( 4) portTypeAcceptor, /* An intermidiate stage when accepting
+( 5) on a listen port */
+( 6) portTypeConnector, /* An intermediate stage when connecting */
+( 7) portTypeCommand, /* A connected open port in command mode */
+( 8) portTypeIntermediate, /* A connected open port in special
+( 9) half active mode */
+(10) portTypeData /* A connectec open port in data mode */
+(11) } PortType; ]]></code>
+ <p>Lets look at the different types:</p>
+ <list type="bulleted">
+ <item>portTypeUnknown - The type a port has when it's opened, but
+ not actually bound to any file descriptor.</item>
+ <item>portTypeListener - A port that is connected to a listen
+ socket. This port will not do especially much, there will be no data
+ pumping done on this socket, but there will be read data available
+ when one is trying to do an accept on the port.</item>
+ <item>portTypeAcceptor - This is a port that is to represent the
+ result of an accept operation. It is created when one wants to
+ accept from a listen socket, and it will be converted to a
+ portTypeCommand when the accept succeeds.</item>
+ <item>portTypeConnector - Very similar to portTypeAcceptor, an
+ intermediate stage between the request for a connect operation and
+ that the socket is really connected to an accepting ditto in the
+ other end. As soon as the sockets are connected, the port will
+ switch type to portTypeCommand.</item>
+ <item>portTypeCommand - A connected socket (or accepted socket if
+ you want) that is in the command mode mentioned earlier.</item>
+ <item>portTypeIntermediate - The intermediate stage for a connected
+ socket. There should be no processing of input for this socket.</item>
+ <item>portTypeData - The mode where data is pumped through the port
+ and the uds_command routine will regard every call as a call where
+ sending is wanted. In this mode all input available will be read and
+ sent to Erlang as soon as it arrives on the socket, much like in the
+ active mode of a <c><![CDATA[gen_tcp]]></c> socket.</item>
+ </list>
+ <p>Now lets look at the state we'll need for our ports. One can note
+ that not all fields are used for all types of ports and that one
+ could save some space by using unions, but that would clutter the
+ code with multiple indirections, so i simply use one struct for
+ all types of ports, for readability.</p>
+ <code type="none"><![CDATA[
+( 1) typedef unsigned char Byte;
+( 2) typedef unsigned int Word;
+
+( 3) typedef struct uds_data {
+( 4) int fd; /* File descriptor */
+( 5) ErlDrvPort port; /* The port identifier */
+( 6) int lockfd; /* The file descriptor for a lock file in
+( 7) case of listen sockets */
+( 8) Byte creation; /* The creation serial derived from the
+( 9) lockfile */
+(10) PortType type; /* Type of port */
+(11) char *name; /* Short name of socket for unlink */
+(12) Word sent; /* Bytes sent */
+(13) Word received; /* Bytes received */
+(14) struct uds_data *partner; /* The partner in an accept/listen pair */
+(15) struct uds_data *next; /* Next structure in list */
+(16) /* The input buffer and it's data */
+(17) int buffer_size; /* The allocated size of the input buffer */
+(18) int buffer_pos; /* Current position in input buffer */
+(19) int header_pos; /* Where the current header is in the
+(20) input buffer */
+(21) Byte *buffer; /* The actual input buffer */
+(22) } UdsData; ]]></code>
+ <p>This structure is used for all types of ports although some
+ fields are useless for some types. The least memory consuming
+ solution would be to arrange this structure as a union of
+ structures, but the multiple indirections in the code to
+ access a field in such a structure will clutter the code to
+ much for an example.</p>
+ <p>Let's look at the fields in our structure:</p>
+ <list type="bulleted">
+ <item>fd - The file descriptor of the socket associated with the
+ port.</item>
+ <item>port - The port identifier for the port which this structure
+ corresponds to. It is needed for most <c><![CDATA[driver_XXX]]></c>
+ calls from the driver back to the emulator.</item>
+ <item>
+ <p>lockfd - If the socket is a listen socket, we use a separate
+ (regular) file for two purposes:</p>
+ <list type="bulleted">
+ <item>We want a locking mechanism that gives no race
+ conditions, so that we can be sure of if another Erlang
+ node uses the listen socket name we require or if the
+ file is only left there from a previous (crashed)
+ session.</item>
+ <item>
+ <p>We store the <em>creation</em> serial number in the
+ file. The <em>creation</em> is a number that should
+ change between different instances of different Erlang
+ emulators with the same name, so that process
+ identifiers from one emulator won't be valid when sent
+ to a new emulator with the same distribution name. The
+ creation can be between 0 and 3 (two bits) and is stored
+ in every process identifier sent to another node. </p>
+ <p>In a system with TCP based distribution, this data is
+ kept in the <em>Erlang port mapper daemon</em>
+ (<c><![CDATA[epmd]]></c>), which is contacted when a distributed
+ node starts. The lock-file and a convention for the UDS
+ listen socket's name will remove the need for
+ <c><![CDATA[epmd]]></c> when using this distribution module. UDS
+ is always restricted to one host, why avoiding a port
+ mapper is easy.</p>
+ </item>
+ </list>
+ </item>
+ <item>creation - The creation number for a listen socket, which is
+ calculated as (the value found in the lock-file + 1) rem
+ 4. This creation value is also written back into the
+ lock-file, so that the next invocation of the emulator will
+ found our value in the file.</item>
+ <item>type - The current type/state of the port, which can be one
+ of the values declared above.</item>
+ <item>name - The name of the socket file (the path prefix
+ removed), which allows for deletion (<c><![CDATA[unlink]]></c>) when the
+ socket is closed.</item>
+ <item>sent - How many bytes that have been sent over the
+ socket. This may wrap, but that's no problem for the
+ distribution, as the only thing that interests the Erlang
+ distribution is if this value has changed (the Erlang
+ net_kernel <em>ticker</em> uses this value by calling the
+ driver to fetch it, which is done through the
+ <c>erlang:port_control</c> routine).</item>
+ <item>received - How many bytes that are read (received) from the
+ socket, used in similar ways as <c><![CDATA[sent]]></c>.</item>
+ <item>partner - A pointer to another port structure, which is
+ either the listen port from which this port is accepting a
+ connection or the other way around. The "partner relation"
+ is always bidirectional.</item>
+ <item>next - Pointer to next structure in a linked list of all
+ port structures. This list is used when accepting
+ connections and when the driver is unloaded.</item>
+ <item>buffer_size, buffer_pos, header_pos, buffer - data for input
+ buffering. Refer to the source code (in the kernel/examples
+ directory) for details about the input buffering. That
+ certainly goes beyond the scope of this document.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Selected parts of the distribution driver implementation</title>
+ <p>The distribution drivers implementation is not completely
+ covered in this text, details about buffering and other things
+ unrelated to driver writing are not explained. Likewise are
+ some peculiarities of the UDS protocol not explained in
+ detail. The chosen protocol is not important.</p>
+ <p>Prototypes for the driver call-back routines can be found in
+ the <c><![CDATA[erl_driver.h]]></c> header file.</p>
+ <p>The driver initialization routine is (usually) declared with a
+ macro to make the driver easier to port between different
+ operating systems (and flavours of systems). This is the only
+ routine that has to have a well defined name. All other
+ call-backs are reached through the driver structure. The macro
+ to use is named <c><![CDATA[DRIVER_INIT]]></c> and takes the driver name
+ as parameter.</p>
+ <code type="none"><![CDATA[
+(1) /* Beginning of linked list of ports */
+(2) static UdsData *first_data;
+
+
+(3) DRIVER_INIT(uds_drv)
+(4) {
+(5) first_data = NULL;
+(6) return &uds_driver_entry;
+(7) } ]]></code>
+ <p>The routine initializes the single global data structure and
+ returns a pointer to the driver entry. The routine will be
+ called when <c><![CDATA[erl_ddll:load_driver]]></c> is called from Erlang.</p>
+ <p>The <c><![CDATA[uds_start]]></c> routine is called when a port is opened
+ from Erlang. In our case, we only allocate a structure and
+ initialize it. Creating the actual socket is left to the
+ <c><![CDATA[uds_command]]></c> routine.</p>
+ <code type="none"><![CDATA[
+( 1) static ErlDrvData uds_start(ErlDrvPort port, char *buff)
+( 2) {
+( 3) UdsData *ud;
+( 4)
+( 5) ud = ALLOC(sizeof(UdsData));
+( 6) ud->fd = -1;
+( 7) ud->lockfd = -1;
+( 8) ud->creation = 0;
+( 9) ud->port = port;
+(10) ud->type = portTypeUnknown;
+(11) ud->name = NULL;
+(12) ud->buffer_size = 0;
+(13) ud->buffer_pos = 0;
+(14) ud->header_pos = 0;
+(15) ud->buffer = NULL;
+(16) ud->sent = 0;
+(17) ud->received = 0;
+(18) ud->partner = NULL;
+(19) ud->next = first_data;
+(20) first_data = ud;
+(21)
+(22) return((ErlDrvData) ud);
+(23) } ]]></code>
+ <p>Every data item is initialized, so that no problems will arise
+ when a newly created port is closed (without there being any
+ corresponding socket). This routine is called when
+ <c><![CDATA[open_port({spawn, "uds_drv"},[])]]></c> is called from Erlang.</p>
+ <p>The <c><![CDATA[uds_command]]></c> routine is the routine called when an
+ Erlang process sends data to the port. All asynchronous
+ commands when the port is in <em>command mode</em> as well as
+ the sending of all data when the port is in <em>data mode</em>
+ is handled in this9s routine. Let's have a look at it:</p>
+ <code type="none"><![CDATA[
+( 1) static void uds_command(ErlDrvData handle, char *buff, int bufflen)
+( 2) {
+( 3) UdsData *ud = (UdsData *) handle;
+
+( 4) if (ud->type == portTypeData || ud->type == portTypeIntermediate) {
+( 5) DEBUGF(("Passive do_send %d",bufflen));
+( 6) do_send(ud, buff + 1, bufflen - 1); /* XXX */
+( 7) return;
+( 8) }
+( 9) if (bufflen == 0) {
+(10) return;
+(11) }
+(12) switch (*buff) {
+(13) case 'L':
+(14) if (ud->type != portTypeUnknown) {
+(15) driver_failure_posix(ud->port, ENOTSUP);
+(16) return;
+(17) }
+(18) uds_command_listen(ud,buff,bufflen);
+(19) return;
+(20) case 'A':
+(21) if (ud->type != portTypeUnknown) {
+(22) driver_failure_posix(ud->port, ENOTSUP);
+(23) return;
+(24) }
+(25) uds_command_accept(ud,buff,bufflen);
+(26) return;
+(27) case 'C':
+(28) if (ud->type != portTypeUnknown) {
+(29) driver_failure_posix(ud->port, ENOTSUP);
+(30) return;
+(31) }
+(32) uds_command_connect(ud,buff,bufflen);
+(33) return;
+(34) case 'S':
+(35) if (ud->type != portTypeCommand) {
+(36) driver_failure_posix(ud->port, ENOTSUP);
+(37) return;
+(38) }
+(39) do_send(ud, buff + 1, bufflen - 1);
+(40) return;
+(41) case 'R':
+(42) if (ud->type != portTypeCommand) {
+(43) driver_failure_posix(ud->port, ENOTSUP);
+(44) return;
+(45) }
+(46) do_recv(ud);
+(47) return;
+(48) default:
+(49) return;
+(50) }
+(51) } ]]></code>
+ <p>The command routine takes three parameters; the handle
+ returned for the port by <c><![CDATA[uds_start]]></c>, which is a pointer
+ to the internal port structure, the data buffer and the length
+ of the data buffer. The buffer is the data sent from Erlang
+ (a list of bytes) converted to an C array (of bytes). </p>
+ <p>If Erlang sends i.e. the list <c><![CDATA[[$a,$b,$c]]]></c> to the port,
+ the <c><![CDATA[bufflen]]></c> variable will be <c><![CDATA[3]]></c> ant the
+ <c><![CDATA[buff]]></c> variable will contain <c><![CDATA[{'a','b','c'}]]></c> (no
+ null termination). Usually the first byte is used as an
+ opcode, which is the case in our driver to (at least when the
+ port is in command mode). The opcodes are defined as:</p>
+ <list type="bulleted">
+ <item>'L'&lt;socketname&gt;: Create and listen on socket with the
+ given name.</item>
+ <item>'A'&lt;listennumber as 32 bit bigendian&gt;: Accept from the
+ listen socket identified by the given identification
+ number. The identification number is retrieved with the
+ uds_control routine.</item>
+ <item>'C'&lt;socketname&gt;: Connect to the socket named
+ &lt;socketname&gt;.</item>
+ <item>'S'&lt;data&gt;: Send the data &lt;data&gt; on the
+ connected/accepted socket (in command mode). The sending is
+ acked when the data has left this process.</item>
+ <item>'R': Receive one packet of data.</item>
+ </list>
+ <p>One may wonder what is meant by "one packet of data" in the
+ 'R' command. This driver always sends data packeted with a 4
+ byte header containing a big endian 32 bit integer that
+ represents the length of the data in the packet. There is no
+ need for different packet sizes or some kind of streamed
+ mode, as this driver is for the distribution only. One may
+ wonder why the header word is coded explicitly in big endian
+ when an UDS socket is local to the host. The answer simply is
+ that I see it as a good practice when writing a distribution
+ driver, as distribution in practice usually cross the host
+ boundaries. </p>
+ <p>On line 4-8 we handle the case where the port is in data or
+ intermediate mode, the rest of the routine handles the
+ different commands. We see (first on line 15) that the routine
+ uses the <c><![CDATA[driver_failure_posix()]]></c> routine to report
+ errors. One important thing to remember is that the failure
+ routines make a call to our <c><![CDATA[uds_stop]]></c> routine, which
+ will remove the internal port data. The handle (and the casted
+ handle <c><![CDATA[ud]]></c>) is therefore <em>invalid pointers</em> after a
+ <c><![CDATA[driver_failure]]></c> call and we should <em>immediately return</em>. The runtime system will send exit signals to all
+ linked processes.</p>
+ <p>The uds_input routine gets called when data is available on a
+ file descriptor previously passed to the <c><![CDATA[driver_select]]></c>
+ routine. Typically this happens when a read command is issued
+ and no data is available. Lets look at the <c><![CDATA[do_recv]]></c>
+ routine:</p>
+ <code type="none"><![CDATA[
+( 1) static void do_recv(UdsData *ud)
+( 2) {
+( 3) int res;
+( 4) char *ibuf;
+( 5) for(;;) {
+( 6) if ((res = buffered_read_package(ud,&ibuf)) < 0) {
+( 7) if (res == NORMAL_READ_FAILURE) {
+( 8) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 1);
+( 9) } else {
+(10) driver_failure_eof(ud->port);
+(11) }
+(12) return;
+(13) }
+(14) /* Got a package */
+(15) if (ud->type == portTypeCommand) {
+(16) ibuf[-1] = 'R'; /* There is always room for a single byte
+(17) opcode before the actual buffer
+(18) (where the packet header was) */
+(19) driver_output(ud->port,ibuf - 1, res + 1);
+(20) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ,0);
+(21) return;
+(22) } else {
+(23) ibuf[-1] = DIST_MAGIC_RECV_TAG; /* XXX */
+(24) driver_output(ud->port,ibuf - 1, res + 1);
+(25) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ,1);
+(26) }
+(27) }
+(28) } ]]></code>
+ <p>The routine tries to read data until a packet is read or the
+ <c><![CDATA[buffered_read_package]]></c> routine returns a
+ <c><![CDATA[NORMAL_READ_FAILURE]]></c> (an internally defined constant for
+ the module that means that the read operation resulted in an
+ <c><![CDATA[EWOULDBLOCK]]></c>). If the port is in command mode, the
+ reading stops when one package is read, but if it is in data
+ mode, the reading continues until the socket buffer is empty
+ (read failure). If no more data can be read and more is wanted
+ (always the case when socket is in data mode) driver_select is
+ called to make the <c><![CDATA[uds_input]]></c> call-back be called when
+ more data is available for reading.</p>
+ <p>When the port is in data mode, all data is sent to Erlang in a
+ format that suits the distribution, in fact the raw data will
+ never reach any Erlang process, but will be
+ translated/interpreted by the emulator itself and then
+ delivered in the correct format to the correct processes. In
+ the current emulator version, received data should be tagged
+ with a single byte of 100. Thats what the macro
+ <c><![CDATA[DIST_MAGIC_RECV_TAG]]></c> is defined to. The tagging of data
+ in the distribution will possibly change in the future.</p>
+ <p>The <c><![CDATA[uds_input]]></c> routine will handle other input events
+ (like nonblocking <c><![CDATA[accept]]></c>), but most importantly handle
+ data arriving at the socket by calling <c><![CDATA[do_recv]]></c>:</p>
+ <code type="none"><![CDATA[
+( 1) static void uds_input(ErlDrvData handle, ErlDrvEvent event)
+( 2) {
+( 3) UdsData *ud = (UdsData *) handle;
+
+( 4) if (ud->type == portTypeListener) {
+( 5) UdsData *ad = ud->partner;
+( 6) struct sockaddr_un peer;
+( 7) int pl = sizeof(struct sockaddr_un);
+( 8) int fd;
+
+( 9) if ((fd = accept(ud->fd, (struct sockaddr *) &peer, &pl)) < 0) {
+(10) if (errno != EWOULDBLOCK) {
+(11) driver_failure_posix(ud->port, errno);
+(12) return;
+(13) }
+(14) return;
+(15) }
+(16) SET_NONBLOCKING(fd);
+(17) ad->fd = fd;
+(18) ad->partner = NULL;
+(19) ad->type = portTypeCommand;
+(20) ud->partner = NULL;
+(21) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0);
+(22) driver_output(ad->port, "Aok",3);
+(23) return;
+(24) }
+(25) do_recv(ud);
+(26) } ]]></code>
+ <p>The important line here is the last line in the function, the
+ <c><![CDATA[do_read]]></c> routine is called to handle new input. The rest
+ of the function handles input on a listen socket, which means
+ that there should be possible to do an accept on the
+ socket, which is also recognized as a read event.</p>
+ <p>The output mechanisms are similar to the input. Lets first
+ look at the <c><![CDATA[do_send]]></c> routine:</p>
+ <code type="none"><![CDATA[
+( 1) static void do_send(UdsData *ud, char *buff, int bufflen)
+( 2) {
+( 3) char header[4];
+( 4) int written;
+( 5) SysIOVec iov[2];
+( 6) ErlIOVec eio;
+( 7) ErlDrvBinary *binv[] = {NULL,NULL};
+
+( 8) put_packet_length(header, bufflen);
+( 9) iov[0].iov_base = (char *) header;
+(10) iov[0].iov_len = 4;
+(11) iov[1].iov_base = buff;
+(12) iov[1].iov_len = bufflen;
+(13) eio.iov = iov;
+(14) eio.binv = binv;
+(15) eio.vsize = 2;
+(16) eio.size = bufflen + 4;
+(17) written = 0;
+(18) if (driver_sizeq(ud->port) == 0) {
+(19) if ((written = writev(ud->fd, iov, 2)) == eio.size) {
+(20) ud->sent += written;
+(21) if (ud->type == portTypeCommand) {
+(22) driver_output(ud->port, "Sok", 3);
+(23) }
+(24) return;
+(25) } else if (written < 0) {
+(26) if (errno != EWOULDBLOCK) {
+(27) driver_failure_eof(ud->port);
+(28) return;
+(29) } else {
+(30) written = 0;
+(31) }
+(32) } else {
+(33) ud->sent += written;
+(34) }
+(35) /* Enqueue remaining */
+(36) }
+(37) driver_enqv(ud->port, &eio, written);
+(38) send_out_queue(ud);
+(39) } ]]></code>
+ <p>This driver uses the <c><![CDATA[writev]]></c> system call to send data
+ onto the socket. A combination of writev and the driver output
+ queues is very convenient. An <em>ErlIOVec</em> structure
+ contains a <em>SysIOVec</em> (which is equivalent to the
+ <c><![CDATA[struct iovec]]></c> structure defined in <c><![CDATA[uio.h]]></c>. The
+ ErlIOVec also contains an array of <em>ErlDrvBinary</em>
+ pointers, of the same length as the number of buffers in the
+ I/O vector itself. One can use this to allocate the binaries
+ for the queue "manually" in the driver, but we'll just fill
+ the binary array with NULL values (line 7) , which will make
+ the runtime system allocate it's own buffers when we call
+ <c><![CDATA[driver_enqv]]></c> (line 37).</p>
+ <p></p>
+ <p>The routine builds an I/O vector containing the header bytes
+ and the buffer (the opcode has been removed and the buffer
+ length decreased by the output routine). If the queue is
+ empty, we'll write the data directly to the socket (or at
+ least try to). If any data is left, it is stored in the queue
+ and then we try to send the queue (line 38). An ack is sent
+ when the message is delivered completely (line 22). The
+ <c><![CDATA[send_out_queue]]></c> will send acks if the sending is
+ completed there. If the port is in command mode, the Erlang
+ code serializes the send operations so that only one packet
+ can be waiting for delivery at a time. Therefore the ack can
+ be sent simply whenever the queue is empty.</p>
+ <p></p>
+ <p>A short look at the <c><![CDATA[send_out_queue]]></c> routine:</p>
+ <code type="none"><![CDATA[
+( 1) static int send_out_queue(UdsData *ud)
+( 2) {
+( 3) for(;;) {
+( 4) int vlen;
+( 5) SysIOVec *tmp = driver_peekq(ud->port, &vlen);
+( 6) int wrote;
+( 7) if (tmp == NULL) {
+( 8) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_WRITE, 0);
+( 9) if (ud->type == portTypeCommand) {
+(10) driver_output(ud->port, "Sok", 3);
+(11) }
+(12) return 0;
+(13) }
+(14) if (vlen > IO_VECTOR_MAX) {
+(15) vlen = IO_VECTOR_MAX;
+(16) }
+(17) if ((wrote = writev(ud->fd, tmp, vlen)) < 0) {
+(18) if (errno == EWOULDBLOCK) {
+(19) driver_select(ud->port, (ErlDrvEvent) ud->fd,
+(20) DO_WRITE, 1);
+(21) return 0;
+(22) } else {
+(23) driver_failure_eof(ud->port);
+(24) return -1;
+(25) }
+(26) }
+(27) driver_deq(ud->port, wrote);
+(28) ud->sent += wrote;
+(29) }
+(30) } ]]></code>
+ <p>What we do is simply to pick out an I/O vector from the queue
+ (which is the whole queue as an <em>SysIOVec</em>). If the I/O
+ vector is to long (IO_VECTOR_MAX is defined to 16), the vector
+ length is decreased (line 15), otherwise the <c><![CDATA[writev]]></c>
+ (line 17) call will
+ fail. Writing is tried and anything written is dequeued (line
+ 27). If the write fails with <c><![CDATA[EWOULDBLOCK]]></c> (note that all
+ sockets are in nonblocking mode), <c><![CDATA[driver_select]]></c> is
+ called to make the <c><![CDATA[uds_output]]></c> routine be called when
+ there is space to write again.</p>
+ <p>We will continue trying to write until the queue is empty or
+ the writing would block.</p>
+ <p>The routine above are called from the <c><![CDATA[uds_output]]></c>
+ routine, which looks like this:</p>
+ <code type="none"><![CDATA[
+( 1) static void uds_output(ErlDrvData handle, ErlDrvEvent event)
+( 2) {
+( 3) UdsData *ud = (UdsData *) handle;
+( 4) if (ud->type == portTypeConnector) {
+( 5) ud->type = portTypeCommand;
+( 6) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_WRITE, 0);
+( 7) driver_output(ud->port, "Cok",3);
+( 8) return;
+( 9) }
+(10) send_out_queue(ud);
+(11) } ]]></code>
+ <p>The routine is simple, it first handles the fact that the
+ output select will concern a socket in the business of
+ connecting (and the connecting blocked). If the socket is in
+ a connected state it simply sends the output queue, this
+ routine is called when there is possible to write to a socket
+ where we have an output queue, so there is no question what to
+ do.</p>
+ <p>The driver implements a control interface, which is a
+ synchronous interface called when Erlang calls
+ <c><![CDATA[erlang:port_control/3]]></c>. This is the only interface
+ that can control the driver when it is in data mode and it may
+ be called with the following opcodes:</p>
+ <list type="bulleted">
+ <item>'C': Set port in command mode.</item>
+ <item>'I': Set port in intermediate mode.</item>
+ <item>'D': Set port in data mode.</item>
+ <item>'N': Get identification number for listen port, this
+ identification number is used in an accept command to the
+ driver, it is returned as a big endian 32 bit integer, which
+ happens to be the file identifier for the listen socket.</item>
+ <item>'S': Get statistics, which is the number of bytes received,
+ the number of bytes sent and the number of bytes pending in
+ the output queue. This data is used when the distribution
+ checks that a connection is alive (ticking). The statistics
+ is returned as 3 32 bit big endian integers.</item>
+ <item>'T': Send a tick message, which is a packet of length
+ 0. Ticking is done when the port is in data mode, so the
+ command for sending data cannot be used (besides it ignores
+ zero length packages in command mode). This is used by the
+ ticker to send dummy data when no other traffic is present.
+ <em>Note</em> that it is important that the interface for
+ sending ticks is not blocking. This implementation uses
+ <c>erlang:port_control/3</c> which does not block the caller.
+ If <c>erlang:port_command</c> is used, use
+ <c>erlang:port_command/3</c> and pass <c>[force]</c> as
+ option list; otherwise, the caller can be blocked indefinitely
+ on a busy port and prevent the system from taking down a
+ connection that is not functioning.</item>
+ <item>'R': Get creation number of listen socket, which is used to
+ dig out the number stored in the lock file to differentiate
+ between invocations of Erlang nodes with the same name.\011 </item>
+ </list>
+ <p>The control interface gets a buffer to return its value in,
+ but is free to allocate it's own buffer is the provided one is
+ to small. Here is the code for <c><![CDATA[uds_control]]></c>:</p>
+ <code type="none"><![CDATA[
+( 1) static int uds_control(ErlDrvData handle, unsigned int command,
+( 2) char* buf, int count, char** res, int res_size)
+( 3) {
+( 4) /* Local macro to ensure large enough buffer. */
+( 5) #define ENSURE(N) \\
+( 6) do { \\
+( 7) if (res_size < N) { \\
+( 8) *res = ALLOC(N); \\
+( 9) } \\
+(10) } while(0)
+
+(11) UdsData *ud = (UdsData *) handle;
+
+(12) switch (command) {
+(13) case 'S':
+(14) {
+(15) ENSURE(13);
+(16) **res = 0;
+(17) put_packet_length((*res) + 1, ud->received);
+(18) put_packet_length((*res) + 5, ud->sent);
+(19) put_packet_length((*res) + 9, driver_sizeq(ud->port));
+(20) return 13;
+(21) }
+(22) case 'C':
+(23) if (ud->type < portTypeCommand) {
+(24) return report_control_error(res, res_size, "einval");
+(25) }
+(26) ud->type = portTypeCommand;
+(27) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0);
+(28) ENSURE(1);
+(29) **res = 0;
+(30) return 1;
+(31) case 'I':
+(32) if (ud->type < portTypeCommand) {
+(33) return report_control_error(res, res_size, "einval");
+(34) }
+(35) ud->type = portTypeIntermediate;
+(36) driver_select(ud->port, (ErlDrvEvent) ud->fd, DO_READ, 0);
+(37) ENSURE(1);
+(38) **res = 0;
+(39) return 1;
+(40) case 'D':
+(41) if (ud->type < portTypeCommand) {
+(42) return report_control_error(res, res_size, "einval");
+(43) }
+(44) ud->type = portTypeData;
+(45) do_recv(ud);
+(46) ENSURE(1);
+(47) **res = 0;
+(48) return 1;
+(49) case 'N':
+(50) if (ud->type != portTypeListener) {
+(51) return report_control_error(res, res_size, "einval");
+(52) }
+(53) ENSURE(5);
+(54) (*res)[0] = 0;
+(55) put_packet_length((*res) + 1, ud->fd);
+(56) return 5;
+(57) case 'T': /* tick */
+(58) if (ud->type != portTypeData) {
+(59) return report_control_error(res, res_size, "einval");
+(60) }
+(61) do_send(ud,"",0);
+(62) ENSURE(1);
+(63) **res = 0;
+(64) return 1;
+(65) case 'R':
+(66) if (ud->type != portTypeListener) {
+(67) return report_control_error(res, res_size, "einval");
+(68) }
+(69) ENSURE(2);
+(70) (*res)[0] = 0;
+(71) (*res)[1] = ud->creation;
+(72) return 2;
+(73) default:
+(74) return report_control_error(res, res_size, "einval");
+(75) }
+(76) #undef ENSURE
+(77) } ]]></code>
+ <p>The macro <c><![CDATA[ENSURE]]></c> (line 5 to 10) is used to ensure that
+ the buffer is large enough for our answer. We switch on the
+ command and take actions, there is not much to say about this
+ routine. Worth noting is that we always has read select active
+ on a port in data mode (achieved by calling <c><![CDATA[do_recv]]></c> on
+ line 45), but turn off read selection in intermediate and
+ command modes (line 27 and 36).</p>
+ <p>The rest of the driver is more or less UDS specific and not of
+ general interest.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Putting it all together</title>
+ <p>To test the distribution, one can use the
+ <c><![CDATA[net_kernel:start/1]]></c> function, which is useful as it starts
+ the distribution on a running system, where tracing/debugging
+ can be performed. The <c><![CDATA[net_kernel:start/1]]></c> routine takes a
+ list as it's single argument. The lists first element should be
+ the node name (without the "@hostname") as an atom, and the second (and
+ last) element should be one of the atoms <c><![CDATA[shortnames]]></c> or
+ <c><![CDATA[longnames]]></c>. In the example case <c><![CDATA[shortnames]]></c> is
+ preferred. </p>
+ <p>For net kernel to find out which distribution module to use, the
+ command line argument <c><![CDATA[-proto_dist]]></c> is used. The argument
+ is followed by one or more distribution module names, with the
+ "_dist" suffix removed, i.e. uds_dist as a distribution module
+ is specified as <c><![CDATA[-proto_dist uds]]></c>.</p>
+ <p>If no epmd (TCP port mapper daemon) is used, one should also
+ specify the command line option <c><![CDATA[-no_epmd]]></c>, which will make
+ Erlang skip the epmd startup, both as a OS process and as an
+ Erlang ditto.</p>
+ <p>The path to the directory where the distribution modules reside
+ must be known at boot, which can either be achieved by
+ specifying <c><![CDATA[-pa <path>]]></c> on the command line or by building
+ a boot script containing the applications used for your
+ distribution protocol (in the uds_dist protocol, it's only the
+ uds_dist application that needs to be added to the script).</p>
+ <p>The distribution will be started at boot if all the above is
+ specified and an <c><![CDATA[-sname <name>]]></c> flag is present at the
+ command line, here follows two examples: </p>
+ <pre>
+$ <input>erl -pa $ERL_TOP/lib/kernel/examples/uds_dist/ebin -proto_dist uds -no_epmd</input>
+Erlang (BEAM) emulator version 5.0
+
+Eshell V5.0 (abort with ^G)
+1> <input>net_kernel:start([bing,shortnames]).</input>
+{ok,&lt;0.30.0>}
+(bing@hador)2></pre>
+ <p>...</p>
+ <pre>
+$ <input>erl -pa $ERL_TOP/lib/kernel/examples/uds_dist/ebin -proto_dist uds \\ </input>
+<input> -no_epmd -sname bong</input>
+Erlang (BEAM) emulator version 5.0
+
+Eshell V5.0 (abort with ^G)
+(bong@hador)1></pre>
+ <p>One can utilize the ERL_FLAGS environment variable to store the
+ complicated parameters in:</p>
+ <pre>
+$ <input>ERL_FLAGS=-pa $ERL_TOP/lib/kernel/examples/uds_dist/ebin \\ </input>
+<input> -proto_dist uds -no_epmd</input>
+$ <input>export ERL_FLAGS</input>
+$ <input>erl -sname bang</input>
+Erlang (BEAM) emulator version 5.0
+
+Eshell V5.0 (abort with ^G)
+(bang@hador)1></pre>
+ <p>The <c><![CDATA[ERL_FLAGS]]></c> should preferably not include the name of
+ the node.</p>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/book.xml b/erts/doc/src/book.xml
new file mode 100644
index 0000000000..00a2888685
--- /dev/null
+++ b/erts/doc/src/book.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE book SYSTEM "book.dtd">
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header titlestyle="normal">
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Erlang Run-Time System Application (ERTS)</title>
+ <prepared>Magnus Fr&ouml;berg</prepared>
+ <docno></docno>
+ <date>1997-05-02</date>
+ <rev>4.5.2</rev>
+ <file>book.xml</file>
+ </header>
+ <insidecover>
+ </insidecover>
+ <pagetext>Erlang Run-Time System Application (ERTS)</pagetext>
+ <preamble>
+ <contents level="2"></contents>
+ </preamble>
+ <parts lift="no">
+ <xi:include href="part.xml"/>
+ </parts>
+ <applications>
+ <xi:include href="ref_man.xml"/>
+ </applications>
+ <releasenotes>
+ <xi:include href="notes.xml"/>
+ </releasenotes>
+ <listofterms></listofterms>
+ <index></index>
+</book>
+
diff --git a/erts/doc/src/crash_dump.xml b/erts/doc/src/crash_dump.xml
new file mode 100644
index 0000000000..5182929358
--- /dev/null
+++ b/erts/doc/src/crash_dump.xml
@@ -0,0 +1,518 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1999</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>How to interpret the Erlang crash dumps</title>
+ <prepared>Patrik Nyblom</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>1999-11-11</date>
+ <rev>PA1</rev>
+ <file>crash_dump.xml</file>
+ </header>
+ <p>This document describes the <c><![CDATA[erl_crash.dump]]></c> file generated
+ upon abnormal exit of the Erlang runtime system.</p>
+ <p><em>Important:</em> For OTP release R9C the Erlang crash dump has
+ had a major facelift. This means that the information in this
+ document will not be directly applicable for older dumps. However,
+ if you use the Crashdump Viewer tool on older dumps, the crash
+ dumps are translated into a format similar to this.</p>
+ <p>The system will write the crash dump in the current directory of
+ the emulator or in the file pointed out by the environment variable
+ (whatever that means on the current operating system)
+ ERL_CRASH_DUMP. For a crash dump to be written, there has to be a
+ writable file system mounted.</p>
+ <p>Crash dumps are written mainly for one of two reasons: either the
+ builtin function <c><![CDATA[erlang:halt/1]]></c> is called explicitly with a
+ string argument from running Erlang code, or else the runtime
+ system has detected an error that cannot be handled. The most
+ usual reason that the system can't handle the error is that the
+ cause is external limitations, such as running out of memory. A
+ crash dump due to an internal error may be caused by the system
+ reaching limits in the emulator itself (like the number of atoms
+ in the system, or too many simultaneous ets tables). Usually the
+ emulator or the operating system can be reconfigured to avoid the
+ crash, which is why interpreting the crash dump correctly is
+ important.</p>
+ <p>The erlang crash dump is a readable text file, but it might not be
+ very easy to read. Using the Crashdump Viewer tool in the
+ <c><![CDATA[observer]]></c> application will simplify the task. This is an
+ HTML based tool for browsing Erlang crash dumps.</p>
+
+ <section>
+ <marker id="general_info"></marker>
+ <title>General information</title>
+ <p>The first part of the dump shows the creation time for the dump,
+ a slogan indicating the reason for the dump, the system version,
+ of the node from which the dump originates, the compile time of
+ the emulator running the originating node and the number of
+ atoms in the atom table.
+ </p>
+
+ <section>
+ <title>Reasons for crash dumps (slogan)</title>
+ <p>The reason for the dump is noted in the beginning of the file
+ as <em>Slogan: &lt;reason&gt;</em> (the word "slogan" has historical
+ roots). If the system is halted by the BIF
+ <c><![CDATA[erlang:halt/1]]></c>, the slogan is the string parameter
+ passed to the BIF, otherwise it is a description generated by
+ the emulator or the (Erlang) kernel. Normally the message
+ should be enough to understand the problem, but nevertheless
+ some messages are described here. Note however that the
+ suggested reasons for the crash are <em>only suggestions</em>. The exact reasons for the errors may vary
+ depending on the local applications and the underlying
+ operating system.</p>
+ <list type="bulleted">
+ <item>"<em>&lt;A&gt;</em>: Cannot allocate <em>&lt;N&gt;</em>
+ bytes of memory (of type "<em>&lt;T&gt;</em>")." - The system
+ has run out of memory. &lt;A&gt; is the allocator that failed
+ to allocate memory, &lt;N&gt; is the number of bytes that
+ &lt;A&gt; tried to allocate, and &lt;T&gt; is the memory block
+ type that the memory was needed for. The most common case is
+ that a process stores huge amounts of data. In this case
+ &lt;T&gt; is most often <c><![CDATA[heap]]></c>, <c><![CDATA[old_heap]]></c>,
+ <c><![CDATA[heap_frag]]></c>, or <c><![CDATA[binary]]></c>. For more information on
+ allocators see
+ <seealso marker="erts_alloc">erts_alloc(3)</seealso>.</item>
+ <item>"<em>&lt;A&gt;</em>: Cannot reallocate <em>&lt;N&gt;</em>
+ bytes of memory\011(of type "<em>&lt;T&gt;</em>")." - Same as
+ above with the exception that memory was being reallocated
+ instead of being allocated when the system ran out of memory.</item>
+ <item>"Unexpected op code <em>N</em>" - Error in compiled
+ code, <c><![CDATA[beam]]></c> file damaged or error in the compiler.</item>
+ <item>"Module <em>Name</em> undefined" <c><![CDATA[|]]></c> "Function
+ <em>Name</em> undefined" <c><![CDATA[|]]></c> "No function
+ <em>Name</em>:<em>Name</em>/1" <c><![CDATA[|]]></c> "No function
+ <em>Name</em>:start/2" - The kernel/stdlib applications are
+ damaged or the start script is damaged.</item>
+ <item>"Driver_select called with too large file descriptor
+ <c><![CDATA[N]]></c>" - The number of file descriptors for sockets
+ exceed 1024 (Unix only). The limit on file-descriptors in
+ some Unix flavors can be set to over 1024, but only 1024
+ sockets/pipes can be used simultaneously by Erlang (due to
+ limitations in the Unix <c><![CDATA[select]]></c> call). The number of
+ open regular files is not affected by this.</item>
+ <item>"Received SIGUSR1" - The SIGUSR1 signal was sent to the
+ Erlang machine (Unix only).</item>
+ <item>"Kernel pid terminated (<em>Who</em>)
+ (<em>Exit-reason</em>)" - The kernel supervisor has detected
+ a failure, usually that the <c><![CDATA[application_controller]]></c>
+ has shut down (<c><![CDATA[Who]]></c> = <c><![CDATA[application_controller]]></c>,
+ <c><![CDATA[Why]]></c> = <c><![CDATA[shutdown]]></c>). The application controller
+ may have shut down for a number of reasons, the most usual
+ being that the node name of the distributed Erlang node is
+ already in use. A complete supervisor tree "crash" (i.e.,
+ the top supervisors have exited) will give about the same
+ result. This message comes from the Erlang code and not from
+ the virtual machine itself. It is always due to some kind of
+ failure in an application, either within OTP or a
+ "user-written" one. Looking at the error log for your
+ application is probably the first step to take.</item>
+ <item>"Init terminating in do_boot ()" - The primitive Erlang boot
+ sequence was terminated, most probably because the boot
+ script has errors or cannot be read. This is usually a
+ configuration error - the system may have been started with
+ a faulty <c><![CDATA[-boot]]></c> parameter or with a boot script from
+ the wrong version of OTP.</item>
+ <item>"Could not start kernel pid (<em>Who</em>) ()" - One of the
+ kernel processes could not start. This is probably due to
+ faulty arguments (like errors in a <c><![CDATA[-config]]></c> argument)
+ or faulty configuration files. Check that all files are in
+ their correct location and that the configuration files (if
+ any) are not damaged. Usually there are also messages
+ written to the controlling terminal and/or the error log
+ explaining what's wrong.</item>
+ </list>
+ <p>Other errors than the ones mentioned above may occur, as the
+ <c><![CDATA[erlang:halt/1]]></c> BIF may generate any message. If the
+ message is not generated by the BIF and does not occur in the
+ list above, it may be due to an error in the emulator. There
+ may however be unusual messages that I haven't mentioned, that
+ still are connected to an application failure. There is a lot
+ more information available, so more thorough reading of the
+ crash dump may reveal the crash reason. The size of processes,
+ the number of ets tables and the Erlang data on each process
+ stack can be useful for tracking down the problem.</p>
+ </section>
+
+ <section>
+ <title>Number of atoms</title>
+ <p>The number of atoms in the system at the time of the crash is
+ shown as <em>Atoms: &lt;number&gt;</em>. Some ten thousands atoms is
+ perfectly normal, but more could indicate that the BIF
+ <c><![CDATA[erlang:list_to_atom/1]]></c> is used to dynamically generate a
+ lot of <em>different</em> atoms, which is never a good idea.</p>
+ </section>
+ </section>
+
+ <section>
+ <marker id="memory"></marker>
+ <title>Memory information</title>
+ <p>Under the tag <em>=memory</em> you will find information similar
+ to what you can obtain on a living node with
+ <seealso marker="erts:erlang#erlang:memory/0">erlang:memory()</seealso>.</p>
+ </section>
+
+ <section>
+ <marker id="internal_tables"></marker>
+ <title>Internal table information</title>
+ <p>The tags <em>=hash_table:&lt;table_name&gt;</em> and
+ <em>=index_table:&lt;table_name&gt;</em> presents internal
+ tables. These are mostly of interest for runtime system
+ developers.</p>
+ </section>
+
+ <section>
+ <marker id="allocated_areas"></marker>
+ <title>Allocated areas</title>
+ <p>Under the tag <em>=allocated_areas</em> you will find information
+ similar to what you can obtain on a living node with
+ <seealso marker="erts:erlang#system_info_allocated_areas">erlang:system_info(allocated_areas)</seealso>.</p>
+ </section>
+
+ <section>
+ <marker id="allocator"></marker>
+ <title>Allocator</title>
+ <p>Under the tag <em>=allocator:&lt;A&gt;</em> you will find
+ various information about allocator &lt;A&gt;. The information
+ is similar to what you can obtain on a living node with
+ <seealso marker="erts:erlang#system_info_allocator_tuple">erlang:system_info({allocator, &lt;A&gt;})</seealso>.
+ For more information see the documentation of
+ <seealso marker="erts:erlang#system_info_allocator_tuple">erlang:system_info({allocator, &lt;A&gt;})</seealso>,
+ and the
+ <seealso marker="erts_alloc">erts_alloc(3)</seealso>
+ documentation.</p>
+ </section>
+
+ <section>
+ <marker id="processes"></marker>
+ <title>Process information</title>
+ <p>The Erlang crashdump contains a listing of each living Erlang
+ process in the system. The process information for one process
+ may look like this (line numbers have been added):
+ </p>
+ <p>The following fields can exist for a process:</p>
+ <taglist>
+ <tag><em>=proc:&lt;pid&gt;</em></tag>
+ <item>Heading, states the process identifier</item>
+ <tag><em>State</em></tag>
+ <item>
+ <p>The state of the process. This can be one of the following:</p>
+ <list type="bulleted">
+ <item><em>Scheduled</em> - The process was scheduled to run
+ but not currently running ("in the run queue").</item>
+ <item><em>Waiting</em> - The process was waiting for
+ something (in <c><![CDATA[receive]]></c>).</item>
+ <item><em>Running</em> - The process was currently
+ running. If the BIF <c><![CDATA[erlang:halt/1]]></c> was called, this was
+ the process calling it.</item>
+ <item><em>Exiting</em> - The process was on its way to
+ exit.</item>
+ <item><em>Garbing</em> - This is bad luck, the process was
+ garbage collecting when the crash dump was written, the rest
+ of the information for this process is limited.</item>
+ <item><em>Suspended</em> - The process is suspended, either
+ by the BIF <c><![CDATA[erlang:suspend_process/1]]></c> or because it is
+ trying to write to a busy port.</item>
+ </list>
+ </item>
+ <tag><em>Registered name</em></tag>
+ <item>The registered name of the process, if any.</item>
+ <tag><em>Spawned as</em></tag>
+ <item>The entry point of the process, i.e., what function was
+ referenced in the <c><![CDATA[spawn]]></c> or <c><![CDATA[spawn_link]]></c> call that
+ started the process.</item>
+ <tag><em>Last scheduled in for | Current call</em></tag>
+ <item>The current function of the process. These fields will not
+ always exist.</item>
+ <tag><em>Spawned by</em></tag>
+ <item>The parent of the process, i.e. the process which executed
+ <c><![CDATA[spawn]]></c> or <c><![CDATA[spawn_link]]></c>.</item>
+ <tag><em>Started</em></tag>
+ <item>The date and time when the process was started.</item>
+ <tag><em>Message queue length</em></tag>
+ <item>The number of messages in the process' message queue.</item>
+ <tag><em>Number of heap fragments</em></tag>
+ <item>The number of allocated heap fragments.</item>
+ <tag><em>Heap fragment data</em></tag>
+ <item>Size of fragmented heap data. This is data either created by
+ messages being sent to the process or by the Erlang BIFs. This
+ amount depends on so many things that this field is utterly
+ uninteresting.</item>
+ <tag><em>Link list</em></tag>
+ <item>Process id's of processes linked to this one. May also contain
+ ports. If process monitoring is used, this field also tells in
+ which direction the monitoring is in effect, i.e., a link
+ being "to" a process tells you that the "current" process was
+ monitoring the other and a link "from" a process tells you
+ that the other process was monitoring the current one.</item>
+ <tag><em>Reductions</em></tag>
+ <item>The number of reductions consumed by the process.</item>
+ <tag><em>Stack+heap</em></tag>
+ <item>The size of the stack and heap (they share memory segment)</item>
+ <tag><em>OldHeap</em></tag>
+ <item>The size of the "old heap". The Erlang virtual machine uses
+ generational garbage collection with two generations. There is
+ one heap for new data items and one for the data that have
+ survived two garbage collections. The assumption (which is
+ almost always correct) is that data that survive two garbage
+ collections can be "tenured" to a heap more seldom garbage
+ collected, as they will live for a long period. This is a
+ quite usual technique in virtual machines. The sum of the
+ heaps and stack together constitute most of the process's
+ allocated memory.</item>
+ <tag><em>Heap unused, OldHeap unused</em></tag>
+ <item>The amount of unused memory on each heap. This information is
+ usually useless.</item>
+ <tag><em>Stack</em></tag>
+ <item>If the system uses shared heap, the fields
+ <em>Stack+heap</em>, <em>OldHeap</em>, <em>Heap unused</em>
+ and <em>OldHeap unused</em> do not exist. Instead this field
+ presents the size of the process' stack.</item>
+ <tag><em>Program counter</em></tag>
+ <item>The current instruction pointer. This is only interesting for
+ runtime system developers. The function into which the program
+ counter points is the current function of the process.</item>
+ <tag><em>CP</em></tag>
+ <item>The continuation pointer, i.e. the return address for the
+ current call. Usually useless for other than runtime system
+ developers. This may be followed by the function into which
+ the CP points, which is the function calling the current
+ function.</item>
+ <tag><em>Arity</em></tag>
+ <item>The number of live argument registers. The argument registers,
+ if any are live, will follow. These may contain the arguments
+ of the function if they are not yet moved to the stack.</item>
+ </taglist>
+ <p>See also the section about <seealso marker="#proc_data">process data</seealso>.</p>
+ </section>
+
+ <section>
+ <marker id="ports"></marker>
+ <title>Port information</title>
+ <p>This section lists the open ports, their owners, any linked
+ processed, and the name of their driver or external process.</p>
+ </section>
+
+ <section>
+ <marker id="ets_tables"></marker>
+ <title>ETS tables</title>
+ <p>This section contains information about all the ETS tables in
+ the system. The following fields are interesting for each table:</p>
+ <taglist>
+ <tag><em>=ets:&lt;owner&gt;</em></tag>
+ <item>Heading, states the owner of the table (a process identifier)</item>
+ <tag><em>Table</em></tag>
+ <item>The identifier for the table. If the table is a
+ <c><![CDATA[named_table]]></c>, this is the name.</item>
+ <tag><em>Name</em></tag>
+ <item>The name of the table, regardless of whether it is a
+ <c><![CDATA[named_table]]></c> or not.</item>
+ <tag><em>Buckets</em></tag>
+ <item>This occurs if the table is a hash table, i.e. if it is not an
+ <c><![CDATA[ordered_set]]></c>.</item>
+ <tag><em>Ordered set (AVL tree), Elements</em></tag>
+ <item>This occurs only if the table is an <c><![CDATA[ordered_set]]></c>. (The
+ number of elements is the same as the number of objects in the
+ table.)</item>
+ <tag><em>Objects</em></tag>
+ <item>The number of objects in the table</item>
+ <tag><em>Words</em></tag>
+ <item>The number of words (usually 4 bytes/word) allocated to data
+ in the table.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="timers"></marker>
+ <title>Timers</title>
+ <p>This section contains information about all the timers started
+ with the BIFs <c><![CDATA[erlang:start_timer/3]]></c> and
+ <c><![CDATA[erlang:send_after/3]]></c>. The following fields exists for each
+ timer:</p>
+ <taglist>
+ <tag><em>=timer:&lt;owner&gt;</em></tag>
+ <item>Heading, states the owner of the timer (a process identifier)
+ i.e. the process to receive the message when the timer
+ expires.</item>
+ <tag><em>Message</em></tag>
+ <item>The message to be sent.</item>
+ <tag><em>Time left</em></tag>
+ <item>Number of milliseconds left until the message would have been
+ sent.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="distribution_info"></marker>
+ <title>Distribution information</title>
+ <p>If the Erlang node was alive, i.e., set up for communicating
+ with other nodes, this section lists the connections that were
+ active. The following fields can exist:</p>
+ <taglist>
+ <tag><em>=node:&lt;node_name&gt;</em></tag>
+ <item>The name of the node</item>
+ <tag><em>no_distribution</em></tag>
+ <item>This will only occur if the node was not distributed.</item>
+ <tag><em>=visible_node:&lt;channel&gt;</em></tag>
+ <item>Heading for a visible nodes, i.e. an alive node with a
+ connection to the node that crashed. States the channel number
+ for the node.</item>
+ <tag><em>=hidden_node:&lt;channel&gt;</em></tag>
+ <item>Heading for a hidden node. A hidden node is the same as a
+ visible node, except that it is started with the "-hidden"
+ flag. States the channel number for the node.</item>
+ <tag><em>=not_connected:&lt;channel&gt;</em></tag>
+ <item>Heading for a node which is has been connected to the crashed
+ node earlier. References (i.e. process or port identifiers)
+ to the not connected node existed at the time of the crash.
+ exist. States the channel number for the node.</item>
+ <tag><em>Name</em></tag>
+ <item>The name of the remote node.</item>
+ <tag><em>Controller</em></tag>
+ <item>The port which controls the communication with the remote node.</item>
+ <tag><em>Creation</em></tag>
+ <item>An integer (1-3) which together with the node name identifies
+ a specific instance of the node.</item>
+ <tag><em>Remote monitoring: &lt;local_proc&gt; &lt;remote_proc&gt;</em></tag>
+ <item>The local process was monitoring the remote process at the
+ time of the crash.</item>
+ <tag><em>Remotely monitored by: &lt;local_proc&gt; &lt;remote_proc&gt;</em></tag>
+ <item>The remote process was monitoring the local process at the
+ time of the crash.</item>
+ <tag><em>Remote link: &lt;local_proc&gt; &lt;remote_proc&gt;</em></tag>
+ <item>A link existed between the local process and the remote
+ process at the time of the crash.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="loaded_modules"></marker>
+ <title>Loaded module information</title>
+ <p>This section contains information about all loaded modules.
+ First, the memory usage by loaded code is summarized. There is
+ one field for "Current code" which is code that is the current
+ latest version of the modules. There is also a field for "Old
+ code" which is code where there exists a newer version in the
+ system, but the old version is not yet purged. The memory usage
+ is in bytes.</p>
+ <p>All loaded modules are then listed. The following fields exist:</p>
+ <taglist>
+ <tag><em>=mod:&lt;module_name&gt;</em></tag>
+ <item>Heading, and the name of the module.</item>
+ <tag><em>Current size</em></tag>
+ <item>Memory usage for the loaded code in bytes</item>
+ <tag><em>Old size</em></tag>
+ <item>Memory usage for the old code, if any.</item>
+ <tag><em>Current attributes</em></tag>
+ <item>Module attributes for the current code. This field is decoded
+ when looked at by the Crashdump Viewer tool.</item>
+ <tag><em>Old attributes</em></tag>
+ <item>Module attributes for the old code, if any. This field is
+ decoded when looked at by the Crashdump Viewer tool.</item>
+ <tag><em>Current compilation info</em></tag>
+ <item>Compilation information (options) for the current code. This
+ field is decoded when looked at by the Crashdump Viewer tool.</item>
+ <tag><em>Old compilation info</em></tag>
+ <item>Compilation information (options) for the old code, if
+ any. This field is decoded when looked at by the Crashdump
+ Viewer tool.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="funs"></marker>
+ <title>Fun information</title>
+ <p>In this section, all funs are listed. The following fields exist
+ for each fun:</p>
+ <taglist>
+ <tag><em>=fun</em></tag>
+ <item>Heading</item>
+ <tag><em>Module</em></tag>
+ <item>The name of the module where the fun was defined.</item>
+ <tag><em>Uniq, Index</em></tag>
+ <item>Identifiers</item>
+ <tag><em>Address</em></tag>
+ <item>The address of the fun's code.</item>
+ <tag><em>Native_address</em></tag>
+ <item>The address of the fun's code when HiPE is enabled.</item>
+ <tag><em>Refc</em></tag>
+ <item>The number of references to the fun.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="proc_data"></marker>
+ <title>Process Data</title>
+ <p>For each process there will be at least one <em>=proc_stack</em>
+ and one <em>=proc_heap</em> tag followed by the raw memory
+ information for the stack and heap of the process.</p>
+ <p>For each process there will also be a <em>=proc_messages</em>
+ tag if the process' message queue is non-empty and a
+ <em>=proc_dictionary</em> tag if the process' dictionary (the
+ <c><![CDATA[put/2]]></c> and <c><![CDATA[get/1]]></c> thing) is non-empty.</p>
+ <p>The raw memory information can be decoded by the Crashdump
+ Viewer tool. You will then be able to see the stack dump, the
+ message queue (if any) and the dictionary (if any).</p>
+ <p>The stack dump is a dump of the Erlang process stack. Most of
+ the live data (i.e., variables currently in use) are placed on
+ the stack; thus this can be quite interesting. One has to
+ "guess" what's what, but as the information is symbolic,
+ thorough reading of this information can be very useful. As an
+ example we can find the state variable of the Erlang primitive
+ loader on line <c><![CDATA[(5)]]></c> in the example below:</p>
+ <code type="none"><![CDATA[
+(1) 3cac44 Return addr 0x13BF58 (<terminate process normally>)
+(2) y(0) ["/view/siri_r10_dev/clearcase/otp/erts/lib/kernel/ebin","/view/siri_r10_dev/
+(3) clearcase/otp/erts/lib/stdlib/ebin"]
+(4) y(1) <0.1.0>
+(5) y(2) {state,[],none,#Fun<erl_prim_loader.6.7085890>,undefined,#Fun<erl_prim_loader.7.9000327>,#Fun<erl_prim_loader.8.116480692>,#Port<0.2>,infinity,#Fun<erl_prim_loader.9.10708760>}
+(6) y(3) infinity ]]></code>
+ <p>When interpreting the data for a process, it is helpful to know
+ that anonymous function objects (funs) are given a name
+ constructed from the name of the function in which they are
+ created, and a number (starting with 0) indicating the number of
+ that fun within that function.</p>
+ </section>
+
+ <section>
+ <marker id="atoms"></marker>
+ <title>Atoms</title>
+ <p>Now all the atoms in the system are written. This is only
+ interesting if one suspects that dynamic generation of atoms could
+ be a problem, otherwise this section can be ignored.</p>
+ <p>Note that the last created atom is printed first.</p>
+ </section>
+
+ <section>
+ <title>Disclaimer</title>
+ <p>The format of the crash dump evolves between releases of
+ OTP. Some information here may not apply to your
+ version. A description as this will never be complete; it is meant as
+ an explanation of the crash dump in general and as a help
+ when trying to find application errors, not as a complete
+ specification.</p>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml
new file mode 100644
index 0000000000..c396ee0b90
--- /dev/null
+++ b/erts/doc/src/driver.xml
@@ -0,0 +1,812 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>How to implement a driver</title>
+ <prepared>Jakob C</prepared>
+ <docno></docno>
+ <date>2000-11-28</date>
+ <rev>PA1</rev>
+ <file>driver.xml</file>
+ </header>
+
+ <note><p>This document was written a long time ago. A lot of it is still
+ valid, but some things have changed since it was first written.
+ Updates of this document are planned for the future. The reader
+ is encouraged to also read the
+ <seealso marker="erl_driver">erl_driver</seealso>, and the
+ <seealso marker="erl_driver">driver_entry</seealso> documentation.
+ </p></note>
+
+ <section>
+ <title>Introduction</title>
+ <p>This chapter tells you how to build your own driver for erlang.</p>
+ <p>A driver in Erlang is a library written in C, that is linked to
+ the Erlang emulator and called from erlang. Drivers can be used
+ when C is more suitable than Erlang, to speed things up, or to
+ provide access to OS resources not directly accessible from
+ Erlang.</p>
+ <p>A driver can be dynamically loaded, as a shared library (known as
+ a DLL on windows), or statically loaded, linked with the emulator
+ when it is compiled and linked. Only dynamically loaded drivers
+ are described here, statically linked drivers are beyond the scope
+ of this chapter.</p>
+ <p>When a driver is loaded it is executed in the context of the
+ emulator, shares the same memory and the same thread. This means
+ that all operations in the driver must be non-blocking, and that
+ any crash in the driver will bring the whole emulator down. In
+ short: you have to be extremely careful!</p>
+ <p></p>
+ </section>
+
+ <section>
+ <title>Sample driver</title>
+ <p>This is a simple driver for accessing a postgres
+ database using the libpq C client library. Postgres
+ is used because it's free and open source. For information
+ on postgres, refer to the website www.postgres.org.</p>
+ <p>The driver is synchronous, it uses the synchronous calls of
+ the client library. This is only for simplicity, and is
+ generally not good, since it will
+ halt the emulator while waiting for the database.
+ This will be improved on below with an asynchronous
+ sample driver.</p>
+ <p>The code is quite straight-forward: all
+ communication between Erlang and the driver
+ is done with <c><![CDATA[port_control/3]]></c>, and the
+ driver returns data back using the <c><![CDATA[rbuf]]></c>.</p>
+ <p>An Erlang driver only exports one function: the driver
+ entry function. This is defined with a macro,
+ <c><![CDATA[DRIVER_INIT]]></c>, and returns a pointer to a
+ C <c><![CDATA[struct]]></c> containing the entry points that are
+ called from the emulator. The <c><![CDATA[struct]]></c> defines the
+ entries that the emulator calls to call the driver, with
+ a <c><![CDATA[NULL]]></c> pointer for entries that are not defined
+ and used by the driver.</p>
+ <p>The <c><![CDATA[start]]></c> entry is called when the driver
+ is opened as a port with <c><![CDATA[open_port/2]]></c>. Here
+ we allocate memory for a user data structure.
+ This user data will be passed every time the emulator
+ calls us. First we store the driver handle, because it
+ is needed in subsequent calls. We allocate memory for
+ the connection handle that is used by LibPQ. We also
+ set the port to return allocated driver binaries, by
+ setting the flag <c><![CDATA[PORT_CONTROL_FLAG_BINARY]]></c>, calling
+ <c><![CDATA[set_port_control_flags]]></c>. (This is because
+ we don't know whether our data will fit in the
+ result buffer of <c><![CDATA[control]]></c>, which has a default size
+ set up by the emulator, currently 64 bytes.)</p>
+ <p>There is an entry <c><![CDATA[init]]></c> which is called when
+ the driver is loaded, but we don't use this, since
+ it is executed only once, and we want to have the
+ possibility of several instances of the driver.</p>
+ <p>The <c><![CDATA[stop]]></c> entry is called when the port
+ is closed.</p>
+ <p>The <c><![CDATA[control]]></c> entry is called from the emulator
+ when the Erlang code calls <c><![CDATA[port_control/3]]></c>,
+ to do the actual work. We have defined a simple set of
+ commands: <c><![CDATA[connect]]></c> to login to the database, <c><![CDATA[disconnect]]></c>
+ to log out and <c><![CDATA[select]]></c> to send a SQL-query and get the result.
+ All results are returned through <c><![CDATA[rbuf]]></c>.
+ The library <c><![CDATA[ei]]></c> in <c><![CDATA[erl_interface]]></c> is used
+ to encode data in binary term format. The result is returned
+ to the emulator as binary terms, so <c><![CDATA[binary_to_term]]></c>
+ is called in Erlang to convert the result to term form.</p>
+ <p>The code is available in <c><![CDATA[pg_sync.c]]></c> in the <c><![CDATA[sample]]></c>
+ directory of <c><![CDATA[erts]]></c>.</p>
+ <p>The driver entry contains the functions that
+ will be called by the emulator. In our simple
+ example, we only provide <c><![CDATA[start]]></c>, <c><![CDATA[stop]]></c>
+ and <c><![CDATA[control]]></c>.</p>
+ <code type="none"><![CDATA[
+/* Driver interface declarations */
+static ErlDrvData start(ErlDrvPort port, char *command);
+static void stop(ErlDrvData drv_data);
+static int control(ErlDrvData drv_data, unsigned int command, char *buf,
+ int len, char **rbuf, int rlen);
+
+static ErlDrvEntry pq_driver_entry = {
+ NULL, /* init */
+ start,
+ stop,
+ NULL, /* output */
+ NULL, /* ready_input */
+ NULL, /* ready_output */
+ "pg_sync", /* the name of the driver */
+ NULL, /* finish */
+ NULL, /* handle */
+ control,
+ NULL, /* timeout */
+ NULL, /* outputv */
+ NULL, /* ready_async */
+ NULL, /* flush */
+ NULL, /* call */
+ NULL /* event */
+};
+ ]]></code>
+ <p>We have a structure to store state needed by the driver,
+ in this case we only need to keep the database connection.</p>
+ <code type="none"><![CDATA[
+typedef struct our_data_s {
+ PGconn* conn;
+} our_data_t;
+ ]]></code>
+ <p>These are control codes we have defined.</p>
+ <code type="none"><![CDATA[
+/* Keep the following definitions in alignment with the
+ * defines in erl_pq_sync.erl
+ */
+
+#define DRV_CONNECT 'C'
+#define DRV_DISCONNECT 'D'
+#define DRV_SELECT 'S'
+ ]]></code>
+ <p>This just returns the driver structure. The macro
+ <c><![CDATA[DRIVER_INIT]]></c> defines the only exported function.
+ All the other functions are static, and will not be exported
+ from the library.</p>
+ <code type="none"><![CDATA[
+/* INITIALIZATION AFTER LOADING */
+
+/*
+ * This is the init function called after this driver has been loaded.
+ * It must *not* be declared static. Must return the address to
+ * the driver entry.
+ */
+
+DRIVER_INIT(pq_drv)
+{
+ return &pq_driver_entry;
+}
+ ]]></code>
+ <p>Here we do some initialization, <c><![CDATA[start]]></c> is called from
+ <c><![CDATA[open_port]]></c>. The data will be passed to <c><![CDATA[control]]></c>
+ and <c><![CDATA[stop]]></c>.</p>
+ <code type="none"><![CDATA[
+/* DRIVER INTERFACE */
+static ErlDrvData start(ErlDrvPort port, char *command)
+{
+ our_data_t* data;
+
+ data = (our_data_t*)driver_alloc(sizeof(our_data_t));
+ data->conn = NULL;
+ set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
+ return (ErlDrvData)data;
+}
+ ]]></code>
+ <p>We call disconnect to log out from the database.
+ (This should have been done from Erlang, but just in case.)</p>
+ <code type="none"><![CDATA[
+ static int do_disconnect(our_data_t* data, ei_x_buff* x);
+
+static void stop(ErlDrvData drv_data)
+{
+ do_disconnect((our_data_t*)drv_data, NULL);
+}
+ ]]></code>
+ <p>We use the binary format only to return data to the emulator;
+ input data is a string paramater for <c><![CDATA[connect]]></c> and
+ <c><![CDATA[select]]></c>. The returned data consists of Erlang terms.</p>
+ <p>The functions <c><![CDATA[get_s]]></c> and <c><![CDATA[ei_x_to_new_binary]]></c> are
+ utilities that is used to make the code shorter. <c><![CDATA[get_s]]></c>
+ duplicates the string and zero-terminates it, since the
+ postgres client library wants that. <c><![CDATA[ei_x_to_new_binary]]></c>
+ takes an <c><![CDATA[ei_x_buff]]></c> buffer and allocates a binary and
+ copies the data there. This binary is returned in <c><![CDATA[*rbuf]]></c>.
+ (Note that this binary is freed by the emulator, not by us.)</p>
+ <code type="none"><![CDATA[
+static char* get_s(const char* buf, int len);
+static int do_connect(const char *s, our_data_t* data, ei_x_buff* x);
+static int do_select(const char* s, our_data_t* data, ei_x_buff* x);
+
+/* Since we are operating in binary mode, the return value from control
+ * is irrelevant, as long as it is not negative.
+ */
+static int control(ErlDrvData drv_data, unsigned int command, char *buf,
+ int len, char **rbuf, int rlen)
+{
+ int r;
+ ei_x_buff x;
+ our_data_t* data = (our_data_t*)drv_data;
+ char* s = get_s(buf, len);
+ ei_x_new_with_version(&x);
+ switch (command) {
+ case DRV_CONNECT: r = do_connect(s, data, &x); break;
+ case DRV_DISCONNECT: r = do_disconnect(data, &x); break;
+ case DRV_SELECT: r = do_select(s, data, &x); break;
+ default: r = -1; break;
+ }
+ *rbuf = (char*)ei_x_to_new_binary(&x);
+ ei_x_free(&x);
+ driver_free(s);
+ return r;
+}
+ ]]></code>
+ <p>In <c><![CDATA[do_connect]]></c> is where we log in to the database. If the connection
+ was successful we store the connection handle in our driver
+ data, and return ok. Otherwise, we return the error message
+ from postgres, and store <c><![CDATA[NULL]]></c> in the driver data.</p>
+ <code type="none"><![CDATA[
+static int do_connect(const char *s, our_data_t* data, ei_x_buff* x)
+{
+ PGconn* conn = PQconnectdb(s);
+ if (PQstatus(conn) != CONNECTION_OK) {
+ encode_error(x, conn);
+ PQfinish(conn);
+ conn = NULL;
+ } else {
+ encode_ok(x);
+ }
+ data->conn = conn;
+ return 0;
+}
+ ]]></code>
+ <p>If we are connected (if the connection handle is not <c><![CDATA[NULL]]></c>),
+ we log out from the database. We need to check if a we should
+ encode an ok, since we might get here from the <c><![CDATA[stop]]></c>
+ function, which doesn't return data to the emulator.</p>
+ <code type="none"><![CDATA[
+static int do_disconnect(our_data_t* data, ei_x_buff* x)
+{
+ if (data->conn == NULL)
+ return 0;
+ PQfinish(data->conn);
+ data->conn = NULL;
+ if (x != NULL)
+ encode_ok(x);
+ return 0;
+}
+ ]]></code>
+ <p>We execute a query and encodes the result. Encoding is done
+ in another C module, <c><![CDATA[pg_encode.c]]></c> which is also provided
+ as sample code.</p>
+ <code type="none"><![CDATA[
+static int do_select(const char* s, our_data_t* data, ei_x_buff* x)
+{
+ PGresult* res = PQexec(data->conn, s);
+ encode_result(x, res, data->conn);
+ PQclear(res);
+ return 0;
+}
+ ]]></code>
+ <p>Here we simply checks the result from postgres, and
+ if it's data we encode it as lists of lists with
+ column data. Everything from postgres is C strings,
+ so we just use <c><![CDATA[ei_x_encode_string]]></c> to send
+ the result as strings to Erlang. (The head of the list
+ contains the column names.)</p>
+ <code type="none"><![CDATA[
+void encode_result(ei_x_buff* x, PGresult* res, PGconn* conn)
+{
+ int row, n_rows, col, n_cols;
+ switch (PQresultStatus(res)) {
+ case PGRES_TUPLES_OK:
+ n_rows = PQntuples(res);
+ n_cols = PQnfields(res);
+ ei_x_encode_tuple_header(x, 2);
+ encode_ok(x);
+ ei_x_encode_list_header(x, n_rows+1);
+ ei_x_encode_list_header(x, n_cols);
+ for (col = 0; col < n_cols; ++col) {
+ ei_x_encode_string(x, PQfname(res, col));
+ }
+ ei_x_encode_empty_list(x);
+ for (row = 0; row < n_rows; ++row) {
+ ei_x_encode_list_header(x, n_cols);
+ for (col = 0; col < n_cols; ++col) {
+ ei_x_encode_string(x, PQgetvalue(res, row, col));
+ }
+ ei_x_encode_empty_list(x);
+ }
+ ei_x_encode_empty_list(x);
+ break;
+ case PGRES_COMMAND_OK:
+ ei_x_encode_tuple_header(x, 2);
+ encode_ok(x);
+ ei_x_encode_string(x, PQcmdTuples(res));
+ break;
+ default:
+ encode_error(x, conn);
+ break;
+ }
+}
+ ]]></code>
+ </section>
+
+ <section>
+ <title>Compiling and linking the sample driver</title>
+ <p>The driver should be compiled and linked to a shared
+ library (DLL on windows). With gcc this is done
+ with the link flags <c><![CDATA[-shared]]></c> and <c><![CDATA[-fpic]]></c>.
+ Since we use the <c><![CDATA[ei]]></c> library we should include
+ it too. There are several versions of <c><![CDATA[ei]]></c>, compiled
+ for debug or non-debug and multi-threaded or single-threaded.
+ In the makefile for the samples the <c><![CDATA[obj]]></c> directory
+ is used for the <c><![CDATA[ei]]></c> library, meaning that we use
+ the non-debug, single-threaded version.</p>
+ </section>
+
+ <section>
+ <title>Calling a driver as a port in Erlang</title>
+ <p>Before a driver can be called from Erlang, it must be
+ loaded and opened. Loading is done using the <c><![CDATA[erl_ddll]]></c>
+ module (the <c><![CDATA[erl_ddll]]></c> driver that loads dynamic
+ driver, is actually a driver itself). If loading is ok
+ the port can be opened with <c><![CDATA[open_port/2]]></c>. The port
+ name must match the name of the shared library and
+ the name in the driver entry structure.</p>
+ <p>When the port has been opened, the driver can be called. In
+ the <c><![CDATA[pg_sync]]></c> example, we don't have any data from
+ the port, only the return value from the
+ <c><![CDATA[port_control]]></c>.</p>
+ <p>The following code is the Erlang part of the synchronous
+ postgres driver, <c><![CDATA[pg_sync.erl]]></c>.</p>
+ <code type="none"><![CDATA[
+-module(pg_sync).
+
+-define(DRV_CONNECT, 1).
+-define(DRV_DISCONNECT, 2).
+-define(DRV_SELECT, 3).
+
+-export([connect/1, disconnect/1, select/2]).
+
+connect(ConnectStr) ->
+ case erl_ddll:load_driver(".", "pg_sync") of
+ ok -> ok;
+ {error, already_loaded} -> ok;
+ E -> exit({error, E})
+ end,
+ Port = open_port({spawn, ?MODULE}, []),
+ case binary_to_term(port_control(Port, ?DRV_CONNECT, ConnectStr)) of
+ ok -> {ok, Port};
+ Error -> Error
+ end.
+
+disconnect(Port) ->
+ R = binary_to_term(port_control(Port, ?DRV_DISCONNECT, "")),
+ port_close(Port),
+ R.
+
+select(Port, Query) ->
+ binary_to_term(port_control(Port, ?DRV_SELECT, Query)).
+ ]]></code>
+ <p>The api is simple: <c><![CDATA[connect/1]]></c> loads the driver, opens it
+ and logs on to the database, returning the Erlang port
+ if successful, <c><![CDATA[select/2]]></c> sends a query to the driver,
+ and returns the result, <c><![CDATA[disconnect/1]]></c> closes the
+ database connection and the driver. (It does not unload it,
+ however.) The connection string should be a connection
+ string for postgres.</p>
+ <p>The driver is loaded with <c><![CDATA[erl_ddll:load_driver/2]]></c>,
+ and if this is successful, or if it's already loaded,
+ it is opened. This will call the <c><![CDATA[start]]></c> function
+ in the driver.</p>
+ <p>We use the <c><![CDATA[port_control/3]]></c> function for all
+ calls into the driver, the result from the driver is
+ returned immediately, and converted to terms by calling
+ <c><![CDATA[binary_to_term/1]]></c>. (We trust that the terms returned
+ from the driver are well-formed, otherwise the
+ <c><![CDATA[binary_to_term]]></c> calls could be contained in a
+ <c><![CDATA[catch]]></c>.)</p>
+ </section>
+
+ <section>
+ <title>Sample asynchronous driver</title>
+ <p>Sometimes database queries can take long time to
+ complete, in our <c><![CDATA[pg_sync]]></c> driver, the emulator
+ halts while the driver is doing it's job. This is
+ often not acceptable, since no other Erlang processes
+ gets a chance to do anything. To improve on our
+ postgres driver, we reimplement it using the asynchronous
+ calls in LibPQ.</p>
+ <p>The asynchronous version of the driver is in the
+ sample files <c><![CDATA[pg_async.c]]></c> and <c><![CDATA[pg_asyng.erl]]></c>.</p>
+ <code type="none"><![CDATA[
+/* Driver interface declarations */
+static ErlDrvData start(ErlDrvPort port, char *command);
+static void stop(ErlDrvData drv_data);
+static int control(ErlDrvData drv_data, unsigned int command, char *buf,
+ int len, char **rbuf, int rlen);
+static void ready_io(ErlDrvData drv_data, ErlDrvEvent event);
+
+static ErlDrvEntry pq_driver_entry = {
+ NULL, /* init */
+ start,
+ stop,
+ NULL, /* output */
+ ready_io, /* ready_input */
+ ready_io, /* ready_output */
+ "pg_async", /* the name of the driver */
+ NULL, /* finish */
+ NULL, /* handle */
+ control,
+ NULL, /* timeout */
+ NULL, /* outputv */
+ NULL, /* ready_async */
+ NULL, /* flush */
+ NULL, /* call */
+ NULL /* event */
+};
+
+typedef struct our_data_t {
+ PGconn* conn;
+ ErlDrvPort port;
+ int socket;
+ int connecting;
+} our_data_t;
+ ]]></code>
+ <p>Here some things have changed from <c><![CDATA[pg_sync.c]]></c>: we use the
+ entry <c><![CDATA[ready_io]]></c> for <c><![CDATA[ready_input]]></c> and
+ <c><![CDATA[ready_output]]></c> which will be called from the emulator only
+ when there is input to be read from the socket. (Actually, the
+ socket is used in a <c><![CDATA[select]]></c> function inside
+ the emulator, and when the socket is signalled,
+ indicating there is data to read, the <c><![CDATA[ready_input]]></c> entry
+ is called. More on this below.)</p>
+ <p>Our driver data is also extended, we keep track of the
+ socket used for communication with postgres, and also
+ the port, which is needed when we send data to the port with
+ <c><![CDATA[driver_output]]></c>. We have a flag <c><![CDATA[connecting]]></c> to tell
+ whether the driver is waiting for a connection or waiting
+ for the result of a query. (This is needed since the entry
+ <c><![CDATA[ready_io]]></c> will be called both when connecting and
+ when there is query result.)</p>
+ <code type="none"><![CDATA[
+static int do_connect(const char *s, our_data_t* data)
+{
+ PGconn* conn = PQconnectStart(s);
+ if (PQstatus(conn) == CONNECTION_BAD) {
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ encode_error(&x, conn);
+ PQfinish(conn);
+ conn = NULL;
+ driver_output(data->port, x.buff, x.index);
+ ei_x_free(&x);
+ }
+ PQconnectPoll(conn);
+ int socket = PQsocket(conn);
+ data->socket = socket;
+ driver_select(data->port, (ErlDrvEvent)socket, DO_READ, 1);
+ driver_select(data->port, (ErlDrvEvent)socket, DO_WRITE, 1);
+ data->conn = conn;
+ data->connecting = 1;
+ return 0;
+}
+ ]]></code>
+ <p>The <c><![CDATA[connect]]></c> function looks a bit different too. We connect
+ using the asynchronous <c><![CDATA[PQconnectStart]]></c> function. After the
+ connection is started, we retrieve the socket for the connection
+ with <c><![CDATA[PQsocket]]></c>. This socket is used with the
+ <c><![CDATA[driver_select]]></c> function to wait for connection. When
+ the socket is ready for input or for output, the <c><![CDATA[ready_io]]></c>
+ function will be called.</p>
+ <p>Note that we only return data (with <c><![CDATA[driver_output]]></c>) if there
+ is an error here, otherwise we wait for the connection to be completed,
+ in which case our <c><![CDATA[ready_io]]></c> function will be called.</p>
+ <code type="none"><![CDATA[
+static int do_select(const char* s, our_data_t* data)
+{
+ data->connecting = 0;
+ PGconn* conn = data->conn;
+ /* if there's an error return it now */
+ if (PQsendQuery(conn, s) == 0) {
+\011ei_x_buff x;
+\011ei_x_new_with_version(&x);
+\011encode_error(&x, conn);
+\011driver_output(data->port, x.buff, x.index);
+\011ei_x_free(&x);
+ }
+ /* else wait for ready_output to get results */
+ return 0;
+}
+ ]]></code>
+ <p>The <c><![CDATA[do_select]]></c> function initiates a select, and returns
+ if there is no immediate error. The actual result will be returned
+ when <c><![CDATA[ready_io]]></c> is called.</p>
+ <code type="none"><![CDATA[
+static void ready_io(ErlDrvData drv_data, ErlDrvEvent event)
+{
+ PGresult* res = NULL;
+ our_data_t* data = (our_data_t*)drv_data;
+ PGconn* conn = data->conn;
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ if (data->connecting) {
+\011ConnStatusType status;
+\011PQconnectPoll(conn);
+\011status = PQstatus(conn);
+\011if (status == CONNECTION_OK)
+\011 encode_ok(&x);
+\011else if (status == CONNECTION_BAD)
+\011 encode_error(&x, conn);
+ } else {
+\011PQconsumeInput(conn);
+\011if (PQisBusy(conn))
+\011 return;
+\011res = PQgetResult(conn);
+\011encode_result(&x, res, conn);
+\011PQclear(res);
+\011for (;;) {
+\011 res = PQgetResult(conn);
+\011 if (res == NULL)
+\011\011break;
+\011 PQclear(res);
+\011}
+ }
+ if (x.index > 1) {
+\011driver_output(data->port, x.buff, x.index);
+\011if (data->connecting)
+\011 driver_select(data->port, (ErlDrvEvent)data->socket, DO_WRITE, 0);
+ }
+ ei_x_free(&x);
+}
+ ]]></code>
+ <p>The <c><![CDATA[ready_io]]></c> function will be called when the socket
+ we got from postgres is ready for input or output. Here
+ we first check if we are connecting to the database. In that
+ case we check connection status and return ok if the
+ connection is successful, or error if it's not. If the
+ connection is not yet established, we simply return; <c><![CDATA[ready_io]]></c>
+ will be called again.</p>
+ <p>If we have result from a connect, indicated that we have data in
+ the <c><![CDATA[x]]></c> buffer, we no longer need to select on
+ output (<c><![CDATA[ready_output]]></c>), so we remove this by calling
+ <c><![CDATA[driver_select]]></c>.</p>
+ <p>If we're not connecting, we're waiting for results from a
+ <c><![CDATA[PQsendQuery]]></c>, so we get the result and return it. The
+ encoding is done with the same functions as in the earlier
+ example.</p>
+ <p>We should add error handling here, for instance checking
+ that the socket is still open, but this is just a simple
+ example.</p>
+ <p>The Erlang part of the asynchronous driver consists of the
+ sample file <c><![CDATA[pg_async.erl]]></c>.</p>
+ <code type="none"><![CDATA[
+-module(pg_async).
+
+-define(DRV_CONNECT, $C).
+-define(DRV_DISCONNECT, $D).
+-define(DRV_SELECT, $S).
+
+-export([connect/1, disconnect/1, select/2]).
+
+connect(ConnectStr) ->
+ case erl_ddll:load_driver(".", "pg_async") of
+\011ok -> ok;
+\011{error, already_loaded} -> ok;
+\011_ -> exit({error, could_not_load_driver})
+ end,
+ Port = open_port({spawn, ?MODULE}, [binary]),
+ port_control(Port, ?DRV_CONNECT, ConnectStr),
+ case return_port_data(Port) of
+\011ok ->
+\011 {ok, Port};
+\011Error ->
+\011 Error
+ end.
+
+disconnect(Port) ->
+ port_control(Port, ?DRV_DISCONNECT, ""),
+ R = return_port_data(Port),
+ port_close(Port),
+ R.
+
+select(Port, Query) ->
+ port_control(Port, ?DRV_SELECT, Query),
+ return_port_data(Port).
+
+return_port_data(Port) ->
+ receive
+\011{Port, {data, Data}} ->
+\011 binary_to_term(Data)
+ end.
+ ]]></code>
+ <p>The Erlang code is slightly different, this is because we
+ don't return the result synchronously from <c><![CDATA[port_control]]></c>,
+ instead we get it from <c><![CDATA[driver_output]]></c> as data in the
+ message queue. The function <c><![CDATA[return_port_data]]></c> above
+ receives data from the port. Since the data is in
+ binary format, we use <c><![CDATA[binary_to_term/1]]></c> to convert
+ it to Erlang term. Note that the driver is opened in
+ binary mode, <c><![CDATA[open_port/2]]></c> is called with the option
+ <c><![CDATA[[binary]]]></c>. This means that data sent from the driver
+ to the emulator is sent as binaries. Without the <c><![CDATA[binary]]></c>
+ option, they would have been lists of integers.</p>
+ </section>
+
+ <section>
+ <title>An asynchronous driver using driver_async</title>
+ <p>As a final example we demonstrate the use of <c><![CDATA[driver_async]]></c>.
+ We also use the driver term interface. The driver is written
+ in C++. This enables us to use an algorithm from STL. We will
+ use the <c><![CDATA[next_permutation]]></c> algorithm to get the next permutation
+ of a list of integers. For large lists (more than 100000
+ elements), this will take some time, so we will perform this
+ as an asynchronous task.</p>
+ <p>The asynchronous api for drivers are quite complicated. First
+ of all, the work must be prepared. In our example we do this
+ in <c><![CDATA[output]]></c>. We could have used <c><![CDATA[control]]></c> just as well,
+ but we want some variation in our examples. In our driver, we allocate
+ a structure that contains all needed for the asynchronous task
+ to do the work. This is done in the main emulator thread.
+ Then the asynchronous function is called from a driver thread,
+ separate from the main emulator thread. Note that the driver-
+ functions are not reentrant, so they shouldn't be used.
+ Finally, after the function is completed, the driver callback
+ <c><![CDATA[ready_async]]></c> is called from the main emulator thread,
+ this is where we return the result to Erlang. (We can't
+ return the result from within the asynchronous function, since
+ we can't call the driver-functions.)</p>
+ <p>The code below is from the sample file <c><![CDATA[next_perm.cc]]></c>.</p>
+ <p>The driver entry looks like before, but also contains the
+ call-back <c><![CDATA[ready_async]]></c>.</p>
+ <code type="none"><![CDATA[
+static ErlDrvEntry next_perm_driver_entry = {
+ NULL,\011\011\011/* init */
+ start,
+ NULL, \011\011\011/* stop */
+ output,\011\011\011
+ NULL,\011\011\011/* ready_input */
+ NULL,\011\011\011/* ready_output */
+ "next_perm", /* the name of the driver */
+ NULL,\011\011\011/* finish */
+ NULL,\011\011\011/* handle */
+ NULL,\011\011\011/* control */
+ NULL,\011\011\011/* timeout */
+ NULL,\011\011\011/* outputv */
+ ready_async,
+ NULL,\011\011\011/* flush */
+ NULL,\011\011\011/* call */
+ NULL\011\011\011/* event */
+};
+ ]]></code>
+ <p>The <c><![CDATA[output]]></c> function allocates the work-area of the
+ asynchronous function. Since we use C++, we use a struct,
+ and stuff the data in it. We have to copy the original data,
+ it is not valid after we have returned from the <c><![CDATA[output]]></c>
+ function, and the <c><![CDATA[do_perm]]></c> function will be called later,
+ and from another thread. We return no data here, instead it will
+ be sent later from the <c><![CDATA[ready_async]]></c> call-back.</p>
+ <p>The <c><![CDATA[async_data]]></c> will be passed to the <c><![CDATA[do_perm]]></c> function.
+ We do not use a <c><![CDATA[async_free]]></c> function (the last argument to
+ <c><![CDATA[driver_async]]></c>, it's only used if the task is cancelled
+ programmatically.</p>
+ <code type="none"><![CDATA[
+struct our_async_data {
+ bool prev;
+ vector<int> data;
+ our_async_data(ErlDrvPort p, int command, const char* buf, int len);
+};
+
+our_async_data::our_async_data(ErlDrvPort p, int command,
+\011\011\011 const char* buf, int len)
+ : prev(command == 2),
+ data((int*)buf, (int*)buf + len / sizeof(int))
+{
+}
+
+static void do_perm(void* async_data);
+
+static void output(ErlDrvData drv_data, char *buf, int len)
+{
+ if (*buf < 1 || *buf > 2) return;
+ ErlDrvPort port = reinterpret_cast<ErlDrvPort>(drv_data);
+ void* async_data = new our_async_data(port, *buf, buf+1, len);
+ driver_async(port, NULL, do_perm, async_data, do_free);
+}
+ ]]></code>
+ <p>In the <c><![CDATA[do_perm]]></c> we simply do the work, operating
+ on the structure that was allocated in <c><![CDATA[output]]></c>.</p>
+ <code type="none"><![CDATA[
+static void do_perm(void* async_data)
+{
+ our_async_data* d = reinterpret_cast<our_async_data*>(async_data);
+ if (d->prev)
+\011prev_permutation(d->data.begin(), d->data.end());
+ else
+\011next_permutation(d->data.begin(), d->data.end());
+}
+ ]]></code>
+ <p>In the <c><![CDATA[ready_async]]></c> function, the output is sent back to the
+ emulator. We use the driver term format instead of <c><![CDATA[ei]]></c>.
+ This is the only way to send Erlang terms directly to a driver,
+ without having the Erlang code to call <c><![CDATA[binary_to_term/1]]></c>. In
+ our simple example this works well, and we don't need to use
+ <c><![CDATA[ei]]></c> to handle the binary term format.</p>
+ <p>When the data is returned we deallocate our data.</p>
+ <code type="none"><![CDATA[
+static void ready_async(ErlDrvData drv_data, ErlDrvThreadData async_data)
+{
+ ErlDrvPort port = reinterpret_cast<ErlDrvPort>(drv_data);
+ our_async_data* d = reinterpret_cast<our_async_data*>(async_data);
+ int n = d->data.size(), result_n = n*2 + 3;
+ ErlDrvTermData* result = new ErlDrvTermData[result_n], * rp = result;
+ for (vector<int>::iterator i = d->data.begin();
+\011 i != d->data.end(); ++i) {
+\011*rp++ = ERL_DRV_INT;
+\011*rp++ = *i;
+ }
+ *rp++ = ERL_DRV_NIL;
+ *rp++ = ERL_DRV_LIST;
+ *rp++ = n+1;
+ driver_output_term(port, result, result_n);
+ delete[] result;
+ delete d;
+}
+ ]]></code>
+ <p>This driver is called like the others from Erlang, however, since
+ we use <c><![CDATA[driver_output_term]]></c>, there is no need to call
+ binary_to_term. The Erlang code is in the sample file
+ <c><![CDATA[next_perm.erl]]></c>.</p>
+ <p>The input is changed into a list of integers and sent to
+ the driver.</p>
+ <code type="none"><![CDATA[
+-module(next_perm).
+
+-export([next_perm/1, prev_perm/1, load/0, all_perm/1]).
+
+load() ->
+ case whereis(next_perm) of
+\011undefined ->
+\011 case erl_ddll:load_driver(".", "next_perm") of
+\011\011ok -> ok;
+\011\011{error, already_loaded} -> ok;
+\011\011E -> exit(E)
+\011 end,
+\011 Port = open_port({spawn, "next_perm"}, []),
+\011 register(next_perm, Port);
+\011_ ->
+\011 ok
+ end.
+
+list_to_integer_binaries(L) ->
+ [<<I:32/integer-native>> || I <- L].
+
+next_perm(L) ->
+ next_perm(L, 1).
+
+prev_perm(L) ->
+ next_perm(L, 2).
+
+next_perm(L, Nxt) ->
+ load(),
+ B = list_to_integer_binaries(L),
+ port_control(next_perm, Nxt, B),
+ receive
+\011Result ->
+\011 Result
+ end.
+
+all_perm(L) ->
+ New = prev_perm(L),
+ all_perm(New, L, [New]).
+
+all_perm(L, L, Acc) ->
+ Acc;
+all_perm(L, Orig, Acc) ->
+ New = prev_perm(L),
+ all_perm(New, Orig, [New | Acc]).
+ ]]></code>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml
new file mode 100644
index 0000000000..6b7d2acf24
--- /dev/null
+++ b/erts/doc/src/driver_entry.xml
@@ -0,0 +1,453 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>driver_entry</title>
+ <prepared>Jakob Cederlund</prepared>
+ <responsible>Jakob Cederlund</responsible>
+ <docno>1</docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2001-10-01</date>
+ <rev>PA1</rev>
+ <file>driver_entry.xml</file>
+ </header>
+ <lib>driver_entry</lib>
+ <libsummary>The driver-entry structure used by erlang drivers.</libsummary>
+ <description>
+ <p>As of erts version 5.5.3 the driver interface has been extended
+ (see <seealso marker="driver_entry#extended_marker">extended marker</seealso>).
+ The extended interface introduce
+ <seealso marker="erl_driver#version_management">version management</seealso>,
+ the possibility to pass capability flags
+ (see <seealso marker="driver_entry#driver_flags">driver flags</seealso>)
+ to the runtime system at driver initialization, and some new
+ driver API functions. </p>
+ <note>
+ <p>Old drivers (compiled with an <c>erl_driver.h</c> from an
+ earlier erts version than 5.5.3) have to be recompiled
+ (but does not have to use the extended interface).</p>
+ </note>
+ <p>The <c>driver_entry</c> structure is a C struct that all erlang
+ drivers defines. It contains entry points for the erlang driver
+ that are called by the erlang emulator when erlang code accesses
+ the driver.</p>
+ <p>
+ <marker id="emulator"></marker>
+ The <seealso marker="driver_entry">erl_driver</seealso> driver
+ API functions needs a port handle
+ that identifies the driver instance (and the port in the
+ emulator). This is only passed to the <c>start</c> function, but
+ not to the other functions. The <c>start</c> function returns a
+ driver-defined handle that is passed to the other functions. A
+ common practice is to have the <c>start</c> function allocating
+ some application-defined structure and stash the <c>port</c>
+ handle in it, to use it later with the driver API functions.</p>
+ <p>The driver call-back functions are called synchronously from the
+ erlang emulator. If they take too long before completing, they
+ can cause timeouts in the emulator. Use the queue or
+ asynchronous calls if necessary, since the emulator must be
+ responsive.</p>
+ <p>The driver structure contains the name of the driver and some
+ 15 function pointers. These pointers are called at different
+ times by the emulator.</p>
+ <p>The only exported function from the driver is
+ <c>driver_init</c>. This function returns the <c>driver_entry</c>
+ structure that points to the other functions in the driver. The
+ <c>driver_init</c> function is declared with a macro
+ <c>DRIVER_INIT(drivername)</c>. (This is because different OS's
+ have different names for it.)</p>
+ <p>When writing a driver in C++, the driver entry should be of
+ <c>"C"</c> linkage. One way to do this is to put this line
+ somewhere before the driver entry:
+ <c>extern "C" DRIVER_INIT(drivername);</c>.</p>
+ <p>When the driver has passed the <c>driver_entry</c> over to
+ the emulator, the driver is <em>not</em> allowed to modify the
+ <c>driver_entry</c>.</p>
+ <note>
+ <p>Do <em>not</em> declare the <c>driver_entry</c><c>const</c>. This since the emulator needs to
+ modify the <c>handle</c>, and the <c>handle2</c>
+ fields. A statically allocated, and <c>const</c>
+ declared <c>driver_entry</c> may be located in
+ read only memory which will cause the emulator
+ to crash.</p>
+ </note>
+ </description>
+
+ <section>
+ <title>DATA TYPES</title>
+ <taglist>
+ <tag><b>ErlDrvEntry</b></tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef struct erl_drv_entry {
+ int (*init)(void); /* called at system start up for statically
+ linked drivers, and after loading for
+ dynamically loaded drivers */
+
+#ifndef ERL_SYS_DRV
+ ErlDrvData (*start)(ErlDrvPort port, char *command);
+ /* called when open_port/2 is invoked.
+ return value -1 means failure. */
+#else
+ ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts);
+ /* special options, only for system driver */
+#endif
+ void (*stop)(ErlDrvData drv_data);
+ /* called when port is closed, and when the
+ emulator is halted. */
+ void (*output)(ErlDrvData drv_data, char *buf, int len);
+ /* called when we have output from erlang to
+ the port */
+ void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event);
+ /* called when we have input from one of
+ the driver's handles) */
+ void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event);
+ /* called when output is possible to one of
+ the driver's handles */
+ char *driver_name; /* name supplied as command
+ in open_port XXX ? */
+ void (*finish)(void); /* called before unloading the driver -
+ DYNAMIC DRIVERS ONLY */
+ void *handle; /* Reserved -- Used by emulator internally */
+ int (*control)(ErlDrvData drv_data, unsigned int command, char *buf,
+ int len, char **rbuf, int rlen);
+ /* "ioctl" for drivers - invoked by
+ port_control/3) */
+ void (*timeout)(ErlDrvData drv_data); /* Handling of timeout in driver */
+ void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev);
+ /* called when we have output from erlang
+ to the port */
+ void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data);
+ void (*flush)(ErlDrvData drv_data);
+ /* called when the port is about to be
+ closed, and there is data in the
+ driver queue that needs to be flushed
+ before 'stop' can be called */
+ int (*call)(ErlDrvData drv_data, unsigned int command, char *buf,
+ int len, char **rbuf, int rlen, unsigned int *flags);
+ /* Works mostly like 'control', a syncronous
+ call into the driver. */
+ void (*event)(ErlDrvData drv_data, ErlDrvEvent event,
+ ErlDrvEventData event_data);
+ /* Called when an event selected by
+ driver_event() has occurred */
+ int extended_marker; /* ERL_DRV_EXTENDED_MARKER */
+ int major_version; /* ERL_DRV_EXTENDED_MAJOR_VERSION */
+ int minor_version; /* ERL_DRV_EXTENDED_MINOR_VERSION */
+ int driver_flags; /* ERL_DRV_FLAGs */
+ void *handle2; /* Reserved -- Used by emulator internally */
+ void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor);
+ /* Called when a process monitor fires */
+ void (*stop_select)(ErlDrvEvent event, void* reserved);
+ /* Called to close an event object */
+ } ErlDrvEntry;
+ </code>
+ <p/>
+ <taglist>
+ <tag><marker id="init"/>int (*init)(void)</tag>
+ <item>
+ <p>This is called directly after the driver has been loaded by
+ <c>erl_ddll:load_driver/2</c>. (Actually when the driver is
+ added to the driver list.) The driver should return 0, or if
+ the driver can't initialize, -1.</p>
+ </item>
+ <tag><marker id="start"/>int (*start)(ErlDrvPort port, char* command)</tag>
+ <item>
+ <p>This is called when the driver is instantiated, when
+ <c>open_port/2</c> is called. The driver should return a
+ number &gt;= 0 or a pointer, or if the driver can't be started,
+ one of three error codes should be returned:</p>
+ <p>ERL_DRV_ERROR_GENERAL - general error, no error code</p>
+ <p>ERL_DRV_ERROR_ERRNO - error with error code in erl_errno</p>
+ <p>ERL_DRV_ERROR_BADARG - error, badarg</p>
+ <p>If an error code is returned, the port isn't started.</p>
+ </item>
+ <tag><marker id="stop"/>void (*stop)(ErlDrvData drv_data)</tag>
+ <item>
+ <p>This is called when the port is closed, with
+ <c>port_close/1</c> or <c>Port ! {self(), close}</c>. Note
+ that terminating the port owner process also closes the
+ p\011 port.</p>
+ </item>
+ <tag><marker id="output"/>void (*output)(ErlDrvData drv_data, char *buf, int len)</tag>
+ <item>
+ <p>This is called when an erlang process has sent data to the
+ port. The data is pointed to by <c>buf</c>, and is
+ <c>len</c> bytes. Data is sent to the port with <c>Port ! {self(), {command, Data}}</c>, or with
+ <c>port_command/2</c>. Depending on how the port was opened,
+ it should be either a list of integers 0...255 or a
+ binary. See <c>open_port/3</c> and <c>port_command/2</c>.</p>
+ </item>
+
+ <tag><marker id="ready_input"/>void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event)</tag>
+ <tag><marker id="ready_output"/>void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event)</tag>
+ <item>
+ <p>This is called when a driver event (given in the
+ <c>event</c> parameter) is signaled. This is used to help
+ asynchronous drivers "wake up" when something happens.</p>
+ <p>On unix the <c>event</c> is a pipe or socket handle (or
+ something that the <c>select</c> system call understands).</p>
+ <p>On Windows the <c>event</c> is an Event or Semaphore (or
+ something that the <c>WaitForMultipleObjects</c> API
+ function understands). (Some trickery in the emulator allows
+ more than the built-in limit of 64 <c>Events</c> to be used.)</p>
+ <p>To use this with threads and asynchronous routines, create a
+ pipe on unix and an Event on Windows. When the routine
+ completes, write to the pipe (use <c>SetEvent</c> on
+ Windows), this will make the emulator call
+ <c>ready_input</c> or <c>ready_output</c>.</p>
+ </item>
+ <tag><marker id="driver_name"/>char *driver_name</tag>
+ <item>
+ <p>This is the name of the driver, it must correspond to the
+ atom used in <c>open_port</c>, and the name of the driver
+ library file (without the extension).</p>
+ </item>
+ <tag><marker id="finish"/>void (*finish)(void)</tag>
+ <item>
+ <p>This function is called by the <c>erl_ddll</c> driver when the
+ driver is unloaded. (It is only called in dynamic drivers.)</p>
+ <p>The driver is only unloaded as a result of calling
+ <c>unload_driver/1</c>, or when the emulator halts.</p>
+ </item>
+ <tag>void *handle</tag>
+ <item>
+ <p>This field is reserved for the emulators internal use. The
+ emulator will modify this field; therefore, it is important
+ that the <c>driver_entry</c> isn't declared <c>const</c>.</p>
+ </item>
+ <tag><marker id="control"></marker>int (*control)(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen)</tag>
+ <item>
+ <p>This is a special routine invoked with the erlang function
+ <c>port_control/3</c>. It works a little like an "ioctl" for
+ erlang drivers. The data given to <c>port_control/3</c>
+ arrives in <c>buf</c> and <c>len</c>. The driver may send
+ data back, using <c>*rbuf</c> and <c>rlen</c>.</p>
+ <p>This is the fastest way of calling a driver and get a
+ response. It won't make any context switch in the erlang
+ emulator, and requires no message passing. It is suitable
+ for calling C function to get faster execution, when erlang
+ is too slow.</p>
+ <p>If the driver wants to return data, it should return it in
+ <c>rbuf</c>. When <c>control</c> is called,
+ <c>*rbuf</c> points to a default buffer of <c>rlen</c> bytes, which
+ can be used to return data. Data is returned different depending on
+ the port control flags (those that are set with
+ <seealso marker="erl_driver#set_port_control_flags">set_port_control_flags</seealso>).
+ </p>
+ <p>If the flag is set to <c>PORT_CONTROL_FLAG_BINARY</c>,
+ a binary will be returned. Small binaries can be returned by writing
+ the raw data into the default buffer. A binary can also be
+ returned by setting <c>*rbuf</c> to point to a binary allocated with
+ <seealso marker="erl_driver#driver_alloc_binary">driver_alloc_binary</seealso>.
+ This binary will be freed automatically after <c>control</c> has returned.
+ The driver can retain the binary for <em>read only</em> access with
+ <seealso marker="erl_driver#driver_binary_inc_refc">driver_binary_inc_refc</seealso> to be freed later with
+ <seealso marker="erl_driver#driver_free_binary">driver_free_binary</seealso>.
+ It is never allowed to alter the binary after <c>control</c> has returned.
+ If <c>*rbuf</c> is set to NULL, an empty list will be returned.
+ </p>
+ <p>If the flag is set to <c>0</c>, data is returned as a
+ list of integers. Either use the default buffer or set
+ <c>*rbuf</c> to point to a larger buffer allocated with
+ <seealso marker="erl_driver#driver_alloc">driver_alloc</seealso>.
+ The buffer will be freed automatically after <c>control</c> has returned.</p>
+ <p>Using binaries is faster if more than a few bytes are returned.</p>
+ <p>The return value is the number of bytes returned in
+ <c>*rbuf</c>.</p>
+ </item>
+
+ <tag><marker id="timeout"/>void (*timeout)(ErlDrvData drv_data)</tag>
+ <item>
+ <p>This function is called any time after the driver's timer
+ reaches 0. The timer is activated with
+ <c>driver_set_timer</c>. There are no priorities or ordering
+ among drivers, so if several drivers time out at the same
+ time, any one of them is called first.</p>
+ </item>
+
+ <tag><marker id="outputv"/>void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev)</tag>
+ <item>
+ <p>This function is called whenever the port is written to. If
+ it is <c>NULL</c>, the <c>output</c> function is called
+ instead. This function is faster than <c>output</c>, because
+ it takes an <c>ErlIOVec</c> directly, which requires no
+ copying of the data. The port should be in binary mode, see
+ <c>open_port/2</c>.</p>
+ <p>The <c>ErlIOVec</c> contains both a <c>SysIOVec</c>,
+ suitable for <c>writev</c>, and one or more binaries. If
+ these binaries should be retained, when the driver returns
+ from <c>outputv</c>, they can be queued (using <seealso marker="erl_driver#driver_enq_bin">driver_enq_bin</seealso>
+ for instance), or if they are kept in a static or global
+ variable, the reference counter can be incremented.</p>
+ </item>
+ <tag><marker id="ready_async"/>void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data)</tag>
+ <item>
+ <p>This function is called after an asynchronous call has
+ completed. The asynchronous call is started with <seealso marker="erl_driver#driver_async">driver_async</seealso>.
+ This function is called from the erlang emulator thread, as
+ opposed to the asynchronous function, which is called in
+ some thread (if multithreading is enabled).</p>
+ </item>
+ <tag><marker id="call"/>int (*call)(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen, unsigned int *flags)</tag>
+ <item>
+ <p>This function is called from <c>erlang:port_call/3</c>. It
+ works a lot like the <c>control</c> call-back, but uses the
+ external term format for input and output.</p>
+ <p><c>command</c> is an integer, obtained from the call from
+ erlang (the second argument to <c>erlang:port_call/3</c>).</p>
+ <p><c>buf</c> and <c>len</c> provide the arguments to the call
+ (the third argument to <c>erlang:port_call/3</c>). They can
+ be decoded using <c>ei</c> functions.</p>
+ <p><c>rbuf</c> points to a return buffer, <c>rlen</c> bytes
+ long. The return data should be a valid erlang term in the
+ external (binary) format. This is converted to an erlang
+ term and returned by <c>erlang:port_call/3</c> to the
+ caller. If more space than <c>rlen</c> bytes is needed to
+ return data, <c>*rbuf</c> can be set to memory allocated with
+ <c>driver_alloc</c>. This memory will be freed automatically
+ after <c>call</c> has returned.</p>
+ <p>The return value is the number of bytes returned in
+ <c>*rbuf</c>. If <c>ERL_DRV_ERROR_GENERAL</c> is returned
+ (or in fact, anything &lt; 0), <c>erlang:port_call/3</c> will
+ throw a <c>BAD_ARG</c>.</p>
+ </item>
+ <tag>void (*event)(ErlDrvData drv_data, ErlDrvEvent event, ErlDrvEventData event_data)</tag>
+ <item>
+ <p>Intentionally left undocumented.</p>
+ </item>
+ <tag><marker id="extended_marker"/>int extended_marker</tag>
+ <item>
+ <p>
+ This field should either be equal to <c>ERL_DRV_EXTENDED_MARKER</c>
+ or <c>0</c>. An old driver (not aware of the extended driver
+ interface) should set this field to <c>0</c>. If this field is
+ equal to <c>0</c>, all the fields following this field also
+ <em>have</em> to be <c>0</c>, or <c>NULL</c> in case it is a
+ pointer field.
+ </p>
+ </item>
+ <tag>int major_version</tag>
+ <item>
+ <p>This field should equal <c>ERL_DRV_EXTENDED_MAJOR_VERSION</c> if
+ the <c>extended_marker</c> field equals
+ <c>ERL_DRV_EXTENDED_MARKER</c>.</p>
+ </item>
+ <tag>int minor_version</tag>
+ <item>
+ <p>
+ This field should equal <c>ERL_DRV_EXTENDED_MINOR_VERSION</c> if
+ the <c>extended_marker</c> field equals
+ <c>ERL_DRV_EXTENDED_MARKER</c>.
+ </p>
+ </item>
+
+ <tag><marker id="driver_flags"/>int driver_flags</tag>
+ <item>
+ <p>This field is used to pass driver capability information to the
+ runtime system. If the <c>extended_marker</c> field equals
+ <c>ERL_DRV_EXTENDED_MARKER</c>, it should contain <c>0</c> or
+ driver flags (<c>ERL_DRV_FLAG_*</c>) ored bitwise. Currently
+ the following driver flags exist:
+ </p>
+ <taglist>
+ <tag><c>ERL_DRV_FLAG_USE_PORT_LOCKING</c></tag>
+ <item>
+ The runtime system will use port level locking on
+ all ports executing this driver instead of driver
+ level locking when the driver is run in a runtime
+ system with SMP support. For more information see the
+ <seealso marker="erl_driver#smp_support">erl_driver</seealso>
+ documentation.
+ </item>
+ <tag><c>ERL_DRV_FLAG_SOFT_BUSY</c></tag>
+ <item>
+ Marks that driver instances can handle being called
+ in the <seealso marker="#output">output</seealso> and/or
+ <seealso marker="#outputv">outputv</seealso> callbacks even
+ though a driver instance has marked itself as busy (see
+ <seealso marker="erl_driver#set_busy_port">set_busy_port()</seealso>).
+ Since erts version 5.7.4 this flag is required for drivers used
+ by the Erlang distribution (the behaviour has always been
+ required by drivers used by the distribution).
+ </item>
+ </taglist>
+ </item>
+ <tag>void *handle2</tag>
+ <item>
+ <p>
+ This field is reserved for the emulators internal use. The
+ emulator will modify this field; therefore, it is important
+ that the <c>driver_entry</c> isn't declared <c>const</c>.
+ </p>
+ </item>
+ <tag><marker id="process_exit"/>void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor)</tag>
+ <item>
+ <p>This callback is called when a monitored process exits. The
+ <c>drv_data</c> is the data associated with the port for which
+ the process is monitored (using <seealso marker="erl_driver#driver_monitor_process">driver_monitor_process</seealso>)
+ and the <c>monitor</c> corresponds to the <c>ErlDrvMonitor</c>
+ structure filled
+ in when creating the monitor. The driver interface function
+ <seealso marker="erl_driver#driver_get_monitored_process">driver_get_monitored_process</seealso>
+ can be used to retrieve the process id of the exiting process as
+ an <c>ErlDrvTermData</c>.</p>
+ </item>
+ <tag><marker id="stop_select"/>void (*stop_select)(ErlDrvEvent event, void* reserved)</tag>
+ <item>
+ <p>This function is called on behalf of
+ <seealso marker="erl_driver#driver_select">driver_select</seealso>
+ when it is safe to close an event object.</p>
+ <p>A typical implementation on Unix is to do
+ <c>close((int)event)</c>.</p>
+ <p>Argument <c>reserved</c> is intended for future use and should be ignored.</p>
+ <p>In contrast to most of the other call-back functions,
+ <c>stop_select</c> is called independent of any port. No
+ <c>ErlDrvData</c> argument is passed to the function. No
+ driver lock or port lock is guaranteed to be held. The port that
+ called <c>driver_select</c> might even be closed at the
+ time <c>stop_select</c> is called. But it could also be
+ the case that <c>stop_select</c> is called directly by
+ <c>driver_select</c>.</p>
+ <p>It is not allowed to call any functions in the
+ <seealso marker="erl_driver">driver API</seealso> from
+ <c>stop_select</c>. This strict limitation is due to the
+ volatile context that <c>stop_select</c> may be called.</p>
+ </item>
+
+ </taglist>
+ </item>
+
+ </taglist>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="erl_driver">erl_driver(3)</seealso>,
+ <seealso marker="kernel:erl_ddll">erl_ddll(3)</seealso>,
+ <seealso marker="erts:erlang">erlang(3)</seealso>,
+ kernel(3)</p>
+ </section>
+</cref>
+
diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml
new file mode 100644
index 0000000000..796ab3820b
--- /dev/null
+++ b/erts/doc/src/epmd.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>epmd</title>
+ <prepared>Claes Wikstr&ouml;m</prepared>
+ <responsible></responsible>
+ <docno>1</docno>
+ <approved></approved>
+ <checked></checked>
+ <date>98-01-05</date>
+ <rev>A</rev>
+ <file>epmd.xml</file>
+ </header>
+ <com>epmd</com>
+ <comsummary>Erlang Port Mapper Daemon </comsummary>
+ <description>
+ <p>This daemon acts as a name server on all hosts involved in
+ distributed Erlang computations. When an Erlang node
+ starts, the node has a name and it obtains an address from the host
+ OS kernel.
+ The name and the address are sent to the
+ <c><![CDATA[epmd]]></c> daemon running on the local host.
+ In a TCP/IP environment, the address consists
+ of the IP address and a port number. The name of the node is
+ an atom on the form of <c><![CDATA[Name@Node]]></c>.
+ The job of the <c><![CDATA[epmd]]></c> daemon is to keep track of which
+ node name listens on which address. Hence, <c><![CDATA[epmd]]></c> map
+ symbolic node names to machine addresses.</p>
+ <p>The daemon is started automatically by the Erlang start-up script.</p>
+ <p>The program <c><![CDATA[epmd]]></c> can also be used for a variety of other
+ purposes, for example checking the DNS (Domain Name System)
+ configuration of a host.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>epmd [-daemon] </name>
+ <fsummary>Start a name server as a daemon</fsummary>
+ <desc>
+ <p>Starts a name server as a daemon. If it has no argument, the
+ <c><![CDATA[epmd]]></c> runs as a normal program with the controlling terminal
+ of the shell in which it is started. Normally, it should run as a
+ daemon.</p>
+ </desc>
+ </func>
+ <func>
+ <name>epmd -names</name>
+ <fsummary>Request the names of the registered Erlang nodes on this host</fsummary>
+ <desc>
+ <p>Requests the names of the local Erlang nodes <c><![CDATA[epmd]]></c> has
+ registered.</p>
+ </desc>
+ </func>
+ <func>
+ <name>epmd -kill</name>
+ <fsummary>Kill the <c><![CDATA[epmd]]></c>process</fsummary>
+ <desc>
+ <p>Kills the <c><![CDATA[epmd]]></c> process.</p>
+ </desc>
+ </func>
+ <func>
+ <name>epmd -help</name>
+ <fsummary>List options</fsummary>
+ <desc>
+ <p>Write short info about the usage including some debugging
+ options not listed here.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <marker id="environment_variables"></marker>
+ <title>Environment variables</title>
+ <taglist>
+ <tag><c><![CDATA[ERL_EPMD_PORT]]></c></tag>
+ <item>
+ <p>This environment variable can contain the port number epmd will use.
+ The default port will work fine in most cases. A different port can
+ be specified to allow several instances of epmd, representing
+ independent clusters of nodes, to co-exist on the same host.
+ All nodes in a cluster must use the same epmd port number.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Logging</title>
+ <p>On some operating systems <em>syslog</em> will be used for
+ error reporting when epmd runs as an daemon. To enable
+ the error logging you have to edit <path unix="" windows="">/etc/syslog.conf</path>
+ file and add an entry</p>
+ <code type="none"><![CDATA[
+ !epmd
+ *.*<TABs>/var/log/epmd.log
+ ]]></code>
+ <p>where &lt;TABs&gt; are at least one real tab character. Spaces will
+ silently be ignored.
+ </p>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
new file mode 100644
index 0000000000..90a3c53a37
--- /dev/null
+++ b/erts/doc/src/erl.xml
@@ -0,0 +1,928 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erl</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>erl.xml</file>
+ </header>
+ <com>erl</com>
+ <comsummary>The Erlang Emulator</comsummary>
+ <description>
+ <p>The <c><![CDATA[erl]]></c> program starts an Erlang runtime system.
+ The exact details (for example, whether <c><![CDATA[erl]]></c> is a script or
+ a program and which other programs it calls) are system-dependent.</p>
+ <p>Windows users probably wants to use the <c><![CDATA[werl]]></c> program
+ instead, which runs in its own window with scrollbars and supports
+ command-line editing. The <c><![CDATA[erl]]></c> program on Windows provides
+ no line editing in its shell, and on Windows 95 there is no way
+ to scroll back to text which has scrolled off the screen.
+ The <c><![CDATA[erl]]></c> program must be used, however, in pipelines or if
+ you want to redirect standard input or output.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>erl &lt;arguments></name>
+ <fsummary>Start an Erlang runtime system</fsummary>
+ <desc>
+ <p>Starts an Erlang runtime system.</p>
+ <p>The arguments can be divided into <em>emulator flags</em>,
+ <em>flags</em> and <em>plain arguments</em>:</p>
+ <list type="bulleted">
+ <item>
+ <p>Any argument starting with the character <c><![CDATA[+]]></c> is
+ interpreted as an <seealso marker="#emu_flags">emulator flag</seealso>.</p>
+ <p>As indicated by the name, emulator flags controls
+ the behavior of the emulator.</p>
+ </item>
+ <item>
+ <p>Any argument starting with the character <c><![CDATA[-]]></c>
+ (hyphen) is interpreted as a
+ <seealso marker="#init_flags">flag</seealso> which should
+ be passed to the Erlang part of the runtime system, more
+ specifically to the <c><![CDATA[init]]></c> system process, see
+ <seealso marker="init">init(3)</seealso>.</p>
+ <p>The <c><![CDATA[init]]></c> process itself interprets some of these
+ flags, the <em>init flags</em>. It also stores any
+ remaining flags, the <em>user flags</em>. The latter can
+ be retrieved by calling <c><![CDATA[init:get_argument/1]]></c>.</p>
+ <p>It can be noted that there are a small number of "-"
+ flags which now actually are emulator flags, see
+ the description below.</p>
+ </item>
+ <item>
+ <p>Plain arguments are not interpreted in any way. They are
+ also stored by the <c><![CDATA[init]]></c> process and can be
+ retrieved by calling <c><![CDATA[init:get_plain_arguments/0]]></c>.
+ Plain arguments can occur before the first flag, or after
+ a <c><![CDATA[--]]></c> flag. Additionally, the flag <c><![CDATA[-extra]]></c>
+ causes everything that follows to become plain arguments.</p>
+ </item>
+ </list>
+ <p>Example:</p>
+ <pre>
+% <input>erl +W w -sname arnie +R 9 -s my_init -extra +bertie</input>
+(arnie@host)1> <input>init:get_argument(sname).</input>
+{ok,[["arnie"]]}
+(arnie@host)2> <input>init:get_plain_arguments().</input>
+["+bertie"]</pre>
+ <p>Here <c><![CDATA[+W w]]></c> and <c><![CDATA[+R 9]]></c> are emulator flags.
+ <c><![CDATA[-s my_init]]></c> is an init flag, interpreted by <c><![CDATA[init]]></c>.
+ <c><![CDATA[-sname arnie]]></c> is a user flag, stored by <c><![CDATA[init]]></c>.
+ It is read by Kernel and will cause the Erlang runtime system
+ to become distributed. Finally, everything after <c><![CDATA[-extra]]></c>
+ (that is, <c><![CDATA[+bertie]]></c>) is considered as plain arguments.</p>
+ <pre>
+% <input>erl -myflag 1</input>
+1> <input>init:get_argument(myflag).</input>
+{ok,[["1"]]}
+2> <input>init:get_plain_arguments().</input>
+[]</pre>
+ <p>Here the user flag <c><![CDATA[-myflag 1]]></c> is passed to and stored
+ by the <c><![CDATA[init]]></c> process. It is a user defined flag,
+ presumably used by some user defined application.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <marker id="init_flags"></marker>
+ <title>Flags</title>
+ <p>In the following list, init flags are marked (init flag).
+ Unless otherwise specified, all other flags are user flags, for
+ which the values can be retrieved by calling
+ <c><![CDATA[init:get_argument/1]]></c>. Note that the list of user flags is
+ not exhaustive, there may be additional, application specific
+ flags which instead are documented in the corresponding
+ application documentation.</p>
+ <taglist>
+ <tag><c><![CDATA[--]]></c>(init flag)</tag>
+ <item>
+ <p>Everything following <c><![CDATA[--]]></c> up to the next flag
+ (<c><![CDATA[-flag]]></c> or <c><![CDATA[+flag]]></c>) is considered plain arguments
+ and can be retrieved using <c><![CDATA[init:get_plain_arguments/0]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-Application Par Val]]></c></tag>
+ <item>
+ <p>Sets the application configuration parameter <c><![CDATA[Par]]></c> to
+ the value <c><![CDATA[Val]]></c> for the application <c><![CDATA[Application]]></c>,
+ see <seealso marker="kernel:app">app(4)</seealso> and
+ <seealso marker="kernel:application">application(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-args_file FileName]]></c></tag>
+ <item>
+ <marker id="args_file"></marker>
+ <p>Command line arguments are read from the file <c><![CDATA[FileName]]></c>.
+ The arguments read from the file replace the
+ '<c><![CDATA[-args_file FileName]]></c>' flag on the resulting command line.</p>
+ <p>The file <c><![CDATA[FileName]]></c> should be a plain text file and may
+ contain comments and command line arguments. A comment begins
+ with a # character and continues until next end of line character.
+ Backslash (\\) is used as quoting character. All command line
+ arguments accepted by <c><![CDATA[erl]]></c> are allowed, also the
+ <c><![CDATA[-args_file FileName]]></c> flag. Be careful not to cause circular
+ dependencies between files containing the <c><![CDATA[-args_file]]></c> flag,
+ though.</p>
+ <p>The <c><![CDATA[-extra]]></c> flag is treated specially. Its scope ends
+ at the end of the file. Arguments following an <c><![CDATA[-extra]]></c>
+ flag are moved on the command line into the <c><![CDATA[-extra]]></c> section,
+ i.e. the end of the command line following after an <c><![CDATA[-extra]]></c>
+ flag.</p>
+ </item>
+ <tag><c><![CDATA[-async_shell_start]]></c></tag>
+ <item>
+ <p>The initial Erlang shell does not read user input until
+ the system boot procedure has been completed (Erlang 5.4 and
+ later). This flag disables the start synchronization feature
+ and lets the shell start in parallel with the rest of
+ the system.</p>
+ </item>
+ <tag><c><![CDATA[-boot File]]></c></tag>
+ <item>
+ <p>Specifies the name of the boot file, <c><![CDATA[File.boot]]></c>,
+ which is used to start the system. See
+ <seealso marker="init">init(3)</seealso>. Unless
+ <c><![CDATA[File]]></c> contains an absolute path, the system searches
+ for <c><![CDATA[File.boot]]></c> in the current and <c><![CDATA[$ROOT/bin]]></c>
+ directories.</p>
+ <p>Defaults to <c><![CDATA[$ROOT/bin/start.boot]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-boot_var Var Dir]]></c></tag>
+ <item>
+ <p>If the boot script contains a path variable <c><![CDATA[Var]]></c> other
+ than <c><![CDATA[$ROOT]]></c>, this variable is expanded to <c><![CDATA[Dir]]></c>.
+ Used when applications are installed in another directory
+ than <c><![CDATA[$ROOT/lib]]></c>, see
+ <seealso marker="sasl:systools#make_script/1">systools:make_script/1,2</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-code_path_cache]]></c></tag>
+ <item>
+ <p>Enables the code path cache of the code server, see
+ <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-compile Mod1 Mod2 ...]]></c></tag>
+ <item>
+ <p>Compiles the specified modules and then terminates (with
+ non-zero exit code if the compilation of some file did not
+ succeed). Implies <c><![CDATA[-noinput]]></c>. Not recommended - use
+ <seealso marker="erlc">erlc</seealso> instead.</p>
+ </item>
+ <tag><c><![CDATA[-config Config]]></c></tag>
+ <item>
+ <p>Specifies the name of a configuration file,
+ <c><![CDATA[Config.config]]></c>, which is used to configure
+ applications. See
+ <seealso marker="kernel:app">app(4)</seealso> and
+ <seealso marker="kernel:application">application(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-connect_all false]]></c></tag>
+ <item>
+ <marker id="connect_all"></marker>
+ <p>If this flag is present, <c><![CDATA[global]]></c> will not maintain a
+ fully connected network of distributed Erlang nodes, and then
+ global name registration cannot be used. See
+ <seealso marker="kernel:global">global(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-cookie Cookie]]></c></tag>
+ <item>
+ <p>Obsolete flag without any effect and common misspelling for
+ <c><![CDATA[-setcookie]]></c>. Use <c><![CDATA[-setcookie]]></c> instead.</p>
+ </item>
+ <tag><c><![CDATA[-detached]]></c></tag>
+ <item>
+ <p>Starts the Erlang runtime system detached from the system
+ console. Useful for running daemons and backgrounds processes.</p>
+ </item>
+ <tag><c><![CDATA[-emu_args]]></c></tag>
+ <item>
+ <p>Useful for debugging. Prints out the actual arguments
+ sent to the emulator.</p>
+ </item>
+ <tag><c><![CDATA[-env Variable Value]]></c></tag>
+ <item>
+ <p>Sets the host OS environment variable <c><![CDATA[Variable]]></c> to
+ the value <c><![CDATA[Value]]></c> for the Erlang runtime system.
+ Example:</p>
+ <pre>
+% <input>erl -env DISPLAY gin:0</input></pre>
+ <p>In this example, an Erlang runtime system is started with
+ the <c><![CDATA[DISPLAY]]></c> environment variable set to <c><![CDATA[gin:0]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-eval Expr]]></c>(init flag)</tag>
+ <item>
+ <p>Makes <c><![CDATA[init]]></c> evaluate the expression <c><![CDATA[Expr]]></c>, see
+ <seealso marker="init">init(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-extra]]></c>(init flag)</tag>
+ <item>
+ <p>Everything following <c><![CDATA[-extra]]></c> is considered plain
+ arguments and can be retrieved using
+ <c><![CDATA[init:get_plain_arguments/0]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-heart]]></c></tag>
+ <item>
+ <p>Starts heart beat monitoring of the Erlang runtime system.
+ See <seealso marker="kernel:heart">heart(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-hidden]]></c></tag>
+ <item>
+ <p>Starts the Erlang runtime system as a hidden node, if it is
+ run as a distributed node. Hidden nodes always establish
+ hidden connections to all other nodes except for nodes in the
+ same global group. Hidden connections are not published on
+ neither of the connected nodes, i.e. neither of the connected
+ nodes are part of the result from <c><![CDATA[nodes/0]]></c> on the other
+ node. See also hidden global groups,
+ <seealso marker="kernel:global_group">global_group(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-hosts Hosts]]></c></tag>
+ <item>
+ <p>Specifies the IP addresses for the hosts on which Erlang
+ boot servers are running, see
+ <seealso marker="kernel:erl_boot_server">erl_boot_server(3)</seealso>.
+ This flag is mandatory if the <c><![CDATA[-loader inet]]></c> flag is
+ present.</p>
+ <p>The IP addresses must be given in the standard form (four
+ decimal numbers separated by periods, for example
+ <c><![CDATA["150.236.20.74"]]></c>. Hosts names are not acceptable, but
+ a broadcast address (preferably limited to the local network)
+ is.</p>
+ </item>
+ <tag><c><![CDATA[-id Id]]></c></tag>
+ <item>
+ <p>Specifies the identity of the Erlang runtime system. If it is
+ run as a distributed node, <c><![CDATA[Id]]></c> must be identical to
+ the name supplied together with the <c><![CDATA[-sname]]></c> or
+ <c><![CDATA[-name]]></c> flag.</p>
+ </item>
+ <tag><c><![CDATA[-init_debug]]></c></tag>
+ <item>
+ <p>Makes <c><![CDATA[init]]></c> write some debug information while
+ interpreting the boot script.</p>
+ </item>
+ <tag><c><![CDATA[-instr]]></c>(emulator flag)</tag>
+ <item>
+ <marker id="instr"></marker>
+ <p>Selects an instrumented Erlang runtime system (virtual
+ machine) to run, instead of the ordinary one. When running an
+ instrumented runtime system, some resource usage data can be
+ obtained and analysed using the module <c><![CDATA[instrument]]></c>.
+ Functionally, it behaves exactly like an ordinary Erlang
+ runtime system.</p>
+ </item>
+ <tag><c><![CDATA[-loader Loader]]></c></tag>
+ <item>
+ <p>Specifies the method used by <c><![CDATA[erl_prim_loader]]></c> to load
+ Erlang modules into the system. See
+ <seealso marker="erl_prim_loader">erl_prim_loader(3)</seealso>.
+ Two <c><![CDATA[Loader]]></c> methods are supported, <c><![CDATA[efile]]></c> and
+ <c><![CDATA[inet]]></c>. <c><![CDATA[efile]]></c> means use the local file system,
+ this is the default. <c><![CDATA[inet]]></c> means use a boot server on
+ another machine, and the <c><![CDATA[-id]]></c>, <c><![CDATA[-hosts]]></c> and
+ <c><![CDATA[-setcookie]]></c> flags must be specified as well. If
+ <c><![CDATA[Loader]]></c> is something else, the user supplied
+ <c><![CDATA[Loader]]></c> port program is started.</p>
+ </item>
+ <tag><c><![CDATA[-make]]></c></tag>
+ <item>
+ <p>Makes the Erlang runtime system invoke <c><![CDATA[make:all()]]></c> in
+ the current working directory and then terminate. See
+ <seealso marker="tools:make">make(3)</seealso>. Implies
+ <c><![CDATA[-noinput]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-man Module]]></c></tag>
+ <item>
+ <p>Displays the manual page for the Erlang module <c><![CDATA[Module]]></c>.
+ Only supported on Unix.</p>
+ </item>
+ <tag><c><![CDATA[-mode interactive | embedded]]></c></tag>
+ <item>
+ <p>Indicates if the system should load code dynamically
+ (<c><![CDATA[interactive]]></c>), or if all code should be loaded
+ during system initialization (<c><![CDATA[embedded]]></c>), see
+ <seealso marker="kernel:code">code(3)</seealso>. Defaults to
+ <c><![CDATA[interactive]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-name Name]]></c></tag>
+ <item>
+ <p>Makes the Erlang runtime system into a distributed node.
+ This flag invokes all network servers necessary for a node to
+ become distributed. See
+ <seealso marker="kernel:net_kernel">net_kernel(3)</seealso>.
+ It is also ensured that <c><![CDATA[epmd]]></c> runs on the current host
+ before Erlang is started. See
+ <seealso marker="epmd">epmd(1)</seealso>.</p>
+ <p>The name of the node will be <c><![CDATA[Name@Host]]></c>, where
+ <c><![CDATA[Host]]></c> is the fully qualified host name of the current
+ host. For short names, use the <c><![CDATA[-sname]]></c> flag instead.</p>
+ </item>
+ <tag><c><![CDATA[-noinput]]></c></tag>
+ <item>
+ <p>Ensures that the Erlang runtime system never tries to read
+ any input. Implies <c><![CDATA[-noshell]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-noshell]]></c></tag>
+ <item>
+ <p>Starts an Erlang runtime system with no shell. This flag
+ makes it possible to have the Erlang runtime system as a
+ component in a series of UNIX pipes.</p>
+ </item>
+ <tag><c><![CDATA[-nostick]]></c></tag>
+ <item>
+ <p>Disables the sticky directory facility of the Erlang code
+ server, see
+ <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-oldshell]]></c></tag>
+ <item>
+ <p>Invokes the old Erlang shell from Erlang 3.3. The old shell
+ can still be used.</p>
+ </item>
+ <tag><c><![CDATA[-pa Dir1 Dir2 ...]]></c></tag>
+ <item>
+ <p>Adds the specified directories to the beginning of the code
+ path, similar to <c><![CDATA[code:add_pathsa/1]]></c>. See
+ <seealso marker="kernel:code">code(3)</seealso>.
+ As an alternative to <c>-pa</c>, if several directories are
+ to be prepended to the code and the directories have a
+ common parent directory, that parent directory could be
+ specified in the <c>ERL_LIBS</c> environment variable.
+ See <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-pz Dir1 Dir2 ...]]></c></tag>
+ <item>
+ <p>Adds the specified directories to the end of the code path,
+ similar to <c><![CDATA[code:add_pathsz/1]]></c>. See
+ <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-remsh Node]]></c></tag>
+ <item>
+ <p>Starts Erlang with a remote shell connected to <c><![CDATA[Node]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-rsh Program]]></c></tag>
+ <item>
+ <p>Specifies an alternative to <c><![CDATA[rsh]]></c> for starting a slave
+ node on a remote host. See
+ <seealso marker="stdlib:slave">slave(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-run Mod [Func [Arg1, Arg2, ...]]]]></c>(init flag)</tag>
+ <item>
+ <p>Makes <c><![CDATA[init]]></c> call the specified function. <c><![CDATA[Func]]></c>
+ defaults to <c><![CDATA[start]]></c>. If no arguments are provided,
+ the function is assumed to be of arity 0. Otherwise it is
+ assumed to be of arity 1, taking the list
+ <c><![CDATA[[Arg1,Arg2,...]]]></c> as argument. All arguments are passed
+ as strings. See
+ <seealso marker="init">init(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-s Mod [Func [Arg1, Arg2, ...]]]]></c>(init flag)</tag>
+ <item>
+ <p>Makes <c><![CDATA[init]]></c> call the specified function. <c><![CDATA[Func]]></c>
+ defaults to <c><![CDATA[start]]></c>. If no arguments are provided,
+ the function is assumed to be of arity 0. Otherwise it is
+ assumed to be of arity 1, taking the list
+ <c><![CDATA[[Arg1,Arg2,...]]]></c> as argument. All arguments are passed
+ as atoms. See
+ <seealso marker="init">init(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-setcookie Cookie]]></c></tag>
+ <item>
+ <p>Sets the magic cookie of the node to <c><![CDATA[Cookie]]></c>, see
+ <seealso marker="erlang#erlang:set_cookie/2">erlang:set_cookie/2</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[-shutdown_time Time]]></c></tag>
+ <item>
+ <p>Specifies how long time (in milliseconds) the <c><![CDATA[init]]></c>
+ process is allowed to spend shutting down the system. If
+ <c><![CDATA[Time]]></c> ms have elapsed, all processes still existing are
+ killed. Defaults to <c><![CDATA[infinity]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[-sname Name]]></c></tag>
+ <item>
+ <p>Makes the Erlang runtime system into a distributed node,
+ similar to <c><![CDATA[-name]]></c>, but the host name portion of the node
+ name <c><![CDATA[Name@Host]]></c> will be the short name, not fully
+ qualified.</p>
+ <p>This is sometimes the only way to run distributed Erlang if
+ the DNS (Domain Name System) is not running. There can be no
+ communication between nodes running with the <c><![CDATA[-sname]]></c>
+ flag and those running with the <c><![CDATA[-name]]></c> flag, as node
+ names must be unique in distributed Erlang systems.</p>
+ </item>
+ <tag><c><![CDATA[-smp [enable|auto|disable]]]></c></tag>
+ <item>
+ <marker id="smp"></marker>
+ <p><c>-smp enable</c> and <c>-smp</c> starts the Erlang runtime
+ system with SMP support enabled. This may 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 are detected.
+ <c>-smp disable</c> starts a runtime system without SMP support.
+ By default <c>-smp auto</c> will be used unless a conflicting
+ parameter has been passed, then <c>-smp disable</c> will be
+ used. Currently only the <c>-hybrid</c> parameter conflicts
+ with <c>-smp auto</c>.</p>
+ <p><em>NOTE</em>: The runtime system with SMP support will not
+ be available on all supported platforms. See also the
+ <seealso marker="#+S">+S</seealso> flag.</p>
+ </item>
+ <tag><c><![CDATA[-version]]></c>(emulator flag)</tag>
+ <item>
+ <p>Makes the emulator print out its version number. The same
+ as <c><![CDATA[erl +V]]></c>.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="emu_flags"></marker>
+ <title>Emulator Flags</title>
+ <p><c><![CDATA[erl]]></c> invokes the code for the Erlang emulator (virtual
+ machine), which supports the following flags:</p>
+ <taglist>
+ <tag><c><![CDATA[+a size]]></c></tag>
+ <item>
+ <marker id="async_thread_stack_size"></marker>
+ <p>Suggested stack size, in kilowords, for threads in the
+ async-thread pool. Valid range is 16-8192 kilowords. The
+ default suggested stack size is 16 kilowords, i.e, 64
+ kilobyte on 32-bit architectures. This small default size
+ has been chosen since the amount of async-threads might
+ be quite large. The default size is enough for drivers
+ delivered with Erlang/OTP, but might not be sufficiently
+ large for other dynamically linked in drivers that use the
+ <seealso marker="erl_driver#driver_async">driver_async()</seealso>
+ functionality. Note that the value passed is only a
+ suggestion, and it might even be ignored on some
+ platforms.</p>
+ </item>
+ <tag><c><![CDATA[+A size]]></c></tag>
+ <item>
+ <marker id="async_thread_pool_size"></marker>
+ <p>Sets the number of threads in async thread pool, valid range
+ is 0-1024. Default is 0.</p>
+ </item>
+ <tag><c><![CDATA[+B [c | d | i]]]></c></tag>
+ <item>
+ <p>The <c><![CDATA[c]]></c> option makes <c><![CDATA[Ctrl-C]]></c> interrupt the current
+ shell instead of invoking the emulator break handler.
+ The <c><![CDATA[d]]></c> option (same as specifying <c><![CDATA[+B]]></c> without an
+ extra option) disables the break handler. The <c><![CDATA[i]]></c> option
+ makes the emulator ignore any break signal.</p>
+ <p>If the <c><![CDATA[c]]></c> option is used with <c><![CDATA[oldshell]]></c> on Unix,
+ <c><![CDATA[Ctrl-C]]></c> will restart the shell process rather than
+ interrupt it.</p>
+ <p>Note that on Windows, this flag is only applicable for
+ <c><![CDATA[werl]]></c>, not <c><![CDATA[erl]]></c> (<c><![CDATA[oldshell]]></c>). Note also that
+ <c><![CDATA[Ctrl-Break]]></c> is used instead of <c><![CDATA[Ctrl-C]]></c> on Windows.</p>
+ </item>
+ <tag><c><![CDATA[+c]]></c></tag>
+ <item>
+ <p>Disable compensation for sudden changes of system time.</p>
+ <p>Normally, <c><![CDATA[erlang:now/0]]></c> will not immediately reflect
+ sudden changes in the system time, in order to keep timers
+ (including <c><![CDATA[receive-after]]></c>) working. Instead, the time
+ maintained by <c><![CDATA[erlang:now/0]]></c> is slowly adjusted towards
+ the new system time. (Slowly means in one percent adjustments;
+ if the time is off by one minute, the time will be adjusted
+ in 100 minutes.)</p>
+ <p>When the <c><![CDATA[+c]]></c> option is given, this slow adjustment
+ will not take place. Instead <c><![CDATA[erlang:now/0]]></c> will always
+ reflect the current system time. Note that timers are based
+ on <c><![CDATA[erlang:now/0]]></c>. If the system time jumps, timers
+ then time out at the wrong time.</p>
+ </item>
+ <tag><c><![CDATA[+d]]></c></tag>
+ <item>
+ <p>If the emulator detects an internal error (or runs out of memory),
+ it will by default generate both a crash dump and a core dump.
+ The core dump will, however, not be very useful since the content
+ of process heaps is destroyed by the crash dump generation.</p>
+
+ <p>The <c>+d</c> option instructs the emulator to only produce a
+ core dump and no crash dump if an internal error is detected.</p>
+
+ <p>Calling <c>erlang:halt/1</c> with a string argument will still
+ produce a crash dump.</p>
+ </item>
+ <tag><c><![CDATA[+h Size]]></c></tag>
+ <item>
+ <p>Sets the default heap size of processes to the size
+ <c><![CDATA[Size]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[+K true | false]]></c></tag>
+ <item>
+ <p>Enables or disables the kernel poll functionality if
+ the emulator supports it. Default is <c><![CDATA[false]]></c> (disabled).
+ If the emulator does not support kernel poll, and
+ the <c><![CDATA[+K]]></c> flag is passed to the emulator, a warning is
+ issued at startup.</p>
+ </item>
+ <tag><c><![CDATA[+l]]></c></tag>
+ <item>
+ <p>Enables auto load tracing, displaying info while loading
+ code.</p>
+ </item>
+ <tag><c><![CDATA[+MFlag Value]]></c></tag>
+ <item>
+ <marker id="erts_alloc"></marker>
+ <p>Memory allocator specific flags, see
+ <seealso marker="erts_alloc">erts_alloc(3)</seealso> for
+ further information.</p>
+ </item>
+ <tag><c><![CDATA[+P Number]]></c></tag>
+ <item>
+ <marker id="max_processes"></marker>
+ <p>Sets the maximum number of concurrent processes for this
+ system. <c><![CDATA[Number]]></c> must be in the range 16..134217727.
+ Default is 32768.</p>
+ </item>
+ <tag><c><![CDATA[+R ReleaseNumber]]></c></tag>
+ <item>
+ <marker id="compat_rel"></marker>
+ <p>Sets the compatibility mode.</p>
+ <p>The distribution mechanism is not backwards compatible by
+ default. This flags sets the emulator in compatibility mode
+ with an earlier Erlang/OTP release <c><![CDATA[ReleaseNumber]]></c>.
+ The release number must be in the range
+ <c><![CDATA[7..<current release>]]></c>. This limits the emulator,
+ making it possible for it to communicate with Erlang nodes
+ (as well as C- and Java nodes) running that earlier release.</p>
+ <p>For example, an R10 node is not automatically compatible
+ with an R9 node, but R10 nodes started with the <c><![CDATA[+R 9]]></c>
+ flag can co-exist with R9 nodes in the same distributed
+ Erlang system, they are R9-compatible.</p>
+ <p>Note: Make sure all nodes (Erlang-, C-, and Java nodes) of
+ a distributed Erlang system is of the same Erlang/OTP release,
+ or from two different Erlang/OTP releases X and Y, where
+ <em>all</em> Y nodes have compatibility mode X.</p>
+ <p>For example: A distributed Erlang system can consist of
+ R10 nodes, or of R9 nodes and R9-compatible R10 nodes, but
+ not of R9 nodes, R9-compatible R10 nodes and "regular" R10
+ nodes, as R9 and "regular" R10 nodes are not compatible.</p>
+ </item>
+ <tag><c><![CDATA[+r]]></c></tag>
+ <item>
+ <p>Force ets memory block to be moved on realloc.</p>
+ </item>
+ <tag><c><![CDATA[+S Schedulers:SchedulerOnline]]></c></tag>
+ <item>
+ <marker id="+S"></marker>
+ <p>Sets the amount of scheduler threads to create and scheduler
+ threads to set online when SMP support has been enabled.
+ Valid range for both values are 1-1024. If the
+ Erlang runtime system is able to determine the amount
+ of logical processors configured and logical processors available,
+ <c>Schedulers</c> will default to logical processors configured,
+ and <c>SchedulersOnline</c> will default to logical processors
+ available; otherwise, the default values will be 1. <c>Schedulers</c>
+ may be omitted if <c>:SchedulerOnline</c> is not and vice versa. The
+ amount of schedulers online can be changed at run time via
+ <seealso marker="erlang#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>.
+ </p>
+ <p>This flag will be ignored if the emulator doesn't have
+ SMP support enabled (see the <seealso marker="#smp">-smp</seealso>
+ flag).</p>
+ </item>
+ <tag><c><![CDATA[+sFlag Value]]></c></tag>
+ <item>
+ <p>Scheduling specific flags.</p>
+ <taglist>
+ <tag>+sbt BindType</tag>
+ <item>
+ <marker id="+sbt"></marker>
+ <p>Set scheduler bind type. Currently valid <c>BindType</c>s:
+ </p>
+ <taglist>
+ <tag><c>u</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, unbound)</seealso>.
+ </p></item>
+ <tag><c>ns</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, no_spread)</seealso>.
+ </p></item>
+ <tag><c>ts</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, thread_spread)</seealso>.
+ </p></item>
+ <tag><c>ps</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, processor_spread)</seealso>.
+ </p></item>
+ <tag><c>s</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, spread)</seealso>.
+ </p></item>
+ <tag><c>nnts</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, no_node_thread_spread)</seealso>.
+ </p></item>
+ <tag><c>nnps</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, no_node_processor_spread)</seealso>.
+ </p></item>
+ <tag><c>tnnps</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, thread_no_node_processor_spread)</seealso>.
+ </p></item>
+ <tag><c>db</c></tag>
+ <item><p>Same as
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, default_bind)</seealso>.
+ </p></item>
+ </taglist>
+ <p>Binding of schedulers are currently only supported on newer
+ Linux and Solaris systems.</p>
+ <p>If no CPU topology is available when the <c>+sbt</c> flag
+ is processed and <c>BindType</c> is any other type than
+ <c>u</c>, the runtime system will fail to start. CPU
+ topology can be defined using the
+ <seealso marker="#+sct">+sct</seealso> flag. Note
+ that the <c>+sct</c> flag may have to be passed before the
+ <c>+sbt</c> flag on the command line (in case no CPU topology
+ has been automatically detected).</p>
+ <p>For more information, see
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, SchedulerBindType)</seealso>.
+ </p>
+ </item>
+ <tag><c>+sct CpuTopology</c></tag>
+ <item>
+ <marker id="+sct"></marker>
+ <list type="bulleted">
+ <item><c><![CDATA[<Id> = integer(); when 0 =< <Id> =< 65535]]></c></item>
+ <item><c><![CDATA[<IdRange> = <Id>-<Id>]]></c></item>
+ <item><c><![CDATA[<IdOrIdRange> = <Id> | <IdRange>]]></c></item>
+ <item><c><![CDATA[<IdList> = <IdOrIdRange>,<IdOrIdRange> | <IdOrIdRange>]]></c></item>
+ <item><c><![CDATA[<LogicalIds> = L<IdList>]]></c></item>
+ <item><c><![CDATA[<ThreadIds> = T<IdList> | t<IdList>]]></c></item>
+ <item><c><![CDATA[<CoreIds> = C<IdList> | c<IdList>]]></c></item>
+ <item><c><![CDATA[<ProcessorIds> = P<IdList> | p<IdList>]]></c></item>
+ <item><c><![CDATA[<NodeIds> = N<IdList> | n<IdList>]]></c></item>
+ <item><c><![CDATA[<IdDefs> = <LogicalIds><ThreadIds><CoreIds><ProcessorIds><NodeIds> | <LogicalIds><ThreadIds><CoreIds><NodeIds><ProcessorIds>]]></c></item>
+ <item><c><![CDATA[CpuTopology = <IdDefs>:<IdDefs> | <IdDefs>]]></c></item>
+ </list>
+ <p>Upper-case letters signify real identifiers and lower-case
+ letters signify fake identifiers only used for description
+ of the topology. Identifiers passed as real identifiers may
+ be used by the runtime system when trying to access specific
+ hardware and if they are not correct the behavior is
+ undefined. Faked logical CPU identifiers are not accepted
+ since there is no point in defining the CPU topology without
+ real logical CPU identifiers. Thread, core, processor, and
+ node identifiers may be left out. If left out, thread id
+ defaults to <c>t0</c>, core id defaults to <c>c0</c>,
+ processor id defaults to <c>p0</c>, and node id will
+ be left undefined. Either each logical processor must
+ belong to one and only one NUMA node, or no logical
+ processors must belong to any NUMA nodes.
+ </p>
+ <p>Both increasing and decreasing <c><![CDATA[<IdRange>]]></c>s
+ are allowed.</p>
+ <p>NUMA node identifiers are system wide. That is, each NUMA
+ node on the system have to have a unique identifier. Processor
+ identifiers are also system wide. Core identifiers are
+ processor wide. Thread identifiers are core wide.</p>
+ <p>The order of the identifier types imply the hierarchy of the
+ CPU topology. Valid orders are either
+ <c><![CDATA[<LogicalIds><ThreadIds><CoreIds><ProcessorIds><NodeIds>]]></c>,
+ or
+ <c><![CDATA[<LogicalIds><ThreadIds><CoreIds><NodeIds><ProcessorIds>]]></c>.
+ That is, thread is part of a core which is part of a processor
+ which is part of a NUMA node, or thread is part of a core which
+ is part of a NUMA node which is part of a processor. A cpu
+ topology can consist of both processor external, and processor
+ internal NUMA nodes as long as each logical processor belongs
+ to one and only one NUMA node. If <c><![CDATA[<ProcessorIds>]]></c>
+ is left out, its default position will be before
+ <c><![CDATA[<NodeIds>]]></c>. That is, the default is
+ processor external NUMA nodes.
+ </p>
+ <p>If a list of identifiers is used in an
+ <c><![CDATA[<IdDefs>]]></c>:</p>
+ <list type="bulleted">
+ <item><c><![CDATA[<LogicalIds>]]></c> have to be a list
+ of identifiers.</item>
+ <item>At least one other identifier type apart from
+ <c><![CDATA[<LogicalIds>]]></c> also have to have a
+ list of identifiers.</item>
+ <item>All lists of identifiers have to produce the
+ same amount of identifiers.</item>
+ </list>
+ <p>A simple example. A single quad core processor may be
+ described this way:</p>
+<pre>
+% <input>erl +sct L0-3c0-3</input>
+1> <input>erlang:system_info(cpu_topology).</input>
+[{processor,[{core,{logical,0}},
+ {core,{logical,1}},
+ {core,{logical,2}},
+ {core,{logical,3}}]}]
+</pre>
+ <p>A little more complicated example. Two quad core
+ processors. Each processor in its own NUMA node.
+ The ordering of logical processors is a little weird.
+ This in order to give a better example of identifier
+ lists:</p>
+<pre>
+% <input>erl +sct L0-1,3-2c0-3p0N0:L7,4,6-5c0-3p1N1</input>
+1> <input>erlang:system_info(cpu_topology).</input>
+[{node,[{processor,[{core,{logical,0}},
+ {core,{logical,1}},
+ {core,{logical,3}},
+ {core,{logical,2}}]}]},
+ {node,[{processor,[{core,{logical,7}},
+ {core,{logical,4}},
+ {core,{logical,6}},
+ {core,{logical,5}}]}]}]
+</pre>
+ <p>As long as real identifiers are correct it is okay
+ to pass a CPU topology that is not a correct
+ description of the CPU topology. When used with
+ care this can actually be very useful. This in
+ order to trick the emulator to bind its schedulers
+ as you want. For example, if you want to run multiple
+ Erlang runtime systems on the same machine, you
+ want to reduce the amount of schedulers used and
+ manipulate the CPU topology so that they bind to
+ different logical CPUs. An example, with two Erlang
+ runtime systems on a quad core machine:</p>
+<pre>
+% <input>erl +sct L0-3c0-3 +sbt db +S3:2 -detached -noinput -noshell -sname one</input>
+% <input>erl +sct L3-0c0-3 +sbt db +S3:2 -detached -noinput -noshell -sname two</input>
+</pre>
+ <p>In this example each runtime system have two
+ schedulers each online, and all schedulers online
+ will run on different cores. If we change to one
+ scheduler online on one runtime system, and three
+ schedulers online on the other, all schedulers
+ online will still run on different cores.</p>
+ <p>Note that a faked CPU topology that does not reflect
+ how the real CPU topology looks like is likely to
+ decrease the performance of the runtime system.</p>
+ <p>For more information, see
+ <seealso marker="erlang#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>.</p>
+ </item>
+ </taglist>
+ </item>
+ <tag><c><![CDATA[+sss size]]></c></tag>
+ <item>
+ <marker id="sched_thread_stack_size"></marker>
+ <p>Suggested stack size, in kilowords, for scheduler threads.
+ Valid range is 4-8192 kilowords. The default stack size
+ is OS dependent.</p>
+ </item>
+ <tag><c><![CDATA[+T Level]]></c></tag>
+ <item>
+ <marker id="+T"></marker>
+ <p>Enables modified timing and sets the modified timing level.
+ Currently valid range is 0-9. The timing of the runtime system
+ will change. A high level usually means a greater change than
+ a low level. Changing the timing can be very useful for finding
+ timing related bugs.</p>
+ <p>Currently, modified timing affects the following:</p>
+ <taglist>
+ <tag>Process spawning</tag>
+ <item>
+ <p>A process calling <c><![CDATA[spawn]]></c>, <c><![CDATA[spawn_link]]></c>,
+ <c><![CDATA[spawn_monitor]]></c>, or <c><![CDATA[spawn_opt]]></c> will be scheduled
+ out immediately after completing the call. When higher modified
+ timing levels are used, the caller will also sleep for a while
+ after being scheduled out.</p>
+ </item>
+ <tag>Context reductions</tag>
+ <item>The amount of reductions a process is a allowed to
+ use before being scheduled out is increased or reduced.</item>
+ <tag>Input reductions</tag>
+ <item>The amount of reductions performed before checking I/O
+ is increased or reduced.</item>
+ </taglist>
+ <p><em>NOTE:</em> Performance will suffer when modified timing
+ is enabled. This flag is <em>only</em> intended for testing and
+ debugging. Also note that <c><![CDATA[return_to]]></c> and <c><![CDATA[return_from]]></c>
+ trace messages will be lost when tracing on the spawn BIFs. This
+ flag may be removed or changed at any time without prior notice.</p>
+ </item>
+ <tag><c><![CDATA[+V]]></c></tag>
+ <item>
+ <p>Makes the emulator print out its version number.</p>
+ </item>
+ <tag><c><![CDATA[+v]]></c></tag>
+ <item>
+ <p>Verbose.</p>
+ </item>
+ <tag><c><![CDATA[+W w | i]]></c></tag>
+ <item>
+ <p>Sets the mapping of warning messages for <c><![CDATA[error_logger]]></c>.
+ Messages sent to the error logger using one of the warning
+ routines can be mapped either to errors (default), warnings
+ (<c><![CDATA[+W w]]></c>), or info reports (<c><![CDATA[+W i]]></c>). The current
+ mapping can be retrieved using
+ <c><![CDATA[error_logger:warning_map/0]]></c>. See
+ <seealso marker="kernel:error_logger#warning_map/0">error_logger(3)</seealso>
+ for further information.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="environment_variables"></marker>
+ <title>Environment variables</title>
+ <taglist>
+ <tag><c><![CDATA[ERL_CRASH_DUMP]]></c></tag>
+ <item>
+ <p>If the emulator needs to write a crash dump, the value of this
+ variable will be the file name of the crash dump file.
+ If the variable is not set, the name of the crash dump file will
+ be <c><![CDATA[erl_crash.dump]]></c> in the current directory.</p>
+ </item>
+ <tag><c><![CDATA[ERL_CRASH_DUMP_NICE]]></c></tag>
+ <item>
+ <p><em>Unix systems</em>: If the emulator needs to write a crash dump,
+ it will use the value of this variable to set the nice value
+ for the process, thus lowering its priority. The allowable range is
+ 1 through 39 (higher values will be replaced with 39). The highest
+ value, 39, will give the process the lowest priority.</p>
+ </item>
+ <tag><c><![CDATA[ERL_CRASH_DUMP_SECONDS]]></c></tag>
+ <item>
+ <p><em>Unix systems</em>: This variable gives the number of seconds that
+ the emulator will be allowed to spend writing a crash dump. When
+ the given number of seconds have elapsed, the emulator will be
+ terminated by a SIGALRM signal.</p>
+ </item>
+ <tag><c><![CDATA[ERL_AFLAGS]]></c></tag>
+ <item>
+ <p>The content of this environment variable will be added to the
+ beginning of the command line for <c><![CDATA[erl]]></c>.</p>
+ <p>The <c><![CDATA[-extra]]></c> flag is treated specially. Its scope ends
+ at the end of the environment variable content. Arguments
+ following an <c><![CDATA[-extra]]></c> flag are moved on the command line into
+ the <c><![CDATA[-extra]]></c> section, i.e. the end of the command line
+ following after an <c><![CDATA[-extra]]></c> flag.</p>
+ </item>
+ <tag><c><![CDATA[ERL_ZFLAGS]]></c>and <c><![CDATA[ERL_FLAGS]]></c></tag>
+ <item>
+ <p>The content of these environment variables will be added to the
+ end of the command line for <c><![CDATA[erl]]></c>.</p>
+ <p>The <c><![CDATA[-extra]]></c> flag is treated specially. Its scope ends
+ at the end of the environment variable content. Arguments
+ following an <c><![CDATA[-extra]]></c> flag are moved on the command line into
+ the <c><![CDATA[-extra]]></c> section, i.e. the end of the command line
+ following after an <c><![CDATA[-extra]]></c> flag.</p>
+ </item>
+ <tag><c><![CDATA[ERL_LIBS]]></c></tag>
+ <item>
+ <p>This environment variable contains a list of additional library
+ directories that the code server will search for applications and
+ add to the code path.
+ See <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </item>
+ <tag><c><![CDATA[ERL_EPMD_PORT]]></c></tag>
+ <item>
+ <p>This environment variable can contain the port number to use when
+ communicating with <seealso marker="epmd">epmd</seealso>. The default
+ port will work fine in most cases. A different port can be specified
+ to allow nodes of independent clusters to co-exist on the same host.
+ All nodes in a cluster must use the same epmd port number.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="init">init(3)</seealso>,
+ <seealso marker="erl_prim_loader">erl_prim_loader(3)</seealso>,
+ <seealso marker="kernel:erl_boot_server">erl_boot_server(3)</seealso>,
+ <seealso marker="kernel:code">code(3)</seealso>,
+ <seealso marker="kernel:application">application(3)</seealso>,
+ <seealso marker="kernel:heart">heart(3)</seealso>,
+ <seealso marker="kernel:net_kernel">net_kernel(3)</seealso>,
+ <seealso marker="kernel:auth">auth(3)</seealso>,
+ <seealso marker="tools:make">make(3)</seealso>,
+ <seealso marker="epmd">epmd(1)</seealso>,
+ <seealso marker="erts_alloc">erts_alloc(3)</seealso></p>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml
new file mode 100644
index 0000000000..9a203289e9
--- /dev/null
+++ b/erts/doc/src/erl_dist_protocol.xml
@@ -0,0 +1,802 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2007</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>Distribution Protocol</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2007-09-21</date>
+ <rev>PA1</rev>
+ <file>erl_dist_protocol.xml</file>
+ </header>
+
+<p>
+The description here is far from complete and will therefore be further
+refined in upcoming releases.
+
+The protocols both from Erlang nodes towards
+EPMD (Erlang Port Mapper Daemon) and between Erlang nodes, however, are
+stable since many years.
+</p>
+
+<p>The distribution protocol can be divided into four (4) parts:</p>
+<list>
+ <item>
+ <p>
+ 1. Low level socket connection.
+ </p>
+ </item>
+ <item>
+ 2. Handshake, interchange node name and authenticate.
+ </item>
+ <item>
+ 3. Authentication (done by net_kernel).
+ </item>
+ <item>
+ 4. Connected.
+ </item>
+</list>
+<p>
+ A node fetches the Port number of another node through the EPMD (at the
+ other host) in order to initiate a connection request.
+</p>
+<p>
+For each host where a distributed Erlang node is running there should also
+be an EPMD running. The EPMD can be started explicitly or automatically
+as a result of the Erlang node startup.
+</p>
+<p>
+By default EPMD listens on port 4369.
+</p>
+<p>
+ 3 and 4 are performed at the same level but the net_kernel disconnects the
+ other node if it communicates using an invalid cookie (after one (1) second).
+</p>
+
+<p>The integers in all multi-byte fields are in big-endian order.</p>
+
+ <section>
+ <title>EPMD Protocol</title>
+ <p>
+ The requests served by the EPMD (Erlang Port Mapper Daemon) are
+ summarized in the figure below.
+ </p>
+
+ <image file="erl_ext_fig.gif">
+ <icaption>
+ Summary of EPMD requests.
+ </icaption>
+ </image>
+ <p>
+ Each request <c>*_REQ</c> is preceded by a two-byte length field.
+ Thus, the overall request format is:
+ </p>
+
+ <table align="left">
+ <row>
+ <cell align="center">2</cell>
+ <cell align="center">n</cell>
+ </row>
+ <row>
+ <cell align="center">Length</cell>
+ <cell align="center">Request</cell>
+ </row>
+ <tcaption></tcaption></table>
+
+ <section>
+ <title>Register a node in the EPMD</title>
+ <p>
+ When a distributed node is started it registers itself in EPMD.
+ The message ALIVE2_REQ described below is sent from the node towards
+ EPMD. The response from EPMD is ALIVE2_RESP.
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">2</cell>
+ <cell align="center">2</cell>
+ <cell align="center">Nlen</cell>
+ <cell align="center">2</cell>
+ <cell align="center">Elen</cell>
+ </row>
+ <row>
+ <cell align="center">120</cell>
+ <cell align="center">PortNo</cell>
+ <cell align="center">NodeType</cell>
+ <cell align="center">Protocol</cell>
+ <cell align="center">LowestVersion</cell>
+ <cell align="center">HighestVersion</cell>
+ <cell align="center">Nlen</cell>
+ <cell align="center">NodeName</cell>
+ <cell align="center">Elen</cell>
+ <cell align="center">Extra</cell>
+ </row>
+ <tcaption>ALIVE2_REQ (120)</tcaption></table>
+ <taglist>
+ <tag><c>PortNo</c></tag>
+ <item>
+ The port number on which the node accept connection requests.
+ </item>
+ <tag><c>NodeType</c></tag>
+ <item>
+ 77 = normal Erlang node, 72 = hidden node (C-node),...
+ </item>
+ <tag><c>Protocol</c></tag>
+ <item>
+ 0 = tcp/ip-v4, ...
+ </item>
+ <tag><c>LowestVersion</c></tag>
+ <item>
+ The lowest distribution version that this node can handle.
+ See the next field for possible values.
+ </item>
+ <tag><c>HighestVersion</c></tag>
+ <item>
+ The highest distribution version that this node can handle.
+ The value in R6B and later is 5.
+ </item>
+ <tag><c>Nlen</c></tag>
+ <item>
+ The length of the <c>NodeName</c>.
+ </item>
+ <tag><c>NodeName</c></tag>
+ <item>
+ The NodeName as a string of length <c>Nlen</c>.
+ </item>
+ <tag><c>Elen</c></tag>
+ <item>
+ The length of the <c>Extra</c> field.
+ </item>
+ <tag><c>Extra</c></tag>
+ <item>
+ Extra field of <c>Elen</c> bytes.
+ </item>
+ </taglist>
+ <p>
+ The connection created to the EPMD must be kept as long as the
+ node is a distributed node. When the connection is closed
+ the node is automatically unregistered from the EPMD.
+ </p>
+ <p>
+ The response message ALIVE2_RESP is described below.
+ </p>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ </row>
+ <row>
+ <cell align="center">121</cell>
+ <cell align="center">Result</cell>
+ <cell align="center">Creation</cell>
+ </row>
+ <tcaption>ALIVE2_RESP (121)</tcaption></table>
+ <p>
+ Result = 0 -> ok, Result > 0 -> error
+ </p>
+ </section>
+
+ <section>
+ <title>Unregister a node from the EPMD</title>
+ <p>
+ A node unregister itself from the EPMD by simply closing the
+ TCP connection towards EPMD established when the node was registered.
+ </p>
+ </section>
+
+ <section>
+ <title>Get the distribution port of another node</title>
+ <p>
+ When one node wants to connect to another node it starts with
+ a PORT_PLEASE2_REQ request towards EPMD on the host where the
+ node resides in order to get the distribution port that the node
+ listens to.
+ </p>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">N</cell>
+ </row>
+ <row>
+ <cell align="center">122</cell>
+ <cell align="center">NodeName</cell>
+ </row>
+ <tcaption>PORT_PLEASE2_REQ (122)</tcaption></table>
+ <p>
+ where N = Length - 1
+ </p>
+
+ <p>
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center">119</cell>
+ <cell align="center">Result</cell>
+ </row>
+ <tcaption>
+ PORT2_RESP (119) response indicating error, Result > 0.
+ </tcaption>
+ </table>
+ <p>Or</p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">2</cell>
+ <cell align="center">2</cell>
+ <cell align="center">Nlen</cell>
+ <cell align="center">2</cell>
+ <cell align="center">Elen</cell>
+ </row>
+ <row>
+ <cell align="center">119</cell>
+ <cell align="center">Result</cell>
+ <cell align="center">PortNo</cell>
+ <cell align="center">NodeType</cell>
+ <cell align="center">Protocol</cell>
+ <cell align="center">HighestVersion</cell>
+ <cell align="center">LowestVersion</cell>
+ <cell align="center">Nlen</cell>
+ <cell align="center">NodeName</cell>
+ <cell align="center">Elen</cell>
+ <cell align="center">Extra</cell>
+ </row>
+ <tcaption>PORT2_RESP when Result = 0.</tcaption></table>
+<p>
+If Result > 0, the packet only consists of [119, Result].
+</p>
+
+ <p>EPMD will close the socket as soon as it has sent the information.</p>
+ </section>
+
+ <section>
+ <title>Get all registered names from EPMD</title>
+ <p>
+ This request is used via the Erlang function
+ <c>net_adm:names/1,2</c>. A TCP connection is opened
+ towards EPMD and this request is sent.
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center">110</cell>
+ </row>
+ <tcaption>NAMES_REQ (110)</tcaption></table>
+
+
+ <p>The response for a <c>NAMES_REQ</c> looks like this:</p>
+ <table align="left">
+ <row>
+ <cell align="center">4</cell>
+ <cell align="center">&nbsp;</cell>
+ </row>
+ <row>
+ <cell align="center">EPMDPortNo</cell>
+ <cell align="center">NodeInfo*</cell>
+ </row>
+ <tcaption>NAMES_RESP</tcaption></table>
+ <p>
+ NodeInfo is a string written for each active node.
+ When all NodeInfo has been written the connection is
+ closed by EPMD.
+ </p>
+ <p>
+ NodeInfo is, as expressed in Erlang:
+ </p>
+ <code>
+ io:format("name ~s at port ~p~n", [NodeName, Port]).
+ </code>
+ </section>
+
+
+ <section>
+ <title>Dump all data from EPMD</title>
+ <p>
+ This request is not really used, it should be regarded as a debug
+ feature.
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center">100</cell>
+ </row>
+ <tcaption>DUMP_REQ</tcaption></table>
+
+ <p>The response for a <c>DUMP_REQ</c> looks like this:</p>
+ <table align="left">
+ <row>
+ <cell align="center">4</cell>
+ <cell align="center">&nbsp;</cell>
+ </row>
+ <row>
+ <cell align="center">EPMDPortNo</cell>
+ <cell align="center">NodeInfo*</cell>
+ </row>
+ <tcaption>DUMP_RESP</tcaption></table>
+ <p>
+ NodeInfo is a string written for each node kept in EPMD.
+ When all NodeInfo has been written the connection is
+ closed by EPMD.
+ </p>
+ <p>
+ NodeInfo is, as expressed in Erlang:
+ </p>
+ <code>
+ io:format("active name ~s at port ~p, fd = ~p ~n",
+ [NodeName, Port, Fd]).
+ </code>
+ <p>
+ or
+ </p>
+ <code>
+ io:format("old/unused name ~s at port ~p, fd = ~p~n",
+ [NodeName, Port, Fd]).
+ </code>
+
+ </section>
+
+ <section>
+ <title>Kill the EPMD</title>
+ <p>
+ This request will kill the running EPMD. It is almost never used.
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center">107</cell>
+ </row>
+ <tcaption>KILL_REQ</tcaption></table>
+
+ <p>The response fo a <c>KILL_REQ</c> looks like this:</p>
+ <table align="left">
+ <row>
+ <cell align="center">2</cell>
+ </row>
+ <row>
+ <cell align="center">OKString</cell>
+ </row>
+ <tcaption>KILL_RESP</tcaption></table>
+ <p>
+ where <c>OKString</c> is "OK".
+ </p>
+ </section>
+
+ <section>
+ <title>STOP_REQ (Not Used)</title>
+ <p></p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">n</cell>
+ </row>
+ <row>
+ <cell align="center">115</cell>
+ <cell align="center">NodeName</cell>
+ </row>
+ <tcaption>STOP_REQ</tcaption></table>
+ <p>
+ where n = Length - 1
+ </p>
+ <p>
+ The current implementation of Erlang does not care if the connection
+ to the EPMD is broken.
+ </p>
+ <p>The response for a <c>STOP_REQ</c> looks like this.</p>
+ <table align="left">
+ <row>
+ <cell align="center">7</cell>
+ </row>
+ <row>
+ <cell align="center">OKString</cell>
+ </row>
+ <tcaption>STOP_RESP</tcaption></table>
+ <p>
+ where OKString is "STOPPED".
+ </p>
+ <p>A negative response can look like this.</p>
+ <table align="left">
+ <row>
+ <cell align="center">7</cell>
+ </row>
+ <row>
+ <cell align="center">NOKString</cell>
+ </row>
+ <tcaption>STOP_NOTOK_RESP</tcaption></table>
+ <p>
+ where NOKString is "NOEXIST".
+ </p>
+ </section>
+<!--
+ <section>
+ <title>ALIVE_REQ (97)</title>
+ <p></p>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">n</cell>
+ </row>
+ <row>
+ <cell align="center">97</cell>
+ <cell align="center">PortNo</cell>
+ <cell align="center">NodeName</cell>
+ </row>
+ <tcaption></tcaption></table>
+
+ <p>
+ where n = Length - 3
+ </p>
+ <p>
+ The connection created to the EPMD must be kept until the node is
+ not a distributed node any longer.
+ </p>
+ </section>
+
+ <section>
+ <title>ALIVE_OK_RESP (89)</title>
+ <p></p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ </row>
+ <row>
+ <cell align="center">89</cell>
+ <cell align="center">Creation</cell>
+ </row>
+ <tcaption></tcaption></table>
+ </section>
+
+
+ <section>
+ <title>ALIVE_NOTOK_RESP ()</title>
+ <p>
+ EPMD closed the connection.
+ </p>
+ </section>
+
+ <section>
+ <title>PORT_PLEASE_REQ (112)</title>
+ <p></p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">n</cell>
+ </row>
+ <row>
+ <cell align="center">112</cell>
+ <cell align="center">NodeName</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ where n = Length - 1
+ </p>
+ </section>
+
+ <section>
+ <title>PORT_OK_RESP ()</title>
+ <p></p>
+ <table align="left">
+ <row>
+ <cell align="center">2</cell>
+ </row>
+ <row>
+ <cell align="center">PortNo</cell>
+ </row>
+ <tcaption></tcaption></table>
+
+ </section>
+
+ <section>
+ <title>PORT_NOTOK_RESP ()</title>
+ <p>
+ EPMD closed the connection.
+ </p>
+ </section>
+
+
+ <section>
+ <title>PORT_NOTOK_RESP ()</title>
+ <p>
+ EPMD closed the connection.
+ </p>
+ </section>
+-->
+
+ </section>
+
+ <section>
+ <title>Handshake</title>
+ <p>
+ The handshake is discussed in detail in the internal documentation for
+ the kernel (Erlang) application.
+ </p>
+ </section>
+
+ <section>
+ <marker id="connected_nodes"/>
+ <title>Protocol between connected nodes</title>
+ <p>
+ As of erts version 5.7.2 the runtime system passes a distribution
+ flag in the handshake stage that enables the use of a
+ <seealso marker="erl_ext_dist#distribution_header">distribution
+ header</seealso> on all messages passed. Messages passed between
+ nodes are in this case on the following format:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">4</cell>
+ <cell align="center">d</cell>
+ <cell align="center">n</cell>
+ <cell align="center">m</cell>
+ </row>
+ <row>
+ <cell align="center"><c>Length</c></cell>
+ <cell align="center"><c>DistributionHeader</c></cell>
+ <cell align="center"><c>ControlMessage</c></cell>
+ <cell align="center"><c>Message</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ where:
+ </p>
+ <p>
+ <c>Length</c> is equal to d + n + m
+ </p>
+ <p>
+ <c>ControlMessage</c> is a tuple passed using the external format of
+ Erlang.
+ </p>
+ <p>
+ <c>Message</c> is the message sent to another node using the '!'
+ (in external format). Note that <c>Message</c> is only passed in
+ combination with a <c>ControlMessage</c> encoding a send ('!').
+ </p>
+ <p>
+ Also note that <seealso marker="erl_ext_dist#overall_format">the
+ version number is omitted from the terms that follow a
+ distribution header</seealso>.
+ </p>
+ <p>
+ Nodes with an erts version less than 5.7.2 does not pass the
+ distribution flag that enables the distribution header. Messages
+ passed between nodes are in this case on the following format:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">4</cell>
+ <cell align="center">1</cell>
+ <cell align="center">n</cell>
+ <cell align="center">m</cell>
+ </row>
+ <row>
+ <cell align="center"><c>Length</c></cell>
+ <cell align="center"><c>Type</c></cell>
+ <cell align="center"><c>ControlMessage</c></cell>
+ <cell align="center"><c>Message</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ where:
+ </p>
+ <p>
+ <c>Length</c> is equal to 1 + n + m
+ </p>
+ <p>
+ Type is: 112 (pass through)
+ </p>
+ <p>
+ <c>ControlMessage</c> is a tuple passed using the external format of
+ Erlang.
+ </p>
+ <p>
+ <c>Message</c> is the message sent to another node using the '!'
+ (in external format). Note that <c>Message</c> is only passed in
+ combination with a <c>ControlMessage</c> encoding a send ('!').
+ </p>
+ <p>
+ The <c>ControlMessage</c> is a tuple, where the first element
+ indicates which distributed operation it encodes.
+ </p>
+ <taglist>
+ <tag><c>LINK</c></tag>
+ <item>
+ <p>
+ <c>{1, FromPid, ToPid}</c>
+ </p>
+ </item>
+
+ <tag><c>SEND</c></tag>
+ <item>
+ <p>
+ <c>{2, Cookie, ToPid}</c>
+ </p>
+ <p>
+ <em>Note</em> followed by <c>Message</c>
+ </p>
+ </item>
+
+ <tag><c>EXIT</c></tag>
+ <item>
+ <p>
+ <c>{3, FromPid, ToPid, Reason}</c>
+ </p>
+ </item>
+
+ <tag><c>UNLINK</c></tag>
+ <item>
+ <p>
+ <c>{4, FromPid, ToPid}</c>
+ </p>
+ </item>
+
+ <tag><c>NODE_LINK</c></tag>
+ <item>
+ <p>
+ <c>{5}</c>
+ </p>
+ </item>
+
+ <tag><c>REG_SEND</c></tag>
+ <item>
+ <p>
+ <c>{6, FromPid, Cookie, ToName}</c>
+ </p>
+ <p>
+ <em>Note</em> followed by <c>Message</c>
+ </p>
+ </item>
+
+ <tag><c>GROUP_LEADER</c></tag>
+ <item>
+ <p>
+ <c>{7, FromPid, ToPid}</c>
+ </p>
+ </item>
+
+ <tag><c>EXIT2</c></tag>
+ <item>
+ <p>
+ <c>{8, FromPid, ToPid, Reason}</c>
+ </p>
+ </item>
+ </taglist>
+ </section>
+
+
+ <section>
+ <title>New Ctrlmessages for distrvsn = 1 (OTP R4)</title>
+ <taglist>
+ <tag><c>SEND_TT</c></tag>
+ <item>
+ <p>
+ <c>{12, Cookie, ToPid, TraceToken}</c>
+ </p>
+ <p>
+ <em>Note</em> followed by <c>Message</c>
+ </p>
+ </item>
+
+ <tag><c>EXIT_TT</c></tag>
+ <item>
+ <p>
+ <c>{13, FromPid, ToPid, TraceToken, Reason}</c>
+ </p>
+ </item>
+
+ <tag><c>REG_SEND_TT</c></tag>
+ <item>
+ <p>
+ <c>{16, FromPid, Cookie, ToName, TraceToken}</c>
+ </p>
+ <p>
+ <em>Note</em> followed by <c>Message</c>
+ </p>
+ </item>
+
+ <tag><c>EXIT2_TT</c></tag>
+ <item>
+ <p>
+ <c>{18, FromPid, ToPid, TraceToken, Reason}</c>
+ </p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>New Ctrlmessages for distrvsn = 2</title>
+ <p>
+ distrvsn 2 was never used.
+ </p>
+ </section>
+
+ <section>
+ <title>New Ctrlmessages for distrvsn = 3 (OTP R5C)</title>
+ <p>
+ None, but the version number was increased anyway.
+ </p>
+ </section>
+
+ <section>
+ <title>New Ctrlmessages for distrvsn = 4 (OTP R6)</title>
+ <p>
+ These are only recognized by Erlang nodes, not by hidden nodes.
+ </p>
+ <taglist>
+ <tag><c>MONITOR_P</c></tag>
+ <item>
+ <p>
+ <c>{19, FromPid, ToProc, Ref}</c>
+
+ <c>FromPid</c> = monitoring process
+ <c>ToProc</c> = monitored process pid or name (atom)
+ </p>
+ </item>
+
+ <tag><c>DEMONITOR_P</c></tag>
+ <item>
+ <p>
+ <c>{20, FromPid, ToProc, Ref}</c>
+ We include the FromPid just in case we want to trace this.
+
+ <c>FromPid</c> = monitoring process
+ <c>ToProc</c> = monitored process pid or name (atom)
+ </p>
+ </item>
+
+ <tag><c>MONITOR_P_EXIT</c></tag>
+ <item>
+ <p>
+ <c>{21, FromProc, ToPid, Ref, Reason}</c>
+
+ <c>FromProc</c> = monitored process pid or name (atom)
+ <c>ToPid</c> = monitoring process
+ <c>Reason</c> = exit reason for the monitored process
+ </p>
+ </item>
+ </taglist>
+ </section>
+ </chapter>
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
new file mode 100644
index 0000000000..0b11f4bbcb
--- /dev/null
+++ b/erts/doc/src/erl_driver.xml
@@ -0,0 +1,2465 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erl_driver</title>
+ <prepared>Jakob Cederlund</prepared>
+ <responsible>Jakob Cederlund</responsible>
+ <docno>1</docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2000-11-27</date>
+ <rev>PA1</rev>
+ <file>erl_driver.xml</file>
+ </header>
+ <lib>erl_driver</lib>
+ <libsummary>API functions for an Erlang driver</libsummary>
+ <description>
+ <p>As of erts version 5.5.3 the driver interface has been extended
+ (see <seealso marker="driver_entry#extended_marker">extended marker</seealso>).
+ The extended interface introduce
+ <seealso marker="erl_driver#version_management">version management</seealso>,
+ the possibility to pass capability flags
+ (see <seealso marker="driver_entry#driver_flags">driver flags</seealso>)
+ to the runtime system at driver initialization, and some new
+ driver API functions. </p>
+ <note>
+ <p>Old drivers (compiled with an <c>erl_driver.h</c> from an
+ earlier erts version than 5.5.3) have to be recompiled
+ (but does not have to use the extended interface).</p>
+ </note>
+ <p>The driver calls back to the emulator, using the API
+ functions declared in <c>erl_driver.h</c>. They are used for
+ outputting data from the driver, using timers, etc.</p>
+ <p>A driver is a library with a set of function that the emulator
+ calls, in response to Erlang functions and message
+ sending. There may be multiple instances of a driver, each
+ instance is connected to an Erlang port. Every port has a port
+ owner process. Communication with the port is normally done
+ through the port owner process.</p>
+ <p>Most of the functions takes the <c>port</c> handle as an
+ argument. This identifies the driver instance. Note that this
+ port handle must be stored by the driver, it is not given when
+ the driver is called from the emulator (see
+ <seealso marker="driver_entry#emulator">driver_entry</seealso>).</p>
+ <p>Some of the functions takes a parameter of type
+ <c>ErlDrvBinary</c>, a driver binary. It should be both
+ allocated and freed by the caller. Using a binary directly avoid
+ one extra copying of data.</p>
+ <p>Many of the output functions has a "header buffer", with
+ <c>hbuf</c> and <c>hlen</c> parameters. This buffer is sent as a
+ list before the binary (or list, depending on port mode) that is
+ sent. This is convenient when matching on messages received from
+ the port. (Although in the latest versions of Erlang, there is
+ the binary syntax, that enables you to match on the beginning of
+ a binary.)
+ <marker id="smp_support"></marker>
+</p>
+ <p>In the runtime system with SMP support, drivers are locked either
+ on driver level or port level (driver instance level). By default
+ driver level locking will be used, i.e., only one emulator thread
+ will execute code in the driver at a time. If port level locking
+ is used, multiple emulator threads may execute code in the driver
+ at the same time. There will only be one thread at a time calling
+ driver call-backs corresponding to the same port, though. In order
+ to enable port level locking set the <c>ERL_DRV_FLAG_USE_PORT_LOCKING</c>
+ <seealso marker="driver_entry#driver_flags">driver flag</seealso> in
+ the <seealso marker="driver_entry">driver_entry</seealso>
+ used by the driver. When port level locking is used it is the
+ responsibility of the driver writer to synchronize all accesses
+ to data shared by the ports (driver instances).</p>
+ <p>Most drivers written before the runtime system with SMP
+ support existed will be able to run in the runtime system
+ with SMP support without being rewritten if driver
+ level locking is used.</p>
+ <note>
+ <p>It is assumed that drivers does not access other drivers. If
+ drivers should access each other they have to provide their own
+ mechanism for thread safe synchronization. Such "inter driver
+ communication" is strongly discouraged.</p>
+ </note>
+ <p>Previously, in the runtime system without SMP support,
+ specific driver call-backs were always called from the same
+ thread. This is <em>not</em> the case in the runtime system
+ with SMP support. Regardless of locking scheme used, calls
+ to driver call-backs may be made from different threads, e.g.,
+ two consecutive calls to exactly the same call-back for exactly
+ the same port may be made from two different threads. This
+ will for <em>most</em> drivers not be a problem, but it might.
+ Drivers that depend on all call-backs being called in the
+ same thread, <em>have</em> to be rewritten before being used
+ in the runtime system with SMP support.</p>
+ <note>
+ <p>Regardless of locking scheme used, calls to driver
+ call-backs may be made from different threads.</p>
+ </note>
+ <p>Most functions in this API are <em>not</em> thread-safe, i.e.,
+ they may <em>not</em> be called from an arbitrary thread. Function
+ that are not documented as thread-safe may only be called from
+ driver call-backs or function calls descending from a driver
+ call-back call. Note that driver call-backs may be called from
+ different threads. This, however, is not a problem for any
+ functions in this API, since the emulator have control over
+ these threads.</p>
+ <note>
+ <p>Functions not explicitly documented as thread-safe are
+ <em>not</em> thread-safe. Also note that some functions
+ are <em>only</em> thread safe when used in a runtime
+ system with SMP support.</p>
+ </note>
+ </description>
+
+ <section>
+ <title>FUNCTIONALITY</title>
+ <p>All functions that a driver needs to do with Erlang are
+ performed through driver API functions. There are functions
+ for the following functionality:</p>
+ <taglist>
+ <tag>Timer functions</tag>
+ <item>Timer functions are used to control the timer that a driver
+ may use. The timer will have the emulator call the
+ <seealso marker="driver_entry#timeout">timeout</seealso> entry
+ function after a specified time. Only one timer is available
+ for each driver instance.</item>
+ <tag>Queue handling</tag>
+ <item>
+ <p>Every driver instance has an associated queue. This queue is a
+ <c>SysIOVec</c> that works as a buffer. It's mostly used for
+ the driver to buffer data that should be written to a device,
+ it is a byte stream. If the port owner process closes the
+ driver, and the queue is not empty, the driver will not be
+ closed. This enables the driver to flush its buffers before
+ closing.</p>
+ <p>The queue can be manipulated from arbitrary threads if
+ a port data lock is used. See documentation of the
+ <seealso marker="#ErlDrvPDL">ErlDrvPDL</seealso> type for
+ more information.</p>
+ </item>
+ <tag>Output functions</tag>
+ <item>With the output functions, the driver sends data back
+ the emulator. They will be received as messages by the port owner
+ process, see <c>open_port/2</c>. The vector function and the
+ function taking a driver binary is faster, because that avoid
+ copying the data buffer. There is also a fast way of sending
+ terms from the driver, without going through the binary term
+ format.</item>
+ <tag>Failure</tag>
+ <item>The driver can exit and signal errors up to Erlang. This is
+ only for severe errors, when the driver can't possibly keep
+ open.</item>
+ <tag>Asynchronous calls</tag>
+ <item>The latest Erlang versions (R7B and later) has provision for
+ asynchronous function calls, using a thread pool provided by
+ Erlang. There is also a select call, that can be used for
+ asynchronous drivers.</item>
+ <tag>Multi-threading</tag>
+ <item><marker id="multi_threading"></marker>
+ <p>A POSIX thread like API for multi-threading is provided. The
+ Erlang driver thread API only provide a subset of the functionality
+ provided by the POSIX thread API. The subset provided is
+ more or less the basic functionality needed for multi-threaded
+ programming:
+ </p>
+ <list>
+ <item><seealso marker="#ErlDrvTid">Threads</seealso></item>
+ <item><seealso marker="#ErlDrvMutex">Mutexes</seealso></item>
+ <item><seealso marker="#ErlDrvCond">Condition variables</seealso></item>
+ <item><seealso marker="#ErlDrvRWLock">Read/Write locks</seealso></item>
+ <item><seealso marker="#ErlDrvTSDKey">Thread specific data</seealso></item>
+ </list>
+ <p>The Erlang driver thread API can be used in conjunction with
+ the POSIX thread API on UN-ices and with the Windows native thread
+ API on Windows. The Erlang driver thread API has the advantage of
+ being portable, but there might exist situations where you want to
+ use functionality from the POSIX thread API or the Windows
+ native thread API.
+ </p>
+ <p>The Erlang driver thread API only return error codes when it is
+ reasonable to recover from an error condition. If it isn't reasonable
+ to recover from an error condition, the whole runtime system is
+ terminated. For example, if a create mutex operation fails, an error
+ code is returned, but if a lock operation on a mutex fails, the
+ whole runtime system is terminated.
+ </p>
+ <p>Note that there exist no "condition variable wait with timeout" in
+ the Erlang driver thread API. This is due to issues with
+ <c>pthread_cond_timedwait()</c>. When the system clock suddenly
+ is changed, it isn't always guaranteed that you will wake up from
+ the call as expected. An Erlang runtime system has to be able to
+ cope with sudden changes of the system clock. Therefore, we have
+ omitted it from the Erlang driver thread API. In the Erlang driver
+ case, timeouts can and should be handled with the timer functionality
+ of the Erlang driver API.
+ </p>
+ <p>In order for the Erlang driver thread API to function, thread
+ support has to be enabled in the runtime system. An Erlang driver
+ can check if thread support is enabled by use of
+ <seealso marker="#driver_system_info">driver_system_info()</seealso>.
+ Note that some functions in the Erlang driver API are thread-safe
+ only when the runtime system has SMP support, also this
+ information can be retrieved via
+ <seealso marker="#driver_system_info">driver_system_info()</seealso>.
+ Also note that a lot of functions in the Erlang driver API are
+ <em>not</em> thread-safe regardless of whether SMP support is
+ enabled or not. If a function isn't documented as thread-safe it
+ is <em>not</em> thread-safe.
+ </p>
+ <p><em>NOTE</em>: When executing in an emulator thread, it is
+ <em>very important</em> that you unlock <em>all</em> locks you
+ have locked before letting the thread out of your control;
+ otherwise, you are <em>very likely</em> to deadlock the whole
+ emulator. If you need to use thread specific data in an emulator
+ thread, only have the thread specific data set while the thread is
+ under your control, and clear the thread specific data before
+ you let the thread out of your control.
+ </p>
+ <p>In the future there will probably be debug functionality
+ integrated with the Erlang driver thread API. All functions
+ that create entities take a <c>name</c> argument. Currently
+ the <c>name</c> argument is unused, but it will be used when
+ the debug functionality has been implemented. If you name all
+ entities created well, the debug functionality will be able
+ to give you better error reports.
+ </p>
+ </item>
+ <tag>Adding / remove drivers</tag>
+ <item>A driver can add and later remove drivers.</item>
+ <tag>Monitoring processes</tag>
+ <item>A driver can monitor a process that does not own a port.</item>
+ <tag>Version management</tag>
+ <item>
+ <marker id="version_management"></marker>
+ <p>Version management is enabled for drivers that have set the
+ <seealso marker="driver_entry#extended_marker">extended_marker</seealso>
+ field of their
+ <seealso marker="driver_entry">driver_entry</seealso>
+ to <c>ERL_DRV_EXTENDED_MARKER</c>. <c>erl_driver.h</c> defines
+ <c>ERL_DRV_EXTENDED_MARKER</c>,
+ <c>ERL_DRV_EXTENDED_MAJOR_VERSION</c>, and
+ <c>ERL_DRV_EXTENDED_MINOR_VERSION</c>.
+ <c>ERL_DRV_EXTENDED_MAJOR_VERSION</c> will be incremented when
+ driver incompatible changes are made to the Erlang runtime
+ system. Normally it will suffice to recompile drivers when the
+ <c>ERL_DRV_EXTENDED_MAJOR_VERSION</c> has changed, but it
+ could, under rare circumstances, mean that drivers have to
+ be slightly modified. If so, this will of course be documented.
+ <c>ERL_DRV_EXTENDED_MINOR_VERSION</c> will be incremented when
+ new features are added. The runtime system use the minor version
+ of the driver to determine what features to use.
+ The runtime system will refuse to load a driver if the major
+ versions differ, or if the major versions are equal and the
+ minor version used by the driver is greater than the one used
+ by the runtime system.</p>
+ <p>The emulator tries to check that a driver that doesn't use the
+ extended driver interface isn't incompatible when loading it.
+ It can, however, not make sure that it isn't incompatible. Therefore,
+ when loading a driver that doesn't use the extended driver
+ interface, there is a risk that it will be loaded also when
+ the driver is incompatible. When the driver use the extended driver
+ interface, the emulator can verify that it isn't of an incompatible
+ driver version. You are therefore advised to use the extended driver
+ interface.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>DATA TYPES</title>
+
+ <taglist>
+ <tag><marker id="ErlDrvSysInfo"/>ErlDrvSysInfo</tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef struct ErlDrvSysInfo {
+ int driver_major_version;
+ int driver_minor_version;
+ char *erts_version;
+ char *otp_release;
+ int thread_support;
+ int smp_support;
+ int async_threads;
+ int scheduler_threads;
+} ErlDrvSysInfo;
+ </code>
+
+ <p>
+ The <c>ErlDrvSysInfo</c> structure is used for storage of
+ information about the Erlang runtime system.
+ <seealso marker="#driver_system_info">driver_system_info()</seealso>
+ will write the system information when passed a reference to
+ a <c>ErlDrvSysInfo</c> structure. A description of the
+ fields in the structure follow:
+ </p>
+ <taglist>
+ <tag><c>driver_major_version</c></tag>
+ <item>The value of
+ <seealso marker="#version_management">ERL_DRV_EXTENDED_MAJOR_VERSION</seealso>
+ when the runtime system was compiled. This value is the same
+ as the value of
+ <seealso marker="#version_management">ERL_DRV_EXTENDED_MAJOR_VERSION</seealso>
+ used when compiling the driver; otherwise, the runtime system
+ would have refused to load the driver.
+ </item>
+ <tag><c>driver_minor_version</c></tag>
+ <item>The value of
+ <seealso marker="#version_management">ERL_DRV_EXTENDED_MINOR_VERSION</seealso>
+ when the runtime system was compiled. This value might differ
+ from the value of
+ <seealso marker="#version_management">ERL_DRV_EXTENDED_MINOR_VERSION</seealso>
+ used when compiling the driver.
+ </item>
+ <tag><c>erts_version</c></tag>
+ <item>A string containing the version number of the runtime system
+ (the same as returned by
+ <seealso marker="erts:erlang#system_info_version">erlang:system_info(version)</seealso>).
+ </item>
+ <tag><c>otp_release</c></tag>
+ <item>A string containing the OTP release number
+ (the same as returned by
+ <seealso marker="erts:erlang#system_info_otp_release">erlang:system_info(otp_release)</seealso>).
+ </item>
+ <tag><c>thread_support</c></tag>
+ <item>A value <c>!= 0</c> if the runtime system has thread support;
+ otherwise, <c>0</c>.
+ </item>
+ <tag><c>smp_support</c></tag>
+ <item>A value <c>!= 0</c> if the runtime system has SMP support;
+ otherwise, <c>0</c>.
+ </item>
+ <tag><c>thread_support</c></tag>
+ <item>A value <c>!= 0</c> if the runtime system has thread support;
+ otherwise, <c>0</c>.
+ </item>
+ <tag><c>smp_support</c></tag>
+ <item>A value <c>!= 0</c> if the runtime system has SMP support;
+ otherwise, <c>0</c>.
+ </item>
+ <tag><c>async_threads</c></tag>
+ <item>The number of async threads in the async thread pool used
+ by <seealso marker="#driver_async">driver_async()</seealso>
+ (the same as returned by
+ <seealso marker="erts:erlang#system_info_thread_pool_size">erlang:system_info(thread_pool_size)</seealso>).
+ </item>
+ <tag><c>scheduler_threads</c></tag>
+ <item>The number of scheduler threads used by the runtime system
+ (the same as returned by
+ <seealso marker="erts:erlang#system_info_schedulers">erlang:system_info(schedulers)</seealso>).
+ </item>
+ </taglist>
+ </item>
+
+ <tag><marker id="ErlDrvBinary"/>ErlDrvBinary</tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef struct ErlDrvBinary {
+ int orig_size;
+ char orig_bytes[];
+} ErlDrvBinary;
+</code>
+ <p>The <c>ErlDrvBinary</c> structure is a binary, as sent
+ between the emulator and the driver. All binaries are
+ reference counted; when <c>driver_binary_free</c> is called,
+ the reference count is decremented, when it reaches zero,
+ the binary is deallocated. The <c>orig_size</c> is the size
+ of the binary, and <c>orig_bytes</c> is the buffer. The
+ <c>ErlDrvBinary</c> does not have a fixed size, its size is
+ <c>orig_size + 2 * sizeof(int)</c>.</p>
+ <note>
+ <p>The <c>refc</c> field has been removed. The reference count of
+ an <c>ErlDrvBinary</c> is now stored elsewhere. The
+ reference count of an <c>ErlDrvBinary</c> can be accessed via
+ <seealso marker="#driver_binary_get_refc">driver_binary_get_refc()</seealso>,
+ <seealso marker="#driver_binary_inc_refc">driver_binary_inc_refc()</seealso>,
+ and
+ <seealso marker="#driver_binary_dec_refc">driver_binary_dec_refc()</seealso>.</p>
+ </note>
+ <p>Some driver calls, such as <c>driver_enq_binary</c>,
+ increments the driver reference count, and others, such as
+ <c>driver_deq</c> decrements it.</p>
+ <p>Using a driver binary instead of a normal buffer, is often
+ faster, since the emulator doesn't need to copy the data,
+ only the pointer is used.</p>
+ <p>A driver binary allocated in the driver, with
+ <c>driver_alloc_binary</c>, should be freed in the driver (unless otherwise stated),
+ with <c>driver_free_binary</c>. (Note that this doesn't
+ necessarily deallocate it, if the driver is still referred
+ in the emulator, the ref-count will not go to zero.)</p>
+ <p>Driver binaries are used in the <c>driver_output2</c> and
+ <c>driver_outputv</c> calls, and in the queue. Also the
+ driver call-back <seealso marker="driver_entry#outputv">outputv</seealso> uses driver
+ binaries.</p>
+ <p>If the driver of some reason or another, wants to keep a
+ driver binary around, in a static variable for instance, the
+ reference count should be incremented,
+ and the binary can later be freed in the <seealso marker="driver_entry#stop">stop</seealso> call-back, with
+ <c>driver_free_binary</c>.</p>
+ <p>Note that since a driver binary is shared by the driver and
+ the emulator, a binary received from the emulator or sent to
+ the emulator, must not be changed by the driver.</p>
+ <p>From erts version 5.5 (OTP release R11B), orig_bytes is
+ guaranteed to be properly aligned for storage of an array of
+ doubles (usually 8-byte aligned).</p>
+ </item>
+ <tag>ErlDrvData</tag>
+ <item>
+ <p>The <c>ErlDrvData</c> is a handle to driver-specific data,
+ passed to the driver call-backs. It is a pointer, and is
+ most often casted to a specific pointer in the driver.</p>
+ </item>
+ <tag>SysIOVec</tag>
+ <item>
+ <p>This is a system I/O vector, as used by <c>writev</c> on
+ unix and <c>WSASend</c> on Win32. It is used in
+ <c>ErlIOVec</c>.</p>
+ </item>
+ <tag><marker id="ErlIOVec"/>ErlIOVec</tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef struct ErlIOVec {
+ int vsize;
+ int size;
+ SysIOVec* iov;
+ >ErlDrvBinary** binv;
+} ErlIOVec;
+</code>
+ <p>The I/O vector used by the emulator and drivers, is a list
+ of binaries, with a <c>SysIOVec</c> pointing to the buffers
+ of the binaries. It is used in <c>driver_outputv</c> and the
+ <seealso marker="driver_entry#outputv">outputv</seealso>
+ driver call-back. Also, the driver queue is an
+ <c>ErlIOVec</c>.</p>
+ </item>
+
+ <tag>ErlDrvMonitor</tag>
+ <item>
+ <p>When a driver creates a monitor for a process, a
+ <c>ErlDrvMonitor</c> is filled in. This is an opaque
+ data-type which can be assigned to but not compared without
+ using the supplied compare function (i.e. it behaves like a struct).</p>
+ <p>The driver writer should provide the memory for storing the
+ monitor when calling <seealso marker="#driver_monitor_process">driver_monitor_process</seealso>. The
+ address of the data is not stored outside of the driver, so
+ the <c>ErlDrvMonitor</c> can be used as any other datum, it
+ can be copied, moved in memory, forgotten etc.</p>
+ </item>
+ <tag><marker id="ErlDrvNowData"/>ErlDrvNowData</tag>
+ <item>
+ <p>The <c>ErlDrvNowData</c> structure holds a timestamp
+ consisting of three values measured from some arbitrary
+ point in the past. The three structure members are:</p>
+ <taglist>
+ <tag>megasecs</tag>
+ <item>The number of whole megaseconds elapsed since the arbitrary
+ point in time</item>
+ <tag>secs</tag>
+ <item>The number of whole seconds elapsed since the arbitrary
+ point in time</item>
+ <tag>microsecs</tag>
+ <item>The number of whole microseconds elapsed since the arbitrary
+ point in time</item>
+ </taglist>
+ </item>
+ <tag><marker id="ErlDrvPDL"/>ErlDrvPDL</tag>
+ <item>
+ <p>If certain port specific data have to be accessed from other
+ threads than those calling the driver call-backs, a port data lock
+ can be used in order to synchronize the operations on the data.
+ Currently, the only port specific data that the emulator
+ associates with the port data lock is the driver queue.</p>
+ <p>Normally a driver instance does not have a port data lock. If
+ the driver instance want to use a port data lock, it has to
+ create the port data lock by calling
+ <seealso marker="#driver_pdl_create">driver_pdl_create()</seealso>.
+ <em>NOTE</em>: Once the port data lock has been created, every
+ access to data associated with the port data lock have to be done
+ while having the port data lock locked. The port data lock is
+ locked, and unlocked, respectively, by use of
+ <seealso marker="#driver_pdl_lock">driver_pdl_lock()</seealso>, and
+ <seealso marker="#driver_pdl_unlock">driver_pdl_unlock()</seealso>.</p>
+ <p>A port data lock is reference counted, and when the reference
+ count reach zero, it will be destroyed. The emulator will at
+ least increment the reference count once when the lock is
+ created and decrement it once when the port associated with
+ the lock terminates. The emulator will also increment the
+ reference count when an async job is enqueued and decrement
+ it after an async job has been invoked, or canceled. Besides
+ this, it is the responsibility of the driver to ensure that
+ the reference count does not reach zero before the last use
+ of the lock by the driver has been made. The reference count
+ can be read, incremented, and decremented, respectively, by
+ use of
+ <seealso marker="#driver_pdl_get_refc">driver_pdl_get_refc()</seealso>,
+ <seealso marker="#driver_pdl_inc_refc">driver_pdl_inc_refc()</seealso>, and
+ <seealso marker="#driver_pdl_dec_refc">driver_pdl_dec_refc()</seealso>.</p>
+ </item>
+
+ <tag><marker id="ErlDrvTid"/>ErlDrvTid</tag>
+ <item>
+ <p>Thread identifier.</p>
+ <p>See also:
+ <seealso marker="#erl_drv_thread_create">erl_drv_thread_create()</seealso>,
+ <seealso marker="#erl_drv_thread_exit">erl_drv_thread_exit()</seealso>,
+ <seealso marker="#erl_drv_thread_join">erl_drv_thread_join()</seealso>,
+ <seealso marker="#erl_drv_thread_self">erl_drv_thread_self()</seealso>,
+ and
+ <seealso marker="#erl_drv_equal_tids">erl_drv_equal_tids()</seealso>.
+ </p>
+ </item>
+ <tag><marker id="ErlDrvThreadOpts"/>ErlDrvThreadOpts</tag>
+ <item>
+ <p/>
+ <code type="none">
+ int suggested_stack_size;
+ </code>
+ <p>Thread options structure passed to
+ <seealso marker="#erl_drv_thread_create">erl_drv_thread_create()</seealso>.
+ Currently the following fields exist:
+ </p>
+ <taglist>
+ <tag>suggested_stack_size</tag>
+ <item>A suggestion, in kilo-words, on how large stack to use. A value less
+ than zero means default size.
+ </item>
+ </taglist>
+ <p>See also:
+ <seealso marker="#erl_drv_thread_opts_create">erl_drv_thread_opts_create()</seealso>,
+ <seealso marker="#erl_drv_thread_opts_destroy">erl_drv_thread_opts_destroy()</seealso>,
+ and
+ <seealso marker="#erl_drv_thread_create">erl_drv_thread_create()</seealso>.
+ </p>
+ </item>
+
+ <tag><marker id="ErlDrvMutex"/>ErlDrvMutex</tag>
+ <item>
+ <p>Mutual exclusion lock. Used for synchronizing access to shared data.
+ Only one thread at a time can lock a mutex.
+ </p>
+ <p>See also:
+ <seealso marker="#erl_drv_mutex_create">erl_drv_mutex_create()</seealso>,
+ <seealso marker="#erl_drv_mutex_destroy">erl_drv_mutex_destroy()</seealso>,
+ <seealso marker="#erl_drv_mutex_lock">erl_drv_mutex_lock()</seealso>,
+ <seealso marker="#erl_drv_mutex_trylock">erl_drv_mutex_trylock()</seealso>,
+ and
+ <seealso marker="#erl_drv_mutex_unlock">erl_drv_mutex_unlock()</seealso>.
+ </p>
+ </item>
+ <tag><marker id="ErlDrvCond"/>ErlDrvCond</tag>
+ <item>
+ <p>Condition variable. Used when threads need to wait for a specific
+ condition to appear before continuing execution. Condition variables
+ need to be used with associated mutexes.
+ </p>
+ <p>See also:
+ <seealso marker="#erl_drv_cond_create">erl_drv_cond_create()</seealso>,
+ <seealso marker="#erl_drv_cond_destroy">erl_drv_cond_destroy()</seealso>,
+ <seealso marker="#erl_drv_cond_signal">erl_drv_cond_signal()</seealso>,
+ <seealso marker="#erl_drv_cond_broadcast">erl_drv_cond_broadcast()</seealso>,
+ and
+ <seealso marker="#erl_drv_cond_wait">erl_drv_cond_wait()</seealso>.
+ </p>
+ </item>
+ <tag><marker id="ErlDrvRWLock"/>ErlDrvRWLock</tag>
+ <item>
+ <p>Read/write lock. Used to allow multiple threads to read shared data
+ while only allowing one thread to write the same data. Multiple threads
+ can read lock an rwlock at the same time, while only one thread can
+ read/write lock an rwlock at a time.
+ </p>
+ <p>See also:
+ <seealso marker="#erl_drv_rwlock_create">erl_drv_rwlock_create()</seealso>,
+ <seealso marker="#erl_drv_rwlock_destroy">erl_drv_rwlock_destroy()</seealso>,
+ <seealso marker="#erl_drv_rwlock_rlock">erl_drv_rwlock_rlock()</seealso>,
+ <seealso marker="#erl_drv_rwlock_tryrlock">erl_drv_rwlock_tryrlock()</seealso>,
+ <seealso marker="#erl_drv_rwlock_runlock">erl_drv_rwlock_runlock()</seealso>,
+ <seealso marker="#erl_drv_rwlock_rwlock">erl_drv_rwlock_rwlock()</seealso>,
+ <seealso marker="#erl_drv_rwlock_tryrwlock">erl_drv_rwlock_tryrwlock()</seealso>,
+ and
+ <seealso marker="#erl_drv_rwlock_rwunlock">erl_drv_rwlock_rwunlock()</seealso>.
+ </p>
+ </item>
+ <tag><marker id="ErlDrvTSDKey"/>ErlDrvTSDKey</tag>
+ <item>
+ <p>Key which thread specific data can be associated with.</p>
+ <p>See also:
+ <seealso marker="#erl_drv_tsd_key_create">erl_drv_tsd_key_create()</seealso>,
+ <seealso marker="#erl_drv_tsd_key_destroy">erl_drv_tsd_key_destroy()</seealso>,
+ <seealso marker="#erl_drv_tsd_set">erl_drv_tsd_set()</seealso>,
+ and
+ <seealso marker="#erl_drv_tsd_get">erl_drv_tsd_get()</seealso>.
+ </p>
+ </item>
+ </taglist>
+ </section>
+
+ <funcs>
+ <func>
+ <name><ret>void</ret><nametext>driver_system_info(ErlDrvSysInfo *sys_info_ptr, size_t size)</nametext></name>
+ <fsummary>Get information about the Erlang runtime system</fsummary>
+ <desc>
+ <marker id="driver_system_info"></marker>
+ <p>This function will write information about the Erlang runtime
+ system into the
+ <seealso marker="#ErlDrvSysInfo">ErlDrvSysInfo</seealso>
+ structure referred to by the first argument. The second
+ argument should be the size of the
+ <seealso marker="#ErlDrvSysInfo">ErlDrvSysInfo</seealso>
+ structure, i.e., <c>sizeof(ErlDrvSysInfo)</c>.</p>
+ <p>See the documentation of the
+ <seealso marker="#ErlDrvSysInfo">ErlDrvSysInfo</seealso>
+ structure for information about specific fields.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_output(ErlDrvPort port, char *buf, int len)</nametext></name>
+ <fsummary>Send data from driver to port owner</fsummary>
+ <desc>
+ <marker id="driver_output"></marker>
+ <p>The <c>driver_output</c> function is used to send data from
+ the driver up to the emulator. The data will be received as
+ terms or binary data, depending on how the driver port was
+ opened.</p>
+ <p>The data is queued in the port owner process' message
+ queue. Note that this does not yield to the emulator. (Since
+ the driver and the emulator runs in the same thread.)</p>
+ <p>The parameter <c>buf</c> points to the data to send, and
+ <c>len</c> is the number of bytes.</p>
+ <p>The return value for all output functions is 0. (Unless the
+ driver is used for distribution, in which case it can fail
+ and return -1. For normal use, the output function always
+ returns 0.)</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_output2(ErlDrvPort port, char *hbuf, int hlen, char *buf, int len)</nametext></name>
+ <fsummary>Send data and binary data to port owner</fsummary>
+ <desc>
+ <marker id="driver_output2"></marker>
+ <p>The <c>driver_output2</c> function first sends <c>hbuf</c>
+ (length in <c>hlen</c>) data as a list, regardless of port
+ settings. Then <c>buf</c> is sent as a binary or list.
+ E.g. if <c>hlen</c> is 3 then the port owner process will
+ receive <c>[H1, H2, H3 | T]</c>.</p>
+ <p>The point of sending data as a list header, is to facilitate
+ matching on the data received.</p>
+ <p>The return value is 0 for normal use.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_output_binary(ErlDrvPort port, char *hbuf, int hlen, ErlDrvBinary* bin, int offset, int len)</nametext></name>
+ <fsummary>Send data from a driver binary to port owner</fsummary>
+ <desc>
+ <marker id="driver_output_binary"></marker>
+ <p>This function sends data to port owner process from a
+ driver binary, it has a header buffer (<c>hbuf</c>
+ and <c>hlen</c>) just like <c>driver_output2</c>. The
+ <c>hbuf</c> parameter can be <c>NULL</c>.</p>
+ <p>The parameter <c>offset</c> is an offset into the binary and
+ <c>len</c> is the number of bytes to send.</p>
+ <p>Driver binaries are created with <c>driver_alloc_binary</c>.</p>
+ <p>The data in the header is sent as a list and the binary as
+ an Erlang binary in the tail of the list.</p>
+ <p>E.g. if <c>hlen</c> is 2, then the port owner process will
+ receive <c><![CDATA[[H1, H2 | <<T>>]]]></c>.</p>
+ <p>The return value is 0 for normal use.</p>
+ <p>Note that, using the binary syntax in Erlang, the driver
+ application can match the header directly from the binary,
+ so the header can be put in the binary, and hlen can be set
+ to 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_outputv(ErlDrvPort port, char* hbuf, int hlen, ErlIOVec *ev, int skip)</nametext></name>
+ <fsummary>Send vectorized data to port owner</fsummary>
+ <desc>
+ <marker id="driver_outputv"></marker>
+ <p>This function sends data from an IO vector, <c>ev</c>, to
+ the port owner process. It has a header buffer (<c>hbuf</c>
+ and <c>hlen</c>), just like <c>driver_output2</c>.</p>
+ <p>The <c>skip</c> parameter is a number of bytes to skip of
+ the <c>ev</c> vector from the head.</p>
+ <p>You get vectors of <c>ErlIOVec</c> type from the driver
+ queue (see below), and the <seealso marker="driver_entry#outputv">outputv</seealso> driver entry
+ function. You can also make them yourself, if you want to
+ send several <c>ErlDrvBinary</c> buffers at once. Often
+ it is faster to use <c>driver_output</c> or
+ <c>driver_output_binary</c>.</p>
+ <p>E.g. if <c>hlen</c> is 2 and <c>ev</c> points to an array of
+ three binaries, the port owner process will receive <c><![CDATA[[H1, H2, <<B1>>, <<B2>> | <<B3>>]]]></c>.</p>
+ <p>The return value is 0 for normal use.</p>
+ <p>The comment for <c>driver_output_binary</c> applies for
+ <c>driver_outputv</c> too.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_vec_to_buf(ErlIOVec *ev, char *buf, int len)</nametext></name>
+ <fsummary>Collect data segments into a buffer</fsummary>
+ <desc>
+ <marker id="driver_vec_to_buf"></marker>
+ <p>This function collects several segments of data, referenced
+ by <c>ev</c>, by copying them in order to the buffer
+ <c>buf</c>, of the size <c>len</c>.</p>
+ <p>If the data is to be sent from the driver to the port owner
+ process, it is faster to use <c>driver_outputv</c>.</p>
+ <p>The return value is the space left in the buffer, i.e. if
+ the <c>ev</c> contains less than <c>len</c> bytes it's the
+ difference, and if <c>ev</c> contains <c>len</c> bytes or
+ more, it's 0. This is faster if there is more than one header byte,
+ since the binary syntax can construct integers directly from
+ the binary.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_set_timer(ErlDrvPort port, unsigned long time)</nametext></name>
+ <fsummary>Set a timer to call the driver</fsummary>
+ <desc>
+ <marker id="driver_set_timer"></marker>
+ <p>This function sets a timer on the driver, which will count
+ down and call the driver when it is timed out. The
+ <c>time</c> parameter is the time in milliseconds before the
+ timer expires.</p>
+ <p>When the timer reaches 0 and expires, the driver entry
+ function <seealso marker="driver_entry#emulator">timeout</seealso> is called.</p>
+ <p>Note that there is only one timer on each driver instance;
+ setting a new timer will replace an older one.</p>
+ <p>Return value i 0 (-1 only when the <c>timeout</c> driver
+ function is <c>NULL</c>).</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_cancel_timer(ErlDrvPort port)</nametext></name>
+ <fsummary>Cancel a previously set timer</fsummary>
+ <desc>
+ <marker id="driver_cancel_timer"></marker>
+ <p>This function cancels a timer set with
+ <c>driver_set_timer</c>.</p>
+ <p>The return value is 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_read_timer(ErlDrvPort port, unsigned long *time_left)</nametext></name>
+ <fsummary>Read the time left before timeout</fsummary>
+ <desc>
+ <marker id="driver_read_timer"></marker>
+ <p>This function reads the current time of a timer, and places
+ the result in <c>time_left</c>. This is the time in
+ milliseconds, before the timeout will occur.</p>
+ <p>The return value is 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_get_now(ErlDrvNowData *now)</nametext></name>
+ <fsummary>Read a system timestamp</fsummary>
+ <desc>
+ <marker id="driver_get_now"></marker>
+ <p>This function reads a timestamp into the memory pointed to by
+ the parameter <c>now</c>. See the description of <seealso marker="#ErlDrvNowData">ErlDrvNowData</seealso> for
+ specification of it's fields. </p>
+ <p>The return value is 0 unless the <c>now</c> pointer is not
+ valid, in which case it is &lt; 0. </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_select(ErlDrvPort port, ErlDrvEvent event, int mode, int on)</nametext></name>
+ <fsummary>Provide an event for having the emulator call the driver</fsummary>
+ <desc>
+ <marker id="driver_select"></marker>
+ <p>This function is used by drivers to provide the emulator with
+ events to check for. This enables the emulator to call the driver
+ when something has happened asynchronously.</p>
+ <p>The <c>event</c> argument identifies an OS-specific event object.
+ On Unix systems, the functions <c>select</c>/<c>poll</c> are used. The
+ event object must be a socket or pipe (or other object that
+ <c>select</c>/<c>poll</c> can use).
+ On windows, the Win32 API function <c>WaitForMultipleObjects</c>
+ is used. This places other restriction on the event object.
+ Refer to the Win32 SDK documentation.</p>
+ <p>The <c>on</c> parameter should be <c>1</c> for setting events
+ and <c>0</c> for clearing them.</p>
+ <p>The <c>mode</c> argument is bitwise-or combination of
+ <c>ERL_DRV_READ</c>, <c>ERL_DRV_WRITE</c> and <c>ERL_DRV_USE</c>.
+ The first two specifies whether to wait for read events and/or write
+ events. A fired read event will call
+ <seealso marker="driver_entry#ready_input">ready_input</seealso>
+ while a fired write event will call
+ <seealso marker="driver_entry#ready_output">ready_output</seealso>.
+ </p>
+ <note>
+ <p>Some OS (Windows) does not differ between read and write events.
+ The call-back for a fired event then only depends on the value of <c>mode</c>.</p>
+ </note>
+ <p><c>ERL_DRV_USE</c> specifies if we are using the event object or if we want to close it.
+ On an emulator with SMP support, it is not safe to clear all events
+ and then close the event object after <c>driver_select</c> has
+ returned. Another thread may still be using the event object
+ internally. To safely close an event object call
+ <c>driver_select</c> with <c>ERL_DRV_USE</c> and <c>on==0</c>. That
+ will clear all events and then call
+ <seealso marker="driver_entry#stop_select">stop_select</seealso>
+ when it is safe to close the event object.
+ <c>ERL_DRV_USE</c> should be set together with the first event
+ for an event object. It is harmless to set <c>ERL_DRV_USE</c>
+ even though it already has been done. Clearing all events but keeping
+ <c>ERL_DRV_USE</c> set will indicate that we are using the event
+ object and probably will set events for it again.</p>
+ <note>
+ <p>ERL_DRV_USE was added in OTP release R13. Old drivers will still work
+ as before. But it is recommended to update them to use <c>ERL_DRV_USE</c> and
+ <c>stop_select</c> to make sure that event objects are closed in a safe way.</p>
+ </note>
+ <p>The return value is 0 (Failure, -1, only if the
+ <c>ready_input</c>/<c>ready_output</c> is
+ <c>NULL</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void *</ret><nametext>driver_alloc(size_t size)</nametext></name>
+ <fsummary>Allocate memory</fsummary>
+ <desc>
+ <marker id="driver_alloc"></marker>
+ <p>This function allocates a memory block of the size specified
+ in <c>size</c>, and returns it. This only fails on out of
+ memory, in that case <c>NULL</c> is returned. (This is most
+ often a wrapper for <c>malloc</c>).</p>
+ <p>Memory allocated must be explicitly freed with a corresponding
+ call to <c>driver_free</c> (unless otherwise stated).</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void *</ret><nametext>driver_realloc(void *ptr, size_t size)</nametext></name>
+ <fsummary>Resize an allocated memory block</fsummary>
+ <desc>
+ <marker id="driver_realloc"></marker>
+ <p>This function resizes a memory block, either in place, or by
+ allocating a new block, copying the data and freeing the old
+ block. A pointer is returned to the reallocated memory. On
+ failure (out of memory), <c>NULL</c> is returned. (This is
+ most often a wrapper for <c>realloc</c>.)</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>driver_free(void *ptr)</nametext></name>
+ <fsummary>Free an allocated memory block</fsummary>
+ <desc>
+ <marker id="driver_free"></marker>
+ <p>This function frees the memory pointed to by <c>ptr</c>. The
+ memory should have been allocated with
+ <c>driver_alloc</c>. All allocated memory should be
+ deallocated, just once. There is no garbage collection in
+ drivers.</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvBinary*</ret><nametext>driver_alloc_binary(int size)</nametext></name>
+ <fsummary>Allocate a driver binary</fsummary>
+ <desc>
+ <marker id="driver_alloc_binary"></marker>
+ <p>This function allocates a driver binary with a memory block
+ of at least <c>size</c> bytes, and returns a pointer to it,
+ or NULL on failure (out of memory). When a driver binary has
+ been sent to the emulator, it must not be altered. Every
+ allocated binary should be freed by a corresponding call to
+ <c>driver_free_binary</c> (unless otherwise stated).</p>
+ <p>Note that a driver binary has an internal reference counter,
+ this means that calling <c>driver_free_binary</c> it may not
+ actually dispose of it. If it's sent to the emulator, it may
+ be referenced there.</p>
+ <p>The driver binary has a field, <c>orig_bytes</c>, which
+ marks the start of the data in the binary.</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvBinary*</ret><nametext>driver_realloc_binary(ErlDrvBinary *bin, int size)</nametext></name>
+ <fsummary>Resize a driver binary</fsummary>
+ <desc>
+ <marker id="driver_realloc_binary"></marker>
+ <p>This function resizes a driver binary, while keeping the
+ data. The resized driver binary is returned. On failure (out
+ of memory), <c>NULL</c> is returned.</p>
+ <p>This function is only thread-safe when the emulator with SMP
+ support is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>driver_free_binary(ErlDrvBinary *bin)</nametext></name>
+ <fsummary>Free a driver binary</fsummary>
+ <desc>
+ <marker id="driver_free_binary"></marker>
+ <p>This function frees a driver binary <c>bin</c>, allocated
+ previously with <c>driver_alloc_binary</c>. Since binaries
+ in Erlang are reference counted, the binary may still be
+ around.</p>
+ <p>This function is only thread-safe when the emulator with SMP
+ support is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>long</ret><nametext>driver_binary_get_refc(ErlDrvBinary *bin)</nametext></name>
+ <fsummary>Get the reference count of a driver binary</fsummary>
+ <desc>
+ <marker id="driver_binary_get_refc"></marker>
+ <p>Returns current reference count on <c>bin</c>.</p>
+ <p>This function is only thread-safe when the emulator with SMP
+ support is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>long</ret><nametext>driver_binary_inc_refc(ErlDrvBinary *bin)</nametext></name>
+ <fsummary>Increment the reference count of a driver binary</fsummary>
+ <desc>
+ <marker id="driver_binary_inc_refc"></marker>
+ <p>Increments the reference count on <c>bin</c> and returns
+ the reference count reached after the increment.</p>
+ <p>This function is only thread-safe when the emulator with SMP
+ support is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>long</ret><nametext>driver_binary_dec_refc(ErlDrvBinary *bin)</nametext></name>
+ <fsummary>Decrement the reference count of a driver binary</fsummary>
+ <desc>
+ <marker id="driver_binary_dec_refc"></marker>
+ <p>Decrements the reference count on <c>bin</c> and returns
+ the reference count reached after the decrement.</p>
+ <p>This function is only thread-safe when the emulator with SMP
+ support is used.</p>
+ <note>
+ <p>You should normally decrement the reference count of a
+ driver binary by calling
+ <seealso marker="#driver_free_binary">driver_free_binary()</seealso>.
+ <c>driver_binary_dec_refc()</c> does <em>not</em> free
+ the binary if the reference count reaches zero. <em>Only</em>
+ use <c>driver_binary_dec_refc()</c> when you are sure
+ <em>not</em> to reach a reference count of zero.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_enq(ErlDrvPort port, char* buf, int len)</nametext></name>
+ <fsummary>Enqueue data in the driver queue</fsummary>
+ <desc>
+ <marker id="driver_enq"></marker>
+ <p>This function enqueues data in the driver queue. The data in
+ <c>buf</c> is copied (<c>len</c> bytes) and placed at the
+ end of the driver queue. The driver queue is normally used
+ in a FIFO way.</p>
+ <p>The driver queue is available to queue output from the
+ emulator to the driver (data from the driver to the emulator
+ is queued by the emulator in normal erlang message
+ queues). This can be useful if the driver has to wait for
+ slow devices etc, and wants to yield back to the
+ emulator. The driver queue is implemented as an ErlIOVec.</p>
+ <p>When the queue contains data, the driver won't close, until
+ the queue is empty.</p>
+ <p>The return value is 0.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_pushq(ErlDrvPort port, char* buf, int len)</nametext></name>
+ <fsummary>Push data at the head of the driver queue</fsummary>
+ <desc>
+ <marker id="driver_pushq"></marker>
+ <p>This function puts data at the head of the driver queue. The
+ data in <c>buf</c> is copied (<c>len</c> bytes) and placed
+ at the beginning of the queue.</p>
+ <p>The return value is 0.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_deq(ErlDrvPort port, int size)</nametext></name>
+ <fsummary>Dequeue data from the head of the driver queue</fsummary>
+ <desc>
+ <marker id="driver_deq"></marker>
+ <p>This function dequeues data by moving the head pointer
+ forward in the driver queue by <c>size</c> bytes. The data
+ in the queue will be deallocated.</p>
+ <p>The return value is the number of bytes remaining in the queue
+ or -1 on failure.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_sizeq(ErlDrvPort port)</nametext></name>
+ <fsummary>Return the size of the driver queue</fsummary>
+ <desc>
+ <marker id="driver_sizeq"></marker>
+ <p>This function returns the number of bytes currently in the
+ driver queue.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_enq_bin(ErlDrvPort port, ErlDrvBinary *bin, int offset, int len)</nametext></name>
+ <fsummary>Enqueue binary in the driver queue</fsummary>
+ <desc>
+ <marker id="driver_enq_bin"></marker>
+ <p>This function enqueues a driver binary in the driver
+ queue. The data in <c>bin</c> at <c>offset</c> with length
+ <c>len</c> is placed at the end of the queue. This function
+ is most often faster than <c>driver_enq</c>, because the
+ data doesn't have to be copied.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ <p>The return value is 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_pushq_bin(ErlDrvPort port, ErlDrvBinary *bin, int offset, int len)</nametext></name>
+ <fsummary>Push binary at the head of the driver queue</fsummary>
+ <desc>
+ <marker id="driver_pushq_bin"></marker>
+ <p>This function puts data in the binary <c>bin</c>, at
+ <c>offset</c> with length <c>len</c> at the head of the
+ driver queue. It is most often faster than
+ <c>driver_pushq</c>, because the data doesn't have to be
+ copied.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ <p>The return value is 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>SysIOVec*</ret><nametext>driver_peekq(ErlDrvPort port, int *vlen)</nametext></name>
+ <fsummary>Get the driver queue as a vector</fsummary>
+ <desc>
+ <marker id="driver_peekq"></marker>
+ <p>This function retrieves the driver queue as a pointer to an
+ array of <c>SysIOVec</c>s. It also returns the number of
+ elements in <c>vlen</c>. This is the only way to get data
+ out of the queue.</p>
+ <p>Nothing is remove from the queue by this function, that must be done
+ with <c>driver_deq</c>.</p>
+ <p>The returned array is suitable to use with the Unix system
+ call <c>writev</c>.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_enqv(ErlDrvPort port, ErlIOVec *ev, int skip)</nametext></name>
+ <fsummary>Enqueue vector in the driver queue</fsummary>
+ <desc>
+ <marker id="driver_enqv"></marker>
+ <p>This function enqueues the data in <c>ev</c>, skipping the
+ first <c>skip</c> bytes of it, at the end of the driver
+ queue. It is faster than <c>driver_enq</c>, because the data
+ doesn't have to be copied.</p>
+ <p>The return value is 0.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_pushqv(ErlDrvPort port, ErlIOVec *ev, int skip)</nametext></name>
+ <fsummary>Push vector at the head of the driver queue</fsummary>
+ <desc>
+ <marker id="driver_pushqv"></marker>
+ <p>This function puts the data in <c>ev</c>, skipping the first
+ <c>skip</c> bytes of it, at the head of the driver queue.
+ It is faster than <c>driver_pushq</c>, because the data
+ doesn't have to be copied.</p>
+ <p>The return value is 0.</p>
+ <p>This function can be called from an arbitrary thread if a
+ <seealso marker="#ErlDrvPDL">port data lock</seealso>
+ associated with the <c>port</c> is locked by the calling
+ thread during the call.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvPDL</ret><nametext>driver_pdl_create(ErlDrvPort port)</nametext></name>
+ <fsummary>Create a port data lock</fsummary>
+ <desc>
+ <marker id="driver_pdl_create"></marker>
+ <p>This function creates a port data lock associated with
+ the <c>port</c>. <em>NOTE</em>: Once a port data lock has
+ been created, it has to be locked during all operations
+ on the driver queue of the <c>port</c>.</p>
+ <p>On success a newly created port data lock is returned. On
+ failure <c>NULL</c> is returned. <c>driver_pdl_create()</c> will
+ fail if <c>port</c> is invalid or if a port data lock already has
+ been associated with the <c>port</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>driver_pdl_lock(ErlDrvPDL pdl)</nametext></name>
+ <fsummary>Lock port data lock</fsummary>
+ <desc>
+ <marker id="driver_pdl_lock"></marker>
+ <p>This function locks the port data lock passed as argument
+ (<c>pdl</c>).</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>driver_pdl_unlock(ErlDrvPDL pdl)</nametext></name>
+ <fsummary>Unlock port data lock</fsummary>
+ <desc>
+ <marker id="driver_pdl_unlock"></marker>
+ <p>This function unlocks the port data lock passed as argument
+ (<c>pdl</c>).</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>long</ret><nametext>driver_pdl_get_refc(ErlDrvPDL pdl)</nametext></name>
+ <fsummary></fsummary>
+ <desc>
+ <marker id="driver_pdl_get_refc"></marker>
+ <p>This function returns the current reference count of
+ the port data lock passed as argument (<c>pdl</c>).</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>long</ret><nametext>driver_pdl_inc_refc(ErlDrvPDL pdl)</nametext></name>
+ <fsummary></fsummary>
+ <desc>
+ <marker id="driver_pdl_inc_refc"></marker>
+ <p>This function increments the reference count of
+ the port data lock passed as argument (<c>pdl</c>).</p>
+ <p>The current reference count after the increment has
+ been performed is returned.</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>long</ret><nametext>driver_pdl_dec_refc(ErlDrvPDL pdl)</nametext></name>
+ <fsummary></fsummary>
+ <desc>
+ <marker id="driver_pdl_dec_refc"></marker>
+ <p>This function decrements the reference count of
+ the port data lock passed as argument (<c>pdl</c>).</p>
+ <p>The current reference count after the decrement has
+ been performed is returned.</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_monitor_process(ErlDrvPort port, ErlDrvTermData process, ErlDrvMonitor *monitor)</nametext></name>
+ <fsummary>Monitor a process from a driver</fsummary>
+ <desc>
+ <marker id="driver_monitor_process"></marker>
+ <p>Start monitoring a process from a driver. When a process is
+ monitored, a process exit will result in a call to the
+ provided <seealso marker="driver_entry#process_exit">process_exit</seealso> call-back
+ in the <seealso marker="driver_entry">ErlDrvEntry</seealso>
+ structure. The <c>ErlDrvMonitor</c> structure is filled in, for later
+ removal or compare.</p>
+ <p>The <c>process</c> parameter should be the return value of an
+ earlier call to <seealso marker="#driver_caller">driver_caller</seealso> or <seealso marker="#driver_connected">driver_connected</seealso> call.</p>
+ <p>The function returns 0 on success, &lt; 0 if no call-back is
+ provided and &gt; 0 if the process is no longer alive.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_demonitor_process(ErlDrvPort port, const ErlDrvMonitor *monitor)</nametext></name>
+ <fsummary>Stop monitoring a process from a driver</fsummary>
+ <desc>
+ <marker id="driver_demonitor_process"></marker>
+ <p>This function cancels an monitor created earlier. </p>
+ <p>The function returns 0 if a monitor was removed and &gt; 0
+ if the monitor did no longer exist.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvTermData</ret><nametext>driver_get_monitored_process(ErlDrvPort port, const ErlDrvMonitor *monitor)</nametext></name>
+ <fsummary>Retrieve the process id from a monitor</fsummary>
+ <desc>
+ <marker id="driver_get_monitored_process"></marker>
+ <p>The function returns the process id associated with a living
+ monitor. It can be used in the <c>process_exit</c> call-back to
+ get the process identification for the exiting process.</p>
+ <p>The function returns <c>driver_term_nil</c> if the monitor
+ no longer exists.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_compare_monitors(const ErlDrvMonitor *monitor1, const ErlDrvMonitor *monitor2)</nametext></name>
+ <fsummary>Compare two monitors</fsummary>
+ <desc>
+ <marker id="driver_compare_monitors"></marker>
+ <p>This function is used to compare two <c>ErlDrvMonitor</c>s. It
+ can also be used to imply some artificial order on monitors,
+ for whatever reason.</p>
+ <p>The function returns 0 if <c>monitor1</c> and
+ <c>monitor2</c> are equal, &lt; 0 if <c>monitor1</c> is less
+ than <c>monitor2</c> and &gt; 0 if <c>monitor1</c> is greater
+ than <c>monitor2</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>add_driver_entry(ErlDrvEntry *de)</nametext></name>
+ <fsummary>Add a driver entry</fsummary>
+ <desc>
+ <marker id="add_driver_entry"></marker>
+ <p>This function adds a driver entry to the list of drivers
+ known by Erlang. The <seealso marker="driver_entry#init">init</seealso> function of the <c>de</c>
+ parameter is called.</p>
+ <note>
+ <p>To use this function for adding drivers residing in
+ dynamically loaded code is dangerous. If the driver code
+ for the added driver resides in the same dynamically
+ loaded module (i.e. <c>.so</c> file) as a normal
+ dynamically loaded driver (loaded with the <c>erl_ddll</c>
+ interface), the caller should call <seealso marker="#driver_lock_driver">driver_lock_driver</seealso> before
+ adding driver entries.</p>
+ <p>Use of this function is generally deprecated.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>remove_driver_entry(ErlDrvEntry *de)</nametext></name>
+ <fsummary>Remove a driver entry</fsummary>
+ <desc>
+ <marker id="remove_driver_entry"></marker>
+ <p>This function removes a driver entry <c>de</c> previously
+ added with <c>add_driver_entry</c>.</p>
+ <p>Driver entries added by the <c>erl_ddll</c> erlang interface can
+ not be removed by using this interface.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>char*</ret><nametext>erl_errno_id(int error)</nametext></name>
+ <fsummary>Get erlang error atom name from error number</fsummary>
+ <desc>
+ <marker id="erl_errno_id"></marker>
+ <p>This function returns the atom name of the erlang error,
+ given the error number in <c>error</c>. Error atoms are:
+ <c>einval</c>, <c>enoent</c>, etc. It can be used to make
+ error terms from the driver.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>set_busy_port(ErlDrvPort port, int on)</nametext></name>
+ <fsummary>Signal or unsignal port as busy</fsummary>
+ <desc>
+ <marker id="set_busy_port"></marker>
+ <p>This function set and resets the busy status of the port. If
+ <c>on</c> is 1, the port is set to busy, if it's 0 the port
+ is set to not busy.</p>
+ <p>When the port is busy, sending to it with <c>Port ! Data</c>
+ or <c>port_command/2</c>, will block the port owner process,
+ until the port is signaled as not busy.</p>
+ <p>If the
+ <seealso marker="driver_entry#driver_flags"><![CDATA[ERL_DRV_FLAG_SOFT_BUSY]]></seealso>
+ has been set in the
+ <seealso marker="driver_entry">driver_entry</seealso>,
+ data can be forced into the driver via
+ <seealso marker="erlang#erlang:port_command/3">port_command(Port, Data, [force])</seealso>
+ even though the driver has signaled that it is busy.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>void</ret><nametext>set_port_control_flags(ErlDrvPort port, int flags)</nametext></name>
+ <fsummary>Set flags on how to handle control entry function</fsummary>
+ <desc>
+ <marker id="set_port_control_flags"></marker>
+ <p>This function sets flags for how the <seealso marker="driver_entry#control">control</seealso> driver entry
+ function will return data to the port owner process. (The
+ <c>control</c> function is called from <c>port_control/3</c>
+ in erlang.)</p>
+ <p>Currently there are only two meaningful values for
+ <c>flags</c>: 0 means that data is returned in a list, and
+ <c>PORT_CONTROL_FLAG_BINARY</c> means data is returned as
+ a binary from <c>control</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_failure_eof(ErlDrvPort port)</nametext></name>
+ <fsummary>Fail with EOF</fsummary>
+ <desc>
+ <marker id="driver_failure_eof"></marker>
+ <p>This function signals to erlang that the driver has
+ encountered an EOF and should be closed, unless the port was
+ opened with the <c>eof</c> option, in that case eof is sent
+ to the port. Otherwise, the port is close and an
+ <c>'EXIT'</c> message is sent to the port owner process.</p>
+ <p>The return value is 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_failure_atom(ErlDrvPort port, char *string)</nametext></name>
+ <name><ret>int</ret><nametext>driver_failure_posix(ErlDrvPort port, int error)</nametext></name>
+ <name><ret>int</ret><nametext>driver_failure(ErlDrvPort port, int error)</nametext></name>
+ <fsummary>Fail with error</fsummary>
+ <desc>
+ <marker id="driver_failure_atom"></marker>
+ <marker id="driver_failure_posix"></marker>
+ <marker id="driver_failure"></marker>
+ <p>These functions signal to Erlang that the driver has
+ encountered an error and should be closed. The port is
+ closed and the tuple <c>{'EXIT', error, Err}</c>, is sent to
+ the port owner process, where error is an error atom
+ (<c>driver_failure_atom</c> and
+ <c>driver_failure_posix</c>), or an integer
+ (<c>driver_failure</c>).</p>
+ <p>The driver should fail only when in severe error situations,
+ when the driver cannot possibly keep open, for instance
+ buffer allocation gets out of memory. Normal errors is more
+ appropriate to handle with sending error codes with
+ <c>driver_output</c>.</p>
+ <p>The return value is 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvTermData</ret><nametext>driver_connected(ErlDrvPort port)</nametext></name>
+ <fsummary>Return the port owner process</fsummary>
+ <desc>
+ <marker id="driver_connected"></marker>
+ <p>This function returns the port owner process.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvTermData</ret><nametext>driver_caller(ErlDrvPort port)</nametext></name>
+ <fsummary>Return the process making the driver call</fsummary>
+ <desc>
+ <marker id="driver_caller"></marker>
+ <p>This function returns the process id of the process that
+ made the current call to the driver. The process id can be
+ used with <c>driver_send_term</c> to send back data to the
+ caller. <c>driver_caller()</c> only return valid data
+ when currently executing in one of the following driver
+ callbacks:</p>
+ <taglist>
+ <tag><seealso marker="driver_entry#start">start</seealso></tag>
+ <item>Called from <c>open_port/2</c>.</item>
+ <tag><seealso marker="driver_entry#output">output</seealso></tag>
+ <item>Called from <c>erlang:send/2</c>, and
+ <c>erlang:port_command/2</c></item>
+ <tag><seealso marker="driver_entry#outputv">outputv</seealso></tag>
+ <item>Called from <c>erlang:send/2</c>, and
+ <c>erlang:port_command/2</c></item>
+ <tag><seealso marker="driver_entry#control">control</seealso></tag>
+ <item>Called from <c>erlang:port_control/3</c></item>
+ <tag><seealso marker="driver_entry#call">call</seealso></tag>
+ <item>Called from <c>erlang:port_call/3</c></item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_output_term(ErlDrvPort port, ErlDrvTermData* term, int n)</nametext></name>
+ <fsummary>Send term data from driver to port owner</fsummary>
+ <desc>
+ <marker id="driver_output_term"></marker>
+ <p>This functions sends data in the special driver term
+ format. This is a fast way to deliver term data from a
+ driver. It also needs no binary conversion, so the port
+ owner process receives data as normal Erlang terms.</p>
+ <p>The <c>term</c> parameter points to an array of
+ <c>ErlDrvTermData</c>, with <c>n</c> elements. This array
+ contains terms described in the driver term format. Every
+ term consists of one to four elements in the array. The
+ term first has a term type, and then arguments.</p>
+ <p>Tuple and lists (with the exception of strings, see below),
+ are built in reverse polish notation, so that to build a
+ tuple, the elements are given first, and then the tuple
+ term, with a count. Likewise for lists.</p>
+ <p>A tuple must be specified with the number of elements. (The
+ elements precedes the <c>ERL_DRV_TUPLE</c> term.)</p>
+ <p>A list must be specified with the number of elements,
+ including the tail, which is the last term preceding
+ <c>ERL_DRV_LIST</c>.</p>
+ <p>The special term <c>ERL_DRV_STRING_CONS</c> is used to
+ "splice" in a string in a list, a string given this way is
+ not a list per se, but the elements are elements of the
+ surrounding list.</p>
+ <pre>
+Term type Argument(s)
+===========================================
+ERL_DRV_NIL
+ERL_DRV_ATOM ErlDrvTermData atom (from driver_mk_atom(char *string))
+ERL_DRV_INT ErlDrvSInt integer
+ERL_DRV_UINT ErlDrvUInt integer
+ERL_DRV_INT64 ErlDrvSInt64 *integer_ptr
+ERL_DRV_UINT64 ErlDrvUInt64 *integer_ptr
+ERL_DRV_PORT ErlDrvTermData port (from driver_mk_port(ErlDrvPort port))
+ERL_DRV_BINARY ErlDrvBinary *bin, ErlDrvUInt len, ErlDrvUInt offset
+ERL_DRV_BUF2BINARY char *buf, ErlDrvUInt len
+ERL_DRV_STRING char *str, int len
+ERL_DRV_TUPLE int sz
+ERL_DRV_LIST int sz
+ERL_DRV_PID ErlDrvTermData pid (from driver_connected(ErlDrvPort port) or driver_caller(ErlDrvPort port))
+ERL_DRV_STRING_CONS char *str, int len
+ERL_DRV_FLOAT double *dbl
+ERL_DRV_EXT2TERM char *buf, ErlDrvUInt len
+ </pre>
+ <p>The unsigned integer data type <c>ErlDrvUInt</c> and the
+ signed integer data type <c>ErlDrvSInt</c> are 64 bits wide
+ on a 64 bit runtime system and 32 bits wide on a 32 bit
+ runtime system. They were introduced in erts version 5.6,
+ and replaced some of the <c>int</c> arguments in the list above.
+ </p>
+ <p>The unsigned integer data type <c>ErlDrvUInt64</c> and the
+ signed integer data type <c>ErlDrvSInt64</c> are always 64 bits
+ wide. They were introduced in erts version 5.7.4.
+ </p>
+
+ <p>To build the tuple <c>{tcp, Port, [100 | Binary]}</c>, the
+ following call could be made.</p>
+ <code type="none"><![CDATA[
+ ErlDrvBinary* bin = ...
+ ErlDrvPort port = ...
+ ErlDrvTermData spec[] = {
+ ERL_DRV_ATOM, driver_mk_atom("tcp"),
+ ERL_DRV_PORT, driver_mk_port(port),
+ ERL_DRV_INT, 100,
+ ERL_DRV_BINARY, bin, 50, 0,
+ ERL_DRV_LIST, 2,
+ ERL_DRV_TUPLE, 3,
+ };
+ driver_output_term(port, spec, sizeof(spec) / sizeof(spec[0]));
+ ]]>
+ </code>
+ <p>Where <c>bin</c> is a driver binary of length at least 50
+ and <c>port</c> is a port handle. Note that the <c>ERL_DRV_LIST</c>
+ comes after the elements of the list, likewise the
+ <c>ERL_DRV_TUPLE</c>.</p>
+ <p>The term <c>ERL_DRV_STRING_CONS</c> is a way to construct
+ strings. It works differently from how <c>ERL_DRV_STRING</c>
+ works. <c>ERL_DRV_STRING_CONS</c> builds a string list in
+ reverse order, (as opposed to how <c>ERL_DRV_LIST</c>
+ works), concatenating the strings added to a list. The tail
+ must be given before <c>ERL_DRV_STRING_CONS</c>.</p>
+ <p>The <c>ERL_DRV_STRING</c> constructs a string, and ends
+ it. (So it's the same as <c>ERL_DRV_NIL</c> followed by
+ <c>ERL_DRV_STRING_CONS</c>.)</p>
+ <code type="none"><![CDATA[
+ /* to send [x, "abc", y] to the port: */
+ ErlDrvTermData spec[] = {
+ ERL_DRV_ATOM, driver_mk_atom("x"),
+ ERL_DRV_STRING, (ErlDrvTermData)"abc", 3,
+ ERL_DRV_ATOM, driver_mk_atom("y"),
+ ERL_DRV_NIL,
+ ERL_DRV_LIST, 4
+ };
+ driver_output_term(port, spec, sizeof(spec) / sizeof(spec[0]));
+ ]]></code>
+ <p></p>
+ <code type="none"><![CDATA[
+ /* to send "abc123" to the port: */
+ ErlDrvTermData spec[] = {
+ ERL_DRV_NIL, /* with STRING_CONS, the tail comes first */
+ ERL_DRV_STRING_CONS, (ErlDrvTermData)"123", 3,
+ ERL_DRV_STRING_CONS, (ErlDrvTermData)"abc", 3,
+ };
+ driver_output_term(port, spec, sizeof(spec) / sizeof(spec[0]));
+ ]]></code>
+ <p>The <c>ERL_DRV_EXT2TERM</c> term type is used for passing a
+ term encoded with the
+ <seealso marker="erl_ext_dist">external format</seealso>,
+ i.e., a term that has been encoded by
+ <seealso marker="erts:erlang#term_to_binary/2">erlang:term_to_binary</seealso>,
+ <seealso marker="erl_interface:ei">erl_interface</seealso>, etc.
+ For example, if <c>binp</c> is a pointer to an <c>ErlDrvBinary</c>
+ that contains the term <c>{17, 4711}</c> encoded with the
+ <seealso marker="erl_ext_dist">external format</seealso>
+ and you want to wrap it in a two tuple with the tag <c>my_tag</c>,
+ i.e., <c>{my_tag, {17, 4711}}</c>, you can do as follows:
+ </p>
+ <code type="none"><![CDATA[
+ ErlDrvTermData spec[] = {
+ ERL_DRV_ATOM, driver_mk_atom("my_tag"),
+ ERL_DRV_EXT2TERM, (ErlDrvTermData) binp->orig_bytes, binp->orig_size
+ ERL_DRV_TUPLE, 2,
+ };
+ driver_output_term(port, spec, sizeof(spec) / sizeof(spec[0]));
+ ]]></code>
+ <p>If you want to pass a binary and doesn't already have the content
+ of the binary in an <c>ErlDrvBinary</c>, you can benefit from using
+ <c>ERL_DRV_BUF2BINARY</c> instead of creating an <c>ErlDrvBinary</c>
+ via <c>driver_alloc_binary()</c> and then pass the binary via
+ <c>ERL_DRV_BINARY</c>. The runtime system will often allocate
+ binaries smarter if <c>ERL_DRV_BUF2BINARY</c> is used.
+ However, if the content of the binary to pass already resides in
+ an <c>ErlDrvBinary</c>, it is normally better to pass the binary
+ using <c>ERL_DRV_BINARY</c> and the <c>ErlDrvBinary</c> in question.
+ </p>
+ <p>The <c>ERL_DRV_UINT</c>, <c>ERL_DRV_BUF2BINARY</c>, and
+ <c>ERL_DRV_EXT2TERM</c> term types were introduced in the 5.6
+ version of erts.
+ </p>
+ <p>Note that this function is <em>not</em> thread-safe, not
+ even when the emulator with SMP support is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvTermData</ret><nametext>driver_mk_atom(char* string)</nametext></name>
+ <fsummary>Make an atom from a name</fsummary>
+ <desc>
+ <marker id="driver_mk_atom"></marker>
+ <p>This function returns an atom given a name
+ <c>string</c>. The atom is created and won't change, so the
+ return value may be saved and reused, which is faster than
+ looking up the atom several times.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvTermData</ret><nametext>driver_mk_port(ErlDrvPort port)</nametext></name>
+ <fsummary>Make a erlang term port from a port</fsummary>
+ <desc>
+ <marker id="driver_mk_port"></marker>
+ <p>This function converts a port handle to the erlang term
+ format, usable in the <c>driver_output_send</c> function.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_send_term(ErlDrvPort port, ErlDrvTermData receiver, ErlDrvTermData* term, int n)</nametext></name>
+ <fsummary>Send term data to other process than port owner process</fsummary>
+ <desc>
+ <marker id="driver_send_term"></marker>
+ <p>This function is the only way for a driver to send data to
+ <em>other</em> processes than the port owner process. The
+ <c>receiver</c> parameter specifies the process to receive
+ the data.</p>
+ <p>The parameters <c>term</c> and <c>n</c> does the same thing
+ as in <seealso marker="#driver_output_term">driver_output_term</seealso>.</p>
+ <p>This function is only thread-safe when the emulator with SMP
+ support is used.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>long</ret><nametext>driver_async (ErlDrvPort port, unsigned int* key, void (*async_invoke)(void*), void* async_data, void (*async_free)(void*))</nametext></name>
+ <fsummary>Perform an asynchronous call within a driver</fsummary>
+ <desc>
+ <marker id="driver_async"></marker>
+ <p>This function performs an asynchronous call. The function
+ <c>async_invoke</c> is invoked in a thread separate from the
+ emulator thread. This enables the driver to perform
+ time-consuming, blocking operations without blocking the
+ emulator.</p>
+ <p>Erlang is by default started without an async thread pool. The
+ number of async threads that the runtime system should use
+ is specified by the
+ <seealso marker="erl#async_thread_pool_size">+A</seealso>
+ command line argument of <seealso marker="erl">erl(1)</seealso>.
+ If no async thread pool is available, the call is made
+ synchronously in the thread calling <c>driver_async()</c>. The
+ current number of async threads in the async thread pool can be
+ retrieved via
+ <seealso marker="#driver_system_info">driver_system_info()</seealso>.</p>
+ <p>If there is a thread pool available, a thread will be
+ used. If the <c>key</c> argument is null, the threads from the
+ pool are used in a round-robin way, each call to
+ <c>driver_async</c> uses the next thread in the pool. With the
+ <c>key</c> argument set, this behaviour is changed. The two
+ same values of <c>*key</c> always get the same thread.</p>
+ <p>To make sure that a driver instance always uses the same
+ thread, the following call can be used:</p>
+ <p></p>
+ <code type="none"><![CDATA[
+ unsigned int myKey = (unsigned int) myPort;
+
+ r = driver_async(myPort, &myKey, myData, myFunc);
+ ]]></code>
+ <p>It is enough to initialize <c>myKey</c> once for each
+ driver instance.</p>
+ <p>If a thread is already working, the calls will be
+ queued up and executed in order. Using the same thread for
+ each driver instance ensures that the calls will be made in
+ sequence.</p>
+ <p>The <c>async_data</c> is the argument to the functions
+ <c>async_invoke</c> and <c>async_free</c>. It's typically a
+ pointer to a structure that contains a pipe or event that
+ can be used to signal that the async operation completed.
+ The data should be freed in <c>async_free</c>, because it's
+ called if <c>driver_async_cancel</c> is called.</p>
+ <p>When the async operation is done, <seealso marker="driver_entry#ready_async">ready_async</seealso> driver
+ entry function is called. If <c>async_ready</c> is null in
+ the driver entry, the <c>async_free</c> function is called
+ instead.</p>
+ <p>The return value is a handle to the asynchronous task, which
+ can be used as argument to <c>driver_async_cancel</c>.</p>
+ <note>
+ <p>As of erts version 5.5.4.3 the default stack size for
+ threads in the async-thread pool is 16 kilowords,
+ i.e., 64 kilobyte on 32-bit architectures.
+ This small default size has been chosen since the
+ amount of async-threads might be quite large. The
+ default stack size is enough for drivers delivered
+ with Erlang/OTP, but might not be sufficiently large
+ for other dynamically linked in drivers that use the
+ driver_async() functionality. A suggested stack size
+ for threads in the async-thread pool can be configured
+ via the
+ <seealso marker="erl#async_thread_stack_size">+a</seealso>
+ command line argument of
+ <seealso marker="erl">erl(1)</seealso>.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_async_cancel(long id)</nametext></name>
+ <fsummary>Cancel an asynchronous call</fsummary>
+ <desc>
+ <marker id="driver_async_cancel"></marker>
+ <p>This function cancels an asynchronous operation, by removing
+ it from the queue. Only functions in the queue can be
+ cancelled; if a function is executing, it's too late to
+ cancel it. The <c>async_free</c> function is also called.</p>
+ <p>The return value is 1 if the operation was removed from the
+ queue, otherwise 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>driver_lock_driver(ErlDrvPort port)</nametext></name>
+ <fsummary>Make sure the driver is never unloaded</fsummary>
+ <desc>
+ <marker id="driver_lock_driver"></marker>
+ <p>This function locks the driver used by the port <c>port</c>
+ in memory for the rest of the emulator process
+ lifetime. After this call, the driver behaves as one of Erlang's
+ statically linked in drivers.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>ErlDrvPort</ret><nametext>driver_create_port(ErlDrvPort port, ErlDrvTermData owner_pid, char* name, ErlDrvData drv_data)</nametext></name>
+ <fsummary>Create a new port (driver instance)</fsummary>
+ <desc>
+ <p>This function creates a new port executing the same driver
+ code as the port creating the new port.
+ A short description of the arguments:</p>
+ <taglist>
+ <tag><c>port</c></tag>
+ <item>The port handle of the port (driver instance) creating
+ the new port.</item>
+ <tag><c>owner_pid</c></tag>
+ <item>The process id of the Erlang process which will be
+ owner of the new port. This process will be linked
+ to the new port. You usually want to use
+ <c>driver_caller(port)</c> as <c>owner_pid</c>.</item>
+ <tag><c>name</c></tag>
+ <item>The port name of the new port. You usually want to
+ use the same port name as the driver name
+ (<seealso marker="driver_entry#driver_name">driver_name</seealso>
+ field of the
+ <seealso marker="driver_entry">driver_entry</seealso>).</item>
+ <tag><c>drv_data</c></tag>
+ <item>The driver defined handle that will be passed in subsequent
+ calls to driver call-backs. Note, that the
+ <seealso marker="driver_entry#start">driver start call-back</seealso>
+ will not be called for this new driver instance.
+ The driver defined handle is normally created in the
+ <seealso marker="driver_entry#start">driver start call-back</seealso>
+ when a port is created via
+ <seealso marker="erts:erlang#open_port/2">erlang:open_port/2</seealso>. </item>
+ </taglist>
+ <p>The caller of <c>driver_create_port()</c> is allowed to
+ manipulate the newly created port when <c>driver_create_port()</c>
+ has returned. When
+ <seealso marker="#smp_support">port level locking</seealso>
+ is used, the creating port is, however, only allowed to
+ manipulate the newly created port until the current driver
+ call-back that was called by the emulator returns.</p>
+ <note>
+ <p>When
+ <seealso marker="#smp_support">port level locking</seealso>
+ is used, the creating port is only allowed to manipulate
+ the newly created port until the current driver call-back
+ returns.</p>
+ </note>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_thread_create(char *name,
+ ErlDrvTid *tid,
+ void * (*func)(void *),
+ void *arg,
+ ErlDrvThreadOpts *opts)</nametext></name>
+ <fsummary>Create a thread</fsummary>
+ <desc>
+ <marker id="erl_drv_thread_create"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>A string identifying the created thread. It will be used
+ to identify the thread in planned future debug
+ functionality.
+ </item>
+ <tag><c>tid</c></tag>
+ <item>A pointer to a thread identifier variable.</item>
+ <tag><c>func</c></tag>
+ <item>A pointer to a function to execute in the created thread.</item>
+ <tag><c>arg</c></tag>
+ <item>A pointer to argument to the <c>func</c> function.</item>
+ <tag><c>opts</c></tag>
+ <item>A pointer to thread options to use or <c>NULL</c>.</item>
+ </taglist>
+ <p>This function creates a new thread. On success <c>0</c> is returned;
+ otherwise, an <c>errno</c> value is returned to indicate the error.
+ The newly created thread will begin executing in the function pointed
+ to by <c>func</c>, and <c>func</c> will be passed <c>arg</c> as
+ argument. When <c>erl_drv_thread_create()</c> returns the thread
+ identifier of the newly created thread will be available in
+ <c>*tid</c>. <c>opts</c> can be either a <c>NULL</c> pointer, or a
+ pointer to an
+ <seealso marker="#ErlDrvThreadOpts">ErlDrvThreadOpts</seealso>
+ structure. If <c>opts</c> is a <c>NULL</c> pointer, default options
+ will be used; otherwise, the passed options will be used.
+ </p>
+ <warning><p>You are not allowed to allocate the
+ <seealso marker="#ErlDrvThreadOpts">ErlDrvThreadOpts</seealso>
+ structure by yourself. It has to be allocated and
+ initialized by
+ <seealso marker="#erl_drv_thread_opts_create">erl_drv_thread_opts_create()</seealso>.
+ </p></warning>
+ <p>The created thread will terminate either when <c>func</c> returns
+ or if
+ <seealso marker="#erl_drv_thread_exit">erl_drv_thread_exit()</seealso>
+ is called by the thread. The exit value of the thread is either
+ returned from <c>func</c> or passed as argument to
+ <seealso marker="#erl_drv_thread_exit">erl_drv_thread_exit()</seealso>.
+ The driver creating the thread has the responsibility of joining the
+ thread, via
+ <seealso marker="#erl_drv_thread_join">erl_drv_thread_join()</seealso>,
+ before the driver is unloaded. It is not possible to create
+ "detached" threads, i.e., threads that don't need to be joined.
+ </p>
+ <warning><p>All created threads need to be joined by the driver before
+ it is unloaded. If the driver fails to join all threads
+ created before it is unloaded, the runtime system will
+ most likely crash when the code of the driver is unloaded.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlDrvThreadOpts *</ret><nametext>erl_drv_thread_opts_create(char *name)</nametext></name>
+ <fsummary>Create thread options</fsummary>
+ <desc>
+ <marker id="erl_drv_thread_opts_create"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>A string identifying the created thread options. It will be used
+ to identify the thread options in planned future debug
+ functionality.
+ </item>
+ </taglist>
+ <p>This function allocates and initialize a thread option
+ structure. On failure <c>NULL</c> is returned. A thread option
+ structure is used for passing options to
+ <seealso marker="#erl_drv_thread_create">erl_drv_thread_create()</seealso>.
+ If the structure isn't modified before it is passed to
+ <seealso marker="#erl_drv_thread_create">erl_drv_thread_create()</seealso>,
+ the default values will be used.
+ </p>
+ <warning><p>You are not allowed to allocate the
+ <seealso marker="#ErlDrvThreadOpts">ErlDrvThreadOpts</seealso>
+ structure by yourself. It has to be allocated and
+ initialized by <c>erl_drv_thread_opts_create()</c>.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_thread_opts_destroy(ErlDrvThreadOpts *opts)</nametext></name>
+ <fsummary>Destroy thread options</fsummary>
+ <desc>
+ <marker id="erl_drv_thread_opts_destroy"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>opts</c></tag>
+ <item>A pointer to thread options to destroy.</item>
+ </taglist>
+ <p>This function destroys thread options previously created by
+ <seealso marker="#erl_drv_thread_opts_create">erl_drv_thread_opts_create()</seealso>.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_thread_exit(void *exit_value)</nametext></name>
+ <fsummary>Terminate calling thread</fsummary>
+ <desc>
+ <marker id="erl_drv_thread_exit"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>exit_value</c></tag>
+ <item>A pointer to an exit value or <c>NULL</c>.</item>
+ </taglist>
+ <p>This function terminates the calling thread with the exit
+ value passed as argument. You are only allowed to terminate
+ threads created with
+ <seealso marker="#erl_drv_thread_create">erl_drv_thread_create()</seealso>.
+ The exit value can later be retrieved by another thread via
+ <seealso marker="#erl_drv_thread_join">erl_drv_thread_join()</seealso>.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_thread_join(ErlDrvTid tid, void **exit_value)</nametext></name>
+ <fsummary>Join with another thread</fsummary>
+ <desc>
+ <marker id="erl_drv_thread_join"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>tid</c></tag>
+ <item>The thread identifier of the thread to join.</item>
+ <tag><c>exit_value</c></tag>
+ <item>A pointer to a pointer to an exit value, or <c>NULL</c>.</item>
+ </taglist>
+ <p>This function joins the calling thread with another thread, i.e.,
+ the calling thread is blocked until the thread identified by
+ <c>tid</c> has terminated. On success <c>0</c> is returned;
+ otherwise, an <c>errno</c> value is returned to indicate the error.
+ A thread can only be joined once. The behavior of joining
+ more than once is undefined, an emulator crash is likely. If
+ <c>exit_value == NULL</c>, the exit value of the terminated thread
+ will be ignored; otherwise, the exit value of the terminated thread
+ will be stored at <c>*exit_value</c>.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlDrvTid</ret><nametext>erl_drv_thread_self(void)</nametext></name>
+ <fsummary>Get the thread identifier of the current thread</fsummary>
+ <desc>
+ <marker id="erl_drv_thread_self"></marker>
+ <p>This function returns the thread identifier of the
+ calling thread.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_equal_tids(ErlDrvTid tid1, ErlDrvTid tid2)</nametext></name>
+ <fsummary>Compare thread identifiers for equality</fsummary>
+ <desc>
+ <marker id="erl_drv_equal_tids"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>tid1</c></tag>
+ <item>A thread identifier.</item>
+ <tag><c>tid2</c></tag>
+ <item>A thread identifier.</item>
+ </taglist>
+ <p>This function compares two thread identifiers for equality,
+ and returns <c>0</c> it they aren't equal, and
+ a value not equal to <c>0</c> if they are equal.</p>
+ <note><p>A Thread identifier may be reused very quickly after
+ a thread has terminated. Therefore, if a thread
+ corresponding to one of the involved thread identifiers
+ has terminated since the thread identifier was saved,
+ the result of <c>erl_drv_equal_tids()</c> might not give
+ expected result.
+ </p></note>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlDrvMutex *</ret><nametext>erl_drv_mutex_create(char *name)</nametext></name>
+ <fsummary>Create a mutex</fsummary>
+ <desc>
+ <marker id="erl_drv_mutex_create"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>A string identifying the created mutex. It will be used
+ to identify the mutex in planned future debug functionality.
+ </item>
+ </taglist>
+ <p>This function creates a mutex and returns a pointer to it. On
+ failure <c>NULL</c> is returned. The driver creating the mutex
+ has the responsibility of destroying it before the driver is
+ unloaded.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_mutex_destroy(ErlDrvMutex *mtx)</nametext></name>
+ <fsummary>Destroy a mutex</fsummary>
+ <desc>
+ <marker id="erl_drv_mutex_destroy"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>mtx</c></tag>
+ <item>A pointer to a mutex to destroy.</item>
+ </taglist>
+ <p>This function destroys a mutex previously created by
+ <seealso marker="#erl_drv_mutex_create">erl_drv_mutex_create()</seealso>.
+ The mutex has to be in an unlocked state before being
+ destroyed.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_mutex_lock(ErlDrvMutex *mtx)</nametext></name>
+ <fsummary>Lock a mutex</fsummary>
+ <desc>
+ <marker id="erl_drv_mutex_lock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>mtx</c></tag>
+ <item>A pointer to a mutex to lock.</item>
+ </taglist>
+ <p>This function locks a mutex. The calling thread will be
+ blocked until the mutex has been locked. A thread
+ which currently has locked the mutex may <em>not</em> lock
+ the same mutex again.
+ </p>
+ <warning><p>If you leave a mutex locked in an emulator thread
+ when you let the thread out of your control, you will
+ <em>very likely</em> deadlock the whole emulator.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_mutex_trylock(ErlDrvMutex *mtx)</nametext></name>
+ <fsummary>Try lock a mutex</fsummary>
+ <desc>
+ <marker id="erl_drv_mutex_trylock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>mtx</c></tag>
+ <item>A pointer to a mutex to try to lock.</item>
+ </taglist>
+ <p>This function tries to lock a mutex. If successful <c>0</c>,
+ is returned; otherwise, <c>EBUSY</c> is returned. A thread
+ which currently has locked the mutex may <em>not</em> try to
+ lock the same mutex again.
+ </p>
+ <warning><p>If you leave a mutex locked in an emulator thread
+ when you let the thread out of your control, you will
+ <em>very likely</em> deadlock the whole emulator.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_mutex_unlock(ErlDrvMutex *mtx)</nametext></name>
+ <fsummary>Unlock a mutex</fsummary>
+ <desc>
+ <marker id="erl_drv_mutex_unlock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>mtx</c></tag>
+ <item>A pointer to a mutex to unlock.</item>
+ </taglist>
+ <p>This function unlocks a mutex. The mutex currently has to be
+ locked by the calling thread.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlDrvCond *</ret><nametext>erl_drv_cond_create(char *name)</nametext></name>
+ <fsummary>Create a condition variable</fsummary>
+ <desc>
+ <marker id="erl_drv_cond_create"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>A string identifying the created condition variable. It
+ will be used to identify the condition variable in planned
+ future debug functionality.
+ </item>
+ </taglist>
+ <p>This function creates a condition variable and returns a
+ pointer to it. On failure <c>NULL</c> is returned. The driver
+ creating the condition variable has the responsibility of
+ destroying it before the driver is unloaded.</p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_cond_destroy(ErlDrvCond *cnd)</nametext></name>
+ <fsummary>Destroy a condition variable</fsummary>
+ <desc>
+ <marker id="erl_drv_cond_destroy"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>cnd</c></tag>
+ <item>A pointer to a condition variable to destroy.</item>
+ </taglist>
+ <p>This function destroys a condition variable previously
+ created by
+ <seealso marker="#erl_drv_cond_create">erl_drv_cond_create()</seealso>.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_cond_signal(ErlDrvCond *cnd)</nametext></name>
+ <fsummary>Signal on a condition variable</fsummary>
+ <desc>
+ <marker id="erl_drv_cond_signal"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>cnd</c></tag>
+ <item>A pointer to a condition variable to signal on.</item>
+ </taglist>
+ <p>This function signals on a condition variable. That is, if
+ other threads are waiting on the condition variable being
+ signaled, <em>one</em> of them will be woken.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_cond_broadcast(ErlDrvCond *cnd)</nametext></name>
+ <fsummary>Broadcast on a condition variable</fsummary>
+ <desc>
+ <marker id="erl_drv_cond_broadcast"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>cnd</c></tag>
+ <item>A pointer to a condition variable to broadcast on.</item>
+ </taglist>
+ <p>This function broadcasts on a condition variable. That is, if
+ other threads are waiting on the condition variable being
+ broadcasted on, <em>all</em> of them will be woken.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_cond_wait(ErlDrvCond *cnd, ErlDrvMutex *mtx)</nametext></name>
+ <fsummary>Wait on a condition variable</fsummary>
+ <desc>
+ <marker id="erl_drv_cond_wait"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>cnd</c></tag>
+ <item>A pointer to a condition variable to wait on.</item>
+ <tag><c>mtx</c></tag>
+ <item>A pointer to a mutex to unlock while waiting.</item>
+ <tag><c></c></tag>
+ <item></item>
+ </taglist>
+ <p>This function waits on a condition variable. The calling
+ thread is blocked until another thread wakes it by signaling
+ or broadcasting on the condition variable. Before the calling
+ thread is blocked it unlocks the mutex passed as argument, and
+ when the calling thread is woken it locks the same mutex before
+ returning. That is, the mutex currently has to be locked by
+ the calling thread when calling this function.
+ </p>
+ <note><p><c>erl_drv_cond_wait()</c> might return even though
+ no-one has signaled or broadcasted on the condition
+ variable. Code calling <c>erl_drv_cond_wait()</c> should
+ always be prepared for <c>erl_drv_cond_wait()</c>
+ returning even though the condition that the thread was
+ waiting for hasn't occurred. That is, when returning from
+ <c>erl_drv_cond_wait()</c> always check if the condition
+ has occurred, and if not call <c>erl_drv_cond_wait()</c>
+ again.
+ </p></note>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>ErlDrvRWLock *</ret><nametext>erl_drv_rwlock_create(char *name)</nametext></name>
+ <fsummary>Create an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_create"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>A string identifying the created rwlock. It will be used to
+ identify the rwlock in planned future debug functionality.
+ </item>
+ </taglist>
+ <p>This function creates an rwlock and returns a pointer to it. On
+ failure <c>NULL</c> is returned. The driver creating the rwlock
+ has the responsibility of destroying it before the driver is
+ unloaded.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_rwlock_destroy(ErlDrvRWLock *rwlck)</nametext></name>
+ <fsummary>Destroy an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_destroy"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>rwlck</c></tag>
+ <item>A pointer to an rwlock to destroy.</item>
+ </taglist>
+ <p>This function destroys an rwlock previously created by
+ <seealso marker="#erl_drv_rwlock_create">erl_drv_rwlock_create()</seealso>.
+ The rwlock has to be in an unlocked state before being destroyed.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_rwlock_rlock(ErlDrvRWLock *rwlck)</nametext></name>
+ <fsummary>Read lock an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_rlock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>rwlck</c></tag>
+ <item>A pointer to an rwlock to read lock.</item>
+ </taglist>
+ <p>This function read locks an rwlock. The calling thread will be
+ blocked until the rwlock has been read locked. A thread
+ which currently has read or read/write locked the rwlock may
+ <em>not</em> lock the same rwlock again.
+ </p>
+ <warning><p>If you leave an rwlock locked in an emulator thread
+ when you let the thread out of your control, you will
+ <em>very likely</em> deadlock the whole emulator.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_rwlock_tryrlock(ErlDrvRWLock *rwlck)</nametext></name>
+ <fsummary>Try to read lock an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_tryrlock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>rwlck</c></tag>
+ <item>A pointer to an rwlock to try to read lock.</item>
+ </taglist>
+ <p>This function tries to read lock an rwlock. If successful
+ <c>0</c>, is returned; otherwise, <c>EBUSY</c> is returned.
+ A thread which currently has read or read/write locked the
+ rwlock may <em>not</em> try to lock the same rwlock again.
+ </p>
+ <warning><p>If you leave an rwlock locked in an emulator thread
+ when you let the thread out of your control, you will
+ <em>very likely</em> deadlock the whole emulator.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_rwlock_runlock(ErlDrvRWLock *rwlck)</nametext></name>
+ <fsummary>Read unlock an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_runlock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>rwlck</c></tag>
+ <item>A pointer to an rwlock to read unlock.</item>
+ </taglist>
+ <p>This function read unlocks an rwlock. The rwlock currently
+ has to be read locked by the calling thread.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_rwlock_rwlock(ErlDrvRWLock *rwlck)</nametext></name>
+ <fsummary>Read/Write lock an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_rwlock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>rwlck</c></tag>
+ <item>A pointer to an rwlock to read/write lock.</item>
+ </taglist>
+ <p>This function read/write locks an rwlock. The calling thread
+ will be blocked until the rwlock has been read/write locked.
+ A thread which currently has read or read/write locked the
+ rwlock may <em>not</em> lock the same rwlock again.
+ </p>
+ <warning><p>If you leave an rwlock locked in an emulator thread
+ when you let the thread out of your control, you will
+ <em>very likely</em> deadlock the whole emulator.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_rwlock_tryrwlock(ErlDrvRWLock *rwlck)</nametext></name>
+ <fsummary>Try to read/write lock an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_tryrwlock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>rwlck</c></tag>
+ <item>A pointer to an rwlock to try to read/write lock.</item>
+ </taglist>
+ <p>This function tries to read/write lock an rwlock. If successful
+ <c>0</c>, is returned; otherwise, <c>EBUSY</c> is returned.
+ A thread which currently has read or read/write locked the
+ rwlock may <em>not</em> try to lock the same rwlock again.
+ </p>
+ <warning><p>If you leave an rwlock locked in an emulator thread
+ when you let the thread out of your control, you will
+ <em>very likely</em> deadlock the whole emulator.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_rwlock_rwunlock(ErlDrvRWLock *rwlck)</nametext></name>
+ <fsummary>Read/Write unlock an rwlock</fsummary>
+ <desc>
+ <marker id="erl_drv_rwlock_rwunlock"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>rwlck</c></tag>
+ <item>A pointer to an rwlock to read/write unlock.</item>
+ </taglist>
+ <p>This function read/write unlocks an rwlock. The rwlock
+ currently has to be read/write locked by the calling thread.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_tsd_key_create(char *name, ErlDrvTSDKey *key)</nametext></name>
+ <fsummary>Create a thread specific data key</fsummary>
+ <desc>
+ <marker id="erl_drv_tsd_key_create"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>A string identifying the created key. It will be used
+ to identify the key in planned future debug
+ functionality.
+ </item>
+ <tag><c>key</c></tag>
+ <item>A pointer to a thread specific data key variable.</item>
+ </taglist>
+ <p>This function creates a thread specific data key. On success
+ <c>0</c> is returned; otherwise, an <c>errno</c> value is returned
+ to indicate the error. The driver creating the key has the
+ responsibility of destroying it before the driver is unloaded.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_tsd_key_destroy(ErlDrvTSDKey key)</nametext></name>
+ <fsummary>Destroy a thread specific data key</fsummary>
+ <desc>
+ <marker id="erl_drv_tsd_key_destroy"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>key</c></tag>
+ <item>A thread specific data key to destroy.</item>
+ </taglist>
+ <p>This function destroys a thread specific data key
+ previously created by
+ <seealso marker="#erl_drv_tsd_key_create">erl_drv_tsd_key_create()</seealso>.
+ All thread specific data using this key in all threads
+ have to be cleared (see
+ <seealso marker="#erl_drv_tsd_set">erl_drv_tsd_set()</seealso>)
+ prior to the call to <c>erl_drv_tsd_key_destroy()</c>.
+ </p>
+ <warning><p>A destroyed key is very likely to be reused soon.
+ Therefore, if you fail to clear the thread specific
+ data using this key in a thread prior to destroying
+ the key, you will <em>very likely</em> get unexpected
+ errors in other parts of the system.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void</ret><nametext>erl_drv_tsd_set(ErlDrvTSDKey key, void *data)</nametext></name>
+ <fsummary>Set thread specific data</fsummary>
+ <desc>
+ <marker id="erl_drv_tsd_set"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>key</c></tag>
+ <item>A thread specific data key.</item>
+ <tag><c>data</c></tag>
+ <item>A pointer to data to associate with <c>key</c>
+ in calling thread.
+ </item>
+ </taglist>
+ <p>This function sets thread specific data associated with
+ <c>key</c> for the calling thread. You are only allowed to set
+ thread specific data for threads while they are fully under your
+ control. For example, if you set thread specific data in a thread
+ calling a driver call-back function, it has to be cleared, i.e.
+ set to <c>NULL</c>, before returning from the driver call-back
+ function.
+ </p>
+ <warning><p>If you fail to clear thread specific data in an
+ emulator thread before letting it out of your control,
+ you might not ever be able to clear this data with
+ later unexpected errors in other parts of the system as
+ a result.
+ </p></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>void *</ret><nametext>erl_drv_tsd_get(ErlDrvTSDKey key)</nametext></name>
+ <fsummary>Get thread specific data</fsummary>
+ <desc>
+ <marker id="erl_drv_tsd_get"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>key</c></tag>
+ <item>A thread specific data key.</item>
+ </taglist>
+ <p>This function returns the thread specific data
+ associated with <c>key</c> for the calling thread.
+ If no data has been associated with <c>key</c> for
+ the calling thread, <c>NULL</c> is returned.
+ </p>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_putenv(char *key, char *value)</nametext></name>
+ <fsummary>Set the value of an environment variable</fsummary>
+ <desc>
+ <marker id="erl_drv_putenv"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>key</c></tag>
+ <item>A null terminated string containing the
+ name of the environment variable.</item>
+ <tag><c>value</c></tag>
+ <item>A null terminated string containing the
+ new value of the environment variable.</item>
+ </taglist>
+ <p>This function sets the value of an environment variable.
+ It returns <c>0</c> on success, and a value <c>!= 0</c> on
+ failure.
+ </p>
+ <note><p>The result of passing the empty string ("") as a value
+ is platform dependent. On some platforms the value of the
+ variable is set to the empty string, on others, the
+ 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></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name><ret>int</ret><nametext>erl_drv_getenv(char *key, char *value, size_t *value_size)</nametext></name>
+ <fsummary>Get the value of an environment variable</fsummary>
+ <desc>
+ <marker id="erl_drv_getenv"></marker>
+ <p>Arguments:</p>
+ <taglist>
+ <tag><c>key</c></tag>
+ <item>A null terminated string containing the
+ name of the environment variable.</item>
+ <tag><c>value</c></tag>
+ <item>A pointer to an output buffer.</item>
+ <tag><c>value_size</c></tag>
+ <item>A pointer to an integer. The integer is both used for
+ passing input and output sizes (see below).
+ </item>
+ </taglist>
+ <p>This function retrieves the value of an environment variable.
+ When called, <c>*value_size</c> should contain the size of
+ the <c>value</c> buffer. On success <c>0</c> is returned,
+ the value of the environment variable has been written to
+ the <c>value</c> buffer, and <c>*value_size</c> contains the
+ string length (excluding the terminating null character) of
+ the value written to the <c>value</c> buffer. On failure,
+ i.e., no such environment variable was found, a value less than
+ <c>0</c> is returned. When the size of the <c>value</c>
+ buffer is too small, a value greater than <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></warning>
+ <p>This function is thread-safe.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="driver_entry">driver_entry(3)</seealso>,
+ <seealso marker="kernel:erl_ddll">erl_ddll(3)</seealso>,
+ <seealso marker="erts:erlang">erlang(3)</seealso></p>
+ <p>An Alternative Distribution Driver (ERTS User's
+ Guide Ch. 3)</p>
+ </section>
+</cref>
+
diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml
new file mode 100644
index 0000000000..c2d58d1ef1
--- /dev/null
+++ b/erts/doc/src/erl_ext_dist.xml
@@ -0,0 +1,1014 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2007</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>External Term Format</title>
+ <prepared>Kenneth</prepared>
+ <docno></docno>
+ <date>2007-09-21</date>
+ <rev>PA1</rev>
+ <file>erl_ext_dist.xml</file>
+ </header>
+
+ <section>
+ <title>Introduction</title>
+ <p>
+ The external term format is mainly used in the distribution
+ mechanism of Erlang.
+ </p>
+ <p>
+ Since Erlang has a fixed number of types, there is no need for a
+ programmer to define a specification for the external format used
+ within some application.
+ All Erlang terms has an external representation and the interpretation
+ of the different terms are application specific.
+ </p>
+ <p>
+ In Erlang the BIF <seealso marker="erts:erlang#term_to_binary/1">term_to_binary/1,2</seealso> is used to convert a
+ term into the external format.
+ To convert binary data encoding a term the BIF
+ <seealso marker="erts:erlang#binary_to_term/1">
+ binary_to_term/1
+ </seealso>
+ is used.
+ </p>
+ <p>
+ The distribution does this implicitly when sending messages across
+ node boundaries.
+ </p>
+ <marker id="overall_format"/>
+ <p>
+ The overall format of the term format is:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">N</cell>
+ </row>
+ <row>
+ <cell align="center"><c>131</c></cell>
+ <cell align="center"><c>Tag</c></cell>
+ <cell align="center"><c>Data</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <note>
+ <p>
+ When messages are
+ <seealso marker="erl_dist_protocol#connected_nodes">passed between
+ connected nodes</seealso> and a
+ <seealso marker="#distribution_header">distribution
+ header</seealso> is used, the first byte containing the version
+ number (131) is omitted from the terms that follow the distribution
+ header. This since
+ the version number is implied by the version number in the
+ distribution header.
+ </p>
+ </note>
+ <p>
+ A compressed term looks like this:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">N</cell>
+ </row>
+ <row>
+ <cell align="center">131</cell>
+ <cell align="center">80</cell>
+ <cell align="center">UncompressedSize</cell>
+ <cell align="center">Zlib-compressedData</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Uncompressed Size (unsigned 32 bit integer in big-endian byte order)
+ is the size of the data before it was compressed.
+ The compressed data has the following format when it has been
+ expanded:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">Uncompressed Size</cell>
+ </row>
+ <row>
+ <cell align="center">Tag</cell>
+ <cell align="center">Data</cell>
+ </row>
+ <tcaption></tcaption></table>
+ </section>
+
+ <section>
+ <marker id="distribution_header"/>
+ <title>Distribution header</title>
+ <p>
+ As of erts version 5.7.2 the old atom cache protocol was
+ dropped and a new one was introduced. This atom cache protocol
+ introduced the distribution header. Nodes with erts versions
+ earlier than 5.7.2 can still communicate with new nodes,
+ but no distribution header and no atom cache will be used.</p>
+ <p>
+ The distribution header currently only contains an atom cache
+ reference section, but could in the future contain more
+ information. The distribution header precedes one or more Erlang
+ terms on the external format. For more information see the
+ documentation of the
+ <seealso marker="erl_dist_protocol#connected_nodes">protocol between
+ connected nodes</seealso> in the
+ <seealso marker="erl_dist_protocol">distribution protocol</seealso>
+ documentation.
+ </p>
+ <p>
+ <seealso marker="#ATOM_CACHE_REF">ATOM_CACHE_REF</seealso>
+ entries with corresponding <c>AtomCacheReferenceIndex</c> in terms
+ encoded on the external format following a distribution header refers
+ to the atom cache references made in the distribution header. The range
+ is 0 &lt;= <c>AtomCacheReferenceIndex</c> &lt; 255, i.e., at most 255
+ different atom cache references from the following terms can be made.
+ </p>
+ <p>
+ The distribution header format is:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">NumberOfAtomCacheRefs/2+1 | 0</cell>
+ <cell align="center">N | 0</cell>
+ </row>
+ <row>
+ <cell align="center"><c>131</c></cell>
+ <cell align="center"><c>68</c></cell>
+ <cell align="center"><c>NumberOfAtomCacheRefs</c></cell>
+ <cell align="center"><c>Flags</c></cell>
+ <cell align="center"><c>AtomCacheRefs</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ <c>Flags</c> consists of <c>NumberOfAtomCacheRefs/2+1</c> bytes,
+ unless <c>NumberOfAtomCacheRefs</c> is <c>0</c>. If
+ <c>NumberOfAtomCacheRefs</c> is <c>0</c>, <c>Flags</c> and
+ <c>AtomCacheRefs</c> are omitted. Each atom cache reference have
+ a half byte flag field. Flags corresponding to a specific
+ <c>AtomCacheReferenceIndex</c>, are located in flag byte number
+ <c>AtomCacheReferenceIndex/2</c>. Flag byte 0 is the first byte
+ after the <c>NumberOfAtomCacheRefs</c> byte. Flags for an even
+ <c>AtomCacheReferenceIndex</c> are located in the least significant
+ half byte and flags for an odd <c>AtomCacheReferenceIndex</c> are
+ located in the most significant half byte.
+ </p>
+ <p>
+ The flag field of an atom cache reference has the following
+ format:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1 bit</cell>
+ <cell align="center">3 bits</cell>
+ </row>
+ <row>
+ <cell align="center"><c>NewCacheEntryFlag</c></cell>
+ <cell align="center"><c>SegmentIndex</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ The most significant bit is the <c>NewCacheEntryFlag</c>. If set,
+ the corresponding cache reference is new. The three least
+ significant bits are the <c>SegmentIndex</c> of the corresponding
+ atom cache entry. An atom cache consists of 8 segments each of size
+ 256, i.e., an atom cache can contain 2048 entries.
+ </p>
+ <p>
+ After flag fields for atom cache references, another half byte flag
+ field is located which has the following format:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">3 bits</cell>
+ <cell align="center">1 bit</cell>
+ </row>
+ <row>
+ <cell align="center"><c>CurrentlyUnused</c></cell>
+ <cell align="center"><c>LongAtoms</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ The least significant bit in that half byte is the <c>LongAtoms</c>
+ flag. If it is set, 2 bytes are used for atom lengths instead of
+ 1 byte in the distribution header. However, the current emulator
+ cannot handle long atoms, so it will currently always be 0.
+ </p>
+ <p>
+ After the <c>Flags</c> field follow the <c>AtomCacheRefs</c>. The
+ first <c>AtomCacheRef</c> is the one corresponding to
+ <c>AtomCacheReferenceIndex</c> 0. Higher indices follows
+ in sequence up to index <c>NumberOfAtomCacheRefs - 1</c>.
+ </p>
+ <p>
+ If the <c>NewCacheEntryFlag</c> for the next <c>AtomCacheRef</c> has
+ been set, a <c>NewAtomCacheRef</c> on the following format will follow:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1 | 2</cell>
+ <cell align="center">Length</cell>
+ </row>
+ <row>
+ <cell align="center"><c>InternalSegmentIndex</c></cell>
+ <cell align="center"><c>Length</c></cell>
+ <cell align="center"><c>AtomText</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ <c>InternalSegmentIndex</c> together with the <c>SegmentIndex</c>
+ completely identify the location of an atom cache entry in the
+ atom cache. <c>Length</c> is number of one byte characters that
+ the atom text consists of. Length is a two byte big endian integer
+ if the <c>LongAtoms</c> flag has been set, otherwise a one byte
+ integer. Subsequent <c>CachedAtomRef</c>s with the same
+ <c>SegmentIndex</c> and <c>InternalSegmentIndex</c> as this
+ <c>NewAtomCacheRef</c> will refer to this atom until a new
+ <c>NewAtomCacheRef</c> with the same <c>SegmentIndex</c>
+ and <c>InternalSegmentIndex</c> appear.
+ </p>
+ <p>
+ If the <c>NewCacheEntryFlag</c> for the next <c>AtomCacheRef</c>
+ has not been set, a <c>CachedAtomRef</c> on the following format
+ will follow:
+ </p>
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center"><c>InternalSegmentIndex</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ <c>InternalSegmentIndex</c> together with the <c>SegmentIndex</c>
+ identify the location of the atom cache entry in the atom cache.
+ The atom corresponding to this <c>CachedAtomRef</c> is the
+ latest <c>NewAtomCacheRef</c> preceding this <c>CachedAtomRef</c>
+ in another previously passed distribution header.
+ </p>
+ </section>
+
+ <section>
+ <marker id="ATOM_CACHE_REF"/>
+ <title>ATOM_CACHE_REF</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center"><c>82</c></cell>
+ <cell align="center"><c>AtomCacheReferenceIndex</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Refers to the atom with <c>AtomCacheReferenceIndex</c> in the
+ <seealso marker="#distribution_header">distribution header</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <marker id="SMALL_INTEGER_EXT"/>
+ <title>SMALL_INTEGER_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center">97</cell>
+ <cell align="center">Int</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Unsigned 8 bit integer.
+ </p>
+ </section>
+
+ <section>
+ <marker id="INTEGER_EXT"/>
+ <title>INTEGER_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ </row>
+ <row>
+ <cell align="center">98</cell>
+ <cell align="center">Int</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Signed 32 bit integer in big-endian format (i.e. MSB first)
+ </p>
+ </section>
+
+ <section>
+ <marker id="FLOAT_EXT"/>
+ <title>FLOAT_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">31</cell>
+ </row>
+ <row>
+ <cell align="center">99</cell>
+ <cell align="center">Float String</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ A float is stored in string format. the format used in sprintf to
+ format the float is "%.20e"
+ (there are more bytes allocated than necessary).
+ To unpack the float use sscanf with format "%lf".
+ </p>
+ <p>
+ This term is used in minor version 0 of the external format;
+ it has been superseded by
+ <seealso marker="#NEW_FLOAT_EXT">
+ NEW_FLOAT_EXT
+ </seealso>.
+ </p>
+ </section>
+
+ <section>
+ <marker id="ATOM_EXT"/>
+ <title>ATOM_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">Len</cell>
+ </row>
+ <row>
+ <cell align="center"><c>100</c></cell>
+ <cell align="center"><c>Len</c></cell>
+ <cell align="center"><c>AtomName</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ An atom is stored with a 2 byte unsigned length in big-endian order,
+ followed by <c>Len</c> numbers of 8 bit characters that forms the
+ <c>AtomName</c>.
+ Note: The maximum allowed value for <c>Len</c> is 255.
+ </p>
+ </section>
+
+ <section>
+ <marker id="REFERENCE_EXT"/>
+ <title>REFERENCE_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">N</cell>
+ <cell align="center">4</cell>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center"><c>101</c></cell>
+ <cell align="center"><c>Node</c></cell>
+ <cell align="center"><c>ID</c></cell>
+ <cell align="center"><c>Creation</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Encode a reference object (an object generated with <c>make_ref/0</c>).
+ The <c>Node</c> term is an encoded atom, i.e.
+ <seealso marker="#ATOM_EXT">ATOM_EXT</seealso>,
+ <seealso marker="#SMALL_ATOM_EXT">SMALL_ATOM_EXT</seealso> or
+ <seealso marker="#ATOM_CACHE_REF">ATOM_CACHE_REF</seealso>.
+ The <c>ID</c> field contains a big-endian
+ unsigned integer,
+ but <em>should be regarded as uninterpreted data</em>
+ since this field is node specific.
+ <c>Creation</c> is a byte containing a node serial number that
+ makes it possible to separate old (crashed) nodes from a new one.
+ </p>
+ <p>
+ In <c>ID</c>, only 18 bits are significant; the rest should be 0.
+ In <c>Creation</c>, only 2 bits are significant; the rest should be 0.
+
+ See <seealso marker="#NEW_REFERENCE_EXT">NEW_REFERENCE_EXT</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <marker id="PORT_EXT"/>
+ <title>PORT_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">N</cell>
+ <cell align="center">4</cell>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center"><c>102</c></cell>
+ <cell align="center"><c>Node</c></cell>
+ <cell align="center"><c>ID</c></cell>
+ <cell align="center"><c>Creation</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Encode a port object (obtained form <c>open_port/2</c>).
+ The <c>ID</c> is a node specific identifier for a local port.
+ Port operations are not allowed across node boundaries.
+ The <c>Creation</c> works just like in
+ <seealso marker="#REFERENCE_EXT">REFERENCE_EXT</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <marker id="PID_EXT"/>
+ <title>PID_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">N</cell>
+ <cell align="center">4</cell>
+ <cell align="center">4</cell>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center"><c>103</c></cell>
+ <cell align="center"><c>Node</c></cell>
+ <cell align="center"><c>ID</c></cell>
+ <cell align="center"><c>Serial</c></cell>
+ <cell align="center"><c>Creation</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Encode a process identifier object (obtained from <c>spawn/3</c> or
+ friends).
+ The <c>ID</c> and <c>Creation</c> fields works just like in
+ <seealso marker="#REFERENCE_EXT">REFERENCE_EXT</seealso>, while
+ the <c>Serial</c> field is used to improve safety.
+
+ In <c>ID</c>, only 15 bits are significant; the rest should be 0.
+ </p>
+
+ </section>
+
+ <section>
+ <marker id="SMALL_TUPLE_EXT"/>
+ <title>SMALL_TUPLE_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">N</cell>
+ </row>
+ <row>
+ <cell align="center">104</cell>
+ <cell align="center">Arity</cell>
+ <cell align="center">Elements</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ <c>SMALL_TUPLE_EXT</c> encodes a tuple. The <c>Arity</c>
+ field is an unsigned byte that determines how many element
+ that follows in the <c>Elements</c> section.
+ </p>
+ </section>
+
+ <section>
+ <marker id="LARGE_TUPLE_EXT"/>
+ <title>LARGE_TUPLE_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">N</cell>
+ </row>
+ <row>
+ <cell align="center">105</cell>
+ <cell align="center">Arity</cell>
+ <cell align="center">Elements</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Same as
+ <seealso marker="#SMALL_TUPLE_EXT">SMALL_TUPLE_EXT</seealso>
+ with the exception that <c>Arity</c> is an
+ unsigned 4 byte integer in big endian format.
+ </p>
+ </section>
+
+ <section>
+ <marker id="NIL_EXT"/>
+ <title>NIL_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ </row>
+ <row>
+ <cell align="center">106</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ The representation for an empty list, i.e. the Erlang syntax <c>[]</c>.
+ </p>
+ </section>
+
+ <section>
+ <marker id="STRING_EXT"/>
+ <title>STRING_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">Len</cell>
+ </row>
+ <row>
+ <cell align="center">107</cell>
+ <cell align="center">Length</cell>
+ <cell align="center">Characters</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ String does NOT have a corresponding Erlang representation,
+ but is an optimization for sending lists of bytes (integer in
+ the range 0-255) more efficiently over the distribution.
+ Since the <c>Length</c> field is an unsigned 2 byte integer
+ (big endian), implementations must make sure that lists longer than
+ 65535 elements are encoded as
+ <seealso marker="#LIST_EXT">LIST_EXT</seealso>.
+ </p>
+
+ </section>
+
+ <section>
+ <marker id="LIST_EXT"/>
+ <title>LIST_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">&nbsp;</cell>
+ <cell align="center">&nbsp;</cell>
+ </row>
+ <row>
+ <cell align="center">108</cell>
+ <cell align="center">Length</cell>
+ <cell align="center">Elements</cell>
+ <cell align="center">Tail</cell>
+ </row>
+ <tcaption></tcaption></table>
+
+ <p>
+ <c>Length</c> is the number of elements that follows in the
+ <c>Elements</c> section. <c>Tail</c> is the final tail of
+ the list; it is
+ <seealso marker="#NIL_EXT">NIL_EXT</seealso>
+ for a proper list, but may be anything type if the list is
+ improper (for instance <c>[a|b]</c>).
+ </p>
+ </section>
+
+ <section>
+ <marker id="BINARY_EXT"/>
+ <title>BINARY_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">Len</cell>
+ </row>
+ <row>
+ <cell align="center">109</cell>
+ <cell align="center">Len</cell>
+ <cell align="center">Data</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Binaries are generated with bit syntax expression or with
+ <seealso marker="erts:erlang#list_to_binary/1">list_to_binary/1</seealso>,
+ <seealso marker="erts:erlang#term_to_binary/1">term_to_binary/1</seealso>,
+ or as input from binary ports.
+ The <c>Len</c> length field is an unsigned 4 byte integer
+ (big endian).
+ </p>
+ </section>
+
+ <section>
+ <marker id="SMALL_BIG_EXT"/>
+ <title>SMALL_BIG_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">n</cell>
+ </row>
+ <row>
+ <cell align="center">110</cell>
+ <cell align="center">n</cell>
+ <cell align="center">Sign</cell>
+ <cell align="center">d(0) ... d(n-1)</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Bignums are stored in unary form with a <c>Sign</c> byte
+ that is 0 if the binum is positive and 1 if is negative. The
+ digits are stored with the LSB byte stored first. To
+ calculate the integer the following formula can be used:<br/>
+
+ B = 256<br/>
+ (d0*B^0 + d1*B^1 + d2*B^2 + ... d(N-1)*B^(n-1))
+ </p>
+ </section>
+
+ <section>
+ <marker id="LARGE_BIG_EXT"/>
+ <title>LARGE_BIG_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">1</cell>
+ <cell align="center">n</cell>
+ </row>
+ <row>
+ <cell align="center">111</cell>
+ <cell align="center">n</cell>
+ <cell align="center">Sign</cell>
+ <cell align="center">d(0) ... d(n-1)</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Same as <seealso marker="#SMALL_BIG_EXT">SMALL_BIG_EXT</seealso>
+ with the difference that the length field
+ is an unsigned 4 byte integer.
+ </p>
+
+ </section>
+
+ <section>
+ <marker id="NEW_REFERENCE_EXT"/>
+ <title>NEW_REFERENCE_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">2</cell>
+ <cell align="center">N</cell>
+ <cell align="center">1</cell>
+ <cell align="center">N'</cell>
+ </row>
+ <row>
+ <cell align="center">114</cell>
+ <cell align="center">Len</cell>
+ <cell align="center">Node</cell>
+ <cell align="center">Creation</cell>
+ <cell align="center">ID ...</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ Node and Creation are as in
+ <seealso marker="#REFERENCE_EXT">REFERENCE_EXT</seealso>.
+ </p>
+ <p>
+ <c>ID</c> contains a sequence of big-endian unsigned integers
+ (4 bytes each, so <c>N'</c> is a multiple of 4),
+ but should be regarded as uninterpreted data.
+ </p>
+ <p>
+ <c>N'</c> = 4 * <c>Len</c>.
+ </p>
+ <p>
+ In the first word (four bytes) of <c>ID</c>, only 18 bits are
+ significant, the rest should be 0.
+ In <c>Creation</c>, only 2 bits are significant,
+ the rest should be 0.
+ </p>
+ <p>
+ NEW_REFERENCE_EXT was introduced with distribution version 4.
+ In version 4, <c>N'</c> should be at most 12.
+ </p>
+ <p>
+ See <seealso marker="#REFERENCE_EXT">REFERENCE_EXT</seealso>).
+ </p>
+ </section>
+
+ <section>
+ <marker id="SMALL_ATOM_EXT"/>
+ <title>SMALL_ATOM_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">1</cell>
+ <cell align="center">Len</cell>
+ </row>
+ <row>
+ <cell align="center"><c>115</c></cell>
+ <cell align="center"><c>Len</c></cell>
+ <cell align="center"><c>AtomName</c></cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ An atom is stored with a 1 byte unsigned length,
+ followed by <c>Len</c> numbers of 8 bit characters that
+ forms the <c>AtomName</c>. Longer atoms can be represented
+ by <seealso marker="#ATOM_EXT">ATOM_EXT</seealso>. <em>Note</em>
+ the <c>SMALL_ATOM_EXT</c> was introduced in erts version 5.7.2 and
+ require a small atom distribution flag exchanged in the distribution
+ handshake.
+ </p>
+ </section>
+
+ <section>
+ <marker id="FUN_EXT"/>
+ <title>FUN_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">N1</cell>
+ <cell align="center">N2</cell>
+ <cell align="center">N3</cell>
+ <cell align="center">N4</cell>
+ <cell align="center">N5</cell>
+ </row>
+ <row>
+ <cell align="center">117</cell>
+ <cell align="center">NumFree</cell>
+ <cell align="center">Pid</cell>
+ <cell align="center">Module</cell>
+ <cell align="center">Index</cell>
+ <cell align="center">Uniq</cell>
+ <cell align="center">Free vars ...</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <taglist>
+ <tag><c>Pid</c></tag>
+ <item>
+ is a process identifier as in
+ <seealso marker="#PID_EXT">PID_EXT</seealso>.
+ It represents the process in which the fun was created.
+ </item>
+ <tag><c>Module</c></tag>
+ <item>
+ is an encoded as an atom, using
+ <seealso marker="#ATOM_EXT">ATOM_EXT</seealso>,
+ <seealso marker="#SMALL_ATOM_EXT">SMALL_ATOM_EXT</seealso>
+ or <seealso marker="#ATOM_CACHE_REF">ATOM_CACHE_REF</seealso>.
+ This is the module that the fun is implemented in.
+ </item>
+ <tag><c>Index</c></tag>
+ <item>
+ is an integer encoded using
+ <seealso marker="#SMALL_INTEGER_EXT">SMALL_INTEGER_EXT</seealso>
+ or <seealso marker="#INTEGER_EXT">INTEGER_EXT</seealso>.
+ It is typically a small index into the module's fun table.
+ </item>
+ <tag><c>Uniq</c></tag>
+ <item>
+ is an integer encoded using
+ <seealso marker="#SMALL_INTEGER_EXT">SMALL_INTEGER_EXT</seealso> or
+ <seealso marker="#INTEGER_EXT">INTEGER_EXT</seealso>.
+ <c>Uniq</c> is the hash value of the parse for the fun.
+ </item>
+ <tag><c>Free vars</c></tag>
+ <item>
+ is <c>NumFree</c> number of terms, each one encoded according
+ to its type.
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="NEW_FUN_EXT"/>
+ <title>NEW_FUN_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">1</cell>
+ <cell align="center">16</cell>
+ <cell align="center">4</cell>
+ <cell align="center">4</cell>
+ <cell align="center">N1</cell>
+ <cell align="center">N2</cell>
+ <cell align="center">N3</cell>
+ <cell align="center">N4</cell>
+ <cell align="center">N5</cell>
+ </row>
+ <row>
+ <cell align="center">112</cell>
+ <cell align="center">Size</cell>
+ <cell align="center">Arity</cell>
+ <cell align="center">Uniq</cell>
+ <cell align="center">Index</cell>
+ <cell align="center">NumFree</cell>
+ <cell align="center">Module</cell>
+ <cell align="center">OldIndex</cell>
+ <cell align="center">OldUniq</cell>
+ <cell align="center">Pid</cell>
+ <cell align="center">Free Vars</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ This is the new encoding of internal funs: <c>fun F/A</c> and
+ <c>fun(Arg1,..) -> ... end</c>.
+ </p>
+ <taglist>
+ <tag><c>Size</c></tag>
+ <item>
+ is the total number of bytes, including the <c>Size</c> field.
+ </item>
+ <tag><c>Arity</c></tag>
+ <item>
+ is the arity of the function implementing the fun.
+ </item>
+ <tag><c>Uniq</c></tag>
+ <item>
+ is the 16 bytes MD5 of the significant parts of the Beam file.
+ </item>
+ <tag><c>Index</c></tag>
+ <item>
+ is an index number. Each fun within a module has an unique
+ index. <c>Index</c> is stored in big-endian byte order.
+ </item>
+ <tag><c>NumFree</c></tag>
+ <item>
+ is the number of free variables.
+ </item>
+ <tag><c>Module</c></tag>
+ <item>
+ is an encoded as an atom, using
+ <seealso marker="#ATOM_EXT">ATOM_EXT</seealso>,
+ <seealso marker="#SMALL_ATOM_EXT">SMALL_ATOM_EXT</seealso> or
+ <seealso marker="#ATOM_CACHE_REF">ATOM_CACHE_REF</seealso>.
+ This is the module that the fun is implemented in.
+ </item>
+ <tag><c>OldIndex</c></tag>
+ <item>
+ is an integer encoded using
+ <seealso marker="#SMALL_INTEGER_EXT">SMALL_INTEGER_EXT</seealso>
+ or <seealso marker="#INTEGER_EXT">INTEGER_EXT</seealso>.
+ It is typically a small index into the module's fun table.
+ </item>
+ <tag><c>OldUniq</c></tag>
+ <item>
+ is an integer encoded using
+ <seealso marker="#SMALL_INTEGER_EXT">SMALL_INTEGER_EXT</seealso>
+ or
+ <seealso marker="#INTEGER_EXT">INTEGER_EXT</seealso>.
+ <c>Uniq</c> is the hash value of the parse tree for the fun.
+ </item>
+ <tag><c>Pid</c></tag>
+ <item>
+ is a process identifier as in
+ <seealso marker="#PID_EXT">PID_EXT</seealso>.
+ It represents the process in which
+ the fun was created.
+ </item>
+
+ <tag><c>Free vars</c></tag>
+ <item>
+ is <c>NumFree</c> number of terms, each one encoded according
+ to its type.
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="EXPORT_EXT"/>
+ <title>EXPORT_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">N1</cell>
+ <cell align="center">N2</cell>
+ <cell align="center">N3</cell>
+ </row>
+ <row>
+ <cell align="center">113</cell>
+ <cell align="center">Module</cell>
+ <cell align="center">Function</cell>
+ <cell align="center">Arity</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ This term is the encoding for external funs: <c>fun M:F/A</c>.
+ </p>
+ <p>
+ <c>Module</c> and <c>Function</c> are atoms
+ (encoded using <seealso marker="#ATOM_EXT">ATOM_EXT</seealso>,
+ <seealso marker="#SMALL_ATOM_EXT">SMALL_ATOM_EXT</seealso> or
+ <seealso marker="#ATOM_CACHE_REF">ATOM_CACHE_REF</seealso>).
+ </p>
+ <p>
+ <c>Arity</c> is an integer encoded using
+ <seealso marker="#SMALL_INTEGER_EXT">SMALL_INTEGER_EXT</seealso>.
+ </p>
+
+ </section>
+
+ <section>
+ <marker id="BIT_BINARY_EXT"/>
+ <title>BIT_BINARY_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">4</cell>
+ <cell align="center">1</cell>
+ <cell align="center">Len</cell>
+ </row>
+ <row>
+ <cell align="center">77</cell>
+ <cell align="center">Len</cell>
+ <cell align="center">Bits</cell>
+ <cell align="center">Data</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ This term represents a bitstring whose length in bits is not a
+ multiple of 8 (created using the bit syntax in R12B and later).
+ The <c>Len</c> field is an unsigned 4 byte integer (big endian).
+ The <c>Bits</c> field is the number of bits that are used
+ in the last byte in the data field,
+ counting from the most significant bit towards the least
+ significant.
+ </p>
+
+
+ </section>
+
+ <section>
+ <marker id="NEW_FLOAT_EXT"/>
+ <title>NEW_FLOAT_EXT</title>
+
+ <table align="left">
+ <row>
+ <cell align="center">1</cell>
+ <cell align="center">8</cell>
+ </row>
+ <row>
+ <cell align="center">70</cell>
+ <cell align="center">IEEE float</cell>
+ </row>
+ <tcaption></tcaption></table>
+ <p>
+ A float is stored as 8 bytes in big-endian IEEE format.
+ </p>
+ <p>
+ This term is used in minor version 1 of the external format.
+ </p>
+ </section>
+
+
+ </chapter>
+
+
diff --git a/erts/doc/src/erl_ext_fig.gif b/erts/doc/src/erl_ext_fig.gif
new file mode 100755
index 0000000000..14d6bbc871
--- /dev/null
+++ b/erts/doc/src/erl_ext_fig.gif
Binary files differ
diff --git a/erts/doc/src/erl_ext_fig.ps b/erts/doc/src/erl_ext_fig.ps
new file mode 100644
index 0000000000..2501dc3c05
--- /dev/null
+++ b/erts/doc/src/erl_ext_fig.ps
@@ -0,0 +1,153 @@
+%!PS-Adobe-3.0 EPSF-2.0
+%%BoundingBox: 0 0 600 520
+%%Creator: mscgen 1
+%%EndComments
+0.70 0.70 scale
+0 0 moveto
+0 520 lineto
+600 520 lineto
+600 0 lineto
+closepath
+clip
+%PageTrailer
+%Page: 1 1
+/Helvetica findfont
+10 scalefont
+setfont
+0 520 translate
+/mtrx matrix def
+/ellipse
+ { /endangle exch def
+ /startangle exch def
+ /ydia exch def
+ /xdia exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y translate
+ xdia 2 div ydia 2 div scale
+ 0 0 1 startangle endangle arc
+ savematrix setmatrix
+} def
+150 -12 moveto (Client (or Node)) dup stringwidth pop 2 div neg 0 rmoveto show
+450 -12 moveto (EPMD) dup stringwidth pop 2 div neg 0 rmoveto show
+newpath 150 -20 moveto 150 -45 lineto stroke
+newpath 450 -20 moveto 450 -45 lineto stroke
+newpath 150 -32 moveto 450 -32 lineto stroke
+newpath 450 -32 moveto 440 -38 lineto 440 -26 lineto closepath fill
+270 -30 moveto (ALIVE2_REQ) show
+newpath 150 -45 moveto 150 -70 lineto stroke
+newpath 450 -45 moveto 450 -70 lineto stroke
+[2] 0 setdash
+newpath 450 -57 moveto 150 -57 lineto stroke
+[] 0 setdash
+newpath 150 -57 moveto 160 -63 lineto 160 -51 lineto closepath fill
+267 -55 moveto (ALIVE2_RESP) show
+[2] 0 setdash
+newpath 150 -70 moveto 150 -95 lineto stroke
+[] 0 setdash
+[2] 0 setdash
+newpath 450 -70 moveto 450 -95 lineto stroke
+[] 0 setdash
+newpath 150 -95 moveto 150 -120 lineto stroke
+newpath 450 -95 moveto 450 -120 lineto stroke
+newpath 150 -107 moveto 450 -107 lineto stroke
+newpath 450 -107 moveto 440 -113 lineto 440 -101 lineto closepath fill
+253 -105 moveto (ALIVE_CLOSE_REQ) show
+[2] 0 setdash
+newpath 150 -120 moveto 150 -145 lineto stroke
+[] 0 setdash
+[2] 0 setdash
+newpath 450 -120 moveto 450 -145 lineto stroke
+[] 0 setdash
+newpath 150 -145 moveto 150 -170 lineto stroke
+newpath 450 -145 moveto 450 -170 lineto stroke
+newpath 150 -157 moveto 450 -157 lineto stroke
+newpath 450 -157 moveto 440 -163 lineto 440 -151 lineto closepath fill
+248 -155 moveto (PORT_PLEASE2_REQ) show
+newpath 150 -170 moveto 150 -195 lineto stroke
+newpath 450 -170 moveto 450 -195 lineto stroke
+[2] 0 setdash
+newpath 450 -182 moveto 150 -182 lineto stroke
+[] 0 setdash
+newpath 150 -182 moveto 160 -188 lineto 160 -176 lineto closepath fill
+267 -180 moveto (PORT2_RESP) show
+[2] 0 setdash
+newpath 150 -195 moveto 150 -220 lineto stroke
+[] 0 setdash
+[2] 0 setdash
+newpath 450 -195 moveto 450 -220 lineto stroke
+[] 0 setdash
+newpath 150 -220 moveto 150 -245 lineto stroke
+newpath 450 -220 moveto 450 -245 lineto stroke
+newpath 150 -232 moveto 450 -232 lineto stroke
+newpath 450 -232 moveto 440 -238 lineto 440 -226 lineto closepath fill
+269 -230 moveto (NAMES_REQ) show
+newpath 150 -245 moveto 150 -270 lineto stroke
+newpath 450 -245 moveto 450 -270 lineto stroke
+[2] 0 setdash
+newpath 450 -257 moveto 150 -257 lineto stroke
+[] 0 setdash
+newpath 150 -257 moveto 160 -263 lineto 160 -251 lineto closepath fill
+266 -255 moveto (NAMES_RESP) show
+[2] 0 setdash
+newpath 150 -270 moveto 150 -295 lineto stroke
+[] 0 setdash
+[2] 0 setdash
+newpath 450 -270 moveto 450 -295 lineto stroke
+[] 0 setdash
+newpath 150 -295 moveto 150 -320 lineto stroke
+newpath 450 -295 moveto 450 -320 lineto stroke
+newpath 150 -307 moveto 450 -307 lineto stroke
+newpath 450 -307 moveto 440 -313 lineto 440 -301 lineto closepath fill
+272 -305 moveto (DUMP_REQ) show
+newpath 150 -320 moveto 150 -345 lineto stroke
+newpath 450 -320 moveto 450 -345 lineto stroke
+[2] 0 setdash
+newpath 450 -332 moveto 150 -332 lineto stroke
+[] 0 setdash
+newpath 150 -332 moveto 160 -338 lineto 160 -326 lineto closepath fill
+269 -330 moveto (DUMP_RESP) show
+[2] 0 setdash
+newpath 150 -345 moveto 150 -370 lineto stroke
+[] 0 setdash
+[2] 0 setdash
+newpath 450 -345 moveto 450 -370 lineto stroke
+[] 0 setdash
+newpath 150 -370 moveto 150 -395 lineto stroke
+newpath 450 -370 moveto 450 -395 lineto stroke
+newpath 150 -382 moveto 450 -382 lineto stroke
+newpath 450 -382 moveto 440 -388 lineto 440 -376 lineto closepath fill
+277 -380 moveto (KILL_REQ) show
+newpath 150 -395 moveto 150 -420 lineto stroke
+newpath 450 -395 moveto 450 -420 lineto stroke
+[2] 0 setdash
+newpath 450 -407 moveto 150 -407 lineto stroke
+[] 0 setdash
+newpath 150 -407 moveto 160 -413 lineto 160 -401 lineto closepath fill
+274 -405 moveto (KILL_RESP) show
+[2] 0 setdash
+newpath 150 -420 moveto 150 -445 lineto stroke
+[] 0 setdash
+[2] 0 setdash
+newpath 450 -420 moveto 450 -445 lineto stroke
+[] 0 setdash
+newpath 150 -445 moveto 150 -470 lineto stroke
+newpath 450 -445 moveto 450 -470 lineto stroke
+newpath 150 -457 moveto 450 -457 lineto stroke
+newpath 450 -457 moveto 440 -463 lineto 440 -451 lineto closepath fill
+273 -455 moveto (STOP_REQ) show
+newpath 150 -470 moveto 150 -495 lineto stroke
+newpath 450 -470 moveto 450 -495 lineto stroke
+[2] 0 setdash
+newpath 450 -482 moveto 150 -482 lineto stroke
+[] 0 setdash
+newpath 150 -482 moveto 160 -488 lineto 160 -476 lineto closepath fill
+260 -480 moveto (STOP_OK_RESP) show
+newpath 150 -495 moveto 150 -520 lineto stroke
+newpath 450 -495 moveto 450 -520 lineto stroke
+[2] 0 setdash
+newpath 450 -507 moveto 150 -507 lineto stroke
+[] 0 setdash
+newpath 150 -507 moveto 160 -513 lineto 160 -501 lineto closepath fill
+250 -505 moveto (STOP_NOTOK_RESP) show
diff --git a/erts/doc/src/erl_fix_alloc.fig b/erts/doc/src/erl_fix_alloc.fig
new file mode 100644
index 0000000000..57db965a74
--- /dev/null
+++ b/erts/doc/src/erl_fix_alloc.fig
@@ -0,0 +1,104 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 300 1200 2850 3600
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4
+ 750 3600 750 1200 2325 1200 2325 3600
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 750 1500 2325 1500
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 750 1800 2325 1800
+2 1 0 2 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 375 2100 2775 2100
+4 0 -1 0 0 0 12 0.0000 4 180 1275 900 2025 allocated_blocks\001
+4 0 -1 0 0 0 12 0.0000 4 180 630 1200 1725 free_list\001
+4 0 -1 0 0 0 12 0.0000 4 180 735 1200 1425 item_size\001
+-6
+6 3525 1200 5025 1800
+6 3525 1200 5025 1800
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 3525 1200 5025 1200 5025 1800 3525 1800 3525 1200
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3525 1500 5025 1500
+-6
+4 0 -1 0 0 0 12 0.0000 4 105 330 4050 1425 next\001
+4 0 -1 0 0 0 12 0.0000 4 135 405 4050 1725 block\001
+-6
+6 5850 1200 7350 1800
+6 5850 1200 7350 1800
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 5850 1200 7350 1200 7350 1800 5850 1800 5850 1200
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5850 1500 7350 1500
+-6
+4 0 -1 0 0 0 12 0.0000 4 105 330 6375 1425 next\001
+4 0 -1 0 0 0 12 0.0000 4 135 405 6375 1725 block\001
+-6
+2 1 1 2 -1 7 0 0 -1 6.000 0 0 7 0 0 2
+ 3450 5700 5400 5700
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 4
+ 3600 8000 3600 3450 5175 3450 5175 8000
+2 1 1 2 -1 7 0 0 -1 6.000 0 0 -1 0 0 2
+ 3525 6900 5325 6900
+2 2 1 0 -1 7 0 0 42 2.000 0 0 -1 0 0 5
+ 3675 3525 5100 3525 5100 4425 3675 4425 3675 3525
+2 2 1 0 -1 7 0 0 42 2.000 0 0 -1 0 0 5
+ 3675 5775 5100 5775 5100 6825 3675 6825 3675 5775
+2 1 2 1 -1 7 0 0 -1 3.000 0 0 -1 0 0 2
+ 3600 4725 5250 4725
+2 1 2 1 -1 7 0 0 -1 3.000 0 0 -1 0 0 2
+ 3600 4950 5175 4950
+2 2 2 0 -1 7 0 0 42 1.500 0 0 -1 0 0 5
+ 6375 3750 6675 3750 6675 4050 6375 4050 6375 3750
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4275 1800 4275 3400
+2 1 1 2 -1 7 0 0 -1 6.000 0 0 -1 0 0 2
+ 3450 4500 5325 4500
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6600 1800 6600 2925
+2 1 0 2 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 450 600 750 1125
+3 0 0 1 -1 7 0 0 -1 0.000 0 1 0 3
+ 1 1 1.00 60.00 120.00
+ 4875 1350 5400 1350 5775 1200
+3 0 0 1 -1 7 0 0 -1 0.000 0 1 0 3
+ 1 1 1.00 60.00 120.00
+ 7125 1350 7650 1350 8025 1200
+3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 9
+ 1 1 1.00 60.00 120.00
+ 2175 1650 2475 1650 2625 1725 2775 1875 2775 2025 2775 4275
+ 2850 4350 3000 4425 3450 4500
+ 0.00 0.00 2346.89 1637.46 2421.89 1637.46 2514.58 1659.34
+ 2593.04 1701.97 2665.43 1754.14 2753.11 1822.15 2790.48 1912.37
+ 2775.00 1990.83 2775.01 2537.57 2542.79 3714.42 2785.95 4301.43
+ 2829.79 4335.43 2881.96 4373.03 2962.69 4412.87 3076.12 4449.75
+ 3188.62 4468.50 0.00 0.00
+3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 8
+ 1 1 1.00 60.00 120.00
+ 5100 4575 5400 4575 5625 4725 5700 4950 5700 6675 5625 6825
+ 5475 6900 5175 6975
+ 0.00 0.00 5270.86 4558.61 5345.86 4558.61 5465.07 4594.70
+ 5582.72 4669.65 5662.08 4773.55 5691.07 4895.01 5764.92 5349.99
+ 5796.11 6267.84 5690.66 6714.58 5655.36 6794.64 5594.64 6855.36
+ 5511.35 6886.55 5424.73 6918.60 5349.73 6937.35 0.00 0.00
+3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 8
+ 1 1 1.00 60.00 120.00
+ 2250 1950 2475 1950 2625 1875 2775 1725 2925 1425 3000 1350
+ 3150 1275 3450 1200
+ 0.00 0.00 2378.92 1959.40 2435.17 1959.40 2514.58 1940.66
+ 2593.04 1898.04 2665.43 1845.86 2745.86 1765.43 2821.07 1661.08
+ 2878.93 1488.92 2939.57 1404.79 2979.79 1364.57 3031.96 1326.96
+ 3113.65 1288.45 3200.27 1256.40 3275.27 1237.65 0.00 0.00
+4 0 -1 0 0 0 12 0.0000 4 180 720 3975 4650 next_free\001
+4 0 -1 0 0 0 12 0.0000 4 180 450 4050 4875 magic\001
+4 0 -1 0 0 2 14 0.0000 4 195 1860 6825 3975 = allocated memory\001
+4 0 -1 0 0 18 12 0.0000 4 135 1305 3675 1125 AllocatedBlock\001
+4 0 -1 0 0 18 12 0.0000 4 135 660 1575 1125 FixItem\001
+4 0 -1 0 0 18 12 0.0000 4 135 1020 2400 4650 FreeHeader\001
+4 0 -1 0 0 2 12 4.7124 4 180 765 5250 3600 item_size\001
+4 0 -1 0 0 2 18 0.0000 4 255 1080 300 525 fix_array\001
diff --git a/erts/doc/src/erl_fix_alloc.gif b/erts/doc/src/erl_fix_alloc.gif
new file mode 100644
index 0000000000..c6b41ce801
--- /dev/null
+++ b/erts/doc/src/erl_fix_alloc.gif
Binary files differ
diff --git a/erts/doc/src/erl_fix_alloc.ps b/erts/doc/src/erl_fix_alloc.ps
new file mode 100644
index 0000000000..bf65d1556c
--- /dev/null
+++ b/erts/doc/src/erl_fix_alloc.ps
@@ -0,0 +1,646 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: erl_fix_alloc.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Tue May 20 11:10:33 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 506 462
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/MyAppDict 100 dict dup begin def
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-18.0 481.0 translate
+1 -1 scale
+.9 .9 scale % to make patterns same scale as in xfig
+
+% This junk string is used by the show operators
+/PATsstr 1 string def
+/PATawidthshow { % cx cy cchar rx ry string
+ % Loop over each character in the string
+ { % cx cy cchar rx ry char
+ % Show the character
+ dup % cx cy cchar rx ry char char
+ PATsstr dup 0 4 -1 roll put % cx cy cchar rx ry char (char)
+ false charpath % cx cy cchar rx ry char
+ /clip load PATdraw
+ % Move past the character (charpath modified the
+ % current point)
+ currentpoint % cx cy cchar rx ry char x y
+ newpath
+ moveto % cx cy cchar rx ry char
+ % Reposition by cx,cy if the character in the string is cchar
+ 3 index eq { % cx cy cchar rx ry
+ 4 index 4 index rmoveto
+ } if
+ % Reposition all characters by rx ry
+ 2 copy rmoveto % cx cy cchar rx ry
+ } forall
+ pop pop pop pop pop % -
+ currentpoint
+ newpath
+ moveto
+} bind def
+/PATcg {
+ 7 dict dup begin
+ /lw currentlinewidth def
+ /lc currentlinecap def
+ /lj currentlinejoin def
+ /ml currentmiterlimit def
+ /ds [ currentdash ] def
+ /cc [ currentrgbcolor ] def
+ /cm matrix currentmatrix def
+ end
+} bind def
+% PATdraw - calculates the boundaries of the object and
+% fills it with the current pattern
+/PATdraw { % proc
+ save exch
+ PATpcalc % proc nw nh px py
+ 5 -1 roll exec % nw nh px py
+ newpath
+ PATfill % -
+ restore
+} bind def
+% PATfill - performs the tiling for the shape
+/PATfill { % nw nh px py PATfill -
+ PATDict /CurrentPattern get dup begin
+ setfont
+ % Set the coordinate system to Pattern Space
+ PatternGState PATsg
+ % Set the color for uncolored pattezns
+ PaintType 2 eq { PATDict /PColor get PATsc } if
+ % Create the string for showing
+ 3 index string % nw nh px py str
+ % Loop for each of the pattern sources
+ 0 1 Multi 1 sub { % nw nh px py str source
+ % Move to the starting location
+ 3 index 3 index % nw nh px py str source px py
+ moveto % nw nh px py str source
+ % For multiple sources, set the appropriate color
+ Multi 1 ne { dup PC exch get PATsc } if
+ % Set the appropriate string for the source
+ 0 1 7 index 1 sub { 2 index exch 2 index put } for pop
+ % Loop over the number of vertical cells
+ 3 index % nw nh px py str nh
+ { % nw nh px py str
+ currentpoint % nw nh px py str cx cy
+ 2 index show % nw nh px py str cx cy
+ YStep add moveto % nw nh px py str
+ } repeat % nw nh px py str
+ } for
+ 5 { pop } repeat
+ end
+} bind def
+
+% PATkshow - kshow with the current pattezn
+/PATkshow { % proc string
+ exch bind % string proc
+ 1 index 0 get % string proc char
+ % Loop over all but the last character in the string
+ 0 1 4 index length 2 sub {
+ % string proc char idx
+ % Find the n+1th character in the string
+ 3 index exch 1 add get % string proe char char+1
+ exch 2 copy % strinq proc char+1 char char+1 char
+ % Now show the nth character
+ PATsstr dup 0 4 -1 roll put % string proc chr+1 chr chr+1 (chr)
+ false charpath % string proc char+1 char char+1
+ /clip load PATdraw
+ % Move past the character (charpath modified the current point)
+ currentpoint newpath moveto
+ % Execute the user proc (should consume char and char+1)
+ mark 3 1 roll % string proc char+1 mark char char+1
+ 4 index exec % string proc char+1 mark...
+ cleartomark % string proc char+1
+ } for
+ % Now display the last character
+ PATsstr dup 0 4 -1 roll put % string proc (char+1)
+ false charpath % string proc
+ /clip load PATdraw
+ neewath
+ pop pop % -
+} bind def
+% PATmp - the makepattern equivalent
+/PATmp { % patdict patmtx PATmp patinstance
+ exch dup length 7 add % We will add 6 new entries plus 1 FID
+ dict copy % Create a new dictionary
+ begin
+ % Matrix to install when painting the pattern
+ TilingType PATtcalc
+ /PatternGState PATcg def
+ PatternGState /cm 3 -1 roll put
+ % Check for multi pattern sources (Level 1 fast color patterns)
+ currentdict /Multi known not { /Multi 1 def } if
+ % Font dictionary definitions
+ /FontType 3 def
+ % Create a dummy encoding vector
+ /Encoding 256 array def
+ 3 string 0 1 255 {
+ Encoding exch dup 3 index cvs cvn put } for pop
+ /FontMatrix matrix def
+ /FontBBox BBox def
+ /BuildChar {
+ mark 3 1 roll % mark dict char
+ exch begin
+ Multi 1 ne {PaintData exch get}{pop} ifelse % mark [paintdata]
+ PaintType 2 eq Multi 1 ne or
+ { XStep 0 FontBBox aload pop setcachedevice }
+ { XStep 0 setcharwidth } ifelse
+ currentdict % mark [paintdata] dict
+ /PaintProc load % mark [paintdata] dict paintproc
+ end
+ gsave
+ false PATredef exec true PATredef
+ grestore
+ cleartomark % -
+ } bind def
+ currentdict
+ end % newdict
+ /foo exch % /foo newlict
+ definefont % newfont
+} bind def
+% PATpcalc - calculates the starting point and width/height
+% of the tile fill for the shape
+/PATpcalc { % - PATpcalc nw nh px py
+ PATDict /CurrentPattern get begin
+ gsave
+ % Set up the coordinate system to Pattern Space
+ % and lock down pattern
+ PatternGState /cm get setmatrix
+ BBox aload pop pop pop translate
+ % Determine the bounding box of the shape
+ pathbbox % llx lly urx ury
+ grestore
+ % Determine (nw, nh) the # of cells to paint width and height
+ PatHeight div ceiling % llx lly urx qh
+ 4 1 roll % qh llx lly urx
+ PatWidth div ceiling % qh llx lly qw
+ 4 1 roll % qw qh llx lly
+ PatHeight div floor % qw qh llx ph
+ 4 1 roll % ph qw qh llx
+ PatWidth div floor % ph qw qh pw
+ 4 1 roll % pw ph qw qh
+ 2 index sub cvi abs % pw ph qs qh-ph
+ exch 3 index sub cvi abs exch % pw ph nw=qw-pw nh=qh-ph
+ % Determine the starting point of the pattern fill
+ %(px, py)
+ 4 2 roll % nw nh pw ph
+ PatHeight mul % nw nh pw py
+ exch % nw nh py pw
+ PatWidth mul exch % nw nh px py
+ end
+} bind def
+
+% Save the original routines so that we can use them later on
+/oldfill /fill load def
+/oldeofill /eofill load def
+/oldstroke /stroke load def
+/oldshow /show load def
+/oldashow /ashow load def
+/oldwidthshow /widthshow load def
+/oldawidthshow /awidthshow load def
+/oldkshow /kshow load def
+
+% These defs are necessary so that subsequent procs don't bind in
+% the originals
+/fill { oldfill } bind def
+/eofill { oldeofill } bind def
+/stroke { oldstroke } bind def
+/show { oldshow } bind def
+/ashow { oldashow } bind def
+/widthshow { oldwidthshow } bind def
+/awidthshow { oldawidthshow } bind def
+/kshow { oldkshow } bind def
+/PATredef {
+ MyAppDict begin
+ {
+ /fill { /clip load PATdraw newpath } bind def
+ /eofill { /eoclip load PATdraw newpath } bind def
+ /stroke { PATstroke } bind def
+ /show { 0 0 null 0 0 6 -1 roll PATawidthshow } bind def
+ /ashow { 0 0 null 6 3 roll PATawidthshow }
+ bind def
+ /widthshow { 0 0 3 -1 roll PATawidthshow }
+ bind def
+ /awidthshow { PATawidthshow } bind def
+ /kshow { PATkshow } bind def
+ } {
+ /fill { oldfill } bind def
+ /eofill { oldeofill } bind def
+ /stroke { oldstroke } bind def
+ /show { oldshow } bind def
+ /ashow { oldashow } bind def
+ /widthshow { oldwidthshow } bind def
+ /awidthshow { oldawidthshow } bind def
+ /kshow { oldkshow } bind def
+ } ifelse
+ end
+} bind def
+false PATredef
+% Conditionally define setcmykcolor if not available
+/setcmykcolor where { pop } {
+ /setcmykcolor {
+ 1 sub 4 1 roll
+ 3 {
+ 3 index add neg dup 0 lt { pop 0 } if 3 1 roll
+ } repeat
+ setrgbcolor - pop
+ } bind def
+} ifelse
+/PATsc { % colorarray
+ aload length % c1 ... cn length
+ dup 1 eq { pop setgray } { 3 eq { setrgbcolor } { setcmykcolor
+ } ifelse } ifelse
+} bind def
+/PATsg { % dict
+ begin
+ lw setlinewidth
+ lc setlinecap
+ lj setlinejoin
+ ml setmiterlimit
+ ds aload pop setdash
+ cc aload pop setrgbcolor
+ cm setmatrix
+ end
+} bind def
+
+/PATDict 3 dict def
+/PATsp {
+ true PATredef
+ PATDict begin
+ /CurrentPattern exch def
+ % If it's an uncolored pattern, save the color
+ CurrentPattern /PaintType get 2 eq {
+ /PColor exch def
+ } if
+ /CColor [ currentrgbcolor ] def
+ end
+} bind def
+% PATstroke - stroke with the current pattern
+/PATstroke {
+ countdictstack
+ save
+ mark
+ {
+ currentpoint strokepath moveto
+ PATpcalc % proc nw nh px py
+ clip newpath PATfill
+ } stopped {
+ (*** PATstroke Warning: Path is too complex, stroking
+ with gray) =
+ cleartomark
+ restore
+ countdictstack exch sub dup 0 gt
+ { { end } repeat } { pop } ifelse
+ gsave 0.5 setgray oldstroke grestore
+ } { pop restore pop } ifelse
+ newpath
+} bind def
+/PATtcalc { % modmtx tilingtype PATtcalc tilematrix
+ % Note: tiling types 2 and 3 are not supported
+ gsave
+ exch concat % tilingtype
+ matrix currentmatrix exch % cmtx tilingtype
+ % Tiling type 1 and 3: constant spacing
+ 2 ne {
+ % Distort the pattern so that it occupies
+ % an integral number of device pixels
+ dup 4 get exch dup 5 get exch % tx ty cmtx
+ XStep 0 dtransform
+ round exch round exch % tx ty cmtx dx.x dx.y
+ XStep div exch XStep div exch % tx ty cmtx a b
+ 0 YStep dtransform
+ round exch round exch % tx ty cmtx a b dy.x dy.y
+ YStep div exch YStep div exch % tx ty cmtx a b c d
+ 7 -3 roll astore % { a b c d tx ty }
+ } if
+ grestore
+} bind def
+/PATusp {
+ false PATredef
+ PATDict begin
+ CColor PATsc
+ end
+} bind def
+
+% right30
+11 dict begin
+/PaintType 1 def
+/PatternType 1 def
+/TilingType 1 def
+/BBox [0 0 1 1] def
+/XStep 1 def
+/YStep 1 def
+/PatWidth 1 def
+/PatHeight 1 def
+/Multi 2 def
+/PaintData [
+ { clippath } bind
+ { 32 16 true [ 32 0 0 -16 0 16 ]
+ {<00030003000c000c0030003000c000c0030003000c000c00
+ 30003000c000c00000030003000c000c0030003000c000c0
+ 030003000c000c0030003000c000c000>}
+ imagemask } bind
+] def
+/PaintProc {
+ pop
+ exec fill
+} def
+currentdict
+end
+/P2 exch def
+1.1111 1.1111 scale %restore scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawSplineSection {
+ /y3 exch def
+ /x3 exch def
+ /y2 exch def
+ /x2 exch def
+ /y1 exch def
+ /x1 exch def
+ /xa x1 x2 x1 sub 0.666667 mul add def
+ /ya y1 y2 y1 sub 0.666667 mul add def
+ /xb x3 x2 x3 sub 0.666667 mul add def
+ /yb y3 y2 y3 sub 0.666667 mul add def
+ x1 y1 lineto
+ xa ya xb yb x3 y3 curveto
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Polyline
+n 750 3600 m 750 1200 l 2325 1200 l 2325 3600 l gs col-1 s gr
+% Polyline
+n 750 1500 m 2325 1500 l gs col-1 s gr
+% Polyline
+n 750 1800 m 2325 1800 l gs col-1 s gr
+15.000 slw
+% Polyline
+n 375 2100 m 2775 2100 l gs col-1 s gr
+/Times-Roman ff 180.00 scf sf
+900 2025 m
+gs 1 -1 sc (allocated_blocks) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+1200 1725 m
+gs 1 -1 sc (free_list) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+1200 1425 m
+gs 1 -1 sc (item_size) col-1 sh gr
+7.500 slw
+% Polyline
+n 3525 1200 m 5025 1200 l 5025 1800 l 3525 1800 l cp gs col-1 s gr
+% Polyline
+n 3525 1500 m 5025 1500 l gs col-1 s gr
+/Times-Roman ff 180.00 scf sf
+4050 1425 m
+gs 1 -1 sc (next) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+4050 1725 m
+gs 1 -1 sc (block) col-1 sh gr
+% Polyline
+n 5850 1200 m 7350 1200 l 7350 1800 l 5850 1800 l cp gs col-1 s gr
+% Polyline
+n 5850 1500 m 7350 1500 l gs col-1 s gr
+/Times-Roman ff 180.00 scf sf
+6375 1425 m
+gs 1 -1 sc (next) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+6375 1725 m
+gs 1 -1 sc (block) col-1 sh gr
+15.000 slw
+% Polyline
+ [100.0] 0 sd
+n 3450 5700 m 5400 5700 l gs col-1 s gr [] 0 sd
+7.500 slw
+% Polyline
+n 3600 8000 m 3600 3450 l 5175 3450 l 5175 8000 l gs col-1 s gr
+15.000 slw
+% Polyline
+ [100.0] 0 sd
+n 3525 6900 m 5325 6900 l gs col-1 s gr [] 0 sd
+0.000 slw
+% Polyline
+ [33.3] 0 sd
+n 3675 3525 m 5100 3525 l 5100 4425 l 3675 4425 l cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 245.00 235.00] PATmp PATsp ef gr PATusp [] 0 sd
+% Polyline
+ [33.3] 0 sd
+n 3675 5775 m 5100 5775 l 5100 6825 l 3675 6825 l cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 245.00 385.00] PATmp PATsp ef gr PATusp [] 0 sd
+7.500 slw
+% Polyline
+ [15 50.0] 50.0 sd
+n 3600 4725 m 5250 4725 l gs col-1 s gr [] 0 sd
+% Polyline
+ [15 50.0] 50.0 sd
+n 3600 4950 m 5175 4950 l gs col-1 s gr [] 0 sd
+0.000 slw
+% Polyline
+ [15 25.0] 25.0 sd
+n 6375 3750 m 6675 3750 l 6675 4050 l 6375 4050 l cp gs /PC [[1.00 1.00 1.00] [0.00 0.00 0.00]] def
+15.00 15.00 sc P2 [16 0 0 -8 425.00 250.00] PATmp PATsp ef gr PATusp [] 0 sd
+7.500 slw
+% Polyline
+gs clippath
+4305 3253 m 4275 3373 l 4245 3253 l 4245 3415 l 4305 3415 l cp clip
+n 4275 1800 m 4275 3400 l gs col-1 s gr gr
+
+% arrowhead
+n 4305 3253 m 4275 3373 l 4245 3253 l 4275 3253 l 4305 3253 l cp gs 0.00 setgray ef gr col-1 s
+15.000 slw
+% Polyline
+ [100.0] 0 sd
+n 3450 4500 m 5325 4500 l gs col-1 s gr [] 0 sd
+7.500 slw
+% Polyline
+gs clippath
+6630 2778 m 6600 2898 l 6570 2778 l 6570 2940 l 6630 2940 l cp clip
+n 6600 1800 m 6600 2925 l gs col-1 s gr gr
+
+% arrowhead
+n 6630 2778 m 6600 2898 l 6570 2778 l 6600 2778 l 6630 2778 l cp gs 0.00 setgray ef gr col-1 s
+15.000 slw
+% Polyline
+gs clippath
+656 840 m 723 1078 l 552 900 l 713 1181 l 817 1121 l cp clip
+n 450 600 m 750 1125 l gs col-1 s gr gr
+
+% arrowhead
+n 656 840 m 723 1078 l 552 900 l 604 870 l 656 840 l cp gs 0.00 setgray ef gr col-1 s
+% Open spline
+gs clippath
+5627 1227 m 5749 1210 l 5650 1282 l 5800 1222 l 5778 1167 l cp clip
+7.500 slw
+n 4875.0 1350.0 m 5137.5 1350.0 l
+ 5137.5 1350.0 5400.0 1350.0 5587.5 1275.0 DrawSplineSection
+ 5775.0 1200.0 l gs col-1 s gr
+ gr
+
+% arrowhead
+n 5627 1227 m 5749 1210 l 5650 1282 l 5639 1255 l 5627 1227 l cp gs 0.00 setgray ef gr col-1 s
+% Open spline
+gs clippath
+7877 1227 m 7999 1210 l 7900 1282 l 8050 1222 l 8028 1167 l cp clip
+n 7125.0 1350.0 m 7387.5 1350.0 l
+ 7387.5 1350.0 7650.0 1350.0 7837.5 1275.0 DrawSplineSection
+ 8025.0 1200.0 l gs col-1 s gr
+ gr
+
+% arrowhead
+n 7877 1227 m 7999 1210 l 7900 1282 l 7889 1255 l 7877 1227 l cp gs 0.00 setgray ef gr col-1 s
+% Interp Spline
+gs clippath
+3308 4453 m 3423 4496 l 3300 4512 l 3461 4532 l 3468 4472 l cp clip
+n 2175 1650 m
+ 2346.9 1637.5 2421.9 1637.5 2475 1650 curveto
+ 2514.6 1659.3 2593.0 1702.0 2625 1725 curveto
+ 2665.4 1754.1 2753.1 1822.2 2775 1875 curveto
+ 2790.5 1912.4 2775.0 1990.8 2775 2025 curveto
+ 2775.0 2537.6 2542.8 3714.4 2775 4275 curveto
+ 2785.9 4301.4 2829.8 4335.4 2850 4350 curveto
+ 2882.0 4373.0 2962.7 4412.9 3000 4425 curveto
+ 3076.1 4449.8 3188.6 4468.5 3450 4500 curveto
+ gs col-1 s gr
+ gr
+
+% arrowhead
+n 3308 4453 m 3423 4496 l 3300 4512 l 3304 4483 l 3308 4453 l cp gs 0.00 setgray ef gr col-1 s
+% Interp Spline
+gs clippath
+5325 6973 m 5201 6969 l 5312 6914 l 5154 6949 l 5167 7007 l cp clip
+n 5100 4575 m
+ 5270.9 4558.6 5345.9 4558.6 5400 4575 curveto
+ 5465.1 4594.7 5582.7 4669.6 5625 4725 curveto
+ 5662.1 4773.6 5691.1 4895.0 5700 4950 curveto
+ 5764.9 5350.0 5796.1 6267.8 5700 6675 curveto
+ 5690.7 6714.6 5655.4 6794.6 5625 6825 curveto
+ 5594.6 6855.4 5511.4 6886.6 5475 6900 curveto
+ 5424.7 6918.6 5349.7 6937.4 5175 6975 curveto
+ gs col-1 s gr
+ gr
+
+% arrowhead
+n 5325 6973 m 5201 6969 l 5312 6914 l 5319 6944 l 5325 6973 l cp gs 0.00 setgray ef gr col-1 s
+% Interp Spline
+gs clippath
+3300 1202 m 3423 1205 l 3313 1261 l 3471 1226 l 3458 1168 l cp clip
+n 2250 1950 m
+ 2378.9 1959.4 2435.2 1959.4 2475 1950 curveto
+ 2514.6 1940.7 2593.0 1898.0 2625 1875 curveto
+ 2665.4 1845.9 2745.9 1765.4 2775 1725 curveto
+ 2821.1 1661.1 2878.9 1488.9 2925 1425 curveto
+ 2939.6 1404.8 2979.8 1364.6 3000 1350 curveto
+ 3032.0 1327.0 3113.7 1288.5 3150 1275 curveto
+ 3200.3 1256.4 3275.3 1237.7 3450 1200 curveto
+ gs col-1 s gr
+ gr
+
+% arrowhead
+n 3300 1202 m 3423 1205 l 3313 1261 l 3306 1231 l 3300 1202 l cp gs 0.00 setgray ef gr col-1 s
+/Times-Roman ff 180.00 scf sf
+3975 4650 m
+gs 1 -1 sc (next_free) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+4050 4875 m
+gs 1 -1 sc (magic) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+6825 3975 m
+gs 1 -1 sc (= allocated memory) col-1 sh gr
+/Helvetica-Bold ff 180.00 scf sf
+3675 1125 m
+gs 1 -1 sc (AllocatedBlock) col-1 sh gr
+/Helvetica-Bold ff 180.00 scf sf
+1575 1125 m
+gs 1 -1 sc (FixItem) col-1 sh gr
+/Helvetica-Bold ff 180.00 scf sf
+2400 4650 m
+gs 1 -1 sc (FreeHeader) col-1 sh gr
+/Times-Bold ff 180.00 scf sf
+5250 3600 m
+gs 1 -1 sc 270.0 rot (item_size) col-1 sh gr
+/Times-Bold ff 270.00 scf sf
+300 525 m
+gs 1 -1 sc (fix_array) col-1 sh gr
+$F2psEnd
+rs
+end
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
new file mode 100644
index 0000000000..c636d65ef3
--- /dev/null
+++ b/erts/doc/src/erl_nif.xml
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erl_nif</title>
+ <prepared>Sverker Eriksson</prepared>
+ <responsible>Sverker Eriksson</responsible>
+ <docno>1</docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2009-11-17</date>
+ <rev>PA1</rev>
+ <file>erl_nif.xml</file>
+ </header>
+ <lib>erl_nif</lib>
+ <libsummary>API functions for an Erlang NIF library</libsummary>
+ <description>
+ <warning><p>The NIF concept is introduced in R13B03 as an
+ EXPERIMENTAL feature. The interfaces may be changed in any way
+ in coming releases. The API introduced in this release is very
+ sparse and contains only the most basic functions to read and
+ write Erlang terms.
+ </p></warning>
+
+ <p>A NIF library contains native implementation of some functions
+ of an erlang module. The native implemented functions (NIFs) are
+ called like any other functions without any difference to the
+ caller. Each NIF must also have an implementation in Erlang that
+ will be invoked if the function is called before the NIF library
+ has been successfully loaded. A typical such stub implementation
+ is to throw an exception. But it can also be used as a fallback
+ implementation if the NIF library is not implemented for some
+ architecture.</p>
+ <p>A minimal example of a NIF library can look like this:</p>
+ <p/>
+ <code type="none">
+/* niftest.c */
+#include "erl_nif.h"
+
+static ERL_NIF_TERM hello(ErlNifEnv* env)
+{
+ return enif_make_string(env, "Hello world!");
+}
+
+static ErlNifFunc nif_funcs[] =
+{
+ {"hello", 0, hello}
+};
+
+ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)
+</code>
+
+ <p>and the erlang module would have to look something like
+ this:</p>
+ <p/>
+ <code type="none">
+-module(niftest).
+
+-export([init/0, hello/0]).
+
+init() ->
+ erlang:load_nif("./niftest", 0).
+
+hello() ->
+ "NIF library not loaded".
+</code>
+ <p>and compile and test something like this (on Linux):</p>
+ <p/>
+ <code type="none">
+$> gcc -fPIC -shared -o niftest.so niftest.c -I $ERL_ROOT/usr/include/
+$> erl
+
+1> c(niftest).
+{ok,niftest}
+2> niftest:hello().
+"NIF library not loaded"
+3> niftest:init().
+ok
+4> niftest:hello().
+"Hello world!"
+</code>
+
+ <p>A better solution for a real module is to take advantage of
+ the new attribute <c>on_load</c> to automatically load the NIF
+ library when the module is loaded.</p>
+ <p>A loaded NIF library is tied to the Erlang module code version
+ that loaded it. If the module is upgraded with a new version, the
+ new code will have to load its own NIF library (or maybe choose not
+ to). The new code version can however choose to load the exact
+ same NIF library as the old code if it wants to. Sharing the same
+ dynamic library will mean that static data defined by the library
+ will be shared as well. To avoid unintentionally shared static
+ data, each Erlang module code can keep its own private data. This
+ global private data can be set when the NIF library is loaded and
+ then retrieved by calling <seealso marker="erl_nif#enif_get_data">enif_get_data()</seealso>.</p>
+ <p>There is currently no way to explicitly unload a NIF
+ library. A library will be automatically unloaded when the module
+ code that it belongs to is purged by the code server. A NIF
+ library will can also be unloaded by replacing it with another
+ version of the library by a second call to
+ <c>erlang:load_nif/2</c> from the same module code.</p>
+ </description>
+
+ <section>
+ <title>INITIALIZATION</title>
+ <taglist>
+ <tag><marker id="ERL_NIF_INIT"/>ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)</tag>
+ <item><p>This is the magic macro to initialize a NIF library. It
+ should be evaluated in global file scope.</p>
+ <p><c>MODULE</c> is the name of the Erlang module as an
+ identifier without string quotations. It will be stringified by
+ the macro.</p>
+ <p><c>funcs</c> is a static array of function descriptors for
+ all the implemented NIFs in this library.</p>
+ <p><c>load</c>, <c>reload</c>, <c>upgrade</c> and <c>unload</c>
+ are pointers to functions. One of <c>load</c>, <c>reload</c> or
+ <c>upgrade</c> will be called to initialize the library.
+ <c>unload</c> is called to release the library. They are all
+ described individually below.</p>
+ </item>
+
+ <tag><marker id="load"/>int (*load)(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)</tag>
+ <item><p><c>load</c> is called when the NIF library is loaded
+ and there is no previously loaded library for this module.</p>
+ <p><c>*priv_data</c> can be set to point to some private data
+ that the library needs in able to keep a state between NIF
+ calls. <c>enif_get_data()</c> will return this pointer.</p>
+ <p><c>load_info</c> is the second argument to <seealso
+ marker="erlang#erlang:load_nif-2">erlang:load_nif/2</seealso>.</p>
+ <p>The library will fail to load if <c>load</c> returns
+ anything other than 0. <c>load</c> can be NULL in case no
+ initialization is needed.</p>
+ </item>
+
+ <tag><marker id="reload"/>int (*reload)(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)</tag>
+ <item><p><c>reload</c> is called when the NIF library is loaded
+ and there is already a previously loaded library for this
+ module code.</p>
+ <p>Works the same as <c>load</c>. The only difference is that
+ <c>*priv_data</c> already contains the value set by the
+ previous call to <c>load</c> or <c>reload</c>.</p>
+ <p>The library will fail to load if <c>reload</c> returns
+ anything other than 0 or if <c>reload</c> is NULL.</p>
+ </item>
+
+ <tag><marker id="upgrade"/>int (*upgrade)(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)</tag>
+ <item><p><c>upgrade</c> is called when the NIF library is loaded
+ and there is no previously loaded library for this module
+ code, BUT there is old code of this module with a
+ loaded NIF library.</p>
+ <p>Works the same as <c>load</c>. The only difference is that
+ <c>*old_priv_data</c> already contains the value set by the
+ last call to <c>load</c> or <c>reload</c> for the old module
+ code. It is allowed to write to both *priv_data and
+ *old_priv_data.</p>
+ <p>The library will fail to load if <c>upgrade</c> returns
+ anything other than 0 or if <c>upgrade</c> is NULL.</p>
+ </item>
+
+ <tag><marker id="unload"/>void (*unload)(ErlNifEnv* env, void* priv_data)</tag>
+ <item><p><c>unload</c> is called when the module code that
+ the NIF library belongs to is purged as old. New code
+ of the same module may or may not exist.</p>
+ </item>
+
+
+ </taglist>
+ </section>
+
+ <section>
+ <title>DATA TYPES</title>
+
+ <taglist>
+ <tag><marker id="ErlDrvEnv"/>ErlDrvEnv</tag>
+ <item>
+ <p><c>ErlNifEnv</c> contains information about the context in
+ which a NIF call is made. This pointer should not be
+ dereferenced in any way, but only passed on to API
+ functions. An <c>ErlNifEnv</c> pointer is only valid until
+ the function, where is what supplied as argument,
+ returns. There is thus useless and dangerous to store <c>ErlNifEnv</c>
+ pointers in between NIF calls.</p>
+ </item>
+ <tag><marker id="ErlNifFunc"/>ErlNifFunc</tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef struct {
+ const char* name;
+ unsigned arity;
+ ERL_NIF_TERM (*fptr)(ErlNifEnv* env, ...);
+} ErlNifFunc;
+</code>
+ <p>Describes a NIF by its name, arity and implementation.
+ <c>fptr</c> is a pointer to the function that implements the
+ NIF. The number of arguments must match the arity. A NIF of
+ arity 2 will thus look like:</p>
+ <p/>
+ <code type="none">
+ERL_NIF_TERM my_nif(ErlNifEnv* env, ERL_NIF_TERM arg1, ERL_NIF_TERM arg2)
+{
+ /* ... */
+}
+</code>
+ <p>The maximum allowed arity for a NIF is 3 in current implementation.</p>
+ </item>
+ <tag><marker id="ErlNifBinary"/>ErlNifBinary</tag>
+ <item>
+ <p/>
+ <code type="none">
+typedef struct {
+ unsigned size;
+ unsigned char* data;
+} ErlNifBinary;
+</code>
+ <p><c>ErlNifBinary</c> contains transient information about an
+ inspected binary term. <c>data</c> is a pointer to a buffer
+ of <c>size</c> bytes with the raw content of the binary.</p>
+ </item>
+ <tag><marker id="ERL_NIF_TERM"/>ERL_NIF_TERM</tag>
+ <item>
+ <p>Variables of type <c>ERL_NIF_TERM</c> can refere to any
+ Erlang term. This is an opaque type and values of it can only
+ by used either as arguments to API functions or as return
+ values from NIFs. A variable of type <c>ERL_NIF_TERM</c> is
+ only valid until the NIF call, where it was obtained,
+ returns.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <funcs>
+ <func><name><ret>void*</ret><nametext>enif_get_data(ErlNifEnv* env)</nametext></name>
+ <fsummary>Get the private data of a NIF library</fsummary>
+ <desc><p>Returns the pointer to the private data that was set by <c>load</c>, <c>reload</c> or <c>upgrade</c>.</p></desc>
+ </func>
+ <func><name><ret>void*</ret><nametext>enif_alloc(ErlNifEnv* env, size_t size)</nametext></name>
+ <fsummary>Allocate dynamic memory.</fsummary>
+ <desc><p>Allocate memory of <c>size</c> bytes.</p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_free(ErlNifEnv* env, void* ptr)</nametext></name>
+ <fsummary>Free dynamic memory</fsummary>
+ <desc><p>Free memory allocated by <c>enif_alloc</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a binary</fsummary>
+ <desc><p>Return true if <c>term</c> is a binary</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_inspect_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, ErlNifBinary* bin)</nametext></name>
+ <fsummary>Inspect the content of a binary</fsummary>
+ <desc><p>Initialize the structure pointed to by <c>bin</c> with
+ transient information about the binary term
+ <c>bin_term</c>. Return false if <c>bin_term</c> is not a binary.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin)</nametext></name>
+ <fsummary>Create a new binary.</fsummary>
+ <desc><p>Allocate a new binary of size of <c>size</c>
+ bytes. Initialize the structure pointed to by <c>bin</c> to
+ refer to the allocated binary.</p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
+ <fsummary>Release a binary.</fsummary>
+ <desc><p>Release a binary obtained from <c>enif_alloc_binary</c> or <c>enif_inspect_binary</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_int(ErlNifEnv* env, ERL_NIF_TERM term, int* ip)</nametext></name>
+ <fsummary>Read an integer term.</fsummary>
+ <desc><p>Set <c>*ip</c> to the integer value of
+ <c>term</c> or return false if <c>term</c> is not an integer or is
+ outside the bounds of type <c>int</c></p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM term, unsigned long* ip)</nametext></name>
+ <fsummary>Read an unsigned long integer</fsummary>
+ <desc><p>Set <c>*ip</c> to the unsigned long integer value of
+ <c>term</c> or return false if <c>term</c> is not an unsigned
+ integer or is outside the bounds of type <c>unsigned long</c></p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_list_cell(ErlNifEnv* env, ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail)</nametext></name>
+ <fsummary>Get head and tail from a list</fsummary>
+ <desc><p>Set <c>*head</c> and <c>*tail</c> from
+ <c>list</c> or return false if <c>list</c> is not a non-empty
+ list.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
+ <fsummary>Make a binary term.</fsummary>
+ <desc><p>Make a binary term from <c>bin</c>. Will also release
+ the binary.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name>
+ <fsummary>Make a badarg exception.</fsummary>
+ <desc><p>Make a badarg exception to be returned from a NIF.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_int(ErlNifEnv* env, int i)</nametext></name>
+ <fsummary>Create an integer term</fsummary>
+ <desc><p>Create an integer term.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ulong(ErlNifEnv* env, unsigned long i)</nametext></name>
+ <fsummary>Create an integer term from an unsigned long int</fsummary>
+ <desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom(ErlNifEnv* env, const char* name)</nametext></name>
+ <fsummary>Create an atom term</fsummary>
+ <desc><p>Create an atom term from the C-string <c>name</c>. Atom
+ terms may be saved and used between NIF calls.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
+ <fsummary>Create a tuple term.</fsummary>
+ <desc><p>Create a tuple term of arity <c>cnt</c>. Expects
+ <c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
+ elements of the tuple.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
+ <fsummary>Create a list term.</fsummary>
+ <desc><p>Create an ordinary list term of length <c>cnt</c>. Expects
+ <c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
+ elements of the list. An empty list is returned if <c>cnt</c> is 0.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list_cell(ErlNifEnv* env, ERL_NIF_TERM head, ERL_NIF_TERM tail)</nametext></name>
+ <fsummary>Create a list cell.</fsummary>
+ <desc><p>Create a list cell <c>[head | tail]</c>.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string(ErlNifEnv* env, const char* string)</nametext></name>
+ <fsummary>Create a string.</fsummary>
+ <desc><p>Creates a list containing the characters of the
+ C-string <c>string</c>.</p></desc>
+ </func>
+ </funcs>
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="erlang#erlang:load_nif-2">load_nif(3)</seealso></p>
+ </section>
+</cref>
+
diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml
new file mode 100644
index 0000000000..ccaa9b725f
--- /dev/null
+++ b/erts/doc/src/erl_prim_loader.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erl_prim_loader</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>erl_prim_loader.xml</file>
+ </header>
+ <module>erl_prim_loader</module>
+ <modulesummary>Low Level Erlang Loader</modulesummary>
+ <description>
+ <p><c>erl_prim_loader</c> is used to load all Erlang modules into
+ the system. The start script is also fetched with this low level
+ loader.</p>
+ <p><c>erl_prim_loader</c> knows about the environment and how to
+ fetch modules. The loader could, for example, fetch files using
+ the file system (with absolute file names as input), or a
+ database (where the binary format of a module is stored).</p>
+ <p>The <c>-loader Loader</c> command line flag can be used to
+ choose the method used by the <c>erl_prim_loader</c>. Two
+ <c>Loader</c> methods are supported by the Erlang runtime system:
+ <c>efile</c> and <c>inet</c>. If another loader is required, then
+ it has to be implemented by the user. The <c>Loader</c> provided
+ by the user must fulfill the protocol defined below, and it is
+ started with the <c>erl_prim_loader</c> by evaluating
+ <c>open_port({spawn,Loader},[binary])</c>.</p>
+
+ <warning><p>The support for loading of code from archive files is
+ experimental. The sole purpose of releasing it before it is ready
+ is to obtain early feedback. The file format, semantics,
+ interfaces etc. may be changed in a future release. The functions
+ <c>list_dir/1</c> and <c>read_file_info/1</c> as well as the flag
+ <c>-loader_debug</c> are also experimental</p></warning>
+
+ </description>
+ <funcs>
+ <func>
+ <name>start(Id, Loader, Hosts) -> {ok, Pid} | {error, What}</name>
+ <fsummary>Start the Erlang low level loader</fsummary>
+ <type>
+ <v>Id = term()</v>
+ <v>Loader = atom() | string()</v>
+ <v>Hosts = [Host]</v>
+ <v>Host = atom()</v>
+ <v>Pid = pid()</v>
+ <v>What = term()</v>
+ </type>
+ <desc>
+ <p>Starts the Erlang low level loader. This function is called
+ by the <c>init</c> process (and module). The <c>init</c>
+ process reads the command line flags <c>-id Id</c>,
+ <c>-loader Loader</c>, and <c>-hosts Hosts</c>. These are
+ the arguments supplied to the <c>start/3</c> function.</p>
+ <p>If <c>-loader</c> is not given, the default loader is
+ <c>efile</c> which tells the system to read from the file
+ system.</p>
+ <p>If <c>-loader</c> is <c>inet</c>, the <c>-id Id</c>,
+ <c>-hosts Hosts</c>, and <c>-setcookie Cookie</c> flags must
+ also be supplied. <c>Hosts</c> identifies hosts which this
+ node can contact in order to load modules. One Erlang
+ runtime system with a <c>erl_boot_server</c> process must be
+ started on each of hosts given in <c>Hosts</c> in order to
+ answer the requests. See <seealso
+ marker="kernel:erl_boot_server">erl_boot_server(3)</seealso>.</p>
+ <p>If <c>-loader</c> is something else, the given port program
+ is started. The port program is supposed to follow
+ the protocol specified below.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_file(Filename) -> {ok, Bin, FullName} | error</name>
+ <fsummary>Get a file</fsummary>
+ <type>
+ <v>Filename = string()</v>
+ <v>Bin = binary()</v>
+ <v>FullName = string()</v>
+ </type>
+ <desc>
+ <p>This function fetches a file using the low level loader.
+ <c>Filename</c> is either an absolute file name or just the name
+ of the file, for example <c>"lists.beam"</c>. If an internal
+ path is set to the loader, this path is used to find the file.
+ If a user supplied loader is used, the path can be stripped
+ off if it is obsolete, and the loader does not use a path.
+ <c>FullName</c> is the complete name of the fetched file.
+ <c>Bin</c> is the contents of the file as a binary.</p>
+
+ <p>The <c>Filename</c> can also be a file in an archive. For example
+ <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin/mnesia_backup.beam</c>
+ See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_path() -> {ok, Path}</name>
+ <fsummary>Get the path set in the loader</fsummary>
+ <type>
+ <v>Path = [Dir]</v>
+ <v>Dir = string()</v>
+ </type>
+ <desc>
+ <p>This function gets the path set in the loader. The path is
+ set by the <c>init</c> process according to information found
+ in the start script.</p>
+ </desc>
+ </func>
+ <func>
+ <name>list_dir(Dir) -> {ok, Filenames} | error</name>
+ <fsummary>List files in a directory</fsummary>
+ <type>
+ <v>Dir = name()</v>
+ <v>Filenames = [Filename]</v>
+ <v>Filename = string()</v>
+ </type>
+ <desc>
+ <p>Lists all the files in a directory. Returns
+ <c>{ok, Filenames}</c> if successful. Otherwise, it returns
+ <c>error</c>. <c>Filenames</c> is a list of
+ the names of all the files in the directory. The names are
+ not sorted.</p>
+ <p>The <c>Dir</c> can also be a directory in an archive. For example
+ <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c>
+ See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p>
+ </desc>
+ </func>
+ <func>
+ <name>read_file_info(Filename) -> {ok, FileInfo} | error</name>
+ <fsummary>Get information about a file</fsummary>
+ <type>
+ <v>Filename = name()</v>
+ <v>FileInfo = #file_info{}</v>
+ </type>
+ <desc>
+ <p>Retrieves information about a file. Returns
+ <c>{ok, FileInfo}</c> if successful, otherwise
+ <c>error</c>. <c>FileInfo</c> is a record
+ <c>file_info</c>, defined in the Kernel include file
+ <c>file.hrl</c>. Include the following directive in the module
+ from which the function is called:</p>
+ <code type="none">
+-include_lib("kernel/include/file.hrl").</code>
+ <p>See <seealso marker="kernel:file">file(3)</seealso> for more info about
+ the record <c>file_info</c>.</p>
+ <p>The <c>Filename</c> can also be a file in an archive. For example
+ <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin/mnesia_backup.beam</c>
+ See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p>
+ </desc>
+ </func>
+ <func>
+ <name>set_path(Path) -> ok</name>
+ <fsummary>Set the path of the loader</fsummary>
+ <type>
+ <v>Path = [Dir]</v>
+ <v>Dir = string()</v>
+ </type>
+ <desc>
+ <p>This function sets the path of the loader if <c>init</c>
+ interprets a <c>path</c> command in the start script.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Protocol</title>
+ <p>The following protocol must be followed if a user provided
+ loader port program is used. The <c>Loader</c> port program is
+ started with the command
+ <c>open_port({spawn,Loader},[binary])</c>. The protocol is as
+ follows:</p>
+ <pre>
+Function Send Receive
+-------------------------------------------------------------
+get_file [102 | FileName] [121 | BinaryFile] (on success)
+ [122] (failure)
+
+stop eof terminate</pre>
+ </section>
+
+ <section>
+ <title>Command Line Flags</title>
+ <p>The <c>erl_prim_loader</c> module interprets the following
+ command line flags:</p>
+ <taglist>
+ <tag><c>-loader Loader</c></tag>
+ <item>
+ <p>Specifies the name of the loader used by
+ <c>erl_prim_loader</c>. <c>Loader</c> can be <c>efile</c>
+ (use the local file system), or <c>inet</c> (load using
+ the <c>boot_server</c> on another Erlang node). If
+ <c>Loader</c> is user defined, the defined <c>Loader</c> port
+ program is started.</p>
+ <p>If the <c>-loader</c> flag is omitted, it defaults to
+ <c>efile</c>.</p>
+ </item>
+ <tag><c>-loader_debug</c></tag>
+ <item>
+ <p>Makes the <c>efile</c> loader write some debug information,
+ such as the reason for failures, while it handles files.</p>
+ </item>
+ <tag><c>-hosts Hosts</c></tag>
+ <item>
+ <p>Specifies which other Erlang nodes the <c>inet</c> loader
+ can use. This flag is mandatory if the <c>-loader inet</c>
+ flag is present. On each host, there must be on Erlang node
+ with the <c>erl_boot_server</c> which handles the load
+ requests. <c>Hosts</c> is a list of IP addresses (hostnames
+ are not acceptable).</p>
+ </item>
+ <tag><c>-id Id</c></tag>
+ <item>
+ <p>Specifies the identity of the Erlang runtime system. If
+ the system runs as a distributed node, <c>Id</c> must be
+ identical to the name supplied with the <c>-sname</c> or
+ <c>-name</c> distribution flags.</p>
+ </item>
+ <tag><c>-setcookie Cookie</c></tag>
+ <item>
+ <p>Specifies the cookie of the Erlang runtime system. This flag
+ is mandatory if the <c>-loader inet</c> flag is present.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="init">init(3)</seealso>,
+ <seealso marker="kernel:erl_boot_server">erl_boot_server(3)</seealso></p>
+ </section>
+</erlref>
+
diff --git a/erts/doc/src/erl_set_memory_block.xml b/erts/doc/src/erl_set_memory_block.xml
new file mode 100644
index 0000000000..d77da56d95
--- /dev/null
+++ b/erts/doc/src/erl_set_memory_block.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>1998</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erl_set_memory_block</title>
+ <prepared>Patrik Nyblom</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>98-08-05</date>
+ <rev>A</rev>
+ <file>erl_set_memory_block.xml</file>
+ </header>
+ <lib>erl_set_memory_block</lib>
+ <libsummary>Custom memory allocation for Erlang on VxWorks&reg;</libsummary>
+ <description>
+ <p>This documentation is specific to VxWorks.</p>
+ <p>The <c><![CDATA[erl_set_memory_block]]></c> function/command initiates custom
+ memory allocation for the Erlang emulator. It has to be called
+ before the Erlang emulator is started and makes Erlang use one
+ single large memory block for all memory allocation.</p>
+ <p>The memory within the block can be utilized by other tasks than
+ Erlang. This is accomplished by calling the functions
+ <c><![CDATA[sys_alloc]]></c>, <c><![CDATA[sys_realloc]]></c> and <c><![CDATA[sys_free]]></c> instead
+ of <c><![CDATA[malloc]]></c>, <c><![CDATA[realloc]]></c> and <c><![CDATA[free]]></c> respectively.</p>
+ <p>The purpose of this is to avoid problems inherent in the
+ VxWorks systems <c><![CDATA[malloc]]></c> library. The memory allocation within the
+ large memory block avoids fragmentation by using an "address
+ order first fit" algorithm. Another advantage of using a
+ separate memory block is that resource reclamation can be made
+ more easily when Erlang is stopped.</p>
+ <p>The <c><![CDATA[erl_set_memory_block]]></c> function is callable from any C
+ program as an ordinary 10 argument function as well as
+ from the commandline.</p>
+ </description>
+ <funcs>
+ <func>
+ <name><ret>int</ret><nametext>erl_set_memory_block(size_t size, void *ptr, int warn_mixed_malloc, int realloc_always_moves, int use_reclaim, ...)</nametext></name>
+ <fsummary>Specify parameters for Erlang internal memory allocation.</fsummary>
+ <desc>
+ <p>The function is called before Erlang is
+ started to specify a large memory block where Erlang can
+ maintain memory internally.</p>
+ <p>Parameters:</p>
+ <taglist>
+ <tag>size_t size</tag>
+ <item>The size in bytes of Erlang's internal memory block. Has to
+ be specified. Note that the VxWorks system uses dynamic
+ memory allocation heavily, so leave some memory to the system.</item>
+ <tag>void *ptr</tag>
+ <item>
+ <p>A pointer to the actual memory block of size
+ <c><![CDATA[size]]></c>. If this is specified as 0 (NULL), Erlang will
+ allocate the memory when starting and will reclaim the
+ memory block (as a whole) when stopped.</p>
+ <p>If a memory block is allocated and provided here, the
+ <c><![CDATA[sys_alloc]]></c> etc routines can still be used after
+ the Erlang emulator is stopped. The Erlang emulator can
+ also be restarted while other tasks using the memory
+ block are running without destroying the memory. If
+ Erlang is to be restarted, also set the
+ <c><![CDATA[use_reclaim]]></c> flag.</p>
+ <p>If 0 is specified here, the Erlang system should not
+ be stopped while some other task uses the memory block
+ (has called <c><![CDATA[sys_alloc]]></c>).</p>
+ </item>
+ <tag>int warn_mixed_malloc</tag>
+ <item>
+ <p>If this flag is set to true (anything else than 0), the
+ system will write a warning message on the console if a
+ program is mixing normal <c><![CDATA[malloc]]></c> with
+ <c><![CDATA[sys_realloc]]></c> or <c><![CDATA[sys_free]]></c>.</p>
+ </item>
+ <tag>int realloc_always_moves</tag>
+ <item>
+ <p>If this flag is set to true (anything else than 0), all
+ calls to <c><![CDATA[sys_realloc]]></c> result in a moved memory
+ block. This can in certain conditions give less
+ fragmentation. This flag may be removed in future releases.</p>
+ </item>
+ <tag>int use_reclaim</tag>
+ <item>
+ <p>If this flag is set to true (anything else than 0), all
+ memory allocated with <c><![CDATA[sys_alloc]]></c> is automatically
+ reclaimed as soon as a task exits. This is very useful
+ to make writing port programs (and other programs as
+ well) easier. Combine this with using the routines
+ <c><![CDATA[save_open]]></c> etc. specified in the reclaim.h
+ file delivered in the Erlang distribution.</p>
+ </item>
+ </taglist>
+ <p>Return Value:</p>
+ <p>Returns 0 (OK) on success, otherwise a value &lt;&gt; 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_memory_show(...)</nametext></name>
+ <fsummary>A utility similar to VxWorks <c><![CDATA[memShow]]></c>, but for the Erlang memory area.</fsummary>
+ <desc>
+ <p>Return Value:</p>
+ <p>Returns 0 (OK) on success, otherwise a value &lt;&gt; 0.</p>
+ </desc>
+ </func>
+ <func>
+ <name><ret>int</ret><nametext>erl_mem_info_get(MEM_PART_STATS *stats)</nametext></name>
+ <fsummary>A utility similar to VxWorks <c><![CDATA[memPartInfoGet]]></c>, but for the Erlang memory area.</fsummary>
+ <desc>
+ <p>Parameter:</p>
+ <taglist>
+ <tag>MEM_PART_STATS *stats</tag>
+ <item>A pointer to a MEM_PART_STATS structure as defined in
+ <c><![CDATA[<memLib.h>]]></c>. A successful call will fill in all
+ fields of the structure, on error all fields are left untouched. </item>
+ </taglist>
+ <p>Return Value:</p>
+ <p>Returns 0 (OK) on success, otherwise a value &lt;&gt; 0</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>NOTES</title>
+ <p>The memory block used by Erlang actually does not need to be
+ inside the area known to ordinary <c><![CDATA[malloc]]></c>. It is possible
+ to set the <c><![CDATA[USER_RESERVED_MEM]]></c> preprocessor symbol when compiling
+ the wind kernel and then use user reserved memory for
+ Erlang. Erlang can therefor utilize memory above the 32 Mb limit
+ of VxWorks on the PowerPC architecture.</p>
+ <p>Example:</p>
+ <p>In config.h for the wind kernel:</p>
+ <code type="none"><![CDATA[
+ #undef LOCAL_MEM_AUTOSIZE
+ #undef LOCAL_MEM_SIZE
+ #undef USER_RESERVED_MEM
+
+ #define LOCAL_MEM_SIZE 0x05000000
+ #define USER_RESERVED_MEM 0x03000000
+ ]]></code>
+ <p>In the start-up script/code for the VxWorks node:</p>
+ <code type="none"><![CDATA[
+erl_set_memory_block(sysPhysMemTop()-sysMemTop(),sysMemTop(),0,0,1);
+ ]]></code>
+ <p>Setting the <c><![CDATA[use_reclaim]]></c> flag decreases performance of the
+ system, but makes programming much easier. Other similar
+ facilities are present in the Erlang system even without using a
+ separate memory block. The routines called <c><![CDATA[save_malloc]]></c>,
+ <c><![CDATA[save_realloc]]></c> and <c><![CDATA[save_free]]></c> provide the same
+ facilities by using VxWorks own <c><![CDATA[malloc]]></c>. Similar routines
+ exist for files, see the file <c><![CDATA[reclaim.h]]></c> in the distribution.</p>
+ </section>
+</cref>
+
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
new file mode 100644
index 0000000000..fd4447009a
--- /dev/null
+++ b/erts/doc/src/erlang.xml
@@ -0,0 +1,6920 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erlang</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>erlang.xml</file>
+ </header>
+ <module>erlang</module>
+ <modulesummary>The Erlang BIFs</modulesummary>
+ <description>
+ <p>By convention, most built-in functions (BIFs) are seen as being
+ in the module <c>erlang</c>. A number 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 and both the calls <c>atom_to_list(Erlang)</c> and
+ <c>erlang:atom_to_list(Erlang)</c> are identical.</p>
+ <p>In the text, auto-imported BIFs are listed without module prefix.
+ BIFs listed with module prefix are not auto-imported.</p>
+ <p>BIFs may fail for a variety of reasons. All BIFs fail with
+ reason <c>badarg</c> if they are called with arguments of an
+ incorrect type. The other reasons that may make BIFs fail are
+ described in connection with the description of each individual
+ BIF.</p>
+ <p>Some BIFs may be used in guard tests, these are marked with
+ "Allowed in guard tests".</p>
+ </description>
+
+ <section>
+ <title>DATA TYPES</title>
+ <marker id="iolist_definition"></marker>
+ <code type="none">
+ext_binary()
+ a binary data object,
+ structured according to the Erlang external term format
+
+iodata() = iolist() | binary()
+
+iolist() = [char() | binary() | iolist()]
+ a binary is allowed as the tail of the list</code>
+ </section>
+ <funcs>
+ <func>
+ <name>abs(Number) -> int() | float()</name>
+ <fsummary>Arithmetical absolute value</fsummary>
+ <type>
+ <v>Number = number()</v>
+ </type>
+ <desc>
+ <p>Returns an integer or float which is the arithmetical
+ absolute value of <c>Number</c>.</p>
+ <pre>
+> <input>abs(-3.33).</input>
+3.33
+> <input>abs(-3).</input>
+3</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>adler32(Data) -> int()</name>
+ <fsummary>Compute adler32 checksum</fsummary>
+ <type>
+ <v>Data = iodata()</v>
+ </type>
+ <desc>
+ <p>Computes and returns the adler32 checksum for <c>Data</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>adler32(OldAdler, Data) -> int()</name>
+ <fsummary>Compute adler32 checksum</fsummary>
+ <type>
+ <v>OldAdler = int()</v>
+ <v>Data = iodata()</v>
+ </type>
+ <desc>
+ <p>Continue computing the adler32 checksum by combining
+ the previous checksum, <c>OldAdler</c>, with the checksum of
+ <c>Data</c>.</p>
+ <p>The following code:</p>
+ <code>
+ X = adler32(Data1),
+ Y = adler32(X,Data2).
+ </code>
+ <p>- would assign the same value to <c>Y</c> as this would:</p>
+ <code>
+ Y = adler32([Data1,Data2]).
+ </code>
+ </desc>
+ </func>
+ <func>
+ <name>adler32_combine(FirstAdler, SecondAdler, SecondSize) -> int()</name>
+ <fsummary>Combine two adler32 checksums</fsummary>
+ <type>
+ <v>FirstAdler = SecondAdler = int()</v>
+ <v>SecondSize = int()</v>
+ </type>
+ <desc>
+ <p>Combines two previously computed adler32 checksums.
+ This computation requires the size of the data object for
+ the second checksum to be known.</p>
+ <p>The following code:</p>
+ <code>
+ Y = adler32(Data1),
+ Z = adler32(Y,Data2).
+ </code>
+ <p>- would assign the same value to <c>Z</c> as this would:</p>
+ <code>
+ X = adler32(Data1),
+ Y = adler32(Data2),
+ Z = adler32_combine(X,Y,iolist_size(Data2)).
+ </code>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:append_element(Tuple1, Term) -> Tuple2</name>
+ <fsummary>Append an extra element to a tuple</fsummary>
+ <type>
+ <v>Tuple1 = Tuple2 = tuple()</v>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns a new tuple which has one element more than
+ <c>Tuple1</c>, and contains the elements in <c>Tuple1</c>
+ followed by <c>Term</c> as the last element. Semantically
+ equivalent to
+ <c>list_to_tuple(tuple_to_list(Tuple ++ [Term])</c>, but much
+ faster.</p>
+ <pre>
+> <input>erlang:append_element({one, two}, three).</input>
+{one,two,three}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Fun, Args) -> term() | empty()</name>
+ <fsummary>Apply a function to an argument list</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Call a fun, passing the elements in <c>Args</c> as
+ arguments.</p>
+ <p>Note: If the number of elements in the arguments are known at
+ compile-time, the call is better written as
+ <c>Fun(Arg1, Arg2, ... ArgN)</c>.</p>
+ <warning>
+ <p>Earlier, <c>Fun</c> could also be given as
+ <c>{Module, Function}</c>, equivalent to
+ <c>apply(Module, Function, Args)</c>. This usage is
+ deprecated and will stop working in a future release of
+ Erlang/OTP.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Module, Function, Args) -> term() | empty()</name>
+ <fsummary>Apply a function to an argument list</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the result of applying <c>Function</c> in
+ <c>Module</c> to <c>Args</c>. The applied function must
+ be exported from <c>Module</c>. The arity of the function is
+ the length of <c>Args</c>.</p>
+ <pre>
+> <input>apply(lists, reverse, [[a, b, c]]).</input>
+[c,b,a]</pre>
+ <p><c>apply</c> can be used to evaluate BIFs by using
+ the module name <c>erlang</c>.</p>
+ <pre>
+> <input>apply(erlang, atom_to_list, ['Erlang']).</input>
+"Erlang"</pre>
+ <p>Note: If the number of arguments are known at compile-time,
+ the call is better written as
+ <c>Module:Function(Arg1, Arg2, ..., ArgN)</c>.</p>
+ <p>Failure: <c>error_handler:undefined_function/3</c> is called
+ if the applied function is not exported. The error handler
+ can be redefined (see
+ <seealso marker="#process_flag/2">process_flag/2</seealso>).
+ If the <c>error_handler</c> is undefined, or if the user has
+ redefined the default <c>error_handler</c> so the replacement
+ module is undefined, an error with the reason <c>undef</c>
+ is generated.</p>
+ </desc>
+ </func>
+ <func>
+ <name>atom_to_binary(Atom, Encoding) -> binary()</name>
+ <fsummary>Return the binary representation of an atom</fsummary>
+ <type>
+ <v>Atom = atom()</v>
+ <v>Encoding = latin1 | utf8 | unicode</v>
+ </type>
+ <desc>
+ <p>Returns a binary which corresponds to the text
+ representation of <c>Atom</c>. If <c>Encoding</c>
+ is <c>latin1</c>, there will be one byte for each character
+ in the text representation. If <c>Encoding</c> is <c>utf8</c> or
+ <c>unicode</c>, the characters will encoded using UTF-8
+ (meaning that characters from 16#80 up to 0xFF will be
+ encode in two bytes).</p>
+
+ <note><p>Currently, <c>atom_to_binary(Atom, latin1)</c> can
+ never fail because the text representation of an atom can only contain
+ characters from 0 to 16#FF. In a future release, the text representation
+ of atoms might be allowed to contain any Unicode character
+ and <c>atom_to_binary(Atom, latin1)</c> will fail if the
+ text representation for the <c>Atom</c> contains a Unicode
+ character greater than 16#FF.</p></note>
+
+ <pre>
+> <input>atom_to_binary('Erlang', latin1).</input>
+&lt;&lt;"Erlang"&gt;&gt;</pre>
+ </desc>
+ </func>
+ <func>
+ <name>atom_to_list(Atom) -> string()</name>
+ <fsummary>Text representation of an atom</fsummary>
+ <type>
+ <v>Atom = atom()</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Atom</c>.</p>
+ <pre>
+> <input>atom_to_list('Erlang').</input>
+"Erlang"</pre>
+ </desc>
+ </func>
+ <func>
+ <name>binary_to_atom(Binary, Encoding) -> atom()</name>
+ <fsummary>Convert from text representation to an atom</fsummary>
+ <type>
+ <v>Binary = binary()</v>
+ <v>Encoding = latin1 | utf8 | unicode</v>
+ </type>
+ <desc>
+ <p>Returns the atom whose text representation is
+ <c>Binary</c>. If <c>Encoding</c> is <c>latin1</c>, no
+ translation of bytes in the binary is done. If <c>Encoding</c>
+ is <c>utf8</c> or <c>unicode</c>, the binary must contain
+ valid UTF-8 sequences; furthermore, only Unicode characters up
+ to 0xFF are allowed.</p>
+
+ <note><p><c>binary_to_atom(Binary, utf8)</c> will fail if
+ the binary contains Unicode characters greater than 16#FF.
+ In a future release, such Unicode characters might be allowed
+ and <c>binary_to_atom(Binary, utf8)</c>
+ will not fail in that case.</p></note>
+
+ <pre>
+> <input>binary_to_atom(&lt;&lt;"Erlang"&gt;&gt;, latin1).</input>
+'Erlang'
+> <input>binary_to_atom(&lt;&lt;1024/utf8&gt;&gt;, utf8).</input>
+** exception error: bad argument
+ in function binary_to_atom/2
+ called as binary_to_atom(&lt;&lt;208,128&gt;&gt;,utf8)</pre>
+ </desc>
+ </func>
+ <func>
+ <name>binary_to_existing_atom(Binary, Encoding) -> atom()</name>
+ <fsummary>Convert from text representation to an atom</fsummary>
+ <type>
+ <v>Binary = binary()</v>
+ <v>Encoding = latin1 | utf8 | unicode</v>
+ </type>
+ <desc>
+ <p>Works like <seealso marker="#binary_to_atom/2">binary_to_atom/2</seealso>,
+ but the atom must already exist.</p>
+ <p>Failure: <c>badarg</c> if the atom does not already exist.</p>
+ </desc>
+ </func>
+ <func>
+ <name>binary_to_list(Binary) -> [char()]</name>
+ <fsummary>Convert a binary to a list</fsummary>
+ <type>
+ <v>Binary = binary()</v>
+ </type>
+ <desc>
+ <p>Returns a list of integers which correspond to the bytes of
+ <c>Binary</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>binary_to_list(Binary, Start, Stop) -> [char()]</name>
+ <fsummary>Convert part of a binary to a list</fsummary>
+ <type>
+ <v>Binary = binary()</v>
+ <v>Start = Stop = 1..byte_size(Binary)</v>
+ </type>
+ <desc>
+ <p>As <c>binary_to_list/1</c>, but returns a list of integers
+ corresponding to the bytes from position <c>Start</c> to
+ position <c>Stop</c> in <c>Binary</c>. Positions in the
+ binary are numbered starting from 1.</p>
+ </desc>
+ </func>
+ <func>
+ <name>bitstring_to_list(Bitstring) -> [char()|bitstring()]</name>
+ <fsummary>Convert a bitstring to a list</fsummary>
+ <type>
+ <v>Bitstring = bitstring()</v>
+ </type>
+ <desc>
+ <p>Returns a list of integers which correspond to the bytes of
+ <c>Bitstring</c>. If the number of bits in the binary is not
+ divisible by 8, the last element of the list will be a bitstring
+ containing the remaining bits (1 up to 7 bits).</p>
+ </desc>
+ </func>
+ <func>
+ <name>binary_to_term(Binary) -> term()</name>
+ <fsummary>Decode an Erlang external term format binary</fsummary>
+ <type>
+ <v>Binary = ext_binary()</v>
+ </type>
+ <desc>
+ <p>Returns an Erlang term which is the result of decoding
+ the binary object <c>Binary</c>, which must be encoded
+ according to the Erlang external term format. See also
+ <seealso marker="#term_to_binary/1">term_to_binary/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>bit_size(Bitstring) -> int()</name>
+ <fsummary>Return the size of a bitstring</fsummary>
+ <type>
+ <v>Bitstring = bitstring()</v>
+ </type>
+ <desc>
+ <p>Returns an integer which is the size in bits of <c>Bitstring</c>.</p>
+ <pre>
+> <input>bit_size(&lt;&lt;433:16,3:3&gt;&gt;).</input>
+19
+> <input>bit_size(&lt;&lt;1,2,3&gt;&gt;).</input>
+24</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:bump_reductions(Reductions) -> void()</name>
+ <fsummary>Increment the reduction counter</fsummary>
+ <type>
+ <v>Reductions = int()</v>
+ </type>
+ <desc>
+ <p>This implementation-dependent function increments
+ the reduction counter for the calling process. In the Beam
+ emulator, the reduction counter is normally incremented by
+ one for each function and BIF call, and a context switch is
+ forced when the counter reaches the maximum number of reductions
+ for a process (2000 reductions in R12B).</p>
+ <warning>
+ <p>This BIF might be removed in a future version of the Beam
+ machine without prior warning. It is unlikely to be
+ implemented in other Erlang implementations.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>byte_size(Bitstring) -> int()</name>
+ <fsummary>Return the size of a bitstring (or binary)</fsummary>
+ <type>
+ <v>Bitstring = bitstring()</v>
+ </type>
+ <desc>
+ <p>Returns an integer which is the number of bytes needed to contain
+ <c>Bitstring</c>. (That is, if the number of bits in <c>Bitstring</c> is not
+ divisible by 8, the resulting number of bytes will be rounded <em>up</em>.)</p>
+ <pre>
+> <input>byte_size(&lt;&lt;433:16,3:3&gt;&gt;).</input>
+3
+> <input>byte_size(&lt;&lt;1,2,3&gt;&gt;).</input>
+3</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:cancel_timer(TimerRef) -> Time | false</name>
+ <fsummary>Cancel a timer</fsummary>
+ <type>
+ <v>TimerRef = ref()</v>
+ <v>Time = int()</v>
+ </type>
+ <desc>
+ <p>Cancels a timer, where <c>TimerRef</c> was returned by
+ either
+ <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>
+ or
+ <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>.
+ If the timer is there to be removed, the function returns
+ the time in milliseconds left until the timer would have expired,
+ otherwise <c>false</c> (which means that <c>TimerRef</c> was
+ never a timer, that it has already been cancelled, or that it
+ has already delivered its message).</p>
+ <p>See also
+ <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
+ and
+ <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <p>Note: Cancelling a timer does not guarantee that the message
+ has not already been delivered to the message queue.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>check_process_code(Pid, Module) -> bool()</name>
+ <fsummary>Check if a process is executing old code for a module</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if the process <c>Pid</c> is executing
+ old code for <c>Module</c>. That is, if the current call of
+ the process executes old code for this module, or if the
+ process has references to old code for this module, or if the
+ process contains funs that references old code for this
+ module. Otherwise, it returns <c>false</c>.</p>
+ <pre>
+> <input>check_process_code(Pid, lists).</input>
+false</pre>
+ <p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>concat_binary(ListOfBinaries)</name>
+ <fsummary>Concatenate a list of binaries (deprecated)</fsummary>
+ <desc>
+ <p>Do not use; use
+ <seealso marker="#list_to_binary/1">list_to_binary/1</seealso>
+ instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name>crc32(Data) -> int()</name>
+ <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
+ <type>
+ <v>Data = iodata()</v>
+ </type>
+ <desc>
+ <p>Computes and returns the crc32 (IEEE 802.3 style) checksum for <c>Data</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>crc32(OldCrc, Data) -> int()</name>
+ <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
+ <type>
+ <v>OldCrc = int()</v>
+ <v>Data = iodata()</v>
+ </type>
+ <desc>
+ <p>Continue computing the crc32 checksum by combining
+ the previous checksum, <c>OldCrc</c>, with the checksum of
+ <c>Data</c>.</p>
+ <p>The following code:</p>
+ <code>
+ X = crc32(Data1),
+ Y = crc32(X,Data2).
+ </code>
+ <p>- would assign the same value to <c>Y</c> as this would:</p>
+ <code>
+ Y = crc32([Data1,Data2]).
+ </code>
+ </desc>
+ </func>
+ <func>
+ <name>crc32_combine(FirstCrc, SecondCrc, SecondSize) -> int()</name>
+ <fsummary>Combine two crc32 (IEEE 802.3) checksums</fsummary>
+ <type>
+ <v>FirstCrc = SecondCrc = int()</v>
+ <v>SecondSize = int()</v>
+ </type>
+ <desc>
+ <p>Combines two previously computed crc32 checksums.
+ This computation requires the size of the data object for
+ the second checksum to be known.</p>
+ <p>The following code:</p>
+ <code>
+ Y = crc32(Data1),
+ Z = crc32(Y,Data2).
+ </code>
+ <p>- would assign the same value to <c>Z</c> as this would:</p>
+ <code>
+ X = crc32(Data1),
+ Y = crc32(Data2),
+ Z = crc32_combine(X,Y,iolist_size(Data2)).
+ </code>
+ </desc>
+ </func>
+ <func>
+ <name>date() -> {Year, Month, Day}</name>
+ <fsummary>Current date</fsummary>
+ <type>
+ <v>Year = Month = Day = int()</v>
+ </type>
+ <desc>
+ <p>Returns the current date as <c>{Year, Month, Day}</c>.</p>
+ <p>The time zone and daylight saving time correction depend on
+ the underlying OS.</p>
+ <pre>
+> <input>date().</input>
+{1995,2,19}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>decode_packet(Type,Bin,Options) -> {ok,Packet,Rest} | {more,Length} | {error,Reason}</name>
+ <fsummary>Extracts a protocol packet from a binary</fsummary>
+ <type>
+ <v>Bin = binary()</v>
+ <v>Options = [Opt]</v>
+ <v>Packet = binary() | HttpPacket</v>
+ <v>Rest = binary()</v>
+ <v>Length = int() | undefined</v>
+ <v>Reason = term()</v>
+ <v>&nbsp;Type, Opt -- see below</v>
+ <v></v>
+ <v>HttpPacket = HttpRequest | HttpResponse | HttpHeader | http_eoh | HttpError</v>
+ <v>HttpRequest = {http_request, HttpMethod, HttpUri, HttpVersion}</v>
+ <v>HttpResponse = {http_response, HttpVersion, integer(), HttpString}</v>
+ <v>HttpHeader = {http_header, int(), HttpField, Reserved=term(), Value=HttpString}</v>
+ <v>HttpError = {http_error, HttpString}</v>
+ <v>HttpMethod = HttpMethodAtom | HttpString</v>
+ <v>HttpMethodAtom = 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE'</v>
+ <v>HttpUri = '*' | {absoluteURI, http|https, Host=HttpString, Port=int()|undefined, Path=HttpString} |
+ {scheme, Scheme=HttpString, HttpString} | {abs_path, HttpString} | HttpString</v>
+ <v>HttpVersion = {Major=int(), Minor=int()}</v>
+ <v>HttpString = string() | binary()</v>
+ <v>HttpField = HttpFieldAtom | HttpString</v>
+ <v>HttpFieldAtom = 'Cache-Control' | 'Connection' | 'Date' | 'Pragma' | 'Transfer-Encoding' | 'Upgrade' | 'Via' | 'Accept' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Authorization' | 'From' | 'Host' | 'If-Modified-Since' | 'If-Match' | 'If-None-Match' | 'If-Range' | 'If-Unmodified-Since' | 'Max-Forwards' | 'Proxy-Authorization' | 'Range' | 'Referer' | 'User-Agent' | 'Age' | 'Location' | 'Proxy-Authenticate' | 'Public' | 'Retry-After' | 'Server' | 'Vary' | 'Warning' | 'Www-Authenticate' | 'Allow' | 'Content-Base' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Md5' | 'Content-Range' | 'Content-Type' | 'Etag' | 'Expires' | 'Last-Modified' | 'Accept-Ranges' | 'Set-Cookie' | 'Set-Cookie2' | 'X-Forwarded-For' | 'Cookie' | 'Keep-Alive' | 'Proxy-Connection'</v>
+ <v></v>
+ </type>
+ <desc>
+ <p>Decodes the binary <c>Bin</c> according to the packet
+ protocol specified by <c>Type</c>. Very similar to the packet
+ handling done by sockets with the option {packet,Type}.</p>
+ <p>If an entire packet is contained in <c>Bin</c> it is
+ returned together with the remainder of the binary as
+ <c>{ok,Packet,Rest}</c>.</p>
+ <p>If <c>Bin</c> does not contain the entire packet,
+ <c>{more,Length}</c> is returned. <c>Length</c> is either the
+ expected <em>total size</em> of the packet or <c>undefined</c>
+ if the expected packet size is not known. <c>decode_packet</c>
+ can then be called again with more data added.</p>
+ <p>If the packet does not conform to the protocol format
+ <c>{error,Reason}</c> is returned.</p>
+ <p>The following values of <c>Type</c> are valid:</p>
+ <taglist>
+ <tag><c>raw | 0</c></tag>
+ <item>
+ <p>No packet handling is done. Entire binary is
+ returned unless it is empty.</p>
+ </item>
+ <tag><c>1 | 2 | 4</c></tag>
+ <item>
+ <p>Packets consist of a header specifying the number of
+ bytes in the packet, followed by that number of bytes.
+ The length of header can be one, two, or four bytes;
+ the order of the bytes is big-endian. The header
+ will be stripped off when the packet is returned.</p>
+ </item>
+ <tag><c>line</c></tag>
+ <item>
+ <p>A packet is a line terminated with newline. The
+ newline character is included in the returned packet
+ unless the line was truncated according to the option
+ <c>line_length</c>.</p>
+ </item>
+ <tag><c>asn1 | cdr | sunrm | fcgi | tpkt</c></tag>
+ <item>
+ <p>The header is <em>not</em> stripped off.</p>
+ <p>The meanings of the packet types are as follows:</p>
+ <taglist>
+ <tag><c>asn1</c> - ASN.1 BER</tag><item></item>
+ <tag><c>sunrm</c> - Sun's RPC encoding</tag><item></item>
+ <tag><c>cdr</c> - CORBA (GIOP 1.1)</tag><item></item>
+ <tag><c>fcgi</c> - Fast CGI</tag><item></item>
+ <tag><c>tpkt</c> - TPKT format [RFC1006]</tag><item></item>
+ </taglist>
+ </item>
+ <tag><c>http | httph | http_bin | httph_bin</c></tag>
+ <item>
+ <p>The Hypertext Transfer Protocol. The packets
+ are returned with the format according to
+ <c>HttpPacket</c> described above. A packet is either a
+ request, a response, a header or an end of header
+ mark. Invalid lines are returned as <c>HttpError</c>.</p>
+ <p>Recognized request methods and header fields are returned as atoms.
+ Others are returned as strings.</p>
+ <p>The protocol type <c>http</c> should only be used for
+ the first line when a <c>HttpRequest</c> or a
+ <c>HttpResponse</c> is expected. The following calls
+ should use <c>httph</c> to get <c>HttpHeader</c>'s until
+ <c>http_eoh</c> is returned that marks the end of the
+ headers and the beginning of any following message body.</p>
+ <p>The variants <c>http_bin</c> and <c>httph_bin</c> will return
+ strings (<c>HttpString</c>) as binaries instead of lists.</p>
+ </item>
+ </taglist>
+ <p>The following options are available:</p>
+ <taglist>
+ <tag><c>{packet_size, int()}</c></tag>
+ <item><p>Sets the max allowed size of the packet body. If
+ the packet header indicates that the length of the
+ packet is longer than the max allowed length, the packet
+ is considered invalid. Default is 0 which means no
+ size limit.</p>
+ </item>
+ <tag><c>{line_length, int()}</c></tag>
+ <item><p>Applies only to line oriented protocols
+ (<c>line</c>, <c>http</c>). Lines longer than this
+ will be truncated.</p>
+ </item>
+ </taglist>
+ <pre>
+> <input>erlang:decode_packet(1,&lt;&lt;3,"abcd"&gt;&gt;,[]).</input>
+{ok,&lt;&lt;"abc"&gt;&gt;,&lt;&lt;"d"&gt;&gt;}
+> <input>erlang:decode_packet(1,&lt;&lt;5,"abcd"&gt;&gt;,[]).</input>
+{more,6}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>delete_module(Module) -> true | undefined</name>
+ <fsummary>Make the current code for a module old</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Makes the current code for <c>Module</c> become old code, and
+ deletes all references for this module from the export table.
+ Returns <c>undefined</c> if the module does not exist,
+ otherwise <c>true</c>.</p>
+ <warning>
+ <p>This BIF is intended for the code server (see
+ <seealso marker="kernel:code">code(3)</seealso>) and should not be
+ used elsewhere.</p>
+ </warning>
+ <p>Failure: <c>badarg</c> if there is already an old version of
+ <c>Module</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:demonitor(MonitorRef) -> true</name>
+ <fsummary>Stop monitoring</fsummary>
+ <type>
+ <v>MonitorRef = ref()</v>
+ </type>
+ <desc>
+ <p>If <c>MonitorRef</c> is a reference which the calling process
+ obtained by calling
+ <seealso marker="#erlang:monitor/2">erlang:monitor/2</seealso>,
+ this monitoring is turned off. If the monitoring is already
+ turned off, nothing happens.</p>
+ <p>Once <c>erlang:demonitor(MonitorRef)</c> has returned it is
+ guaranteed that no <c>{'DOWN', MonitorRef, _, _, _}</c> message
+ due to the monitor will be placed in the callers message queue
+ in the future. A <c>{'DOWN', MonitorRef, _, _, _}</c> message
+ might have been placed in the callers message queue prior to
+ the call, though. Therefore, in most cases, it is advisable
+ to remove such a <c>'DOWN'</c> message from the message queue
+ after monitoring has been stopped.
+ <seealso marker="#erlang:demonitor/2">erlang:demonitor(MonitorRef, [flush])</seealso> can be used instead of
+ <c>erlang:demonitor(MonitorRef)</c> if this cleanup is wanted.</p>
+ <note>
+ <p>Prior to OTP release R11B (erts version 5.5) <c>erlang:demonitor/1</c>
+ behaved completely asynchronous, i.e., the monitor was active
+ until the "demonitor signal" reached the monitored entity. This
+ had one undesirable effect, though. You could never know when
+ you were guaranteed <em>not</em> to receive a <c>DOWN</c> message
+ due to the monitor.</p>
+ <p>Current behavior can be viewed as two combined operations:
+ asynchronously send a "demonitor signal" to the monitored entity
+ and ignore any future results of the monitor. </p>
+ </note>
+ <p>Failure: It is an error if <c>MonitorRef</c> refers to a
+ monitoring started by another process. Not all such cases are
+ cheap to check; if checking is cheap, the call fails with
+ <c>badarg</c> (for example if <c>MonitorRef</c> is a remote
+ reference).</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:demonitor(MonitorRef, OptionList) -> true|false</name>
+ <fsummary>Stop monitoring</fsummary>
+ <type>
+ <v>MonitorRef = ref()</v>
+ <v>OptionList = [Option]</v>
+ <v>Option = flush</v>
+ <v>Option = info</v>
+ </type>
+ <desc>
+ <p>The returned value is <c>true</c> unless <c>info</c> is part
+ of <c>OptionList</c>.
+ </p>
+ <p><c>erlang:demonitor(MonitorRef, [])</c> is equivalent to
+ <seealso marker="#erlang:demonitor/1">erlang:demonitor(MonitorRef)</seealso>.</p>
+ <p>Currently the following <c>Option</c>s are valid:</p>
+ <taglist>
+ <tag><c>flush</c></tag>
+ <item>
+ <p>Remove (one) <c>{_, MonitorRef, _, _, _}</c> message,
+ if there is one, from the callers message queue after
+ monitoring has been stopped.</p>
+ <p>Calling <c>erlang:demonitor(MonitorRef, [flush])</c>
+ is equivalent to the following, but more efficient:</p>
+ <code type="none">
+
+ erlang:demonitor(MonitorRef),
+ receive
+\011{_, MonitorRef, _, _, _} ->
+\011 true
+ after 0 ->
+\011 true
+ end</code>
+ </item>
+ <tag><c>info</c></tag>
+ <item>
+ <p>The returned value is one of the following:</p>
+ <taglist>
+ <tag><c>true</c></tag>
+ <item><p>The monitor was found and removed. In this case
+ no <c>'DOWN'</c> message due to this monitor have
+ been nor will be placed in the message queue
+ of the caller.
+ </p>
+ </item>
+ <tag><c>false</c></tag>
+ <item><p>The monitor was not found and could not be removed.
+ This probably because someone already has placed a
+ <c>'DOWN'</c> message corresponding to this monitor
+ in the callers message queue.
+ </p>
+ </item>
+ </taglist>
+ <p>If the <c>info</c> option is combined with the <c>flush</c>
+ option, <c>false</c> will be returned if a flush was needed;
+ otherwise, <c>true</c>.
+ </p>
+ </item>
+ </taglist>
+ <note>
+ <p>More options may be added in the future.</p>
+ </note>
+ <p>Failure: <c>badarg</c> if <c>OptionList</c> is not a list, or
+ if <c>Option</c> is not a valid option, or the same failure as for
+ <seealso marker="#erlang:demonitor/1">erlang:demonitor/1</seealso></p>
+ </desc>
+ </func>
+ <func>
+ <name>disconnect_node(Node) -> bool() | ignored</name>
+ <fsummary>Force the disconnection of a node</fsummary>
+ <type>
+ <v>Node = atom()</v>
+ </type>
+ <desc>
+ <p>Forces the disconnection of a node. This will appear to
+ the node <c>Node</c> as if the local node has crashed. This
+ BIF is mainly used in the Erlang network authentication
+ protocols. Returns <c>true</c> if disconnection succeeds,
+ otherwise <c>false</c>. If the local node is not alive,
+ the function returns <c>ignored</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:display(Term) -> true</name>
+ <fsummary>Print a term on standard output</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Prints a text representation of <c>Term</c> on the standard
+ output.</p>
+ <warning>
+ <p>This BIF is intended for debugging only.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>element(N, Tuple) -> term()</name>
+ <fsummary>Get Nth element of a tuple</fsummary>
+ <type>
+ <v>N = 1..tuple_size(Tuple)</v>
+ <v>Tuple = tuple()</v>
+ </type>
+ <desc>
+ <p>Returns the <c>N</c>th element (numbering from 1) of
+ <c>Tuple</c>.</p>
+ <pre>
+> <input>element(2, {a, b, c}).</input>
+b</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erase() -> [{Key, Val}]</name>
+ <fsummary>Return and delete the process dictionary</fsummary>
+ <type>
+ <v>Key = Val = term()</v>
+ </type>
+ <desc>
+ <p>Returns the process dictionary and deletes it.</p>
+ <pre>
+> <input>put(key1, {1, 2, 3}),</input>
+<input>put(key2, [a, b, c]),</input>
+<input>erase().</input>
+[{key1,{1,2,3}},{key2,[a,b,c]}]</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erase(Key) -> Val | undefined</name>
+ <fsummary>Return and delete a value from the process dictionary</fsummary>
+ <type>
+ <v>Key = Val = term()</v>
+ </type>
+ <desc>
+ <p>Returns the value <c>Val</c> associated with <c>Key</c> and
+ deletes it from the process dictionary. Returns
+ <c>undefined</c> if no value is associated with <c>Key</c>.</p>
+ <pre>
+> <input>put(key1, {merry, lambs, are, playing}),</input>
+<input>X = erase(key1),</input>
+<input>{X, erase(key1)}.</input>
+{{merry,lambs,are,playing},undefined}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:error(Reason)</name>
+ <fsummary>Stop execution with a given reason</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Stops the execution of the calling process with the reason
+ <c>Reason</c>, where <c>Reason</c> is any term. The actual
+ exit reason will be <c>{Reason, Where}</c>, where <c>Where</c>
+ is a list of the functions most recently called (the current
+ function first). Since evaluating this function causes
+ the process to terminate, it has no return value.</p>
+ <pre>
+> <input>catch erlang: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>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:error(Reason, Args)</name>
+ <fsummary>Stop execution with a given reason</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Stops the execution of the calling process with the reason
+ <c>Reason</c>, where <c>Reason</c> is any term. The actual
+ exit reason will be <c>{Reason, Where}</c>, where <c>Where</c>
+ is a list of the functions most recently called (the current
+ function first). <c>Args</c> is expected to be the list of
+ arguments for the current function; in Beam it will be used
+ to provide the actual arguments for the current function in
+ the <c>Where</c> term. Since evaluating this function causes
+ the process to terminate, it has no return value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>exit(Reason)</name>
+ <fsummary>Stop execution with a given reason</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Stops the execution of the calling process with the exit
+ reason <c>Reason</c>, where <c>Reason</c> is any term. Since
+ evaluating this function causes the process to terminate, it
+ has no return value.</p>
+ <pre>
+> <input>exit(foobar).</input>
+** exception exit: foobar
+> <input>catch exit(foobar).</input>
+{'EXIT',foobar}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>exit(Pid, Reason) -> true</name>
+ <fsummary>Send an exit signal to a process</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Sends an exit signal with exit reason <c>Reason</c> to
+ the process <c>Pid</c>.</p>
+ <p>The following behavior apply if <c>Reason</c> is any term
+ except <c>normal</c> or <c>kill</c>:</p>
+ <p>If <c>Pid</c> is not trapping exits, <c>Pid</c> itself will
+ exit with exit reason <c>Reason</c>. If <c>Pid</c> is trapping
+ exits, the exit signal is transformed into a message
+ <c>{'EXIT', From, Reason}</c> and delivered to the message
+ queue of <c>Pid</c>. <c>From</c> is the pid of the process
+ which sent the exit signal. See also
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.</p>
+ <p>If <c>Reason</c> is the atom <c>normal</c>, <c>Pid</c> will
+ not exit. If it is trapping exits, the exit signal is
+ transformed into a message <c>{'EXIT', From, normal}</c>
+ and delivered to its message queue.</p>
+ <p>If <c>Reason</c> is the atom <c>kill</c>, that is if
+ <c>exit(Pid, kill)</c> is called, an untrappable exit signal
+ is sent to <c>Pid</c> which will unconditionally exit with
+ exit reason <c>killed</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>float(Number) -> float()</name>
+ <fsummary>Convert a number to a float</fsummary>
+ <type>
+ <v>Number = number()</v>
+ </type>
+ <desc>
+ <p>Returns a float by converting <c>Number</c> to a float.</p>
+ <pre>
+> <input>float(55).</input>
+55.0</pre>
+ <p>Allowed in guard tests.</p>
+ <note>
+ <p>Note that if used on the top-level in a guard, it will
+ test whether the argument is a floating point number; for
+ clarity, use
+ <seealso marker="#is_float/1">is_float/1</seealso> instead.</p>
+ <p>When <c>float/1</c> is used in an expression in a guard,
+ such as '<c>float(A) == 4.0</c>', it converts a number as
+ described above.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name>float_to_list(Float) -> string()</name>
+ <fsummary>Text representation of a float</fsummary>
+ <type>
+ <v>Float = float()</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Float</c>.</p>
+ <pre>
+> <input>float_to_list(7.0).</input>
+"7.00000000000000000000e+00"</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:fun_info(Fun) -> [{Item, Info}]</name>
+ <fsummary>Information about a fun</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ <v>Item, Info -- see below</v>
+ </type>
+ <desc>
+ <p>Returns a list containing information about the fun
+ <c>Fun</c>. Each element of the list is a tuple. The order of
+ the tuples is not defined, and more tuples may be added in a
+ future release.</p>
+ <warning>
+ <p>This BIF is mainly intended for debugging, but it can
+ occasionally be useful in library functions that might need
+ to verify, for instance, the arity of a fun.</p>
+ </warning>
+ <p>There are two types of funs with slightly different
+ semantics:</p>
+ <p>A fun created by <c>fun M:F/A</c> is called an
+ <em>external</em> fun. Calling it will always call the
+ function <c>F</c> with arity <c>A</c> in the latest code for
+ module <c>M</c>. Note that module <c>M</c> does not even need
+ to be loaded when the fun <c>fun M:F/A</c> is created.</p>
+ <p>All other funs are called <em>local</em>. When a local fun
+ is called, the same version of the code that created the fun
+ will be called (even if newer version of the module has been
+ loaded).</p>
+ <p>The following elements will always be present in the list
+ for both local and external funs:</p>
+ <taglist>
+ <tag><c>{type, Type}</c></tag>
+ <item>
+ <p><c>Type</c> is either <c>local</c> or <c>external</c>.</p>
+ </item>
+ <tag><c>{module, Module}</c></tag>
+ <item>
+ <p><c>Module</c> (an atom) is the module name.</p>
+ <p>If <c>Fun</c> is a local fun, <c>Module</c> is the module
+ in which the fun is defined.</p>
+ <p>If <c>Fun</c> is an external fun, <c>Module</c> is the
+ module that the fun refers to.</p>
+ </item>
+ <tag><c>{name, Name}</c></tag>
+ <item>
+ <p><c>Name</c> (an atom) is a function name.</p>
+ <p>If <c>Fun</c> is a local fun, <c>Name</c> is the name
+ of the local function that implements the fun.
+ (This name was generated by the compiler, and is generally
+ only of informational use. As it is a local function, it
+ is not possible to call it directly.)
+ If no code is currently loaded for the fun, <c>[]</c>
+ will be returned instead of an atom.</p>
+ <p>If <c>Fun</c> is an external fun, <c>Name</c> is the name
+ of the exported function that the fun refers to.</p>
+ </item>
+ <tag><c>{arity, Arity}</c></tag>
+ <item>
+ <p><c>Arity</c> is the number of arguments that the fun
+ should be called with.</p>
+ </item>
+ <tag><c>{env, Env}</c></tag>
+ <item>
+ <p><c>Env</c> (a list) is the environment or free variables
+ for the fun. (For external funs, the returned list is
+ always empty.)</p>
+ </item>
+ </taglist>
+ <p>The following elements will only be present in the list if
+ <c>Fun</c> is local:</p>
+ <taglist>
+ <tag><c>{pid, Pid}</c></tag>
+ <item>
+ <p><c>Pid</c> is the pid of the process that originally
+ created the fun.</p>
+ </item>
+ <tag><c>{index, Index}</c></tag>
+ <item>
+ <p><c>Index</c> (an integer) is an index into the module's
+ fun table.</p>
+ </item>
+ <tag><c>{new_index, Index}</c></tag>
+ <item>
+ <p><c>Index</c> (an integer) is an index into the module's
+ fun table.</p>
+ </item>
+ <tag><c>{new_uniq, Uniq}</c></tag>
+ <item>
+ <p><c>Uniq</c> (a binary) is a unique value for this fun.</p>
+ </item>
+ <tag><c>{uniq, Uniq}</c></tag>
+ <item>
+ <p><c>Uniq</c> (an integer) is a unique value for this fun.</p>
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:fun_info(Fun, Item) -> {Item, Info}</name>
+ <fsummary>Information about a fun</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ <v>Item, Info -- see below</v>
+ </type>
+ <desc>
+ <p>Returns information about <c>Fun</c> as specified by
+ <c>Item</c>, in the form <c>{Item,Info}</c>.</p>
+ <p>For any fun, <c>Item</c> can be any of the atoms
+ <c>module</c>, <c>name</c>, <c>arity</c>, or <c>env</c>.</p>
+ <p>For a local fun, <c>Item</c> can also be any of the atoms
+ <c>index</c>, <c>new_index</c>, <c>new_uniq</c>,
+ <c>uniq</c>, and <c>pid</c>. For an external fun, the value
+ of any of these items is always the atom <c>undefined</c>.</p>
+ <p>See
+ <seealso marker="#erlang:fun_info/1">erlang:fun_info/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:fun_to_list(Fun) -> string()</name>
+ <fsummary>Text representation of a fun</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Fun</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:function_exported(Module, Function, Arity) -> bool()</name>
+ <fsummary>Check if a function is exported and loaded</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Arity = int()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if the module <c>Module</c> is loaded
+ and contains an exported function <c>Function/Arity</c>;
+ otherwise <c>false</c>.</p>
+ <p>Returns <c>false</c> for any BIF (functions implemented in C
+ rather than in Erlang).</p>
+ </desc>
+ </func>
+ <func>
+ <name>garbage_collect() -> true</name>
+ <fsummary>Force an immediate garbage collection of the calling process</fsummary>
+ <desc>
+ <p>Forces an immediate garbage collection of the currently
+ executing process. The function should not be used, unless
+ it has been noticed -- or there are good reasons to suspect --
+ that the spontaneous garbage collection will occur too late
+ or not at all. Improper use may seriously degrade system
+ performance.</p>
+ <p>Compatibility note: In versions of OTP prior to R7,
+ the garbage collection took place at the next context switch,
+ not immediately. To force a context switch after a call to
+ <c>erlang:garbage_collect()</c>, it was sufficient to make
+ any function call.</p>
+ </desc>
+ </func>
+ <func>
+ <name>garbage_collect(Pid) -> bool()</name>
+ <fsummary>Force an immediate garbage collection of a process</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ </type>
+ <desc>
+ <p>Works like <c>erlang:garbage_collect()</c> but on any
+ process. The same caveats apply. Returns <c>false</c> if
+ <c>Pid</c> refers to a dead process; <c>true</c> otherwise.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get() -> [{Key, Val}]</name>
+ <fsummary>Return the process dictionary</fsummary>
+ <type>
+ <v>Key = Val = term()</v>
+ </type>
+ <desc>
+ <p>Returns the process dictionary as a list of
+ <c>{Key, Val}</c> tuples.</p>
+ <pre>
+> <input>put(key1, merry),</input>
+<input>put(key2, lambs),</input>
+<input>put(key3, {are, playing}),</input>
+<input>get().</input>
+[{key1,merry},{key2,lambs},{key3,{are,playing}}]</pre>
+ </desc>
+ </func>
+ <func>
+ <name>get(Key) -> Val | undefined</name>
+ <fsummary>Return a value from the process dictionary</fsummary>
+ <type>
+ <v>Key = Val = term()</v>
+ </type>
+ <desc>
+ <p>Returns the value <c>Val</c>associated with <c>Key</c> in
+ the process dictionary, or <c>undefined</c> if <c>Key</c>
+ does not exist.</p>
+ <pre>
+> <input>put(key1, merry),</input>
+<input>put(key2, lambs),</input>
+<input>put({any, [valid, term]}, {are, playing}),</input>
+<input>get({any, [valid, term]}).</input>
+{are,playing}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:get_cookie() -> Cookie | nocookie</name>
+ <fsummary>Get the magic cookie of the local node</fsummary>
+ <type>
+ <v>Cookie = atom()</v>
+ </type>
+ <desc>
+ <p>Returns the magic cookie of the local node, if the node is
+ alive; otherwise the atom <c>nocookie</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_keys(Val) -> [Key]</name>
+ <fsummary>Return a list of keys from the process dictionary</fsummary>
+ <type>
+ <v>Val = Key = term()</v>
+ </type>
+ <desc>
+ <p>Returns a list of keys which are associated with the value
+ <c>Val</c> in the process dictionary.</p>
+ <pre>
+> <input>put(mary, {1, 2}),</input>
+<input>put(had, {1, 2}),</input>
+<input>put(a, {1, 2}),</input>
+<input>put(little, {1, 2}),</input>
+<input>put(dog, {1, 3}),</input>
+<input>put(lamb, {1, 2}),</input>
+<input>get_keys({1, 2}).</input>
+[mary,had,a,little,lamb]</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:get_stacktrace() -> [{Module, Function, Arity | Args}]</name>
+ <fsummary>Get the call stack back-trace of the last exception</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Arity = int()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Get the call stack back-trace (<em>stacktrace</em>) of the last
+ exception in the calling process as a list of
+ <c>{Module,Function,Arity}</c> tuples.
+ The <c>Arity</c> field in the first tuple may 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 []. After a code change for the process,
+ the stacktrace may also be reset to [].</p>
+ <p>The stacktrace is the same data as the <c>catch</c> operator
+ returns, for example:</p>
+ <p><c>{'EXIT',{badarg,Stacktrace}} = catch abs(x)</c></p>
+ <p>See also
+ <seealso marker="#erlang:error/1">erlang:error/1</seealso> and
+ <seealso marker="#erlang:error/2">erlang:error/2</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>group_leader() -> GroupLeader</name>
+ <fsummary>Get the group leader for the calling process</fsummary>
+ <type>
+ <v>GroupLeader = pid()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of the group leader for the process which
+ evaluates the function.</p>
+ <p>Every process is a member of some process group and all
+ groups have a <em>group leader</em>. All IO from the group
+ is channeled to the group leader. When a new process is
+ spawned, it gets the same group leader as the spawning
+ process. Initially, at system start-up, <c>init</c> is both
+ its own group leader and the group leader of all processes.</p>
+ </desc>
+ </func>
+ <func>
+ <name>group_leader(GroupLeader, Pid) -> true</name>
+ <fsummary>Set the group leader for a process</fsummary>
+ <type>
+ <v>GroupLeader = Pid = pid()</v>
+ </type>
+ <desc>
+ <p>Sets the group leader of <c>Pid</c> to <c>GroupLeader</c>.
+ Typically, this is used when a processes started from a
+ certain shell should have another group leader than
+ <c>init</c>.</p>
+ <p>See also
+ <seealso marker="#group_leader/0">group_leader/0</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>halt()</name>
+ <fsummary>Halt the Erlang runtime system and indicate normal exit to the calling environment</fsummary>
+ <desc>
+ <p>Halts the Erlang runtime system and indicates normal exit to
+ the calling environment. Has no return value.</p>
+ <pre>
+> <input>halt().</input>
+os_prompt%</pre>
+ </desc>
+ </func>
+ <func>
+ <name>halt(Status)</name>
+ <fsummary>Halt the Erlang runtime system</fsummary>
+ <type>
+ <v>Status = int()>=0 | string()</v>
+ </type>
+ <desc>
+ <p><c>Status</c> must be a non-negative integer, or a string.
+ Halts the Erlang runtime system. Has no return value.
+ If <c>Status</c> is an integer, it is returned as an exit
+ status of Erlang to the calling environment.
+ If <c>Status</c> is a string, produces an Erlang crash dump
+ with <c>String</c> as slogan, and then exits with a non-zero
+ status code.</p>
+ <p>Note that on many platforms, only the status codes 0-255 are
+ supported by the operating system.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:hash(Term, Range) -> Hash</name>
+ <fsummary>Hash function (deprecated)</fsummary>
+ <desc>
+ <p>Returns a hash value for <c>Term</c> within the range
+ <c>1..Range</c>. The allowed range is 1..2^27-1.</p>
+ <warning>
+ <p>This BIF is deprecated as the hash value may differ on
+ different architectures. Also the hash values for integer
+ terms larger than 2^27 as well as large binaries are very
+ poor. The BIF is retained for backward compatibility
+ reasons (it may have been used to hash records into a file),
+ but all new code should use one of the BIFs
+ <c>erlang:phash/2</c> or <c>erlang:phash2/1,2</c> instead.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>hd(List) -> term()</name>
+ <fsummary>Head of a list</fsummary>
+ <type>
+ <v>List = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the head of <c>List</c>, that is, the first element.</p>
+ <pre>
+> <input>hd([1,2,3,4,5]).</input>
+1</pre>
+ <p>Allowed in guard tests.</p>
+ <p>Failure: <c>badarg</c> if <c>List</c> is the empty list [].</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:hibernate(Module, Function, Args)</name>
+ <fsummary>Hibernate a process until a message is sent to it</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Puts the calling process into a wait state where its memory
+ allocation has been reduced as much as possible, which is
+ useful if the process does not expect to receive any messages
+ in the near future.</p>
+ <p>The process will be awaken when a message is sent to it, and
+ control will resume in <c>Module:Function</c> with
+ the arguments given by <c>Args</c> with the call stack
+ emptied, meaning that the process will terminate when that
+ function returns. Thus <c>erlang:hibernate/3</c> will never
+ return to its caller.</p>
+ <p>If the process has any message in its message queue,
+ the process will be awaken immediately in the same way as
+ described above.</p>
+ <p>In more technical terms, what <c>erlang:hibernate/3</c> does
+ is the following. It discards the call stack for the process.
+ Then it garbage collects the process. After the garbage
+ collection, all live data is in one continuous heap. The heap
+ is then shrunken to the exact same size as the live data
+ which it holds (even if that size is less than the minimum
+ heap size for the process).</p>
+ <p>If the size of the live data in the process is less than
+ the minimum heap size, the first garbage collection occurring
+ after the process has been awaken will ensure that the heap
+ size is changed to a size not smaller than the minimum heap
+ size.</p>
+ <p>Note that emptying the call stack means that any surrounding
+ <c>catch</c> is removed and has to be re-inserted after
+ hibernation. One effect of this is that processes started
+ using <c>proc_lib</c> (also indirectly, such as
+ <c>gen_server</c> processes), should use
+ <seealso marker="stdlib:proc_lib#hibernate/3">proc_lib:hibernate/3</seealso>
+ instead to ensure that the exception handler continues to work
+ when the process wakes up.</p>
+ </desc>
+ </func>
+ <func>
+ <name>integer_to_list(Integer) -> string()</name>
+ <fsummary>Text representation of an integer</fsummary>
+ <type>
+ <v>Integer = int()</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Integer</c>.</p>
+ <pre>
+> <input>integer_to_list(77).</input>
+"77"</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:integer_to_list(Integer, Base) -> string()</name>
+ <fsummary>Text representation of an integer</fsummary>
+ <type>
+ <v>Integer = int()</v>
+ <v>Base = 2..36</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Integer</c> in base <c>Base</c>.</p>
+ <pre>
+> <input>erlang:integer_to_list(1023, 16).</input>
+"3FF"</pre>
+ </desc>
+ </func>
+ <func>
+ <name>iolist_to_binary(IoListOrBinary) -> binary()</name>
+ <fsummary>Convert an iolist to a binary</fsummary>
+ <type>
+ <v>IoListOrBinary = iolist() | binary()</v>
+ </type>
+ <desc>
+ <p>Returns a binary which is made from the integers and
+ binaries in <c>IoListOrBinary</c>.</p>
+ <pre>
+> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
+&lt;&lt;1,2,3&gt;&gt;
+> <input>Bin2 = &lt;&lt;4,5&gt;&gt;.</input>
+&lt;&lt;4,5&gt;&gt;
+> <input>Bin3 = &lt;&lt;6&gt;&gt;.</input>
+&lt;&lt;6&gt;&gt;
+> <input>iolist_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).</input>
+&lt;&lt;1,2,3,1,2,3,4,5,4,6&gt;&gt;</pre>
+ </desc>
+ </func>
+ <func>
+ <name>iolist_size(Item) -> int()</name>
+ <fsummary>Size of an iolist</fsummary>
+ <type>
+ <v>Item = iolist() | binary()</v>
+ </type>
+ <desc>
+ <p>Returns an integer which is the size in bytes
+ of the binary that would be the result of
+ <c>iolist_to_binary(Item)</c>.</p>
+ <pre>
+> <input>iolist_size([1,2|&lt;&lt;3,4>>]).</input>
+4</pre>
+ </desc>
+ </func>
+ <func>
+ <name>is_alive() -> bool()</name>
+ <fsummary>Check whether the local node is alive</fsummary>
+ <desc>
+ <p>Returns <c>true</c> if the local node is alive; that is, if
+ the node can be part of a distributed system. Otherwise, it
+ returns <c>false</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_atom(Term) -> bool()</name>
+ <fsummary>Check whether a term is an atom</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is an atom;
+ otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_binary(Term) -> bool()</name>
+ <fsummary>Check whether a term is a binary</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a binary;
+ otherwise returns <c>false</c>.</p>
+
+ <p>A binary always contains a complete number of bytes.</p>
+
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_bitstring(Term) -> bool()</name>
+ <fsummary>Check whether a term is a bitstring</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a bitstring (including a binary);
+ otherwise returns <c>false</c>.</p>
+
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_boolean(Term) -> bool()</name>
+ <fsummary>Check whether a term is a boolean</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is
+ either the atom <c>true</c> or the atom <c>false</c>
+ (i.e. a boolean); otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:is_builtin(Module, Function, Arity) -> bool()</name>
+ <fsummary>Check if a function is a BIF implemented in C</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Arity = int()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Module:Function/Arity</c> is
+ a BIF implemented in C; otherwise returns <c>false</c>.
+ This BIF is useful for builders of cross reference tools.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_float(Term) -> bool()</name>
+ <fsummary>Check whether a term is a float</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a floating point
+ number; otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_function(Term) -> bool()</name>
+ <fsummary>Check whether a term is a fun</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a fun; otherwise
+ returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_function(Term, Arity) -> bool()</name>
+ <fsummary>Check whether a term is a fun with a given arity</fsummary>
+ <type>
+ <v>Term = term()</v>
+ <v>Arity = int()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a fun that can be
+ applied with <c>Arity</c> number of arguments; otherwise
+ returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ <warning>
+ <p>Currently, <c>is_function/2</c> will also return
+ <c>true</c> if the first argument is a tuple fun (a tuple
+ containing two atoms). In a future release, tuple funs will
+ no longer be supported and <c>is_function/2</c> will return
+ <c>false</c> if given a tuple fun.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>is_integer(Term) -> bool()</name>
+ <fsummary>Check whether a term is an integer</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is an integer;
+ otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_list(Term) -> bool()</name>
+ <fsummary>Check whether a term is a list</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a list with
+ zero or more elements; otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_number(Term) -> bool()</name>
+ <fsummary>Check whether a term is a number</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is either an integer or a
+ floating point number; otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_pid(Term) -> bool()</name>
+ <fsummary>Check whether a term is a pid</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a pid (process
+ identifier); otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_port(Term) -> bool()</name>
+ <fsummary>Check whether a term is a port</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a port identifier;
+ otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_process_alive(Pid) -> bool()</name>
+ <fsummary>Check whether a process is alive</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ </type>
+ <desc>
+ <p>
+ <c>Pid</c> must refer to a process at the local node.
+ Returns <c>true</c> if the process exists and is alive, that
+ is, is not exiting and has not exited. Otherwise, returns
+ <c>false</c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>is_record(Term, RecordTag) -> bool()</name>
+ <fsummary>Check whether a term appears to be a record</fsummary>
+ <type>
+ <v>Term = term()</v>
+ <v>RecordTag = atom()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a tuple and its first
+ element is <c>RecordTag</c>. Otherwise, returns <c>false</c>.</p>
+ <note>
+ <p>Normally the compiler treats calls to <c>is_record/2</c>
+ specially. It emits code to verify that <c>Term</c> is a
+ tuple, that its first element is <c>RecordTag</c>, and that
+ the size is correct. However, if the <c>RecordTag</c> is
+ not a literal atom, the <c>is_record/2</c> BIF will be
+ called instead and the size of the tuple will not be
+ verified.</p>
+ </note>
+ <p>Allowed in guard tests, if <c>RecordTag</c> is a literal
+ atom.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_record(Term, RecordTag, Size) -> bool()</name>
+ <fsummary>Check whether a term appears to be a record</fsummary>
+ <type>
+ <v>Term = term()</v>
+ <v>RecordTag = atom()</v>
+ <v>Size = int()</v>
+ </type>
+ <desc>
+ <p><c>RecordTag</c> must be an atom. Returns <c>true</c> if
+ <c>Term</c> is a tuple, its first element is <c>RecordTag</c>,
+ and its size is <c>Size</c>. Otherwise, returns <c>false</c>.</p>
+ <p>Allowed in guard tests, provided that <c>RecordTag</c> is
+ a literal atom and <c>Size</c> is a literal integer.</p>
+ <note>
+ <p>This BIF is documented for completeness. In most cases
+ <c>is_record/2</c> should be used.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name>is_reference(Term) -> bool()</name>
+ <fsummary>Check whether a term is a reference</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a reference;
+ otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_tuple(Term) -> bool()</name>
+ <fsummary>Check whether a term is a tuple</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if <c>Term</c> is a tuple;
+ otherwise returns <c>false</c>.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>length(List) -> int()</name>
+ <fsummary>Length of a list</fsummary>
+ <type>
+ <v>List = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the length of <c>List</c>.</p>
+ <pre>
+> <input>length([1,2,3,4,5,6,7,8,9]).</input>
+9</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>link(Pid) -> true</name>
+ <fsummary>Create a link to another process (or port)</fsummary>
+ <type>
+ <v>Pid = pid() | port()</v>
+ </type>
+ <desc>
+ <p>Creates a link between the calling process and another
+ process (or port) <c>Pid</c>, if there is not such a link
+ already. If a process attempts to create a link to itself,
+ nothing is done. Returns <c>true</c>.</p>
+ <p>If <c>Pid</c> does not exist, the behavior of the BIF depends
+ on if the calling process is trapping exits or not (see
+ <seealso marker="#process_flag/2">process_flag/2</seealso>):</p>
+ <list type="bulleted">
+ <item>If the calling process is not trapping exits, and
+ checking <c>Pid</c> is cheap -- that is, if <c>Pid</c> is
+ local -- <c>link/1</c> fails with reason <c>noproc</c>.</item>
+ <item>Otherwise, if the calling process is trapping exits,
+ and/or <c>Pid</c> is remote, <c>link/1</c> returns
+ <c>true</c>, but an exit signal with reason <c>noproc</c>
+ is sent to the calling process.</item>
+ </list>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_atom(String) -> atom()</name>
+ <fsummary>Convert from text representation to an atom</fsummary>
+ <type>
+ <v>String = string()</v>
+ </type>
+ <desc>
+ <p>Returns the atom whose text representation is <c>String</c>.</p>
+ <pre>
+> <input>list_to_atom("Erlang").</input>
+'Erlang'</pre>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_binary(IoList) -> binary()</name>
+ <fsummary>Convert a list to a binary</fsummary>
+ <type>
+ <v>IoList = iolist()</v>
+ </type>
+ <desc>
+ <p>Returns a binary which is made from the integers and
+ binaries in <c>IoList</c>.</p>
+ <pre>
+> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
+&lt;&lt;1,2,3&gt;&gt;
+> <input>Bin2 = &lt;&lt;4,5&gt;&gt;.</input>
+&lt;&lt;4,5&gt;&gt;
+> <input>Bin3 = &lt;&lt;6&gt;&gt;.</input>
+&lt;&lt;6&gt;&gt;
+> <input>list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).</input>
+&lt;&lt;1,2,3,1,2,3,4,5,4,6&gt;&gt;</pre>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_bitstring(BitstringList) -> bitstring()</name>
+ <fsummary>Convert a list to a bitstring</fsummary>
+ <type>
+ <v>BitstringList = [BitstringList | bitstring() | char()]</v>
+ </type>
+ <desc>
+ <p>Returns a bitstring which is made from the integers and
+ bitstrings in <c>BitstringList</c>. (The last tail in <c>BitstringList</c>
+ is allowed to be a bitstring.)</p>
+ <pre>
+> <input>Bin1 = &lt;&lt;1,2,3&gt;&gt;.</input>
+&lt;&lt;1,2,3&gt;&gt;
+> <input>Bin2 = &lt;&lt;4,5&gt;&gt;.</input>
+&lt;&lt;4,5&gt;&gt;
+> <input>Bin3 = &lt;&lt;6,7:4,&gt;&gt;.</input>
+&lt;&lt;6&gt;&gt;
+> <input>list_to_binary([Bin1,1,[2,3,Bin2],4|Bin3]).</input>
+&lt;&lt;1,2,3,1,2,3,4,5,4,6,7:46&gt;&gt;</pre>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_existing_atom(String) -> atom()</name>
+ <fsummary>Convert from text representation to an atom</fsummary>
+ <type>
+ <v>String = string()</v>
+ </type>
+ <desc>
+ <p>Returns the atom whose text representation is <c>String</c>,
+ but only if there already exists such atom.</p>
+ <p>Failure: <c>badarg</c> if there does not already exist an atom
+ whose text representation is <c>String</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_float(String) -> float()</name>
+ <fsummary>Convert from text representation to a float</fsummary>
+ <type>
+ <v>String = string()</v>
+ </type>
+ <desc>
+ <p>Returns the float whose text representation is <c>String</c>.</p>
+ <pre>
+> <input>list_to_float("2.2017764e+0").</input>
+2.2017764</pre>
+ <p>Failure: <c>badarg</c> if <c>String</c> contains a bad
+ representation of a float.</p>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_integer(String) -> int()</name>
+ <fsummary>Convert from text representation to an integer</fsummary>
+ <type>
+ <v>String = string()</v>
+ </type>
+ <desc>
+ <p>Returns an integer whose text representation is
+ <c>String</c>.</p>
+ <pre>
+> <input>list_to_integer("123").</input>
+123</pre>
+ <p>Failure: <c>badarg</c> if <c>String</c> contains a bad
+ representation of an integer.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:list_to_integer(String, Base) -> int()</name>
+ <fsummary>Convert from text representation to an integer</fsummary>
+ <type>
+ <v>String = string()</v>
+ <v>Base = 2..36</v>
+ </type>
+ <desc>
+ <p>Returns an integer whose text representation in base
+ <c>Base</c> is <c>String</c>.</p>
+ <pre>
+> <input>erlang:list_to_integer("3FF", 16).</input>
+1023</pre>
+ <p>Failure: <c>badarg</c> if <c>String</c> contains a bad
+ representation of an integer.</p>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_pid(String) -> pid()</name>
+ <fsummary>Convert from text representation to a pid</fsummary>
+ <type>
+ <v>String = string()</v>
+ </type>
+ <desc>
+ <p>Returns a pid whose text representation is <c>String</c>.</p>
+ <warning>
+ <p>This BIF is intended for debugging and for use in
+ the Erlang operating system. It should not be used in
+ application programs.</p>
+ </warning>
+ <pre>
+> <input>list_to_pid("&lt;0.4.1>").</input>
+&lt;0.4.1></pre>
+ <p>Failure: <c>badarg</c> if <c>String</c> contains a bad
+ representation of a pid.</p>
+ </desc>
+ </func>
+ <func>
+ <name>list_to_tuple(List) -> tuple()</name>
+ <fsummary>Convert a list to a tuple</fsummary>
+ <type>
+ <v>List = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns a tuple which corresponds to <c>List</c>. <c>List</c>
+ can contain any Erlang terms.</p>
+ <pre>
+> <input>list_to_tuple([share, ['Ericsson_B', 163]]).</input>
+{share, ['Ericsson_B', 163]}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>load_module(Module, Binary) -> {module, Module} | {error, Reason}</name>
+ <fsummary>Load object code for a module</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>Binary = binary()</v>
+ <v>Reason = badfile | not_purged | badfile</v>
+ </type>
+ <desc>
+ <p>If <c>Binary</c> contains the object code for the module
+ <c>Module</c>, this BIF loads that object code. Also, if
+ the code for the module <c>Module</c> already exists, all
+ export references are replaced so they point to the newly
+ loaded code. The previously loaded code is kept in the system
+ as old code, as there may still be processes which are
+ executing that code. It returns either
+ <c>{module, Module}</c>, or <c>{error, Reason}</c> if loading
+ fails. <c>Reason</c> is one of the following:</p>
+ <taglist>
+ <tag><c>badfile</c></tag>
+ <item>
+ <p>The object code in <c>Binary</c> has an incorrect format.</p>
+ </item>
+ <tag><c>not_purged</c></tag>
+ <item>
+ <p><c>Binary</c> contains a module which cannot be loaded
+ because old code for this module already exists.</p>
+ </item>
+ <tag><c>badfile</c></tag>
+ <item>
+ <p>The object code contains code for another module than
+ <c>Module</c></p>
+ </item>
+ </taglist>
+ <warning>
+ <p>This BIF is intended for the code server (see
+ <seealso marker="kernel:code">code(3)</seealso>) and should not be
+ used elsewhere.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:load_nif(Path, LoadInfo) -> ok | {error, Reason, Text}</name>
+ <fsummary>Load NIF library</fsummary>
+ <type>
+ <v>Path = string()</v>
+ <v>LoadInfo = term()</v>
+ <v>Reason = load_failed | bad_lib | load | reload |
+ upgrade | old_code</v>
+ <v>Text = string()</v>
+ </type>
+ <desc>
+ <warning>
+ <p>This BIF is currently introduced as an experimental
+ feature. The interface may be changed in any way in future
+ releases.</p>
+ </warning>
+ <p>Loads and links a dynamic library containing native
+ implemented functions (NIFs) for a module. <c>Path</c> is a
+ file path to the sharable object/dynamic library file minus
+ the OS-dependant file extension (.so for Unix and .ddl for
+ Windows). See <seealso marker="erl_nif">erl_nif</seealso>
+ on how to implement a NIF library.</p>
+ <p><c>LoadInfo</c> can be any term. It will be passed on to
+ the library as part of the initialization. A good practice is
+ to include a module version number to support future code
+ upgrade scenarios.</p>
+ <p>The call to <c>load_nif/2</c> must be made
+ <em>directly</em> from the Erlang code of the module that the
+ NIF library belongs to.</p>
+ <p>It returns either <c>ok</c>, or <c>{error,Reason,Text}</c>
+ if loading fails. <c>Reason</c> is one of the atoms below,
+ while <c>Text</c> is a human readable string that may give
+ some more information about the failure:</p>
+ <taglist>
+ <tag><c>load_failed</c></tag>
+ <item>
+ <p>The OS failed to load the NIF library.</p>
+ </item>
+ <tag><c>bad_lib</c></tag>
+ <item>
+ <p>The library did not fulfil the requirements as a NIF
+ library of the calling module.</p>
+ </item>
+ <tag><c>load | reload | upgrade</c></tag>
+ <item>
+ <p>The corresponding library callback was not successful.</p>
+ </item>
+ <tag><c>old_code</c></tag>
+ <item>
+ <p>The call to <c>load_nif/2</c> was made from the old
+ code of a module that has been upgraded. This is not
+ allowed.</p>
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:loaded() -> [Module]</name>
+ <fsummary>List of all loaded modules</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns a list of all loaded Erlang modules (current and/or
+ old code), including preloaded modules.</p>
+ <p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:localtime() -> {Date, Time}</name>
+ <fsummary>Current local date and time</fsummary>
+ <type>
+ <v>Date = {Year, Month, Day}</v>
+ <v>Time = {Hour, Minute, Second}</v>
+ <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ </type>
+ <desc>
+ <p>Returns the current local date and time
+ <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c>.</p>
+ <p>The time zone and daylight saving time correction depend
+ on the underlying OS.</p>
+ <pre>
+> <input>erlang:localtime().</input>
+{{1996,11,6},{14,45,17}}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:localtime_to_universaltime({Date1, Time1}) -> {Date2, Time2}</name>
+ <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
+ <type>
+ <v>Date1 = Date2 = {Year, Month, Day}</v>
+ <v>Time1 = Time2 = {Hour, Minute, Second}</v>
+ <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ </type>
+ <desc>
+ <p>Converts local date and time to Universal Time Coordinated
+ (UTC), if this is supported by the underlying OS. Otherwise,
+ no conversion is done and <c>{Date1, Time1}</c> is returned.</p>
+ <pre>
+> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).</input>
+{{1996,11,6},{13,45,17}}</pre>
+ <p>Failure: <c>badarg</c> if <c>Date1</c> or <c>Time1</c> do
+ not denote a valid date or time.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:localtime_to_universaltime({Date1, Time1}, IsDst) -> {Date2, Time2}</name>
+ <fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
+ <type>
+ <v>Date1 = Date2 = {Year, Month, Day}</v>
+ <v>Time1 = Time2 = {Hour, Minute, Second}</v>
+ <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ <v>IsDst = true | false | undefined</v>
+ </type>
+ <desc>
+ <p>Converts local date and time to Universal Time Coordinated
+ (UTC) just like <c>erlang:localtime_to_universaltime/1</c>,
+ but the caller decides if daylight saving time is active or
+ not.</p>
+ <p>If <c>IsDst == true</c> the <c>{Date1, Time1}</c> is during
+ daylight saving time, if <c>IsDst == false</c> it is not,
+ and if <c>IsDst == undefined</c> the underlying OS may
+ guess, which is the same as calling
+ <c>erlang:localtime_to_universaltime({Date1, Time1})</c>.</p>
+ <pre>
+> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, true).</input>
+{{1996,11,6},{12,45,17}}
+> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, false).</input>
+{{1996,11,6},{13,45,17}}
+> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}, undefined).</input>
+{{1996,11,6},{13,45,17}}</pre>
+ <p>Failure: <c>badarg</c> if <c>Date1</c> or <c>Time1</c> do
+ not denote a valid date or time.</p>
+ </desc>
+ </func>
+ <func>
+ <name>make_ref() -> ref()</name>
+ <fsummary>Return an almost unique reference</fsummary>
+ <desc>
+ <p>Returns an almost unique reference.</p>
+ <p>The returned reference will re-occur after approximately 2^82
+ calls; therefore it is unique enough for practical purposes.</p>
+ <pre>
+> <input>make_ref().</input>
+#Ref&lt;0.0.0.135></pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:make_tuple(Arity, InitialValue) -> tuple()</name>
+ <fsummary>Create a new tuple of a given arity</fsummary>
+ <type>
+ <v>Arity = int()</v>
+ <v>InitialValue = term()</v>
+ </type>
+ <desc>
+ <p>Returns a new tuple of the given <c>Arity</c>, where all
+ elements are <c>InitialValue</c>.</p>
+ <pre>
+> <input>erlang:make_tuple(4, []).</input>
+{[],[],[],[]}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:make_tuple(Arity, Default, InitList) -> tuple()</name>
+ <fsummary>Create a new tuple with given arity and contents</fsummary>
+ <type>
+ <v>Arity = int()</v>
+ <v>Default = term()</v>
+ <v>InitList = [{Position,term()}]</v>
+ <v>Position = integer()</v>
+ </type>
+ <desc>
+ <p><c>erlang:make_tuple</c> first creates a tuple of size <c>Arity</c>
+ where each element has the value <c>Default</c>. It then fills
+ in values from <c>InitList</c>. Each list element in <c>InitList</c>
+ must be a two-tuple where the first element is a position in the
+ newly created tuple and the second element is any term. If a position
+ occurs more than once in the list, the term corresponding to
+ last occurrence will be used.</p>
+ <pre>
+> <input>erlang:make_tuple(5, [], [{2,ignored},{5,zz},{2,aa}]).</input>
+{{[],aa,[],[],zz}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:max(Term1, Term2) -> Maximum</name>
+ <fsummary>Return the largest of two term</fsummary>
+ <type>
+ <v>Term1 = Term2 = Maximum = term()</v>
+ </type>
+ <desc>
+ <p>Return the largest of <c>Term1</c> and <c>Term2</c>;
+ if the terms compares equal, <c>Term1</c> will be returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:md5(Data) -> Digest</name>
+ <fsummary>Compute an MD5 message digest</fsummary>
+ <type>
+ <v>Data = iodata()</v>
+ <v>Digest = binary()</v>
+ </type>
+ <desc>
+ <p>Computes an <c>MD5</c> message digest from <c>Data</c>, where
+ the length of the digest is 128 bits (16 bytes). <c>Data</c>
+ is a binary or a list of small integers and binaries.</p>
+ <p>See The MD5 Message Digest Algorithm (RFC 1321) for more
+ information about MD5.</p>
+ <warning><p>The MD5 Message Digest Algorithm is <em>not</em> considered
+ safe for code-signing or software integrity purposes.</p></warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:md5_final(Context) -> Digest</name>
+ <fsummary>Finish the update of an MD5 context and return the computed MD5 message digest</fsummary>
+ <type>
+ <v>Context = Digest = binary()</v>
+ </type>
+ <desc>
+ <p>Finishes the update of an MD5 <c>Context</c> and returns
+ the computed <c>MD5</c> message digest.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:md5_init() -> Context</name>
+ <fsummary>Create an MD5 context</fsummary>
+ <type>
+ <v>Context = binary()</v>
+ </type>
+ <desc>
+ <p>Creates an MD5 context, to be used in subsequent calls to
+ <c>md5_update/2</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:md5_update(Context, Data) -> NewContext</name>
+ <fsummary>Update an MD5 context with data, and return a new context</fsummary>
+ <type>
+ <v>Data = iodata()</v>
+ <v>Context = NewContext = binary()</v>
+ </type>
+ <desc>
+ <p>Updates an MD5 <c>Context</c> with <c>Data</c>, and returns
+ a <c>NewContext</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:memory() -> [{Type, Size}]</name>
+ <fsummary>Information about dynamically allocated memory</fsummary>
+ <type>
+ <v>Type, Size -- see below</v>
+ </type>
+ <desc>
+ <p>Returns a list containing information about memory
+ dynamically allocated by the Erlang emulator. Each element of
+ the list is a tuple <c>{Type, Size}</c>. The first element
+ <c>Type</c>is an atom describing memory type. The second
+ element <c>Size</c>is memory size in bytes. A description of
+ each memory type follows:</p>
+ <taglist>
+ <tag><c>total</c></tag>
+ <item>
+ <p>The total amount of memory currently allocated, which is
+ the same as the sum of memory size for <c>processes</c>
+ and <c>system</c>.</p>
+ </item>
+ <tag><c>processes</c></tag>
+ <item>
+ <p>The total amount of memory currently allocated by
+ the Erlang processes.</p>
+ </item>
+ <tag><c>processes_used</c></tag>
+ <item>
+ <p>The total amount of memory currently used by the Erlang
+ processes.</p>
+ <p>This memory is part of the memory presented as
+ <c>processes</c> memory.</p>
+ </item>
+ <tag><c>system</c></tag>
+ <item>
+ <p>The total amount of memory currently allocated by
+ the emulator that is not directly related to any Erlang
+ process.</p>
+ <p>Memory presented as <c>processes</c> is not included in
+ this memory.</p>
+ </item>
+ <tag><c>atom</c></tag>
+ <item>
+ <p>The total amount of memory currently allocated for atoms.</p>
+ <p>This memory is part of the memory presented as
+ <c>system</c> memory.</p>
+ </item>
+ <tag><c>atom_used</c></tag>
+ <item>
+ <p>The total amount of memory currently used for atoms.</p>
+ <p>This memory is part of the memory presented as
+ <c>atom</c> memory.</p>
+ </item>
+ <tag><c>binary</c></tag>
+ <item>
+ <p>The total amount of memory currently allocated for
+ binaries.</p>
+ <p>This memory is part of the memory presented as
+ <c>system</c> memory.</p>
+ </item>
+ <tag><c>code</c></tag>
+ <item>
+ <p>The total amount of memory currently allocated for
+ Erlang code.</p>
+ <p>This memory is part of the memory presented as
+ <c>system</c> memory.</p>
+ </item>
+ <tag><c>ets</c></tag>
+ <item>
+ <p>The total amount of memory currently allocated for ets
+ tables.</p>
+ <p>This memory is part of the memory presented as
+ <c>system</c> memory.</p>
+ </item>
+ <tag><c>maximum</c></tag>
+ <item>
+ <p>The maximum total amount of memory allocated since
+ the emulator was started.</p>
+ <p>This tuple is only present when the emulator is run with
+ instrumentation.</p>
+ <p>For information on how to run the emulator with
+ instrumentation see
+ <seealso marker="tools:instrument">instrument(3)</seealso>
+ and/or <seealso marker="erts:erl">erl(1)</seealso>.</p>
+ </item>
+ </taglist>
+ <note>
+ <p>The <c>system</c> value is not complete. Some allocated
+ memory that should be part of the <c>system</c> value are
+ not.</p>
+ <p>When the emulator is run with instrumentation,
+ the <c>system</c> value is more accurate, but memory
+ directly allocated by <c>malloc</c> (and friends) are still
+ not part of the <c>system</c> value. Direct calls to
+ <c>malloc</c> are only done from OS specific runtime
+ libraries and perhaps from user implemented Erlang drivers
+ that do not use the memory allocation functions in
+ the driver interface.</p>
+ <p>Since the <c>total</c> value is the sum of <c>processes</c>
+ and <c>system</c> the error in <c>system</c> will propagate
+ to the <c>total</c> value.</p>
+ <p>The different amounts of memory that are summed are
+ <em>not</em> gathered atomically which also introduce
+ an error in the result.</p>
+ </note>
+ <p>The different values has the following relation to each
+ other. Values beginning with an uppercase letter is not part
+ of the result.</p>
+ <code type="none">
+\011total = processes + system
+\011processes = processes_used + ProcessesNotUsed
+\011system = atom + binary + code + ets + OtherSystem
+\011atom = atom_used + AtomNotUsed
+
+\011RealTotal = processes + RealSystem
+\011RealSystem = system + MissedSystem</code>
+ <p>More tuples in the returned list may be added in the future.</p>
+ <note>
+ <p>The <c>total</c> value is supposed to be the total amount
+ of memory dynamically allocated by the emulator. Shared
+ libraries, the code of the emulator itself, and
+ the emulator stack(s) are not supposed to be included. That
+ is, the <c>total</c> value is <em>not</em> supposed to be
+ equal to the total size of all pages mapped to the emulator.
+ Furthermore, due to fragmentation and pre-reservation of
+ memory areas, the size of the memory segments which contain
+ the dynamically allocated memory blocks can be substantially
+ larger than the total size of the dynamically allocated
+ memory blocks.</p>
+ </note>
+ <note>
+ <p>
+ Since erts version 5.6.4 <c>erlang:memory/0</c> requires that
+ all <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
+ allocators are enabled (default behaviour).
+ </p>
+ </note>
+ <p>Failure:</p>
+ <taglist>
+ <tag><c>notsup</c></tag>
+ <item>
+ If an <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
+ allocator has been disabled.
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:memory(Type | [Type]) -> Size | [{Type, Size}]</name>
+ <fsummary>Information about dynamically allocated memory</fsummary>
+ <type>
+ <v>Type, Size -- see below</v>
+ </type>
+ <desc>
+ <p>Returns the memory size in bytes allocated for memory of
+ type <c>Type</c>. The argument can also be given as a list
+ of <c>Type</c> atoms, in which case a corresponding list of
+ <c>{Type, Size}</c> tuples is returned.</p>
+ <note>
+ <p>
+ Since erts version 5.6.4 <c>erlang:memory/1</c> requires that
+ all <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
+ allocators are enabled (default behaviour).
+ </p>
+ </note>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>Type</c> is not one of the memory types listed in the
+ documentation of
+ <seealso marker="#erlang:memory/0">erlang:memory/0</seealso>.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>maximum</c> is passed as <c>Type</c> and the emulator
+ is not run in instrumented mode.
+ </item>
+ <tag><c>notsup</c></tag>
+ <item>
+ If an <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>
+ allocator has been disabled.
+ </item>
+ </taglist>
+ <p>See also
+ <seealso marker="#erlang:memory/0">erlang:memory/0</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:min(Term1, Term2) -> Minimum</name>
+ <fsummary>Return the smallest of two term</fsummary>
+ <type>
+ <v>Term1 = Term2 = Minimum = term()</v>
+ </type>
+ <desc>
+ <p>Return the smallest of <c>Term1</c> and <c>Term2</c>;
+ if the terms compare equal, <c>Term1</c> will be returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>module_loaded(Module) -> bool()</name>
+ <fsummary>Check if a module is loaded</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if the module <c>Module</c> is loaded,
+ otherwise returns <c>false</c>. It does not attempt to load
+ the module.</p>
+ <warning>
+ <p>This BIF is intended for the code server (see
+ <seealso marker="kernel:code">code(3)</seealso>) and should not be
+ used elsewhere.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:monitor(Type, Item) -> MonitorRef</name>
+ <fsummary>Start monitoring</fsummary>
+ <type>
+ <v>Type = process</v>
+ <v>Item = pid() | {RegName, Node} | RegName</v>
+ <v>&nbsp;RegName = atom()</v>
+ <v>&nbsp;Node = node()</v>
+ <v>MonitorRef = reference()</v>
+ </type>
+ <desc>
+ <p>The calling process starts monitoring <c>Item</c> which is
+ an object of type <c>Type</c>.</p>
+ <p>Currently only processes can be monitored, i.e. the only
+ allowed <c>Type</c> is <c>process</c>, but other types may be
+ allowed in the future.</p>
+ <p><c>Item</c> can be:</p>
+ <taglist>
+ <tag><c>pid()</c></tag>
+ <item>
+ <p>The pid of the process to monitor.</p>
+ </item>
+ <tag><c>{RegName, Node}</c></tag>
+ <item>
+ <p>A tuple consisting of a registered name of a process and
+ a node name. The process residing on the node <c>Node</c>
+ with the registered name <c>RegName</c> will be monitored.</p>
+ </item>
+ <tag><c>RegName</c></tag>
+ <item>
+ <p>The process locally registered as <c>RegName</c> will be
+ monitored.</p>
+ </item>
+ </taglist>
+ <note>
+ <p>When a process is monitored by registered name, the process
+ that has the registered name at the time when
+ <c>erlang:monitor/2</c> is called will be monitored.
+ The monitor will not be effected, if the registered name is
+ unregistered.</p>
+ </note>
+ <p>A <c>'DOWN'</c> message will be sent to the monitoring
+ process if <c>Item</c> dies, if <c>Item</c> does not exist,
+ or if the connection is lost to the node which <c>Item</c>
+ resides on. A <c>'DOWN'</c> message has the following pattern:</p>
+ <code type="none">
+{'DOWN', MonitorRef, Type, Object, Info}</code>
+ <p>where <c>MonitorRef</c> and <c>Type</c> are the same as
+ described above, and:</p>
+ <taglist>
+ <tag><c>Object</c></tag>
+ <item>
+ <p>A reference to the monitored object:</p>
+ <list type="bulleted">
+ <item>the pid of the monitored process, if <c>Item</c> was
+ specified as a pid.</item>
+ <item><c>{RegName, Node}</c>, if <c>Item</c> was specified as
+ <c>{RegName, Node}</c>.</item>
+ <item><c>{RegName, Node}</c>, if <c>Item</c> was specified as
+ <c>RegName</c>. <c>Node</c> will in this case be the
+ name of the local node (<c>node()</c>).</item>
+ </list>
+ </item>
+ <tag><c>Info</c></tag>
+ <item>
+ <p>Either the exit reason of the process, <c>noproc</c>
+ (non-existing process), or <c>noconnection</c> (no
+ connection to <c>Node</c>).</p>
+ </item>
+ </taglist>
+ <note>
+ <p>If/when <c>erlang:monitor/2</c> is extended (e.g. to
+ handle other item types than <c>process</c>), other
+ possible values for <c>Object</c>, and <c>Info</c> in the
+ <c>'DOWN'</c> message will be introduced.</p>
+ </note>
+ <p>The monitoring is turned off either when the <c>'DOWN'</c>
+ message is sent, or when
+ <seealso marker="#erlang:demonitor/1">erlang:demonitor/1</seealso>
+ is called.</p>
+ <p>If an attempt is made to monitor a process on an older node
+ (where remote process monitoring is not implemented or one
+ where remote process monitoring by registered name is not
+ implemented), the call fails with <c>badarg</c>.</p>
+ <p>Making several calls to <c>erlang:monitor/2</c> for the same
+ <c>Item</c> is not an error; it results in as many, completely
+ independent, monitorings.</p>
+ <note>
+ <p>The format of the <c>'DOWN'</c> message changed in the 5.2
+ version of the emulator (OTP release R9B) for monitor <em>by registered name</em>. The <c>Object</c> element of
+ the <c>'DOWN'</c> message could in earlier versions
+ sometimes be the pid of the monitored process and sometimes
+ be the registered name. Now the <c>Object</c> element is
+ always a tuple consisting of the registered name and
+ the node name. Processes on new nodes (emulator version 5.2
+ or greater) will always get <c>'DOWN'</c> messages on
+ the new format even if they are monitoring processes on old
+ nodes. Processes on old nodes will always get <c>'DOWN'</c>
+ messages on the old format.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name>monitor_node(Node, Flag) -> true</name>
+ <fsummary>Monitor the status of a node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Flag = bool()</v>
+ </type>
+ <desc>
+ <p>Monitors the status of the node <c>Node</c>. If <c>Flag</c>
+ is <c>true</c>, monitoring is turned on; if <c>Flag</c> is
+ <c>false</c>, monitoring is turned off.</p>
+ <p>Making several calls to <c>monitor_node(Node, true)</c> for
+ the same <c>Node</c> is not an error; it results in as many,
+ completely independent, monitorings.</p>
+ <p>If <c>Node</c> fails or does not exist, the message
+ <c>{nodedown, Node}</c> is delivered to the process. If a
+ process has made two calls to <c>monitor_node(Node, true)</c>
+ and <c>Node</c> terminates, two <c>nodedown</c> messages are
+ delivered to the process. If there is no connection to
+ <c>Node</c>, there will be an attempt to create one. If this
+ fails, a <c>nodedown</c> message is delivered.</p>
+ <p>Nodes connected through hidden connections can be monitored
+ as any other node.</p>
+ <p>Failure: <c>badarg</c>if the local node is not alive.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:monitor_node(Node, Flag, Options) -> true</name>
+ <fsummary>Monitor the status of a node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Flag = bool()</v>
+ <v>Options = [Option]</v>
+ <v>Option = allow_passive_connect</v>
+ </type>
+ <desc>
+ <p>Behaves as <c>monitor_node/2</c> except that it allows an
+ extra option to be given, namely <c>allow_passive_connect</c>.
+ The option allows the BIF to wait the normal net connection
+ timeout for the <em>monitored node</em> to connect itself,
+ even if it cannot be actively connected from this node
+ (i.e. it is blocked). The state where this might be useful can
+ only be achieved by using the kernel option
+ <c>dist_auto_connect once</c>. If that kernel option is not
+ used, the <c>allow_passive_connect</c> option has no
+ effect.</p>
+ <note>
+ <p>The <c>allow_passive_connect</c> option is used
+ internally and is seldom needed in applications where the
+ network topology and the kernel options in effect is known in
+ advance.</p>
+ </note>
+ <p>Failure: <c>badarg</c> if the local node is not alive or the
+ option list is malformed.</p>
+ </desc>
+ </func>
+ <func>
+ <name>node() -> Node</name>
+ <fsummary>Name of the local node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc>
+ <p>Returns the name of the local node. If the node is not alive,
+ <c>nonode@nohost</c> is returned instead.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>node(Arg) -> Node</name>
+ <fsummary>At which node is a pid, port or reference located</fsummary>
+ <type>
+ <v>Arg = pid() | port() | ref()</v>
+ <v>Node = node()</v>
+ </type>
+ <desc>
+ <p>Returns the node where <c>Arg</c> is located. <c>Arg</c> can
+ be a pid, a reference, or a port. If the local node is not
+ alive, <c>nonode@nohost</c> is returned.</p>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>nodes() -> Nodes</name>
+ <fsummary>All visible nodes in the system</fsummary>
+ <type>
+ <v>Nodes = [node()]</v>
+ </type>
+ <desc>
+ <p>Returns a list of all visible nodes in the system, excluding
+ the local node. Same as <c>nodes(visible)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>nodes(Arg | [Arg]) -> Nodes</name>
+ <fsummary>All nodes of a certain type in the system</fsummary>
+ <type>
+ <v>Arg = visible | hidden | connected | this | known</v>
+ <v>Nodes = [node()]</v>
+ </type>
+ <desc>
+ <p>Returns a list of nodes according to argument given.
+ The result returned when the argument is a list, is the list
+ of nodes satisfying the disjunction(s) of the list elements.</p>
+ <p><c>Arg</c> can be any of the following:</p>
+ <taglist>
+ <tag><c>visible</c></tag>
+ <item>
+ <p>Nodes connected to this node through normal connections.</p>
+ </item>
+ <tag><c>hidden</c></tag>
+ <item>
+ <p>Nodes connected to this node through hidden connections.</p>
+ </item>
+ <tag><c>connected</c></tag>
+ <item>
+ <p>All nodes connected to this node.</p>
+ </item>
+ <tag><c>this</c></tag>
+ <item>
+ <p>This node.</p>
+ </item>
+ <tag><c>known</c></tag>
+ <item>
+ <p>Nodes which are known to this node, i.e., connected,
+ previously connected, etc.</p>
+ </item>
+ </taglist>
+ <p>Some equalities: <c>[node()] = nodes(this)</c>,
+ <c>nodes(connected) = nodes([visible, hidden])</c>, and
+ <c>nodes() = nodes(visible)</c>.</p>
+ <p>If the local node is not alive,
+ <c>nodes(this) == nodes(known) == [nonode@nohost]</c>, for
+ any other <c>Arg</c> the empty list [] is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>now() -> {MegaSecs, Secs, MicroSecs}</name>
+ <fsummary>Elapsed time since 00:00 GMT</fsummary>
+ <type>
+ <v>MegaSecs = Secs = MicroSecs = int()</v>
+ </type>
+ <desc>
+ <p>Returns the tuple <c>{MegaSecs, Secs, MicroSecs}</c> which is
+ the elapsed time since 00:00 GMT, January 1, 1970 (zero hour)
+ on the assumption that the underlying OS supports this.
+ Otherwise, some other point in time is chosen. It is also
+ guaranteed that subsequent calls to this BIF returns
+ continuously increasing values. Hence, the return value from
+ <c>now()</c> can be used to generate unique time-stamps. It
+ can only be used to check the local time of day if
+ the time-zone info of the underlying operating system is
+ properly configured.</p>
+ </desc>
+ </func>
+ <func>
+ <name>open_port(PortName, PortSettings) -> port()</name>
+ <fsummary>Open a port</fsummary>
+ <type>
+ <v>PortName = {spawn, Command} | {spawn_driver, Command} | {spawn_executable, Command} | {fd, In, Out}</v>
+ <v>&nbsp;Command = string()</v>
+ <v>&nbsp;In = Out = int()</v>
+ <v>PortSettings = [Opt]</v>
+ <v>&nbsp;Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ string() ]} | {arg0, string()} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof</v>
+ <v>&nbsp;&nbsp;N = 1 | 2 | 4</v>
+ <v>&nbsp;&nbsp;L = int()</v>
+ <v>&nbsp;&nbsp;Dir = string()</v>
+ <v>&nbsp;&nbsp;Env = [{Name, Val}]</v>
+ <v>&nbsp;&nbsp;&nbsp;Name = string()</v>
+ <v>&nbsp;&nbsp;&nbsp;Val = string() | false</v>
+ </type>
+ <desc>
+ <p>Returns a port identifier as the result of opening a
+ new Erlang port. A port can be seen as an external Erlang
+ process. <c>PortName</c> is one of the following:</p>
+ <taglist>
+ <tag><c>{spawn, Command}</c></tag>
+ <item>
+ <p>Starts an external program. <c>Command</c> is the name
+ of the external program which will be run. <c>Command</c>
+ runs outside the Erlang work space unless an Erlang
+ driver with the name <c>Command</c> is found. If found,
+ that driver will be started. A driver runs in the Erlang
+ workspace, 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 with using
+ <c>vfork</c>, setting the environment variable
+ <c>ERL_NO_VFORK</c> to any value will cause <c>fork</c>
+ to be used instead.</p>
+
+ <p>For external programs, the <c>PATH</c> is searched
+ (or an equivalent method is used to find programs,
+ depending on operating system). This is done by invoking
+ the shell och certain platforms. The first space
+ separated token of the command will be considered as the
+ name of the executable (or driver). This (among other
+ things) makes this option unsuitable for running
+ programs having spaces in file or directory names. Use
+ {spawn_executable, Command} instead if spaces in executable
+ file names is desired.</p>
+ </item>
+ <tag><c>{spawn_driver, Command}</c></tag>
+ <item>
+ <p>Works like <c>{spawn, Command}</c>, but demands the
+ first (space separated) token of the command to be the name of a
+ loaded driver. If no driver with that name is loaded, a
+ <c>badarg</c> error is raised.</p>
+ </item>
+ <tag><c>{spawn_executable, Command}</c></tag>
+ <item>
+
+ <p>Works like <c>{spawn, Command}</c>, but only runs
+ external executables. The <c>Command</c> in it's whole
+ is used as the name of the executable, including any
+ spaces. If arguments are to be passed, the
+ <c>args</c> and <c>arg0</c> <c>PortSettings</c> can be used.</p>
+
+ <p>The shell is not usually invoked to start the
+ program, it's executed directly. Neither is the
+ <c>PATH</c> (or equivalent) searched. To find a program
+ in the PATH to execute, use <seealso
+ marker="kernel:os#find_executable/1">os:find_executable/1</seealso>.</p>
+ <p>Only if a shell script or <c>.bat</c> file is
+ executed, the appropriate command interpreter will
+ implicitly be invoked, but there will still be no
+ command argument expansion or implicit PATH search.</p>
+
+ <p>If the <c>Command</c> cannot be run, an error
+ exception, with the posix error code as the reason, is
+ raised. The error reason may differ between operating
+ systems. Typically the error <c>enoent</c> is raised
+ when one tries to run a program that is not found and
+ <c>eaccess</c> is raised when the given file is not
+ executable.</p>
+ </item>
+ <tag><c>{fd, In, Out}</c></tag>
+ <item>
+ <p>Allows an Erlang process to access any currently opened
+ file descriptors used by Erlang. The file descriptor
+ <c>In</c> can be used for standard input, and the file
+ descriptor <c>Out</c> for standard output. It is only
+ used for various servers in the Erlang operating system
+ (<c>shell</c> and <c>user</c>). Hence, its use is very
+ limited.</p>
+ </item>
+ </taglist>
+ <p><c>PortSettings</c> is a list of settings for the port.
+ Valid settings are:</p>
+ <taglist>
+ <tag><c>{packet, N}</c></tag>
+ <item>
+ <p>Messages are preceded by their length, sent in <c>N</c>
+ bytes, with the most significant byte first. Valid values
+ for <c>N</c> are 1, 2, or 4.</p>
+ </item>
+ <tag><c>stream</c></tag>
+ <item>
+ <p>Output messages are sent without packet lengths. A
+ user-defined protocol must be used between the Erlang
+ process and the external object.</p>
+ </item>
+ <tag><c>{line, L}</c></tag>
+ <item>
+ <p>Messages are delivered on a per line basis. Each line
+ (delimited by the OS-dependent newline sequence) is
+ delivered in one single message. The message data format
+ is <c>{Flag, Line}</c>, where <c>Flag</c> is either
+ <c>eol</c> or <c>noeol</c> and <c>Line</c> is the actual
+ data delivered (without the newline sequence).</p>
+ <p><c>L</c> specifies the maximum line length in bytes.
+ Lines longer than this will be delivered in more than one
+ message, with the <c>Flag</c> set to <c>noeol</c> for all
+ but the last message. If end of file is encountered
+ anywhere else than immediately following a newline
+ sequence, the last line will also be delivered with
+ the <c>Flag</c> set to <c>noeol</c>. In all other cases,
+ lines are delivered with <c>Flag</c> set to <c>eol</c>.</p>
+ <p>The <c>{packet, N}</c> and <c>{line, L}</c> settings are
+ mutually exclusive.</p>
+ </item>
+ <tag><c>{cd, Dir}</c></tag>
+ <item>
+ <p>This is only valid for <c>{spawn, Command}</c> and
+ <c>{spawn_executable, Command}</c>.
+ The external program starts using <c>Dir</c> as its
+ working directory. <c>Dir</c> must be a string. Not
+ available on VxWorks.</p>
+ </item>
+ <tag><c>{env, Env}</c></tag>
+ <item>
+ <p>This is only valid for <c>{spawn, Command}</c> and
+ <c>{spawn_executable, Command}</c>.
+ The environment of the started process is extended using
+ the environment specifications in <c>Env</c>.</p>
+ <p><c>Env</c> should be a list of tuples <c>{Name, Val}</c>,
+ where <c>Name</c> is the name of an environment variable,
+ and <c>Val</c> is the value it is to have in the spawned
+ port process. Both <c>Name</c> and <c>Val</c> must be
+ strings. The one exception is <c>Val</c> being the atom
+ <c>false</c> (in analogy with <c>os:getenv/1</c>), which
+ removes the environment variable. Not available on
+ VxWorks.</p>
+ </item>
+ <tag><c>{args, [ string() ]}</c></tag>
+ <item>
+
+ <p>This option is only valid for <c>{spawn_executable, Command}</c>
+ and specifies arguments to the executable. Each argument
+ is given as a separate string and (on Unix) eventually
+ ends up as one element each in the argument vector. On
+ other platforms, similar behavior is mimicked.</p>
+
+ <p>The arguments are not expanded by the shell prior to
+ being supplied to the executable, most notably this
+ means that file wildcard expansion will not happen. Use
+ <seealso
+ marker="stdlib:filelib#wildcard/1">filelib:wildcard/1</seealso>
+ to expand wildcards for the arguments. Note that even if
+ the program is a Unix shell script, meaning that the
+ shell will ultimately be invoked, wildcard expansion
+ will not happen and the script will be provided with the
+ untouched arguments. On Windows&reg;, wildcard expansion
+ is always up to the program itself, why this isn't an
+ issue.</p>
+
+ <p>Note also that the actual executable name (a.k.a. <c>argv[0]</c>)
+ should not be given in this list. The proper executable name will
+ automatically be used as argv[0] where applicable.</p>
+
+ <p>If one, for any reason, wants to explicitly set the
+ program name in the argument vector, the <c>arg0</c>
+ option can be used.</p>
+
+ </item>
+ <tag><c>{arg0, string()}</c></tag>
+ <item>
+
+ <p>This option is only valid for <c>{spawn_executable, Command}</c>
+ and explicitly specifies the program name argument when
+ running an executable. This might in some circumstances,
+ on some operating systems, be desirable. How the program
+ responds to this is highly system dependent and no specific
+ effect is guaranteed.</p>
+
+ </item>
+
+ <tag><c>exit_status</c></tag>
+ <item>
+ <p>This is only valid for <c>{spawn, Command}</c> where
+ <c>Command</c> refers to an external program, and for
+ <c>{spawn_executable, Command}</c>.</p>
+ <p>When the external process connected to the port exits, a
+ message of the form <c>{Port,{exit_status,Status}}</c> is
+ sent to the connected process, where <c>Status</c> is the
+ exit status of the external process. If the program
+ aborts, on Unix the same convention is used as the shells
+ do (i.e., 128+signal).</p>
+ <p>If the <c>eof</c> option has been given as well,
+ the <c>eof</c> message and the <c>exit_status</c> message
+ appear in an unspecified order.</p>
+ <p>If the port program closes its stdout without exiting,
+ the <c>exit_status</c> option will not work.</p>
+ </item>
+ <tag><c>use_stdio</c></tag>
+ <item>
+ <p>This is only valid for <c>{spawn, Command}</c> and
+ <c>{spawn_executable, Command}</c>. It
+ allows the standard input and output (file descriptors 0
+ and 1) of the spawned (UNIX) process for communication
+ with Erlang.</p>
+ </item>
+ <tag><c>nouse_stdio</c></tag>
+ <item>
+ <p>The opposite of <c>use_stdio</c>. Uses file descriptors
+ 3 and 4 for communication with Erlang.</p>
+ </item>
+ <tag><c>stderr_to_stdout</c></tag>
+ <item>
+ <p>Affects ports to external programs. The executed program
+ gets its standard error file redirected to its standard
+ output file. <c>stderr_to_stdout</c> and
+ <c>nouse_stdio</c> are mutually exclusive.</p>
+ </item>
+ <tag><c>overlapped_io</c></tag>
+ <item>
+ <p>Affects ports to external programs on Windows&reg; only.
+ The standard input and standard output handles of the port program
+ will, if this option is supplied, be opened with the flag
+ FILE_FLAG_OVERLAPPED, so that the port program can (and has to) do
+ overlapped I/O on it's standard handles. This is not normally
+ the case for simple port programs, but an option of value for the
+ experienced Windows programmer. <em>On all other platforms, this
+ option is silently discarded</em>.</p>
+ </item>
+ <tag><c>in</c></tag>
+ <item>
+ <p>The port can only be used for input.</p>
+ </item>
+ <tag><c>out</c></tag>
+ <item>
+ <p>The port can only be used for output.</p>
+ </item>
+ <tag><c>binary</c></tag>
+ <item>
+ <p>All IO from the port are binary data objects as opposed
+ to lists of bytes.</p>
+ </item>
+ <tag><c>eof</c></tag>
+ <item>
+ <p>The port will not be closed at the end of the file and
+ produce an exit signal. Instead, it will remain open and
+ a <c>{Port, eof}</c> message will be sent to the process
+ holding the port.</p>
+ </item>
+ <tag><c>hide</c></tag>
+ <item>
+ <p>When running on Windows, suppress creation of a new
+ console window when spawning the port program.
+ (This option has no effect on other platforms.)</p>
+ </item>
+ </taglist>
+ <p>The default is <c>stream</c> for all types of port and
+ <c>use_stdio</c> for spawned ports.</p>
+ <p>Failure: If the port cannot be opened, the exit reason is
+ <c>badarg</c>, <c>system_limit</c>, or the Posix error code which
+ most closely describes the error, or <c>einval</c> if no Posix code
+ is appropriate:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ <p>Bad input arguments to <c>open_port</c>.</p>
+ </item>
+ <tag><c>system_limit</c></tag>
+ <item>
+ <p>All available ports in the Erlang emulator are in use.</p>
+ </item>
+ <tag><c>enomem</c></tag>
+ <item>
+ <p>There was not enough memory to create the port.</p>
+ </item>
+ <tag><c>eagain</c></tag>
+ <item>
+ <p>There are no more available operating system processes.</p>
+ </item>
+ <tag><c>enametoolong</c></tag>
+ <item>
+ <p>The external command given was too long.</p>
+ </item>
+ <tag><c>emfile</c></tag>
+ <item>
+ <p>There are no more available file descriptors (for the operating system process
+ that the Erlang emulator runs in).</p>
+ </item>
+ <tag><c>enfile</c></tag>
+ <item>
+ <p>The file table is full (for the entire operating system).</p>
+ </item>
+ <tag><c>eacces</c></tag>
+ <item>
+ <p>The <c>Command</c> given in <c>{spawn_executable, Command}</c> does not point out an executable file.</p>
+ </item>
+ <tag><c>enoent</c></tag>
+ <item>
+ <p>The <c>Command</c> given in <c>{spawn_executable, Command}</c> does not point out an existing file.</p>
+ </item>
+ </taglist>
+ <p>During use of a port opened using <c>{spawn, Name}</c>,
+ <c>{spawn_driver, Name}</c> or <c>{spawn_executable, Name}</c>,
+ errors arising when sending messages to it are reported to
+ the owning process using signals of the form
+ <c>{'EXIT', Port, PosixCode}</c>. See <c>file(3)</c> for
+ possible values of <c>PosixCode</c>.</p>
+ <p><marker id="ERL_MAX_PORTS"></marker>
+ The maximum number of ports that can be open at the same
+ time is 1024 by default, but can be configured by
+ the environment variable <c>ERL_MAX_PORTS</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:phash(Term, Range) -> Hash</name>
+ <fsummary>Portable hash function</fsummary>
+ <type>
+ <v>Term = term()</v>
+ <v>Range = 1..2^32</v>
+ <v>Hash = 1..Range</v>
+ </type>
+ <desc>
+ <p>Portable hash function that will give the same hash for
+ the same Erlang term regardless of machine architecture and
+ ERTS version (the BIF was introduced in ERTS 4.9.1.1). Range
+ can be between 1 and 2^32, the function returns a hash value
+ for <c>Term</c> within the range <c>1..Range</c>.</p>
+ <p>This BIF could be used instead of the old deprecated
+ <c>erlang:hash/2</c> BIF, as it calculates better hashes for
+ all data-types, but consider using <c>phash2/1,2</c> instead.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:phash2(Term [, Range]) -> Hash</name>
+ <fsummary>Portable hash function</fsummary>
+ <type>
+ <v>Term = term()</v>
+ <v>Range = 1..2^32</v>
+ <v>Hash = 0..Range-1</v>
+ </type>
+ <desc>
+ <p>Portable hash function that will give the same hash for
+ the same Erlang term regardless of machine architecture and
+ ERTS version (the BIF was introduced in ERTS 5.2). Range can
+ be between 1 and 2^32, the function returns a hash value for
+ <c>Term</c> within the range <c>0..Range-1</c>. When called
+ without the <c>Range</c> argument, a value in the range
+ <c>0..2^27-1</c> is returned.</p>
+ <p>This BIF should always be used for hashing terms. It
+ distributes small integers better than <c>phash/2</c>, and
+ it is faster for bignums and binaries.</p>
+ <p>Note that the range <c>0..Range-1</c> is different from
+ the range of <c>phash/2</c> (<c>1..Range</c>).</p>
+ </desc>
+ </func>
+ <func>
+ <name>pid_to_list(Pid) -> string()</name>
+ <fsummary>Text representation of a pid</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Pid</c>.</p>
+ <warning>
+ <p>This BIF is intended for debugging and for use in
+ the Erlang operating system. It should not be used in
+ application programs.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>port_close(Port) -> true</name>
+ <fsummary>Close an open port</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ </type>
+ <desc>
+ <p>Closes an open port. Roughly the same as
+ <c>Port ! {self(), close}</c> except for the error behaviour
+ (see below), and that the port does <em>not</em> reply with
+ <c>{Port, closed}</c>. Any process may close a port with
+ <c>port_close/1</c>, not only the port owner (the connected
+ process).</p>
+ <p>For comparison: <c>Port ! {self(), close}</c> fails with
+ <c>badarg</c> if <c>Port</c> cannot be sent to (i.e.,
+ <c>Port</c> refers neither to a port nor to a process). If
+ <c>Port</c> is a closed port nothing happens. If <c>Port</c>
+ is an open port and the calling process is the port owner,
+ the port replies with <c>{Port, closed}</c> when all buffers
+ have been flushed and the port really closes, but if
+ the calling process is not the port owner the <em>port owner</em> fails with <c>badsig</c>.</p>
+ <p>Note that any process can close a port using
+ <c>Port ! {PortOwner, close}</c> just as if it itself was
+ the port owner, but the reply always goes to the port owner.</p>
+ <p>In short: <c>port_close(Port)</c> has a cleaner and more
+ logical behaviour than <c>Port ! {self(), close}</c>.</p>
+ <p>Failure: <c>badarg</c> if <c>Port</c> is not an open port or
+ the registered name of an open port.</p>
+ </desc>
+ </func>
+ <func>
+ <name>port_command(Port, Data) -> true</name>
+ <fsummary>Send data to a port</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ <v>Data = iodata()</v>
+ </type>
+ <desc>
+ <p>Sends data to a port. Same as
+ <c>Port ! {self(), {command, Data}}</c> except for the error
+ behaviour (see below). Any process may send data to a port
+ with <c>port_command/2</c>, not only the port owner
+ (the connected process).</p>
+ <p>For comparison: <c>Port ! {self(), {command, Data}}</c>
+ fails with <c>badarg</c> if <c>Port</c> cannot be sent to
+ (i.e., <c>Port</c> refers neither to a port nor to a process).
+ If <c>Port</c> is a closed port the data message disappears
+ without a sound. If <c>Port</c> is open and the calling
+ process is not the port owner, the <em>port owner</em> fails
+ with <c>badsig</c>. The port owner fails with <c>badsig</c>
+ also if <c>Data</c> is not a valid IO list.</p>
+ <p>Note that any process can send to a port using
+ <c>Port ! {PortOwner, {command, Data}}</c> just as if it
+ itself was the port owner.</p>
+ <p>In short: <c>port_command(Port, Data)</c> has a cleaner and
+ more logical behaviour than
+ <c>Port ! {self(), {command, Data}}</c>.</p>
+ <p>If the port is busy, the calling process will be suspended
+ until the port is not busy anymore.</p>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>Port</c> is not an open port or the registered name
+ of an open port.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>Data</c> is not a valid io list.
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:port_command(Port, Data, OptionList) -> true|false</name>
+ <fsummary>Send data to a port</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ <v>Data = iodata()</v>
+ <v>OptionList = [Option]</v>
+ <v>Option = force</v>
+ <v>Option = nosuspend</v>
+ </type>
+ <desc>
+ <p>Sends data to a port. <c>port_command(Port, Data, [])</c>
+ equals <c>port_command(Port, Data)</c>.</p>
+ <p>If the port command is aborted <c>false</c> is returned;
+ otherwise, <c>true</c> is returned.</p>
+ <p>If the port is busy, the calling process will be suspended
+ until the port is not busy anymore.</p>
+ <p>Currently the following <c>Option</c>s are valid:</p>
+ <taglist>
+ <tag><c>force</c></tag>
+ <item>The calling process will not be suspended if the port is
+ busy; instead, the port command is forced through. The
+ call will fail with a <c>notsup</c> exception if the
+ driver of the port does not support this. For more
+ information see the
+ <seealso marker="driver_entry#driver_flags"><![CDATA[ERL_DRV_FLAG_SOFT_BUSY]]></seealso>
+ driver flag.
+ </item>
+ <tag><c>nosuspend</c></tag>
+ <item>The calling process will not be suspended if the port is
+ busy; instead, the port command is aborted and
+ <c>false</c> is returned.
+ </item>
+ </taglist>
+ <note>
+ <p>More options may be added in the future.</p>
+ </note>
+ <note>
+ <p><c>erlang:port_command/3</c> is currently not auto imported, but
+ it is planned to be auto imported in OTP R14.</p>
+ </note>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>Port</c> is not an open port or the registered name
+ of an open port.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>Data</c> is not a valid io list.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>OptionList</c> is not a valid option list.
+ </item>
+ <tag><c>notsup</c></tag>
+ <item>
+ If the <c>force</c> option has been passed, but the
+ driver of the port does not allow forcing through
+ a busy port.
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>port_connect(Port, Pid) -> true</name>
+ <fsummary>Set the owner of a port</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ <v>Pid = pid()</v>
+ </type>
+ <desc>
+ <p>Sets the port owner (the connected port) to <c>Pid</c>.
+ Roughly the same as <c>Port ! {self(), {connect, Pid}}</c>
+ except for the following:</p>
+ <list type="bulleted">
+ <item>
+ <p>The error behavior differs, see below.</p>
+ </item>
+ <item>
+ <p>The port does <em>not</em> reply with
+ <c>{Port,connected}</c>.</p>
+ </item>
+ <item>
+ <p>The new port owner gets linked to the port.</p>
+ </item>
+ </list>
+ <p>The old port owner stays linked to the port and have to call
+ <c>unlink(Port)</c> if this is not desired. Any process may
+ set the port owner to be any process with
+ <c>port_connect/2</c>.</p>
+ <p>For comparison: <c>Port ! {self(), {connect, Pid}}</c> fails
+ with <c>badarg</c> if <c>Port</c> cannot be sent to (i.e.,
+ <c>Port</c> refers neither to a port nor to a process). If
+ <c>Port</c> is a closed port nothing happens. If <c>Port</c>
+ is an open port and the calling process is the port owner,
+ the port replies with <c>{Port, connected}</c> to the old
+ port owner. Note that the old port owner is still linked to
+ the port, and that the new is not. If <c>Port</c> is an open
+ port and the calling process is not the port owner,
+ the <em>port owner</em> fails with <c>badsig</c>. The port
+ owner fails with <c>badsig</c> also if <c>Pid</c> is not an
+ existing local pid.</p>
+ <p>Note that any process can set the port owner using
+ <c>Port ! {PortOwner, {connect, Pid}}</c> just as if it
+ itself was the port owner, but the reply always goes to
+ the port owner.</p>
+ <p>In short: <c>port_connect(Port, Pid)</c> has a cleaner and
+ more logical behaviour than
+ <c>Port ! {self(),{connect,Pid}}</c>.</p>
+ <p>Failure: <c>badarg</c> if <c>Port</c> is not an open port
+ or the registered name of an open port, or if <c>Pid</c> is
+ not an existing local pid.</p>
+ </desc>
+ </func>
+ <func>
+ <name>port_control(Port, Operation, Data) -> Res</name>
+ <fsummary>Perform a synchronous control operation on a port</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ <v>Operation = int()</v>
+ <v>Data = Res = iodata()</v>
+ </type>
+ <desc>
+ <p>Performs a synchronous control operation on a port.
+ The meaning of <c>Operation</c> and <c>Data</c> depends on
+ the port, i.e., on the port driver. Not all port drivers
+ support this control feature.</p>
+ <p>Returns: a list of integers in the range 0 through 255, or a
+ binary, depending on the port driver. The meaning of
+ the returned data also depends on the port driver.</p>
+ <p>Failure: <c>badarg</c> if <c>Port</c> is not an open port or
+ the registered name of an open port, if <c>Operation</c>
+ cannot fit in a 32-bit integer, if the port driver does not
+ support synchronous control operations, or if the port driver
+ so decides for any reason (probably something wrong with
+ <c>Operation</c> or <c>Data</c>).</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:port_call(Port, Operation, Data) -> term()</name>
+ <fsummary>Synchronous call to a port with term data</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ <v>Operation = int()</v>
+ <v>Data = term()</v>
+ </type>
+ <desc>
+ <p>Performs a synchronous call to a port. The meaning of
+ <c>Operation</c> and <c>Data</c> depends on the port, i.e.,
+ on the port driver. Not all port drivers support this feature.</p>
+ <p><c>Port</c> is a port identifier, referring to a driver.</p>
+ <p><c>Operation</c> is an integer, which is passed on to
+ the driver.</p>
+ <p><c>Data</c> is any Erlang term. This data is converted to
+ binary term format and sent to the port.</p>
+ <p>Returns: a term from the driver. The meaning of the returned
+ data also depends on the port driver.</p>
+ <p>Failure: <c>badarg</c> if <c>Port</c> is not an open port or
+ the registered name of an open port, if <c>Operation</c>
+ cannot fit in a 32-bit integer, if the port driver does not
+ support synchronous control operations, or if the port driver
+ so decides for any reason (probably something wrong with
+ <c>Operation</c> or <c>Data</c>).</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:port_info(Port) -> [{Item, Info}] | undefined</name>
+ <fsummary>Information about a port</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ <v>Item, Info -- see below</v>
+ </type>
+ <desc>
+ <p>Returns a list containing tuples with information about
+ the <c>Port</c>, or <c>undefined</c> if the port is not open.
+ The order of the tuples is not defined, nor are all the
+ tuples mandatory.</p>
+ <taglist>
+ <tag><c>{registered_name, RegName}</c></tag>
+ <item>
+ <p><c>RegName</c> (an atom) is the registered name of
+ the port. If the port has no registered name, this tuple
+ is not present in the list.</p>
+ </item>
+ <tag><c>{id, Index}</c></tag>
+ <item>
+ <p><c>Index</c> (an integer) is the internal index of the
+ port. This index may be used to separate ports.</p>
+ </item>
+ <tag><c>{connected, Pid}</c></tag>
+ <item>
+ <p><c>Pid</c> is the process connected to the port.</p>
+ </item>
+ <tag><c>{links, Pids}</c></tag>
+ <item>
+ <p><c>Pids</c> is a list of pids to which processes the
+ port is linked.</p>
+ </item>
+ <tag><c>{name, String}</c></tag>
+ <item>
+ <p><c>String</c> is the command name set by
+ <c>open_port</c>.</p>
+ </item>
+ <tag><c>{input, Bytes}</c></tag>
+ <item>
+ <p><c>Bytes</c> is the total number of bytes read from
+ the port.</p>
+ </item>
+ <tag><c>{output, Bytes}</c></tag>
+ <item>
+ <p><c>Bytes</c> is the total number of bytes written to
+ the port.</p>
+ </item>
+ </taglist>
+ <p>Failure: <c>badarg</c> if <c>Port</c> is not a local port.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:port_info(Port, Item) -> {Item, Info} | undefined | []</name>
+ <fsummary>Information about a port</fsummary>
+ <type>
+ <v>Port = port() | atom()</v>
+ <v>Item, Info -- see below</v>
+ </type>
+ <desc>
+ <p>Returns information about <c>Port</c> as specified
+ by <c>Item</c>, or <c>undefined</c> if the port is not open.
+ Also, if <c>Item == registered_name</c> and the port has no
+ registered name, [] is returned.</p>
+ <p>For valid values of <c>Item</c>, and corresponding
+ values of <c>Info</c>, see
+ <seealso marker="#erlang:port_info/1">erlang:port_info/1</seealso>.</p>
+ <p>Failure: <c>badarg</c> if <c>Port</c> is not a local port.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:port_to_list(Port) -> string()</name>
+ <fsummary>Text representation of a port identifier</fsummary>
+ <type>
+ <v>Port = port()</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of the port identifier <c>Port</c>.</p>
+ <warning>
+ <p>This BIF is intended for debugging and for use in
+ the Erlang operating system. It should not be used in
+ application programs.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:ports() -> [port()]</name>
+ <fsummary>All open ports</fsummary>
+ <desc>
+ <p>Returns a list of all ports on the local node.</p>
+ </desc>
+ </func>
+ <func>
+ <name>pre_loaded() -> [Module]</name>
+ <fsummary>List of all pre-loaded modules</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns a list of Erlang modules which are pre-loaded in
+ the system. As all loading of code is done through the file
+ system, the file system must have been loaded previously.
+ Hence, at least the module <c>init</c> must be pre-loaded.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:process_display(Pid, Type) -> void()</name>
+ <fsummary>Write information about a local process on standard error</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Type = backtrace</v>
+ </type>
+ <desc>
+ <p>Writes information about the local process <c>Pid</c> on
+ standard error. The currently allowed value for the atom
+ <c>Type</c> is <c>backtrace</c>, which shows the contents of
+ the call stack, including information about the call chain, with
+ the current function printed first. The format of the output
+ is not further defined.</p>
+ </desc>
+ </func>
+ <func>
+ <name>process_flag(Flag, Value) -> OldValue</name>
+ <fsummary>Set process flags for the calling process</fsummary>
+ <type>
+ <v>Flag, Value, OldValue -- see below</v>
+ </type>
+ <desc>
+ <p>Sets certain flags for the process which calls this
+ function. Returns the old value of the flag.</p>
+ <taglist>
+ <tag><c>process_flag(trap_exit, Boolean)</c></tag>
+ <item>
+ <p>When <c>trap_exit</c> is set to <c>true</c>, exit signals
+ arriving to a process are converted to <c>{'EXIT', From, Reason}</c> messages, which can be received as ordinary
+ messages. If <c>trap_exit</c> is set to <c>false</c>, the
+ process exits if it receives an exit signal other than
+ <c>normal</c> and the exit signal is propagated to its
+ linked processes. Application processes should normally
+ not trap exits.</p>
+ <p>See also <seealso marker="#exit/2">exit/2</seealso>.</p>
+ </item>
+ <tag><c>process_flag(error_handler, Module)</c></tag>
+ <item>
+ <p>This is used by a process to redefine the error handler
+ for undefined function calls and undefined registered
+ processes. Inexperienced users should not use this flag
+ since code auto-loading is dependent on the correct
+ operation of the error handling module.</p>
+ </item>
+ <tag><c>process_flag(min_heap_size, MinHeapSize)</c></tag>
+ <item>
+ <p>This changes the minimum heap size for the calling
+ process.</p>
+ </item>
+ <tag><c>process_flag(priority, Level)</c></tag>
+ <item>
+ <marker id="process_flag_priority"></marker>
+ <p>This sets the process priority. <c>Level</c> is an atom.
+ There are currently four priority levels: <c>low</c>,
+ <c>normal</c>, <c>high</c>, and <c>max</c>. The default
+ priority level is <c>normal</c>. <em>NOTE</em>: The
+ <c>max</c> priority level is reserved for internal use in
+ the Erlang runtime system, and should <em>not</em> be used
+ by others.
+ </p>
+ <p>Internally in each priority level processes are scheduled
+ in a round robin fashion.
+ </p>
+ <p>Execution of processes on priority <c>normal</c> and
+ priority <c>low</c> will be interleaved. Processes on
+ priority <c>low</c> will be selected for execution less
+ frequently than processes on priority <c>normal</c>.
+ </p>
+ <p>When there are runnable processes on priority <c>high</c>
+ no processes on priority <c>low</c>, or <c>normal</c> will
+ be selected for execution. Note, however, that this does
+ <em>not</em> mean that no processes on priority <c>low</c>,
+ or <c>normal</c> will be able to run when there are
+ processes on priority <c>high</c> running. On the runtime
+ system with SMP support there might be more processes running
+ in parallel than processes on priority <c>high</c>, i.e.,
+ a <c>low</c>, and a <c>high</c> priority process might
+ execute at the same time.
+ </p>
+ <p>When there are runnable processes on priority <c>max</c>
+ no processes on priority <c>low</c>, <c>normal</c>, or
+ <c>high</c> will be selected for execution. As with the
+ <c>high</c> priority, processes on lower priorities might
+ execute in parallel with processes on priority <c>max</c>.
+ </p>
+ <p>Scheduling is preemptive. Regardless of priority, a process
+ is preempted when it has consumed more than a certain amount
+ of reductions since the last time it was selected for
+ execution.
+ </p>
+ <p><em>NOTE</em>: You should not depend on the scheduling
+ to remain exactly as it is today. Scheduling, at least on
+ the runtime system with SMP support, is very likely to be
+ modified in the future in order to better utilize available
+ processor cores.
+ </p>
+ <p>There is currently <em>no</em> automatic mechanism for
+ avoiding priority inversion, such as priority inheritance,
+ or priority ceilings. When using priorities you have
+ to take this into account and handle such scenarios by
+ yourself.
+ </p>
+ <p>Making calls from a <c>high</c> priority process into code
+ that you don't have control over may cause the <c>high</c>
+ priority process to wait for a processes with lower
+ priority, i.e., effectively decreasing the priority of the
+ <c>high</c> priority process during the call. Even if this
+ isn't the case with one version of the code that you don't
+ have under your control, it might be the case in a future
+ version of it. This might, for example, happen if a
+ <c>high</c> priority process triggers code loading, since
+ the code server runs on priority <c>normal</c>.
+ </p>
+ <p>Other priorities than <c>normal</c> are normally not needed.
+ When other priorities are used, they need to be used
+ with care, especially the <c>high</c> priority <em>must</em>
+ be used with care. A process on <c>high</c> priority should
+ only perform work for short periods of time. Busy looping for
+ long periods of time in a <c>high</c> priority process will
+ most likely cause problems, since there are important servers
+ in OTP running on priority <c>normal</c>.
+ </p>
+ </item>
+
+ <tag><c>process_flag(save_calls, N)</c></tag>
+ <item>
+ <p>When there are runnable processes on priority <c>max</c>
+ no processes on priority <c>low</c>, <c>normal</c>, or
+ <c>high</c> will be selected for execution. As with the
+ <c>high</c> priority, processes on lower priorities might
+ execute in parallel with processes on priority <c>max</c>.
+ </p>
+ <p><c>N</c> must be an integer in the interval 0..10000.
+ If <c>N</c> &gt; 0, call saving is made active for the
+ process, which means that information about the <c>N</c>
+ most recent global function calls, BIF calls, sends and
+ receives made by the process are saved in a list, which
+ can be retrieved with
+ <c>process_info(Pid, last_calls)</c>. A global function
+ call is one in which the module of the function is
+ explicitly mentioned. Only a fixed amount of information
+ is saved: a tuple <c>{Module, Function, Arity}</c> for
+ function calls, and the mere atoms <c>send</c>,
+ <c>'receive'</c> and <c>timeout</c> for sends and receives
+ (<c>'receive'</c> when a message is received and
+ <c>timeout</c> when a receive times out). If <c>N</c> = 0,
+ call saving is disabled for the process, which is the
+ default. Whenever the size of the call saving list is set,
+ its contents are reset.</p>
+ </item>
+ <tag><c>process_flag(sensitive, Boolean)</c></tag>
+ <item>
+ <p>Set or clear the <c>sensitive</c> flag for the current process.
+ When a process has been marked as sensitive by calling
+ <c>process_flag(sensitive, true)</c>, features in the run-time
+ system that can be used for examining the data and/or inner working
+ of the process are silently disabled.</p>
+ <p>Features that are disabled include (but are not limited to)
+ the following:</p>
+ <p>Tracing: Trace flags can still be set for the process, but no
+ trace messages of any kind will be generated.
+ (If the <c>sensitive</c> flag is turned off, trace messages will
+ again be generated if there are any trace flags set.)</p>
+ <p>Sequential tracing: The sequential trace token will be propagated
+ as usual, but no sequential trace messages will be generated.</p>
+ <p><c>process_info/1,2</c> cannot be used to read out the message
+ queue or the process dictionary (both will be returned as empty lists).</p>
+ <p>Stack back-traces cannot be displayed for the process.</p>
+ <p>In crash dumps, the stack, messages, and the process dictionary
+ will be omitted.</p>
+ <p>If <c>{save_calls,N}</c> has been set for the process, no
+ function calls will be saved to the call saving list.
+ (The call saving list will not be cleared; furthermore, send, receive,
+ and timeout events will still be added to the list.)</p>
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>process_flag(Pid, Flag, Value) -> OldValue</name>
+ <fsummary>Set process flags for a process</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Flag, Value, OldValue -- see below</v>
+ </type>
+ <desc>
+ <p>Sets certain flags for the process <c>Pid</c>, in the same
+ manner as
+ <seealso marker="#process_flag/2">process_flag/2</seealso>.
+ Returns the old value of the flag. The allowed values for
+ <c>Flag</c> are only a subset of those allowed in
+ <c>process_flag/2</c>, namely: <c>save_calls</c>.</p>
+ <p>Failure: <c>badarg</c> if <c>Pid</c> is not a local process.</p>
+ </desc>
+ </func>
+ <func>
+ <name>process_info(Pid) -> InfoResult</name>
+ <fsummary>Information about a process</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Item = atom()</v>
+ <v>Info = term()</v>
+ <v>InfoTuple = {Item, Info}</v>
+ <v>InfoTupleList = [InfoTuple]</v>
+ <v>InfoResult = InfoTupleList | undefined</v>
+ </type>
+ <desc>
+ <p>Returns a list containing <c>InfoTuple</c>s with
+ miscellaneous information about the process identified by
+ <c>Pid</c>, or <c>undefined</c> if the process is not alive.
+ </p>
+ <p>
+ The order of the <c>InfoTuple</c>s is not defined, nor
+ are all the <c>InfoTuple</c>s mandatory. The <c>InfoTuple</c>s
+ part of the result may be changed without prior notice.
+ Currently <c>InfoTuple</c>s with the following <c>Item</c>s
+ are part of the result:
+ <c>current_function</c>, <c>initial_call</c>, <c>status</c>,
+ <c>message_queue_len</c>, <c>messages</c>, <c>links</c>,
+ <c>dictionary</c>, <c>trap_exit</c>, <c>error_handler</c>,
+ <c>priority</c>, <c>group_leader</c>, <c>total_heap_size</c>,
+ <c>heap_size</c>, <c>stack_size</c>, <c>reductions</c>, and
+ <c>garbage_collection</c>.
+ If the process identified by <c>Pid</c> has a registered name
+ also an <c>InfoTuple</c> with <c>Item == registered_name</c>
+ will appear.
+ </p>
+ <p>See <seealso marker="#process_info/2">process_info/2</seealso>
+ for information about specific <c>InfoTuple</c>s.</p>
+ <warning>
+ <p>This BIF is intended for <em>debugging only</em>, use
+ <seealso marker="#process_info/2">process_info/2</seealso>
+ for all other purposes.
+ </p>
+ </warning>
+ <p>Failure: <c>badarg</c> if <c>Pid</c> is not a local process.</p>
+ </desc>
+ </func>
+ <func>
+ <name>process_info(Pid, ItemSpec) -> InfoResult</name>
+ <fsummary>Information about a process</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Item = atom()</v>
+ <v>Info = term()</v>
+ <v>ItemList = [Item]</v>
+ <v>ItemSpec = Item | ItemList</v>
+ <v>InfoTuple = {Item, Info}</v>
+ <v>InfoTupleList = [InfoTuple]</v>
+ <v>InfoResult = InfoTuple | InfoTupleList | undefined | []</v>
+ </type>
+ <desc>
+ <p>Returns information about the process identified by <c>Pid</c>
+ as specified by the <c>ItemSpec</c>, or <c>undefined</c> if the
+ process is not alive.
+ </p>
+ <p>If the process is alive and <c>ItemSpec</c> is a single
+ <c>Item</c>, the returned value is the corresponding
+ <c>InfoTuple</c> unless <c>ItemSpec == registered_name</c>
+ and the process has no registered name. In this case
+ <c>[]</c> is returned. This strange behavior is due to
+ historical reasons, and is kept for backward compatibility.
+ </p>
+ <p>If <c>ItemSpec</c> is an <c>ItemList</c>, the result is an
+ <c>InfoTupleList</c>. The <c>InfoTuple</c>s in the
+ <c>InfoTupleList</c> will appear with the corresponding
+ <c>Item</c>s in the same order as the <c>Item</c>s appeared
+ in the <c>ItemList</c>. Valid <c>Item</c>s may appear multiple
+ times in the <c>ItemList</c>.
+ </p>
+ <note><p>If <c>registered_name</c> is part of an <c>ItemList</c>
+ and the process has no name registered a
+ <c>{registered_name, []}</c> <c>InfoTuple</c> <em>will</em>
+ appear in the resulting <c>InfoTupleList</c>. This
+ behavior is different than when
+ <c>ItemSpec == registered_name</c>, and than when
+ <c>process_info/1</c> is used.
+ </p></note>
+ <p>Currently the following <c>InfoTuple</c>s with corresponding
+ <c>Item</c>s are valid:</p>
+ <taglist>
+ <tag><c>{backtrace, Bin}</c></tag>
+ <item>
+ <p>The binary <c>Bin</c> contains the same information as
+ the output from
+ <c>erlang:process_display(Pid, backtrace)</c>. Use
+ <c>binary_to_list/1</c> to obtain the string of characters
+ from the binary.</p>
+ </item>
+ <tag><c>{binary, BinInfo}</c></tag>
+ <item>
+ <p><c>BinInfo</c> is a list containing miscellaneous information
+ about binaries currently being referred to by this process.
+ This <c>InfoTuple</c> may be changed or removed without prior
+ notice.</p>
+ </item>
+ <tag><c>{catchlevel, CatchLevel}</c></tag>
+ <item>
+ <p><c>CatchLevel</c> is the number of currently active
+ catches in this process. This <c>InfoTuple</c> may be
+ changed or removed without prior notice.</p>
+ </item>
+ <tag><c>{current_function, {Module, Function, Args}}</c></tag>
+ <item>
+ <p><c>Module</c>, <c>Function</c>, <c>Args</c> is
+ the current function call of the process.</p>
+ </item>
+ <tag><c>{dictionary, Dictionary}</c></tag>
+ <item>
+ <p><c>Dictionary</c> is the dictionary of the process.</p>
+ </item>
+ <tag><c>{error_handler, Module}</c></tag>
+ <item>
+ <p><c>Module</c> is the error handler module used by
+ the process (for undefined function calls, for example).</p>
+ </item>
+ <tag><c>{garbage_collection, GCInfo}</c></tag>
+ <item>
+ <p><c>GCInfo</c> is a list which contains miscellaneous
+ information about garbage collection for this process.
+ The content of <c>GCInfo</c> may be changed without
+ prior notice.</p>
+ </item>
+ <tag><c>{group_leader, GroupLeader}</c></tag>
+ <item>
+ <p><c>GroupLeader</c> is group leader for the IO of
+ the process.</p>
+ </item>
+ <tag><c>{heap_size, Size}</c></tag>
+ <item>
+ <p><c>Size</c> is the size in words of youngest heap generation
+ of the process. This generation currently include the stack
+ of the process. This information is highly implementation
+ dependent, and may change if the implementation change.
+ </p>
+ </item>
+ <tag><c>{initial_call, {Module, Function, Arity}}</c></tag>
+ <item>
+ <p><c>Module</c>, <c>Function</c>, <c>Arity</c> is
+ the initial function call with which the process was
+ spawned.</p>
+ </item>
+ <tag><c>{links, Pids}</c></tag>
+ <item>
+ <p><c>Pids</c> is a list of pids, with processes to
+ which the process has a link.</p>
+ </item>
+ <tag><c>{last_calls, false|Calls}</c></tag>
+ <item>
+ <p>The value is <c>false</c> if call saving is not active
+ for the process (see
+ <seealso marker="#process_flag/3">process_flag/3</seealso>).
+ If call saving is active, a list is returned, in which
+ the last element is the most recent called.</p>
+ </item>
+ <tag><c>{memory, Size}</c></tag>
+ <item>
+ <p><c>Size</c> is the size in bytes of the process. This
+ includes call stack, heap and internal structures.</p>
+ </item>
+ <tag><c>{message_binary, BinInfo}</c></tag>
+ <item>
+ <p><c>BinInfo</c> is a list containing miscellaneous information
+ about binaries currently being referred to by the message
+ area. This <c>InfoTuple</c> is only valid on an emulator
+ using the hybrid heap type. This <c>InfoTuple</c> may be
+ changed or removed without prior notice.</p>
+ </item>
+ <tag><c>{message_queue_len, MessageQueueLen}</c></tag>
+ <item>
+ <p><c>MessageQueueLen</c> is the number of messages
+ currently in the message queue of the process. This is
+ the length of the list <c>MessageQueue</c> returned as
+ the info item <c>messages</c> (see below).</p>
+ </item>
+ <tag><c>{messages, MessageQueue}</c></tag>
+ <item>
+ <p><c>MessageQueue</c> is a list of the messages to
+ the process, which have not yet been processed.</p>
+ </item>
+ <tag><c>{monitored_by, Pids}</c></tag>
+ <item>
+ <p>A list of pids that are monitoring the process (with
+ <c>erlang:monitor/2</c>).</p>
+ </item>
+ <tag><c>{monitors, Monitors}</c></tag>
+ <item>
+ <p>A list of monitors (started by <c>erlang:monitor/2</c>)
+ that are active for the process. For a local process
+ monitor or a remote process monitor by pid, the list item
+ is <c>{process, Pid}</c>, and for a remote process
+ monitor by name, the list item is
+ <c>{process, {RegName, Node}}</c>.</p>
+ </item>
+ <tag><c>{priority, Level}</c></tag>
+ <item>
+ <p><c>Level</c> is the current priority level for
+ the process. For more information on priorities see
+ <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso>.</p>
+ </item>
+ <tag><c>{reductions, Number}</c></tag>
+ <item>
+ <p><c>Number</c> is the number of reductions executed by
+ the process.</p>
+ </item>
+ <tag><c>{registered_name, Atom}</c></tag>
+ <item>
+ <p><c>Atom</c> is the registered name of the process. If
+ the process has no registered name, this tuple is not
+ present in the list.</p>
+ </item>
+ <tag><c>{sequential_trace_token, [] | SequentialTraceToken}</c></tag>
+ <item>
+ <p><c>SequentialTraceToken</c> the sequential trace token for
+ the process. This <c>InfoTuple</c> may be changed or removed
+ without prior notice.</p>
+ </item>
+ <tag><c>{stack_size, Size}</c></tag>
+ <item>
+ <p><c>Size</c> is the stack size of the process in words.</p>
+ </item>
+ <tag><c>{status, Status}</c></tag>
+ <item>
+ <p><c>Status</c> is the status of the process. <c>Status</c>
+ is <c>waiting</c> (waiting for a message), <c>running</c>,
+ <c>runnable</c> (ready to run, but another process is
+ running), or <c>suspended</c> (suspended on a "busy" port
+ or by the <c>erlang:suspend_process/[1,2]</c> BIF).</p>
+ </item>
+ <tag><c>{suspending, SuspendeeList}</c></tag>
+ <item>
+ <p><c>SuspendeeList</c> is a list of <c>{Suspendee,
+ ActiveSuspendCount, OutstandingSuspendCount}</c> tuples.
+ <c>Suspendee</c> is the pid of a process that have been or is to
+ be suspended by the process identified by <c>Pid</c> via the
+ <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>
+ BIF, or the
+ <seealso marker="#erlang:suspend_process/1">erlang:suspend_process/1</seealso>
+ BIF. <c>ActiveSuspendCount</c> is the number of times the
+ <c>Suspendee</c> has been suspended by <c>Pid</c>.
+ <c>OutstandingSuspendCount</c> is the number of not yet
+ completed suspend requests sent by <c>Pid</c>. That is,
+ if <c>ActiveSuspendCount /= 0</c>, <c>Suspendee</c> is
+ currently in the suspended state, and if
+ <c>OutstandingSuspendCount /= 0</c> the <c>asynchronous</c>
+ option of <c>erlang:suspend_process/2</c> has been used and
+ the suspendee has not yet been suspended by <c>Pid</c>.
+ Note that the <c>ActiveSuspendCount</c> and
+ <c>OutstandingSuspendCount</c> are not the total suspend count
+ on <c>Suspendee</c>, only the parts contributed by <c>Pid</c>.
+ </p>
+ </item>
+ <tag><c>{total_heap_size, Size}</c></tag>
+ <item>
+ <p><c>Size</c> is the total size in words of all heap
+ fragments of the process. This currently include the stack
+ of the process.
+ </p>
+ </item>
+ <tag><c>{trace, InternalTraceFlags}</c></tag>
+ <item>
+ <p><c>InternalTraceFlags</c> is an integer representing
+ internal trace flag for this process. This <c>InfoTuple</c>
+ may be changed or removed without prior notice.</p>
+ </item>
+ <tag><c>{trap_exit, Boolean}</c></tag>
+ <item>
+ <p><c>Boolean</c> is <c>true</c> if the process is trapping
+ exits, otherwise it is <c>false</c>.</p>
+ </item>
+ </taglist>
+ <p>Note however, that not all implementations support every one
+ of the above <c>Items</c>.</p>
+ <p>Failure: <c>badarg</c> if <c>Pid</c> is not a local process,
+ or if <c>Item</c> is not a valid <c>Item</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>processes() -> [pid()]</name>
+ <fsummary>All processes</fsummary>
+ <desc>
+ <p>Returns a list of process identifiers corresponding to
+ all the processes currently existing on the local node.
+ </p>
+ <p>Note that a process that is exiting, exists but is not alive, i.e.,
+ <c>is_process_alive/1</c> will return <c>false</c> for a process
+ that is exiting, but its process identifier will be part
+ of the result returned from <c>processes/0</c>.
+ </p>
+ <pre>
+> <input>processes().</input>
+[&lt;0.0.0&gt;,&lt;0.2.0&gt;,&lt;0.4.0&gt;,&lt;0.5.0&gt;,&lt;0.7.0&gt;,&lt;0.8.0&gt;]</pre>
+ </desc>
+ </func>
+ <func>
+ <name>purge_module(Module) -> void()</name>
+ <fsummary>Remove old code for a module</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Removes old code for <c>Module</c>. Before this BIF is used,
+ <c>erlang:check_process_code/2</c> should be called to check
+ that no processes are executing old code in the module.</p>
+ <warning>
+ <p>This BIF is intended for the code server (see
+ <seealso marker="kernel:code">code(3)</seealso>) and should not be
+ used elsewhere.</p>
+ </warning>
+ <p>Failure: <c>badarg</c> if there is no old code for
+ <c>Module</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>put(Key, Val) -> OldVal | undefined</name>
+ <fsummary>Add a new value to the process dictionary</fsummary>
+ <type>
+ <v>Key = Val = OldVal = term()</v>
+ </type>
+ <desc>
+ <p>Adds a new <c>Key</c> to the process dictionary, associated
+ with the value <c>Val</c>, and returns <c>undefined</c>. If
+ <c>Key</c> already exists, the old value is deleted and
+ replaced by <c>Val</c> and the function returns the old value.</p>
+ <note>
+ <p>The values stored when <c>put</c> is evaluated within
+ the scope of a <c>catch</c> will not be retracted if a
+ <c>throw</c> is evaluated, or if an error occurs.</p>
+ </note>
+ <pre>
+> <input>X = put(name, walrus), Y = put(name, carpenter),</input>
+<input>Z = get(name),</input>
+<input>{X, Y, Z}.</input>
+{undefined,walrus,carpenter}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:raise(Class, Reason, Stacktrace)</name>
+ <fsummary>Stop execution with an exception of given class, reason and call stack backtrace</fsummary>
+ <type>
+ <v>Class = error | exit | throw</v>
+ <v>Reason = term()</v>
+ <v>Stacktrace = [{Module, Function, Arity | Args} | {Fun, Args}]</v>
+ <v>&nbsp;Module = Function = atom()</v>
+ <v>&nbsp;Arity = int()</v>
+ <v>&nbsp;Args = [term()]</v>
+ <v>&nbsp;Fun = [fun()]</v>
+ </type>
+ <desc>
+ <p>Stops the execution of the calling process with an
+ exception of given class, reason and call stack backtrace
+ (<em>stacktrace</em>).</p>
+ <warning>
+ <p>This BIF is intended for debugging and for use in
+ the Erlang operating system. In general, it should
+ be avoided in applications, unless you know
+ very well what you are doing.</p>
+ </warning>
+ <p><c>Class</c> is one of <c>error</c>, <c>exit</c> or
+ <c>throw</c>, so if it were not for the stacktrace
+ <c>erlang:raise(Class, Reason, Stacktrace)</c> is
+ equivalent to <c>erlang:Class(Reason)</c>.
+ <c>Reason</c> is any term and <c>Stacktrace</c> is a list as
+ returned from <c>get_stacktrace()</c>, that is a list of
+ 3-tuples <c>{Module, Function, Arity | Args}</c> where
+ <c>Module</c> and <c>Function</c> are atoms and the third
+ element is an integer arity or an argument list. The
+ stacktrace may also contain <c>{Fun, Args}</c> tuples where
+ <c>Fun</c> is a local fun and <c>Args</c> is an argument list.</p>
+ <p>The stacktrace is used as the exception stacktrace for the
+ calling process; it will be truncated to the current
+ maximum stacktrace depth.</p>
+ <p>Because evaluating this function causes the process to
+ terminate, it has no return value - unless the arguments are
+ invalid, in which case the function <em>returns the error reason</em>, that is <c>badarg</c>. If you want to be
+ really sure not to return you can call
+ <c>erlang:error(erlang:raise(Class, Reason, Stacktrace))</c>
+ and hope to distinguish exceptions later.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:read_timer(TimerRef) -> int() | false</name>
+ <fsummary>Number of milliseconds remaining for a timer</fsummary>
+ <type>
+ <v>TimerRef = ref()</v>
+ </type>
+ <desc>
+ <p><c>TimerRef</c> is a timer reference returned by
+ <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>
+ or
+ <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>.
+ If the timer is active, the function returns the time in
+ milliseconds left until the timer will expire, otherwise
+ <c>false</c> (which means that <c>TimerRef</c> was never a
+ timer, that it has been cancelled, or that it has already
+ delivered its message).</p>
+ <p>See also
+ <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
+ and
+ <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:ref_to_list(Ref) -> string()</name>
+ <fsummary>Text representation of a reference</fsummary>
+ <type>
+ <v>Ref = ref()</v>
+ </type>
+ <desc>
+ <p>Returns a string which corresponds to the text
+ representation of <c>Ref</c>.</p>
+ <warning>
+ <p>This BIF is intended for debugging and for use in
+ the Erlang operating system. It should not be used in
+ application programs.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>register(RegName, Pid | Port) -> true</name>
+ <fsummary>Register a name for a pid (or port)</fsummary>
+ <type>
+ <v>RegName = atom()</v>
+ <v>Pid = pid()</v>
+ <v>Port = port()</v>
+ </type>
+ <desc>
+ <p>Associates the name <c>RegName</c> with a pid or a port
+ identifier. <c>RegName</c>, which must be an atom, can be used
+ instead of the pid / port identifier in the send operator
+ (<c>RegName ! Message</c>).</p>
+ <pre>
+> <input>register(db, Pid).</input>
+true</pre>
+ <p>Failure: <c>badarg</c> if <c>Pid</c> is not an existing,
+ local process or port, if <c>RegName</c> is already in use,
+ if the process or port is already registered (already has a
+ name), or if <c>RegName</c> is the atom <c>undefined</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>registered() -> [RegName]</name>
+ <fsummary>All registered names</fsummary>
+ <type>
+ <v>RegName = atom()</v>
+ </type>
+ <desc>
+ <p>Returns a list of names which have been registered using
+ <seealso marker="#register/2">register/2</seealso>.</p>
+ <pre>
+> <input>registered().</input>
+[code_server, file_server, init, user, my_db]</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:resume_process(Suspendee) -> true</name>
+ <fsummary>Resume a suspended process</fsummary>
+ <type>
+ <v>Suspendee = pid()</v>
+ </type>
+ <desc>
+ <p>Decreases the suspend count on the process identified by
+ <c>Suspendee</c>. <c>Suspendee</c> should previously have been
+ suspended via
+ <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>,
+ or
+ <seealso marker="#erlang:suspend_process/1">erlang:suspend_process/1</seealso>
+ by the process calling <c>erlang:resume_process(Suspendee)</c>. When
+ the suspend count on <c>Suspendee</c> reach zero, <c>Suspendee</c>
+ will be resumed, i.e., the state of the <c>Suspendee</c> is changed
+ from suspended into the state <c>Suspendee</c> was in before it was
+ suspended.
+ </p>
+ <warning>
+ <p>This BIF is intended for debugging only.</p>
+ </warning>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>Suspendee</c> isn't a process identifier.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the process calling <c>erlang:resume_process/1</c> had
+ not previously increased the suspend count on the process
+ identified by <c>Suspendee</c>.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the process identified by <c>Suspendee</c> is not alive.
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>round(Number) -> int()</name>
+ <fsummary>Return an integer by rounding a number</fsummary>
+ <type>
+ <v>Number = number()</v>
+ </type>
+ <desc>
+ <p>Returns an integer by rounding <c>Number</c>.</p>
+ <pre>
+> <input>round(5.5).</input>
+6</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>self() -> pid()</name>
+ <fsummary>Pid of the calling process</fsummary>
+ <desc>
+ <p>Returns the pid (process identifier) of the calling process.</p>
+ <pre>
+> <input>self().</input>
+&lt;0.26.0></pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:send(Dest, Msg) -> Msg</name>
+ <fsummary>Send a message</fsummary>
+ <type>
+ <v>Dest = pid() | port() | RegName | {RegName, Node}</v>
+ <v>Msg = term()</v>
+ <v>&nbsp;RegName = atom()</v>
+ <v>&nbsp;Node = node()</v>
+ </type>
+ <desc>
+ <p>Sends a message and returns <c>Msg</c>. This is the same as
+ <c>Dest ! Msg</c>.</p>
+ <p><c>Dest</c> may be a remote or local pid, a (local) port, a
+ locally registered name, or a tuple <c>{RegName, Node}</c>
+ for a registered name at another node.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:send(Dest, Msg, [Option]) -> Res</name>
+ <fsummary>Send a message conditionally</fsummary>
+ <type>
+ <v>Dest = pid() | port() | RegName | {RegName, Node}</v>
+ <v>&nbsp;RegName = atom()</v>
+ <v>&nbsp;Node = node()</v>
+ <v>Msg = term()</v>
+ <v>Option = nosuspend | noconnect</v>
+ <v>Res = ok | nosuspend | noconnect</v>
+ </type>
+ <desc>
+ <p>Sends a message and returns <c>ok</c>, or does not send
+ the message but returns something else (see below). Otherwise
+ the same as
+ <seealso marker="#erlang:send/2">erlang:send/2</seealso>. See
+ also
+ <seealso marker="#erlang:send_nosuspend/2">erlang:send_nosuspend/2,3</seealso>.
+ for more detailed explanation and warnings.</p>
+ <p>The possible options are:</p>
+ <taglist>
+ <tag><c>nosuspend</c></tag>
+ <item>
+ <p>If the sender would have to be suspended to do the send,
+ <c>nosuspend</c> is returned instead.</p>
+ </item>
+ <tag><c>noconnect</c></tag>
+ <item>
+ <p>If the destination node would have to be auto-connected
+ before doing the send, <c>noconnect</c> is returned
+ instead.</p>
+ </item>
+ </taglist>
+ <warning>
+ <p>As with <c>erlang:send_nosuspend/2,3</c>: Use with extreme
+ care!</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:send_after(Time, Dest, Msg) -> TimerRef</name>
+ <fsummary>Start a timer</fsummary>
+ <type>
+ <v>Time = int()</v>
+ <v>&nbsp;0 &lt;= Time &lt;= 4294967295</v>
+ <v>Dest = pid() | RegName </v>
+ <v>&nbsp;LocalPid = pid() (of a process, alive or dead, on the local node)</v>
+ <v>Msg = term()</v>
+ <v>TimerRef = ref()</v>
+ </type>
+ <desc>
+ <p>Starts a timer which will send the message <c>Msg</c>
+ to <c>Dest</c> after <c>Time</c> milliseconds.</p>
+ <p>If <c>Dest</c> is an atom, it is supposed to be the name of
+ a registered process. The process referred to by the name is
+ looked up at the time of delivery. No error is given if
+ the name does not refer to a process.</p>
+ <p>If <c>Dest</c> is a pid, the timer will be automatically
+ canceled if the process referred to by the pid is not alive,
+ or when the process exits. This feature was introduced in
+ erts version 5.4.11. Note that timers will not be
+ automatically canceled when <c>Dest</c> is an atom.</p>
+ <p>See also
+ <seealso marker="#erlang:start_timer/3">erlang:start_timer/3</seealso>,
+ <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>,
+ and
+ <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <p>Failure: <c>badarg</c> if the arguments does not satisfy
+ the requirements specified above.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:send_nosuspend(Dest, Msg) -> bool()</name>
+ <fsummary>Try to send a message without ever blocking</fsummary>
+ <type>
+ <v>Dest = pid() | port() | RegName | {RegName, Node}</v>
+ <v>&nbsp;RegName = atom()</v>
+ <v>&nbsp;Node = node()</v>
+ <v>Msg = term()</v>
+ </type>
+ <desc>
+ <p>The same as
+ <seealso marker="#erlang:send/3">erlang:send(Dest, Msg, [nosuspend])</seealso>, but returns <c>true</c> if
+ the message was sent and <c>false</c> if the message was not
+ sent because the sender would have had to be suspended.</p>
+ <p>This function is intended for send operations towards an
+ unreliable remote node without ever blocking the sending
+ (Erlang) process. If the connection to the remote node
+ (usually not a real Erlang node, but a node written in C or
+ Java) is overloaded, this function <em>will not send the message</em> but return <c>false</c> instead.</p>
+ <p>The same happens, if <c>Dest</c> refers to a local port that
+ is busy. For all other destinations (allowed for the ordinary
+ send operator <c>'!'</c>) this function sends the message and
+ returns <c>true</c>.</p>
+ <p>This function is only to be used in very rare circumstances
+ where a process communicates with Erlang nodes that can
+ disappear without any trace causing the TCP buffers and
+ the drivers queue to be over-full before the node will actually
+ be shut down (due to tick timeouts) by <c>net_kernel</c>. The
+ normal reaction to take when this happens is some kind of
+ premature shutdown of the other node.</p>
+ <p>Note that ignoring the return value from this function would
+ result in <em>unreliable</em> message passing, which is
+ contradictory to the Erlang programming model. The message is
+ <em>not</em> sent if this function returns <c>false</c>.</p>
+ <p>Note also that in many systems, transient states of
+ overloaded queues are normal. The fact that this function
+ returns <c>false</c> does not in any way mean that the other
+ node is guaranteed to be non-responsive, it could be a
+ temporary overload. Also a return value of <c>true</c> does
+ only mean that the message could be sent on the (TCP) channel
+ without blocking, the message is not guaranteed to have
+ arrived at the remote node. Also in the case of a disconnected
+ non-responsive node, the return value is <c>true</c> (mimics
+ the behaviour of the <c>!</c> operator). The expected
+ behaviour as well as the actions to take when the function
+ returns <c>false</c> are application and hardware specific.</p>
+ <warning>
+ <p>Use with extreme care!</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:send_nosuspend(Dest, Msg, Options) -> bool()</name>
+ <fsummary>Try to send a message without ever blocking</fsummary>
+ <type>
+ <v>Dest = pid() | port() | RegName | {RegName, Node}</v>
+ <v>&nbsp;RegName = atom()</v>
+ <v>&nbsp;Node = node()</v>
+ <v>Msg = term()</v>
+ <v>Option = noconnect</v>
+ </type>
+ <desc>
+ <p>The same as
+ <seealso marker="#erlang:send/3">erlang:send(Dest, Msg, [nosuspend | Options])</seealso>,
+ but with boolean return value.</p>
+ <p>This function behaves like
+ <seealso marker="#erlang:send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
+ but takes a third parameter, a list of options. The only
+ currently implemented option is <c>noconnect</c>. The option
+ <c>noconnect</c> makes the function return <c>false</c> if
+ the remote node is not currently reachable by the local
+ node. The normal behaviour is to try to connect to the node,
+ which may stall the process for a shorter period. The use of
+ the <c>noconnect</c> option makes it possible to be
+ absolutely sure not to get even the slightest delay when
+ sending to a remote process. This is especially useful when
+ communicating with nodes who expect to always be
+ the connecting part (i.e. nodes written in C or Java).</p>
+ <p>Whenever the function returns <c>false</c> (either when a
+ suspend would occur or when <c>noconnect</c> was specified and
+ the node was not already connected), the message is guaranteed
+ <em>not</em> to have been sent.</p>
+ <warning>
+ <p>Use with extreme care!</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:set_cookie(Node, Cookie) -> true</name>
+ <fsummary>Set the magic cookie of a node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Cookie = atom()</v>
+ </type>
+ <desc>
+ <p>Sets the magic cookie of <c>Node</c> to the atom
+ <c>Cookie</c>. If <c>Node</c> is the local node, the function
+ also sets the cookie of all other unknown nodes to
+ <c>Cookie</c> (see
+ <seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual).</p>
+ <p>Failure: <c>function_clause</c> if the local node is not
+ alive.</p>
+ </desc>
+ </func>
+ <func>
+ <name>setelement(Index, Tuple1, Value) -> Tuple2</name>
+ <fsummary>Set Nth element of a tuple</fsummary>
+ <type>
+ <v>Index = 1..tuple_size(Tuple1)</v>
+ <v>Tuple1 = Tuple2 = tuple()</v>
+ <v>Value = term()</v>
+ </type>
+ <desc>
+ <p>Returns a tuple which is a copy of the argument <c>Tuple1</c>
+ with the element given by the integer argument <c>Index</c>
+ (the first element is the element with index 1) replaced by
+ the argument <c>Value</c>.</p>
+ <pre>
+> <input>setelement(2, {10, green, bottles}, red).</input>
+{10,red,bottles}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>size(Item) -> int()</name>
+ <fsummary>Size of a tuple or binary</fsummary>
+ <type>
+ <v>Item = tuple() | binary()</v>
+ </type>
+ <desc>
+ <p>Returns an integer which is the size of the argument
+ <c>Item</c>, which must be either a tuple or a binary.</p>
+ <pre>
+> <input>size({morni, mulle, bwange}).</input>
+3</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn(Fun) -> pid()</name>
+ <fsummary>Create a new process with a fun as entry point</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Fun</c> to the empty list <c>[]</c>. Otherwise works
+ like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn(Node, Fun) -> pid()</name>
+ <fsummary>Create a new process with a fun as entry point on a given node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Fun = fun()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Fun</c> to the empty list <c>[]</c> on <c>Node</c>. If
+ <c>Node</c> does not exist, a useless pid is returned.
+ Otherwise works like
+ <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn(Module, Function, Args) -> pid()</name>
+ <fsummary>Create a new process with a function as entry point</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Module:Function</c> to <c>Args</c>. The new process
+ created will be placed in the system scheduler queue and be
+ run some time later.</p>
+ <p><c>error_handler:undefined_function(Module, Function, Args)</c> is evaluated by the new process if
+ <c>Module:Function/Arity</c> does not exist (where
+ <c>Arity</c> is the length of <c>Args</c>). The error handler
+ can be redefined (see
+ <seealso marker="#process_flag/2">process_flag/2</seealso>).
+ If <c>error_handler</c> is undefined, or the user has
+ redefined the default <c>error_handler</c> its replacement is
+ undefined, a failure with the reason <c>undef</c> will occur.</p>
+ <pre>
+> <input>spawn(speed, regulator, [high_speed, thin_cut]).</input>
+&lt;0.13.1></pre>
+ </desc>
+ </func>
+ <func>
+ <name>spawn(Node, Module, Function, ArgumentList) -> pid()</name>
+ <fsummary>Create a new process with a function as entry point on a given node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Module:Function</c> to <c>Args</c> on <c>Node</c>. If
+ <c>Node</c> does not exists, a useless pid is returned.
+ Otherwise works like
+ <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_link(Fun) -> pid()</name>
+ <fsummary>Create and link to a new process with a fun as entry point</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Fun</c> to the empty list []. A link is created between
+ the calling process and the new process, atomically.
+ Otherwise works like
+ <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_link(Node, Fun) -></name>
+ <fsummary>Create and link to a new process with a fun as entry point on a specified node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Fun = fun()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Fun</c> to the empty list [] on <c>Node</c>. A link is
+ created between the calling process and the new process,
+ atomically. If <c>Node</c> does not exist, a useless pid is
+ returned (and due to the link, an exit signal with exit
+ reason <c>noconnection</c> will be received). Otherwise works
+ like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_link(Module, Function, Args) -> pid()</name>
+ <fsummary>Create and link to a new process with a function as entry point</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Module:Function</c> to <c>Args</c>. A link is created
+ between the calling process and the new process, atomically.
+ Otherwise works like
+ <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_link(Node, Module, Function, Args) -> pid()</name>
+ <fsummary>Create and link to a new process with a function as entry point on a given node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Module:Function</c> to <c>Args</c> on <c>Node</c>. A
+ link is created between the calling process and the new
+ process, atomically. If <c>Node</c> does not exist, a useless
+ pid is returned (and due to the link, an exit signal with exit
+ reason <c>noconnection</c> will be received). Otherwise works
+ like <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_monitor(Fun) -> {pid(),reference()}</name>
+ <fsummary>Create and monitor a new process with a fun as entry point</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Fun</c> to the empty list [] and reference for a monitor
+ created to the new process.
+ Otherwise works like
+ <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_monitor(Module, Function, Args) -> {pid(),reference()}</name>
+ <fsummary>Create and monitor a new process with a function as entry point</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>A new process is started by the application
+ of <c>Module:Function</c> to <c>Args</c>, and the process is
+ monitored at the same time. Returns the pid and a reference
+ for the monitor.
+ Otherwise works like
+ <seealso marker="#spawn/3">spawn/3</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_opt(Fun, [Option]) -> pid() | {pid(),reference()}</name>
+ <fsummary>Create a new process with a fun as entry point</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>&nbsp;Level = low | normal | high</v>
+ <v>&nbsp;Number = int()</v>
+ <v>&nbsp;Size = int()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Fun</c> to the empty list <c>[]</c>. Otherwise
+ works like
+ <seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
+ <p>If the option <c>monitor</c> is given, the newly created
+ process will be monitored and both the pid and reference for
+ the monitor will be returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_opt(Node, Fun, [Option]) -> pid()</name>
+ <fsummary>Create a new process with a fun as entry point on a given node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Fun = fun()</v>
+ <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>&nbsp;Level = low | normal | high</v>
+ <v>&nbsp;Number = int()</v>
+ <v>&nbsp;Size = int()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Fun</c> to the empty list <c>[]</c> on <c>Node</c>. If
+ <c>Node</c> does not exist, a useless pid is returned.
+ Otherwise works like
+ <seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_opt(Module, Function, Args, [Option]) -> pid() | {pid(),reference()}</name>
+ <fsummary>Create a new process with a function as entry point</fsummary>
+ <type>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>&nbsp;Level = low | normal | high</v>
+ <v>&nbsp;Number = int()</v>
+ <v>&nbsp;Size = int()</v>
+ </type>
+ <desc>
+ <p>Works exactly like
+ <seealso marker="#spawn/3">spawn/3</seealso>, except that an
+ extra option list is given when creating the process.</p>
+ <p>If the option <c>monitor</c> is given, the newly created
+ process will be monitored and both the pid and reference for
+ the monitor will be returned.</p>
+ <taglist>
+ <tag><c>link</c></tag>
+ <item>
+ <p>Sets a link to the parent process (like
+ <c>spawn_link/3</c> does).</p>
+ </item>
+ <tag><c>monitor</c></tag>
+ <item>
+ <p>Monitor the new process (just like
+ <seealso marker="#erlang:monitor/2">erlang:monitor/2</seealso> does).</p>
+ </item>
+ <tag><c>{priority, Level}</c></tag>
+ <item>
+ <p>Sets the priority of the new process. Equivalent to
+ executing
+ <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso> in the start function of the new process,
+ except that the priority will be set before the process is
+ selected for execution for the first time. For more information
+ on priorities see
+ <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso>.</p>
+ </item>
+ <tag><c>{fullsweep_after, Number}</c></tag>
+ <item>
+ <p>This option is only useful for performance tuning.
+ In general, you should not use this option unless you
+ know that there is problem with execution times and/or
+ memory consumption, and you should measure to make sure
+ that the option improved matters.
+ </p>
+ <p>The Erlang runtime system uses a generational garbage
+ collection scheme, using an "old heap" for data that has
+ survived at least one garbage collection. When there is
+ no more room on the old heap, a fullsweep garbage
+ collection will be done.</p>
+ <p>The <c>fullsweep_after</c> option makes it possible to
+ specify the maximum number of generational collections
+ before forcing a fullsweep even if there is still room on
+ the old heap. Setting the number to zero effectively
+ disables the general collection algorithm, meaning that
+ all live data is copied at every garbage collection.</p>
+ <p>Here are a few cases when it could be useful to change
+ <c>fullsweep_after</c>. Firstly, if binaries that are no
+ longer used should be thrown away as soon as possible.
+ (Set <c>Number</c> to zero.) Secondly, a process that
+ mostly have short-lived data will be fullsweeped seldom
+ or never, meaning that the old heap will contain mostly
+ garbage. To ensure a fullsweep once in a while, set
+ <c>Number</c> to a suitable value such as 10 or 20.
+ Thirdly, in embedded systems with limited amount of RAM
+ and no virtual memory, one might want to preserve memory
+ by setting <c>Number</c> to zero. (The value may be set
+ globally, see
+ <seealso marker="#erlang:system_flag/2">erlang:system_flag/2</seealso>.)</p>
+ </item>
+ <tag><c>{min_heap_size, Size}</c></tag>
+ <item>
+ <p>This option is only useful for performance tuning.
+ In general, you should not use this option unless you
+ know that there is problem with execution times and/or
+ memory consumption, and you should measure to make sure
+ that the option improved matters.
+ </p>
+ <p>Gives a minimum heap size in words. Setting this value
+ higher than the system default might speed up some
+ processes because less garbage collection is done.
+ Setting too high value, however, might waste memory and
+ slow down the system due to worse data locality.
+ Therefore, it is recommended to use this option only for
+ fine-tuning an application and to measure the execution
+ time with various <c>Size</c> values.</p>
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>spawn_opt(Node, Module, Function, Args, [Option]) -> pid()</name>
+ <fsummary>Create a new process with a function as entry point on a given node</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v>
+ <v>&nbsp;Level = low | normal | high</v>
+ <v>&nbsp;Number = int()</v>
+ <v>&nbsp;Size = int()</v>
+ </type>
+ <desc>
+ <p>Returns the pid of a new process started by the application
+ of <c>Module:Function</c> to <c>Args</c> on <c>Node</c>. If
+ <c>Node</c> does not exist, a useless pid is returned.
+ Otherwise works like
+ <seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>split_binary(Bin, Pos) -> {Bin1, Bin2}</name>
+ <fsummary>Split a binary into two</fsummary>
+ <type>
+ <v>Bin = Bin1 = Bin2 = binary()</v>
+ <v>Pos = 1..byte_size(Bin)</v>
+ </type>
+ <desc>
+ <p>Returns a tuple containing the binaries which are the result
+ of splitting <c>Bin</c> into two parts at position <c>Pos</c>.
+ This is not a destructive operation. After the operation,
+ there will be three binaries altogether.</p>
+ <pre>
+> <input>B = list_to_binary("0123456789").</input>
+&lt;&lt;"0123456789">>
+> <input>byte_size(B).</input>
+10
+> <input>{B1, B2} = split_binary(B,3).</input>
+{&lt;&lt;"012">>,&lt;&lt;"3456789">>}
+> <input>byte_size(B1).</input>
+3
+> <input>byte_size(B2).</input>
+7</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:start_timer(Time, Dest, Msg) -> TimerRef</name>
+ <fsummary>Start a timer</fsummary>
+ <type>
+ <v>Time = int()</v>
+ <v>&nbsp;0 &lt;= Time &lt;= 4294967295</v>
+ <v>Dest = LocalPid | RegName </v>
+ <v>&nbsp;LocalPid = pid() (of a process, alive or dead, on the local node)</v>
+ <v>&nbsp;RegName = atom()</v>
+ <v>Msg = term()</v>
+ <v>TimerRef = ref()</v>
+ </type>
+ <desc>
+ <p>Starts a timer which will send the message
+ <c>{timeout, TimerRef, Msg}</c> to <c>Dest</c>
+ after <c>Time</c> milliseconds.</p>
+ <p>If <c>Dest</c> is an atom, it is supposed to be the name of
+ a registered process. The process referred to by the name is
+ looked up at the time of delivery. No error is given if
+ the name does not refer to a process.</p>
+ <p>If <c>Dest</c> is a pid, the timer will be automatically
+ canceled if the process referred to by the pid is not alive,
+ or when the process exits. This feature was introduced in
+ erts version 5.4.11. Note that timers will not be
+ automatically canceled when <c>Dest</c> is an atom.</p>
+ <p>See also
+ <seealso marker="#erlang:send_after/3">erlang:send_after/3</seealso>,
+ <seealso marker="#erlang:cancel_timer/1">erlang:cancel_timer/1</seealso>,
+ and
+ <seealso marker="#erlang:read_timer/1">erlang:read_timer/1</seealso>.</p>
+ <p>Failure: <c>badarg</c> if the arguments does not satisfy
+ the requirements specified above.</p>
+ </desc>
+ </func>
+ <func>
+ <name>statistics(Type) -> Res</name>
+ <fsummary>Information about the system</fsummary>
+ <type>
+ <v>Type, Res -- see below</v>
+ </type>
+ <desc>
+ <p>Returns information about the system as specified by
+ <c>Type</c>:</p>
+ <taglist>
+ <tag><c>context_switches</c></tag>
+ <item>
+ <p>Returns <c>{ContextSwitches, 0}</c>, where
+ <c>ContextSwitches</c> is the total number of context
+ switches since the system started.</p>
+ </item>
+ <tag><c>exact_reductions</c></tag>
+ <item>
+ <marker id="statistics_exact_reductions"></marker>
+ <p>Returns
+ <c>{Total_Exact_Reductions, Exact_Reductions_Since_Last_Call}</c>.</p>
+ <p><em>NOTE:</em><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>
+ </item>
+ <tag><c>garbage_collection</c></tag>
+ <item>
+ <p>Returns <c>{Number_of_GCs, Words_Reclaimed, 0}</c>. This
+ information may not be valid for all implementations.</p>
+ </item>
+ <tag><c>io</c></tag>
+ <item>
+ <p>Returns <c>{{input, Input}, {output, Output}}</c>,
+ where <c>Input</c> is the total number of bytes received
+ through ports, and <c>Output</c> is the total number of
+ bytes output to ports.</p>
+ </item>
+ <tag><c>reductions</c></tag>
+ <item>
+ <marker id="statistics_reductions"></marker>
+ <p>Returns
+ <c>{Total_Reductions, Reductions_Since_Last_Call}</c>.</p>
+ <p><em>NOTE:</em> From erts version 5.5 (OTP release R11B)
+ this value does not include reductions performed in current
+ time slices of currently scheduled processes. If an
+ exact value is wanted, use
+ <seealso marker="#statistics_exact_reductions">statistics(exact_reductions)</seealso>.</p>
+ </item>
+ <tag><c>run_queue</c></tag>
+ <item>
+ <p>Returns the length of the run queue, that is, the number
+ of processes that are ready to run.</p>
+ </item>
+ <tag><c>runtime</c></tag>
+ <item>
+ <p>Returns <c>{Total_Run_Time, Time_Since_Last_Call}</c>.
+ Note that the run-time is the sum of the run-time for all
+ threads in the Erlang run-time system and may therefore be greater
+ than the wall-clock time.</p>
+ </item>
+ <tag><c>wall_clock</c></tag>
+ <item>
+ <p>Returns
+ <c>{Total_Wallclock_Time, Wallclock_Time_Since_Last_Call}</c>.
+ <c>wall_clock</c> can be used in the same manner as
+ <c>runtime</c>, except that real time is measured as
+ opposed to runtime or CPU time.</p>
+ </item>
+ </taglist>
+ <p>All times are in milliseconds.</p>
+ <pre>
+> <input>statistics(runtime).</input>
+{1690,1620}
+> <input>statistics(reductions).</input>
+{2046,11}
+> <input>statistics(garbage_collection).</input>
+{85,23961,0}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:suspend_process(Suspendee, OptList) -> true | false</name>
+ <fsummary>Suspend a process</fsummary>
+ <type>
+ <v>Suspendee = pid()</v>
+ <v>OptList = [Opt]</v>
+ <v>Opt = atom()</v>
+ </type>
+ <desc>
+ <p>Increases the suspend count on the process identified by
+ <c>Suspendee</c> and puts it in the suspended state if it isn't
+ already in the suspended state. A suspended process will not be
+ scheduled for execution until the process has been resumed.
+ </p>
+
+ <p>A process can be suspended by multiple processes and can
+ be suspended multiple times by a single process. A suspended
+ process will not leave the suspended state until its suspend
+ count reach zero. The suspend count of <c>Suspendee</c> is
+ decreased when
+ <seealso marker="#erlang:resume_process/1">erlang:resume_process(Suspendee)</seealso>
+ is called by the same process that called
+ <c>erlang:suspend_process(Suspendee)</c>. All increased suspend
+ counts on other processes acquired by a process will automatically be
+ decreased when the process terminates.</p>
+
+ <p>Currently the following options (<c>Opt</c>s) are available:</p>
+ <taglist>
+ <tag><c>asynchronous</c></tag>
+ <item>
+ A suspend request is sent to the process identified by
+ <c>Suspendee</c>. <c>Suspendee</c> will eventually suspend
+ unless it is resumed before it was able to suspend. The caller
+ of <c>erlang:suspend_process/2</c> will return immediately,
+ regardless of whether the <c>Suspendee</c> has suspended yet
+ or not. Note that the point in time when the <c>Suspendee</c>
+ will actually suspend cannot be deduced from other events
+ in the system. The only guarantee given is that the
+ <c>Suspendee</c> will <em>eventually</em> suspend (unless it
+ is resumed). If the <c>asynchronous</c> option has <em>not</em>
+ been passed, the caller of <c>erlang:suspend_process/2</c> will
+ be blocked until the <c>Suspendee</c> has actually suspended.
+ </item>
+ <tag><c>unless_suspending</c></tag>
+ <item>
+ The process identified by <c>Suspendee</c> will be suspended
+ unless the calling process already is suspending the
+ <c>Suspendee</c>. If <c>unless_suspending</c> is combined
+ with the <c>asynchronous</c> option, a suspend request will be
+ sent unless the calling process already is suspending the
+ <c>Suspendee</c> or if a suspend request already has been sent
+ and is in transit. If the calling process already is suspending
+ the <c>Suspendee</c>, or if combined with the <c>asynchronous</c>
+ option and a send request already is in transit,
+ <c>false</c> is returned and the suspend count on <c>Suspendee</c>
+ will remain unchanged.
+ </item>
+ </taglist>
+
+ <p>If the suspend count on the process identified by
+ <c>Suspendee</c> was increased, <c>true</c> is returned; otherwise,
+ <c>false</c> is returned.</p>
+
+ <warning>
+ <p>This BIF is intended for debugging only.</p>
+ </warning>
+ <p>Failures:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>Suspendee</c> isn't a process identifier.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the process identified by <c>Suspendee</c> is same the process as
+ the process calling <c>erlang:suspend_process/2</c>.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the process identified by <c>Suspendee</c> is not alive.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If the process identified by <c>Suspendee</c> resides on another node.
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ If <c>OptList</c> isn't a proper list of valid <c>Opt</c>s.
+ </item>
+ <tag><c>system_limit</c></tag>
+ <item>
+ If the process identified by <c>Suspendee</c> has been suspended more
+ times by the calling process than can be represented by the
+ currently used internal data structures. The current system limit
+ is larger than 2 000 000 000 suspends, and it will never be less
+ than that.
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:suspend_process(Suspendee) -> true</name>
+ <fsummary>Suspend a process</fsummary>
+ <type>
+ <v>Suspendee = pid()</v>
+ </type>
+ <desc>
+ <p>Suspends the process identified by <c>Suspendee</c>. The
+ same as calling
+ <seealso marker="#erlang:suspend_process/2">erlang:suspend_process(Suspendee, [])</seealso>. For more information see the documentation of <seealso marker="#erlang:suspend_process/2">erlang:suspend_process/2</seealso>.
+ </p>
+ <warning>
+ <p>This BIF is intended for debugging only.</p>
+ </warning>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:system_flag(Flag, Value) -> OldValue</name>
+ <fsummary>Set system flags</fsummary>
+ <type>
+ <v>Flag, Value, OldValue -- see below</v>
+ </type>
+ <desc>
+ <p>Sets various system properties of the Erlang node. Returns
+ the old value of the flag.</p>
+ <taglist>
+ <tag><c>erlang:system_flag(backtrace_depth, Depth)</c></tag>
+ <item>
+ <p>Sets the maximum depth of call stack back-traces in the
+ exit reason element of <c>'EXIT'</c> tuples.</p>
+ </item>
+ <tag><c>erlang:system_flag(cpu_topology, CpuTopology)</c></tag>
+ <item>
+ <marker id="system_flag_cpu_topology"></marker>
+ <p>Sets the user defined <c>CpuTopology</c>. The user defined
+ CPU topology will override any automatically detected
+ CPU topology. By passing <c>undefined</c> as <c>CpuTopology</c>
+ the system will revert back to the CPU topology automatically
+ detected. The returned value equals the value returned
+ from <c>erlang:system_info(cpu_topology)</c> before the
+ change was made.
+ </p>
+ <p>The CPU topology is used when binding schedulers to logical
+ processors. If schedulers are already bound when the CPU
+ topology is changed, the schedulers will be sent a request
+ to rebind according to the new CPU topology.
+ </p>
+ <p>The user defined CPU topology can also be set by passing
+ the <seealso marker="erl#+sct">+sct</seealso> command
+ line argument to <c>erl</c>.
+ </p>
+ <p>For information on the <c>CpuTopology</c> type
+ and more, see the documentation of
+ <seealso marker="#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>,
+ the <c>erl</c> <seealso marker="erl#+sct">+sct</seealso>
+ emulator flag, and
+ <seealso marker="#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, How)</seealso>.
+ </p>
+ </item>
+ <tag><c>erlang:system_flag(fullsweep_after, Number)</c></tag>
+ <item>
+ <p><c>Number</c> is a non-negative integer which indicates
+ how many times generational garbage collections can be
+ done without forcing a fullsweep collection. The value
+ applies to new processes; processes already running are
+ not affected.</p>
+ <p>In low-memory systems (especially without virtual
+ memory), setting the value to 0 can help to conserve
+ memory.</p>
+ <p>An alternative way to set this value is through the
+ (operating system) environment variable
+ <c>ERL_FULLSWEEP_AFTER</c>.</p>
+ </item>
+ <tag><c>erlang:system_flag(min_heap_size, MinHeapSize)</c></tag>
+ <item>
+ <p>Sets the default minimum heap size for processes. The
+ size is given in words. The new <c>min_heap_size</c> only
+ effects processes spawned after the change of
+ <c>min_heap_size</c> has been made.
+ The <c>min_heap_size</c> can be set for individual
+ processes by use of
+ <seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or
+ <seealso marker="#process_flag/2">process_flag/2</seealso>. </p>
+ </item>
+ <tag><c>erlang:system_flag(multi_scheduling, BlockState)</c></tag>
+ <item>
+ <marker id="system_flag_multi_scheduling"></marker>
+ <p><c>BlockState = block | unblock</c></p>
+ <p>If multi-scheduling is enabled, more than one scheduler
+ thread is used by the emulator. Multi-scheduling can be
+ blocked. When multi-scheduling has been blocked, only
+ one scheduler thread will schedule Erlang processes.</p>
+ <p>If <c>BlockState =:= block</c>, multi-scheduling will
+ be blocked. If <c>BlockState =:= unblock</c> and no-one
+ else is blocking multi-scheduling and this process has
+ only blocked one time, multi-scheduling will be unblocked.
+ One process can block multi-scheduling multiple times.
+ If a process has blocked multiple times, it has to
+ unblock exactly as many times as it has blocked before it
+ has released its multi-scheduling block. If a process that
+ has blocked multi-scheduling exits, it will release its
+ blocking of multi-scheduling.</p>
+ <p>The return values are <c>disabled</c>, <c>blocked</c>,
+ or <c>enabled</c>. The returned value describes the
+ state just after the call to
+ <c>erlang:system_flag(multi_scheduling, BlockState)</c>
+ has been made. The return values are described in the
+ documentation of <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>.</p>
+ <p><em>NOTE</em>: Blocking of multi-scheduling should normally
+ not be needed. If you feel that you need to
+ block multi-scheduling, think through the
+ problem at least a couple of times again.
+ Blocking multi-scheduling should only be used
+ as a last resort since it will most likely be
+ a <em>very inefficient</em> way to solve the
+ problem.</p>
+ <p>See also <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>,
+ <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
+ </item>
+ <tag><c>erlang:system_flag(scheduler_bind_type, How)</c></tag>
+ <item>
+ <marker id="system_flag_scheduler_bind_type"></marker>
+ <p>Controls if and how schedulers are bound to logical
+ processors.</p>
+ <p>When <c>erlang:system_flag(scheduler_bind_type, How)</c> is
+ called, an asynchronous signal is sent to all schedulers
+ online which causes them to try to bind or unbind as requested.
+ <em>NOTE:</em> If a scheduler fails to bind, this
+ will often be silently ignored. This since it isn't always
+ possible to verify valid logical processor identifiers. If
+ an error is reported, it will be reported to the
+ <c>error_logger</c>. If you want to verify that the
+ schedulers actually have bound as requested, call
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
+ </p>
+ <p>Schedulers can currently only be bound on newer Linux
+ and Solaris systems, but more systems will be supported
+ in the future.
+ </p>
+ <p>In order for the runtime system to be able to bind schedulers,
+ the CPU topology needs to be known. If the runtime system fails
+ to automatically detect the CPU topology, it can be defined.
+ For more information on how to define the CPU topology, see
+ <seealso marker="#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>.
+ </p>
+ <p><em>NOTE:</em> If other programs on the system have bound
+ to processors, e.g. another Erlang runtime system, you
+ may loose performance when binding schedulers. Therefore,
+ schedulers are by default not bound.</p>
+ <p>Schedulers can be bound in different ways. The <c>How</c>
+ argument determines how schedulers are bound. <c>How</c> can
+ currently be one of:</p>
+ <taglist>
+ <tag><c>unbound</c></tag>
+ <item>
+ <p>Schedulers will not be bound to logical processors, i.e.,
+ the operating system decides where the scheduler threads
+ execute, and when to migrate them. This is the default.</p>
+ </item>
+ <tag><c>no_spread</c></tag>
+ <item>
+ <p>Schedulers with close scheduler identifiers will be bound
+ as close as possible in hardware.</p>
+ </item>
+ <tag><c>thread_spread</c></tag>
+ <item>
+ <p>Thread refers to hardware threads (e.g. Intels
+ hyper-threads). Schedulers with low scheduler identifiers,
+ will be bound to the first hardware thread of each core,
+ then schedulers with higher scheduler identifiers will be
+ bound to the second hardware thread of each core, etc.</p>
+ </item>
+ <tag><c>processor_spread</c></tag>
+ <item>
+ <p>Schedulers will be spread like <c>thread_spread</c>, but
+ also over physical processor chips.</p>
+ </item>
+ <tag><c>spread</c></tag>
+ <item>
+ <p>Schedulers will be spread as much as possible.</p>
+ </item>
+ <tag><c>no_node_thread_spread</c></tag>
+ <item>
+ <p>Like <c>thread_spread</c>, but if multiple NUMA
+ (Non-Uniform Memory Access) nodes exists,
+ schedulers will be spread over one NUMA node at a time,
+ i.e., all logical processors of one NUMA node will
+ be bound to schedulers in sequence.</p>
+ </item>
+ <tag><c>no_node_processor_spread</c></tag>
+ <item>
+ <p>Like <c>processor_spread</c>, but if multiple NUMA
+ nodes exists, schedulers will be spread over one
+ NUMA node at a time, i.e., all logical processors of
+ one NUMA node will be bound to schedulers in sequence.</p>
+ </item>
+ <tag><c>thread_no_node_processor_spread</c></tag>
+ <item>
+ <p>A combination of <c>thread_spread</c>, and
+ <c>no_node_processor_spread</c>. Schedulers will be
+ spread over hardware threads across NUMA nodes, but
+ schedulers will only be spread over processors internally
+ in one NUMA node at a time.</p>
+ </item>
+ <tag><c>default_bind</c></tag>
+ <item>
+ <p>Binds schedulers the default way. Currently the default
+ is <c>thread_no_node_processor_spread</c> (which might change
+ in the future).</p>
+ </item>
+ </taglist>
+ <p>How schedulers are bound matters. For example, in
+ situations when there are fewer running processes than
+ schedulers online, the runtime system tries to migrate
+ processes to schedulers with low scheduler identifiers.
+ The more the schedulers are spread over the hardware,
+ the more resources will be available to the runtime
+ system in such situations.
+ </p>
+ <p>The value returned equals <c>How</c> before the
+ <c>scheduler_bind_type</c> flag was changed.</p>
+ <p>Failure:</p>
+ <taglist>
+ <tag><c>notsup</c></tag>
+ <item>
+ <p>If binding of schedulers is not supported.</p>
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ <p>If <c>How</c> isn't one of the documented alternatives.</p>
+ </item>
+ <tag><c>badarg</c></tag>
+ <item>
+ <p>If no CPU topology information is available.</p>
+ </item>
+ </taglist>
+ <p>The scheduler bind type can also be set by passing
+ the <seealso marker="erl#+sbt">+sbt</seealso> command
+ line argument to <c>erl</c>.
+ </p>
+ <p>For more information, see
+ <seealso marker="#system_info_scheduler_bind_type">erlang:system_info(scheduler_bind_type)</seealso>,
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>,
+ the <c>erl</c> <seealso marker="erl#+sbt">+sbt</seealso>
+ emulator flag, and
+ <seealso marker="#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>.
+ </p>
+ </item>
+ <tag><c>erlang:system_flag(schedulers_online, SchedulersOnline)</c></tag>
+ <item>
+ <marker id="system_flag_schedulers_online"></marker>
+ <p>Sets the amount of schedulers online. Valid range is
+ <![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]>.
+ </p>
+ <p>For more information see,
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
+ and
+ <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.
+ </p>
+ </item>
+ <tag><c>erlang:system_flag(trace_control_word, TCW)</c></tag>
+ <item>
+ <p>Sets the value of the node's trace control word to
+ <c>TCW</c>. <c>TCW</c> should be an unsigned integer. For
+ more information see documentation of the
+ <seealso marker="erts:match_spec#set_tcw">set_tcw</seealso>
+ function in the match specification documentation in the
+ ERTS User's Guide.</p>
+ </item>
+ </taglist>
+ <note>
+ <p>The <c>schedulers</c> option has been removed as
+ of erts version 5.5.3. The number of scheduler
+ threads is determined at emulator boot time, and
+ cannot be changed after that.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:system_info(Type) -> Res</name>
+ <fsummary>Information about the system</fsummary>
+ <type>
+ <v>Type, Res -- see below</v>
+ </type>
+ <desc>
+ <p>Returns various information about the current system
+ (emulator) as specified by <c>Type</c>:</p>
+ <taglist>
+ <tag><c>allocated_areas</c></tag>
+ <item>
+ <marker id="system_info_allocated_areas"></marker>
+ <p>Returns a list of tuples with information about
+ miscellaneous allocated memory areas.</p>
+ <p>Each tuple contains an atom describing type of memory as
+ first element and amount of allocated memory in bytes as
+ second element. In those cases when there is information
+ present about allocated and used memory, a third element
+ is present. This third element contains the amount of
+ used memory in bytes.</p>
+ <p><c>erlang:system_info(allocated_areas)</c> is intended
+ for debugging, and the content is highly implementation
+ dependent. The content of the results will therefore
+ change when needed without prior notice.</p>
+ <p><em>Note:</em> The sum of these values is <em>not</em>
+ the total amount of memory allocated by the emulator.
+ Some values are part of other values, and some memory
+ areas are not part of the result. If you are interested
+ in the total amount of memory allocated by the emulator
+ see <seealso marker="#erlang:memory/0">erlang:memory/0,1</seealso>.</p>
+ </item>
+ <tag><c>allocator</c></tag>
+ <item>
+ <marker id="system_info_allocator"></marker>
+ <p>Returns <c>{Allocator, Version, Features, Settings}.</c></p>
+ <p>Types:</p>
+ <list type="bulleted">
+ <item><c>Allocator = undefined | elib_malloc | glibc</c></item>
+ <item><c>Version = [int()]</c></item>
+ <item><c>Features = [atom()]</c></item>
+ <item><c>Settings = [{Subsystem, [{Parameter, Value}]}]</c></item>
+ <item><c>Subsystem = atom()</c></item>
+ <item><c>Parameter = atom()</c></item>
+ <item><c>Value = term()</c></item>
+ </list>
+ <p>Explanation:</p>
+ <list type="bulleted">
+ <item>
+ <p><c>Allocator</c> corresponds to the <c>malloc()</c>
+ implementation used. If <c>Allocator</c> equals
+ <c>undefined</c>, the <c>malloc()</c> implementation
+ used could not be identified. Currently
+ <c>elib_malloc</c> and <c>glibc</c> can be identified.</p>
+ </item>
+ <item>
+ <p><c>Version</c> is a list of integers (but not a
+ string) representing the version of
+ the <c>malloc()</c> implementation used.</p>
+ </item>
+ <item>
+ <p><c>Features</c> is a list of atoms representing
+ allocation features used.</p>
+ </item>
+ <item>
+ <p><c>Settings</c> is a list of subsystems, their
+ configurable parameters, and used values. Settings
+ may differ between different combinations of
+ platforms, allocators, and allocation features.
+ Memory sizes are given in bytes.</p>
+ </item>
+ </list>
+ <p>See also "System Flags Effecting erts_alloc" in
+ <seealso marker="erts:erts_alloc#flags">erts_alloc(3)</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 the
+ <seealso marker="erts:erts_alloc#alloc_util">"the
+ alloc_util framework" section in the
+ erts_alloc(3)</seealso> documentation.
+ </p>
+ </item>
+ <tag><c>{allocator, Alloc}</c></tag>
+ <item>
+ <marker id="system_info_allocator_tuple"></marker>
+ <p>Returns information about the specified allocator.
+ As of erts version 5.6.1 the return value is a list
+ of <c>{instance, InstanceNo, InstanceInfo}</c> tuples
+ where <c>InstanceInfo</c> contains information about
+ a specific instance of the allocator.
+ If <c>Alloc</c> is not a recognized allocator,
+ <c>undefined</c> is returned. If <c>Alloc</c> is disabled,
+ <c>false</c> is returned.</p>
+ <p><em>Note:</em> The information returned is highly
+ implementation dependent and may be changed, or removed
+ at any time without prior notice. It was initially
+ intended as a tool when developing new allocators, but
+ since it might be of interest for others it has been
+ briefly documented.</p>
+ <p>The recognized allocators are listed in
+ <seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>.
+ After reading the <c>erts_alloc(3)</c> documentation,
+ the returned information
+ should more or less speak for itself. But it can be worth
+ explaining some things. Call counts are presented by two
+ values. The first value is giga calls, and the second
+ value is calls. <c>mbcs</c>, and <c>sbcs</c> are
+ abbreviations for, respectively, multi-block carriers, and
+ single-block carriers. Sizes are presented in bytes. When
+ it is not a size that is presented, it is the amount of
+ something. Sizes and amounts are often presented by three
+ values, the first is current value, the second is maximum
+ value since the last call to
+ <c>erlang:system_info({allocator, Alloc})</c>, and
+ the third is maximum value since the emulator was started.
+ If only one value is present, it is the current value.
+ <c>fix_alloc</c> memory block types are presented by two
+ values. The first value is memory pool size and
+ the second value used memory size.</p>
+ </item>
+ <tag><c>{allocator_sizes, Alloc}</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
+ <seealso marker="#system_info_allocator_tuple">erlang:system_info({allocator, Alloc})</seealso>.
+ </p>
+ </item>
+ <tag><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><c>check_io</c></tag>
+ <item>
+ <p>Returns a list containing miscellaneous information
+ regarding the emulators internal I/O checking. Note,
+ the content of the returned list may vary between
+ platforms and over time. The only thing guaranteed is
+ that a list is returned.</p>
+ </item>
+ <tag><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 which the current emulator has been
+ set to be backward compatible with. The compatibility
+ mode can be configured at startup by using the command
+ line flag <c>+R</c>, see
+ <seealso marker="erts:erl#compat_rel">erl(1)</seealso>.</p>
+ </item>
+ <tag><c>cpu_topology</c></tag>
+ <item>
+ <marker id="system_info_cpu_topology"></marker>
+ <p>Returns the <c>CpuTopology</c> which currently is used by the
+ emulator. The CPU topology is used when binding schedulers
+ to logical processors. The CPU topology used is the user defined
+ CPU topology if such exist; otherwise, the automatically
+ detected CPU topology if such exist. If no CPU topology
+ exist <c>undefined</c> is returned.</p>
+ <p>Types:</p>
+ <list type="bulleted">
+ <item><c>CpuTopology = LevelEntryList | undefined</c></item>
+ <item><c>LevelEntryList = [LevelEntry]</c> (all
+ <c>LevelEntry</c>s of a <c>LevelEntryList</c>
+ must contain the same <c>LevelTag</c>, except
+ on the top level where both <c>node</c> and
+ <c>processor</c> <c>LevelTag</c>s may co-exist)</item>
+ <item><c>LevelEntry = {LevelTag, SubLevel}
+ | {LevelTag, InfoList, SubLevel}</c>
+ (<c>{LevelTag, SubLevel}
+ == {LevelTag, [], SubLevel}</c>)</item>
+ <item><c>LevelTag = node|processor|core|thread</c>
+ (more <c>LevelTag</c>s may be introduced in
+ the future)</item>
+ <item><c>SubLevel = [LevelEntry] | LogicalCpuId</c></item>
+ <item><c>LogicalCpuId = {logical, integer()}</c></item>
+ <item><c>InfoList = []</c> (the <c>InfoList</c>
+ may be extended in the future)</item>
+ </list>
+ <p><c>node</c> refers to NUMA (non-uniform memory access)
+ nodes, and <c>thread</c> refers to hardware threads
+ (e.g. Intels hyper-threads).</p>
+ <p>A level in the <c>CpuTopology</c> term can be omitted if
+ only one entry exists and the <c>InfoList</c> is empty.
+ </p>
+ <p><c>thread</c> can only be a sub level to <c>core</c>.
+ <c>core</c> can be a sub level to either <c>processor</c>
+ or <c>node</c>. <c>processor</c> can either be on the
+ top level or a sub level to <c>node</c>. <c>node</c>
+ can either be on the top level or a sub level to
+ <c>processor</c>. That is, NUMA nodes can be processor
+ internal or processor external. A CPU topology can
+ consist of a mix of processor internal and external
+ NUMA nodes, as long as each logical CPU belongs to one
+ and only one NUMA node. Cache hierarchy is not part of
+ the <c>CpuTopology</c> type yet, but will be in the
+ future. Other things may also make it into the CPU
+ topology in the future. In other words, expect the
+ <c>CpuTopology</c> type to change.
+ </p>
+ </item>
+ <tag><c>{cpu_topology, defined}</c></tag>
+ <item>
+ <p>Returns the user defined <c>CpuTopology</c>. For more
+ information see the documentation of
+ <seealso marker="#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>
+ and the documentation of the
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
+ argument.
+ </p>
+ </item>
+ <tag><c>{cpu_topology, detected}</c></tag>
+ <item>
+ <p>Returns the automatically detected <c>CpuTopology</c>. The
+ emulator currently only detects the CPU topology on some newer
+ linux and solaris systems. For more information see the
+ documentation of the
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
+ argument.
+ </p>
+ </item>
+ <tag><c>{cpu_topology, used}</c></tag>
+ <item>
+ <p>Returns the <c>CpuTopology</c> which is used by the
+ emulator. For more information see the
+ documentation of the
+ <seealso marker="#system_info_cpu_topology">cpu_topology</seealso>
+ argument.
+ </p>
+ </item>
+ <tag><c>creation</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. Currently valid
+ creations are integers in the range 1..3, but this may
+ (probably will) change in the future. If the node is not
+ alive, 0 is returned.</p>
+ </item>
+ <tag><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><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 the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso>
+ chapter in the ERTS User's Guide.</p>
+ </item>
+ <tag><c>dist_ctrl</c></tag>
+ <item>
+ <p>Returns a list of tuples
+ <c>{Node, ControllingEntity}</c>, one entry for each
+ connected remote node. The <c>Node</c> is the name of the
+ node and the <c>ControllingEntity</c> is the port or pid
+ responsible for the communication to that node. More
+ specifically, the <c>ControllingEntity</c> for nodes
+ connected via TCP/IP (the normal case) is the socket
+ actually 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 will be on the form
+ <seealso marker="erts:erl_driver#version_management">"&lt;major ver&gt;.&lt;minor ver&gt;"</seealso>.</p>
+ </item>
+ <tag><c>elib_malloc</c></tag>
+ <item>
+ <p>If the emulator uses the <c>elib_malloc</c> memory
+ allocator, a list of two-element tuples containing status
+ information is returned; otherwise, <c>false</c> is
+ returned. The list currently contains the following
+ two-element tuples (all sizes are presented in bytes):</p>
+ <taglist>
+ <tag><c>{heap_size, Size}</c></tag>
+ <item>
+ <p>Where <c>Size</c> is the current heap size.</p>
+ </item>
+ <tag><c>{max_alloced_size, Size}</c></tag>
+ <item>
+ <p>Where <c>Size</c> is the maximum amount of memory
+ allocated on the heap since the emulator started.</p>
+ </item>
+ <tag><c>{alloced_size, Size}</c></tag>
+ <item>
+ <p>Where <c>Size</c> is the current amount of memory
+ allocated on the heap.</p>
+ </item>
+ <tag><c>{free_size, Size}</c></tag>
+ <item>
+ <p>Where <c>Size</c> is the current amount of free
+ memory on the heap.</p>
+ </item>
+ <tag><c>{no_alloced_blocks, No}</c></tag>
+ <item>
+ <p>Where <c>No</c> is the current number of allocated
+ blocks on the heap.</p>
+ </item>
+ <tag><c>{no_free_blocks, No}</c></tag>
+ <item>
+ <p>Where <c>No</c> is the current number of free blocks
+ on the heap.</p>
+ </item>
+ <tag><c>{smallest_alloced_block, Size}</c></tag>
+ <item>
+ <p>Where <c>Size</c> is the size of the smallest
+ allocated block on the heap.</p>
+ </item>
+ <tag><c>{largest_free_block, Size}</c></tag>
+ <item>
+ <p>Where <c>Size</c> is the size of the largest free
+ block on the heap.</p>
+ </item>
+ </taglist>
+ </item>
+ <tag><c>fullsweep_after</c></tag>
+ <item>
+ <p>Returns <c>{fullsweep_after, int()}</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>
+ <item>
+ <p>Returns a list describing the default garbage collection
+ settings. A process spawned on the local node by a
+ <c>spawn</c> or <c>spawn_link</c> will use these
+ garbage collection settings. The default settings can be
+ changed by use of
+ <seealso marker="#erlang:system_flag/2">system_flag/2</seealso>.
+ <seealso marker="#spawn_opt/4">spawn_opt/4</seealso>
+ can spawn a process that does not use the default
+ settings.</p>
+ </item>
+ <tag><c>global_heaps_size</c></tag>
+ <item>
+ <p>Returns the current size of the shared (global) heap.</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.
+ Currently the following heap types exist:</p>
+ <taglist>
+ <tag><c>private</c></tag>
+ <item>
+ <p>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.</p>
+ </item>
+ <tag><c>shared</c></tag>
+ <item>
+ <p>One heap for use by all processes. Messages passed
+ between processes are passed by reference.</p>
+ </item>
+ <tag><c>hybrid</c></tag>
+ <item>
+ <p>A hybrid of the <c>private</c> and <c>shared</c> heap
+ types. A shared heap as well as private heaps are
+ used.</p>
+ </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 the
+ <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter in the ERTS
+ 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 the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter
+ in the ERTS User's Guide.</p>
+ </item>
+ <tag><c>logical_processors</c></tag>
+ <item>
+ <p>Returns the number of logical processors detected on the
+ system as an integer or the atom <c>unknown</c> if the
+ emulator wasn't able to detect any.
+ </p>
+ </item>
+ <tag><c>machine</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 has been enabled; otherwise,
+ <c>undefined</c>. See the <c>+T</c> command line flag
+ in the documentation of the
+ <seealso marker="erts:erl#+T">erl(1)</seealso>
+ command for more information on modified timing.</p>
+ </item>
+ <tag><c>multi_scheduling</c></tag>
+ <item>
+ <marker id="system_info_multi_scheduling"></marker>
+ <p>Returns <c>disabled</c>, <c>blocked</c>, or <c>enabled</c>.
+ A description of the return values:</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>
+ </item>
+ <tag><c>blocked</c></tag>
+ <item>
+ <p>The emulator has more than one scheduler thread,
+ but all scheduler threads but one have been blocked,
+ i.e., only one scheduler thread will schedule
+ Erlang processes and execute Erlang code.</p>
+ </item>
+ <tag><c>enabled</c></tag>
+ <item>
+ <p>The emulator has more than one scheduler thread,
+ and no scheduler threads have been blocked, i.e.,
+ all available scheduler threads will schedule
+ Erlang processes and execute Erlang code.</p>
+ </item>
+ </taglist>
+ <p>See also <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>, and
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
+ </item>
+ <tag><c>multi_scheduling_blockers</c></tag>
+ <item>
+ <marker id="system_info_multi_scheduling_blockers"></marker>
+ <p>Returns a list of <c>PID</c>s when multi-scheduling
+ is blocked; otherwise, the empty list. The <c>PID</c>s
+ in the list is <c>PID</c>s of the processes currently
+ blocking multi-scheduling. A <c>PID</c> will only be
+ present once in the list, even if the corresponding
+ process has blocked multiple times.</p>
+ <p>See also <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
+ </item>
+ <tag><c>otp_release</c></tag>
+ <item>
+ <marker id="system_info_otp_release"></marker>
+ <p>Returns a string containing the OTP release number.</p>
+ </item>
+ <tag><c>process_count</c></tag>
+ <item>
+ <p>Returns the number of processes currently existing at
+ the local node as an integer. The same value as
+ <c>length(processes())</c> returns.</p>
+ </item>
+ <tag><c>process_limit</c></tag>
+ <item>
+ <p>Returns the maximum number of concurrently existing
+ processes at the local node as an integer. This limit
+ can be configured at startup by using the command line
+ flag <c>+P</c>, see
+ <seealso marker="erts:erl#max_processes">erl(1)</seealso>.</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 the <seealso marker="erts:crash_dump">"How to interpret the Erlang crash dumps"</seealso> chapter
+ in the ERTS User's Guide.</p>
+ </item>
+ <tag><c>scheduler_bind_type</c></tag>
+ <item>
+ <marker id="system_info_scheduler_bind_type"></marker>
+ <p>Returns information on how user has requested
+ schedulers to be bound or not bound.</p>
+ <p><em>NOTE:</em> Even though user has requested
+ schedulers to be bound via
+ <seealso marker="#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, How)</seealso>,
+ they might have silently failed to bind. In order to
+ inspect actual scheduler bindings call
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
+ </p>
+ <p>For more information, see
+ <seealso marker="#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, How)</seealso>, and
+ <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>.
+ </p>
+ </item>
+ <tag><c>scheduler_bindings</c></tag>
+ <item>
+ <marker id="system_info_scheduler_bindings"></marker>
+ <p>Returns information on currently used scheduler
+ bindings.</p>
+ <p>A tuple of a size equal to
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso> is returned. The elements of the tuple are integers
+ or the atom <c>unbound</c>. Logical processor identifiers
+ are represented as integers. The <c>N</c>th
+ element of the tuple equals the current binding for
+ the scheduler with the scheduler identifier equal to
+ <c>N</c>. E.g., if the schedulers have been bound,
+ <c>element(erlang:system_info(scheduler_id),
+ erlang:system_info(scheduler_bindings))</c> will return
+ the identifier of the logical processor that the calling
+ process is executing on.
+ </p>
+ <p>Note that only schedulers online can be bound to logical
+ processors.</p>
+ <p>For more information, see
+ <seealso marker="#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, How)</seealso>,
+ <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>.
+ </p>
+ </item>
+ <tag><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>SchedulerId</c> is a positive integer; where
+ <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers)]]></c>. See also
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p>
+ </item>
+ <tag><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
+ and Erlang linked in driver code.</p>
+ <p>The number of scheduler threads is determined at
+ emulator boot time and cannot be changed after
+ that. The amount of schedulers online can
+ however be changed at any time.</p>
+ <p>See also <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</seealso>,
+ <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>,
+ <seealso marker="#system_info_scheduler_id">erlang:system_info(scheduler_id)</seealso>,
+ <seealso marker="#system_flag_multi_scheduling">erlang:system_flag(multi_scheduling, BlockState)</seealso>,
+ <seealso marker="#system_info_multi_scheduling">erlang:system_info(multi_scheduling)</seealso>, and
+ and <seealso marker="#system_info_multi_scheduling_blockers">erlang:system_info(multi_scheduling_blockers)</seealso>.</p>
+ </item>
+ <tag><c>schedulers_online</c></tag>
+ <item>
+ <marker id="system_info_schedulers_online"></marker>
+ <p>Returns the amount of schedulers online. The scheduler
+ identifiers of schedulers online satisfy the following
+ relationship:
+ <c><![CDATA[1 <= SchedulerId <= erlang:system_info(schedulers_online)]]></c>.
+ </p>
+ <p>For more information, see
+ <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>,
+ and
+ <seealso marker="#system_flag_schedulers_online">erlang:system_flag(schedulers_online, SchedulersOnline)</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>.</p>
+ </item>
+ <tag><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><c>system_architecture</c></tag>
+ <item>
+ <p>Returns a string containing the processor and OS
+ architecture the emulator is built for.</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>
+ <item>
+ <marker id="system_info_thread_pool_size"></marker>
+ <p>Returns the number of async threads in the async thread
+ pool used for asynchronous driver calls
+ (<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>)
+ as an integer.</p>
+ </item>
+ <tag><c>trace_control_word</c></tag>
+ <item>
+ <p>Returns the value of the node's trace control word.
+ For more information see documentation of the function
+ <c>get_tcw</c> in "Match Specifications in Erlang",
+ <seealso marker="erts:match_spec#get_tcw">ERTS User's Guide</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>
+ <item>
+ <p>Returns the word size in bytes as an integer, i.e. on a
+ 32-bit architecture 4 is returned, and on a 64-bit
+ architecture 8 is returned.</p>
+ </item>
+ </taglist>
+ <note>
+ <p>The <c>scheduler</c> argument has changed name to
+ <c>scheduler_id</c>. This in order to avoid mixup with
+ the <c>schedulers</c> argument. The <c>scheduler</c>
+ argument was introduced in ERTS version 5.5 and renamed
+ in ERTS version 5.5.1.</p>
+ </note>
+ </desc>
+ </func>
+
+ <func>
+ <name>erlang:system_monitor() -> MonSettings</name>
+ <fsummary>Current system performance monitoring settings</fsummary>
+ <type>
+ <v>MonSettings -> {MonitorPid, Options} | undefined</v>
+ <v>&nbsp;MonitorPid = pid()</v>
+ <v>&nbsp;Options = [Option]</v>
+ <v>&nbsp;&nbsp;Option = {long_gc, Time} | {large_heap, Size} | busy_port | busy_dist_port</v>
+ <v>&nbsp;&nbsp;&nbsp;Time = Size = int()</v>
+ </type>
+ <desc>
+ <p>Returns the current system monitoring settings set by
+ <seealso marker="#erlang:system_monitor/2">erlang:system_monitor/2</seealso>
+ as <c>{MonitorPid, Options}</c>, or <c>undefined</c> if there
+ are no settings. The order of the options may be different
+ from the one that was set.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>erlang:system_monitor(undefined | {MonitorPid, Options}) -> MonSettings</name>
+ <fsummary>Set or clear system performance monitoring options</fsummary>
+ <type>
+ <v>MonitorPid, Options, MonSettings -- see below</v>
+ </type>
+ <desc>
+ <p>When called with the argument <c>undefined</c>, all
+ system performance monitoring settings are cleared.</p>
+ <p>Calling the function with <c>{MonitorPid, Options}</c> as
+ argument, is the same as calling
+ <seealso marker="#erlang:system_monitor/2">erlang:system_monitor(MonitorPid, Options)</seealso>.</p>
+ <p>Returns the previous system monitor settings just like
+ <seealso marker="#erlang:system_monitor/0">erlang:system_monitor/0</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>erlang:system_monitor(MonitorPid, [Option]) -> MonSettings</name>
+ <fsummary>Set system performance monitoring options</fsummary>
+ <type>
+ <v>MonitorPid = pid()</v>
+ <v>Option = {long_gc, Time} | {large_heap, Size} | busy_port | busy_dist_port</v>
+ <v>&nbsp;Time = Size = int()</v>
+ <v>MonSettings = {OldMonitorPid, [Option]}</v>
+ <v>&nbsp;OldMonitorPid = pid()</v>
+ </type>
+ <desc>
+ <p>Sets system performance monitoring options. <c>MonitorPid</c>
+ is a local pid that will receive system monitor messages, and
+ the second argument is a list of monitoring options:</p>
+ <taglist>
+ <tag><c>{long_gc, Time}</c></tag>
+ <item>
+ <p>If a garbage collection in the system takes at least
+ <c>Time</c> wallclock milliseconds, a message
+ <c>{monitor, GcPid, long_gc, Info}</c> is sent to
+ <c>MonitorPid</c>. <c>GcPid</c> is the pid that was
+ garbage collected and <c>Info</c> is a list of two-element
+ tuples describing the result of the garbage collection.
+ One of the tuples is <c>{timeout, GcTime}</c> where
+ <c>GcTime</c> is the actual time for the garbage
+ collection in milliseconds. The other tuples are
+ tagged with <c>heap_size</c>, <c>heap_block_size</c>,
+ <c>stack_size</c>, <c>mbuf_size</c>, <c>old_heap_size</c>,
+ and <c>old_heap_block_size</c>. These tuples are
+ explained in the documentation of the
+ <seealso marker="#gc_start">gc_start</seealso>
+ trace message (see
+ <seealso marker="#erlang:trace/3">erlang:trace/3</seealso>).
+ New tuples may be added, and the order of the tuples in
+ the <c>Info</c> list may be changed at any time without prior
+ notice.
+ </p>
+ </item>
+ <tag><c>{large_heap, Size}</c></tag>
+ <item>
+ <p>If a garbage collection in the system results in
+ the allocated size of a heap being at least <c>Size</c>
+ words, a message <c>{monitor, GcPid, large_heap, Info}</c>
+ is sent to <c>MonitorPid</c>. <c>GcPid</c> and <c>Info</c>
+ are the same as for <c>long_gc</c> above, except that
+ the tuple tagged with <c>timeout</c> is not present.
+ <em>Note</em>: As of erts version 5.6 the monitor message
+ is sent if the sum of the sizes of all memory blocks allocated
+ for all heap generations is equal to or larger than <c>Size</c>.
+ Previously the monitor message was sent if the memory block
+ allocated for the youngest generation was equal to or larger
+ than <c>Size</c>.
+ </p>
+ </item>
+ <tag><c>busy_port</c></tag>
+ <item>
+ <p>If a process in the system gets suspended because it
+ sends to a busy port, a message
+ <c>{monitor, SusPid, busy_port, Port}</c> is sent to
+ <c>MonitorPid</c>. <c>SusPid</c> is the pid that got
+ suspended when sending to <c>Port</c>.</p>
+ </item>
+ <tag><c>busy_dist_port</c></tag>
+ <item>
+ <p>If a process in the system gets suspended because it
+ sends to a process on a remote node whose inter-node
+ communication was handled by a busy port, a message
+ <c>{monitor, SusPid, busy_dist_port, Port}</c> is sent to
+ <c>MonitorPid</c>. <c>SusPid</c> is the pid that got
+ suspended when sending through the inter-node
+ communication port <c>Port</c>.</p>
+ </item>
+ </taglist>
+ <p>Returns the previous system monitor settings just like
+ <seealso marker="#erlang:system_monitor/0">erlang:system_monitor/0</seealso>.</p>
+ <note>
+ <p>If a monitoring process gets so large that it itself
+ starts to cause system monitor messages when garbage
+ collecting, the messages will enlarge the process's
+ message queue and probably make the problem worse.</p>
+ <p>Keep the monitoring process neat and do not set the system
+ monitor limits too tight.</p>
+ </note>
+ <p>Failure: <c>badarg</c> if <c>MonitorPid</c> does not exist.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>erlang:system_profile() -> ProfilerSettings</name>
+ <fsummary>Current system profiling settings</fsummary>
+ <type>
+ <v>ProfilerSettings -> {ProfilerPid, Options} | undefined</v>
+ <v>&nbsp;ProfilerPid = pid() | port()</v>
+ <v>&nbsp;Options = [Option]</v>
+ <v>&nbsp;&nbsp;Option = runnable_procs | runnable_ports | scheduler | exclusive</v>
+ </type>
+ <desc>
+ <p>Returns the current system profiling settings set by
+ <seealso marker="#erlang:system_profile/2">erlang:system_profile/2</seealso>
+ as <c>{ProfilerPid, Options}</c>, or <c>undefined</c> if there
+ are no settings. The order of the options may be different
+ from the one that was set.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>erlang:system_profile(ProfilerPid, Options) -> ProfilerSettings</name>
+ <fsummary>Current system profiling settings</fsummary>
+ <type>
+ <v>ProfilerSettings -> {ProfilerPid, Options} | undefined</v>
+ <v>&nbsp;ProfilerPid = pid() | port()</v>
+ <v>&nbsp;Options = [Option]</v>
+ <v>&nbsp;&nbsp;Option = runnable_procs | runnable_ports | scheduler | exclusive</v>
+ </type>
+ <desc>
+ <p>Sets system profiler options. <c>ProfilerPid</c>
+ is a local pid or port that will receive profiling messages. The
+ receiver is excluded from all profiling.
+ The second argument is a list of profiling options:</p>
+ <taglist>
+ <tag><c>runnable_procs</c></tag>
+ <item>
+ <p>If a process is put into or removed from the run queue a message,
+ <c>{profile, Pid, State, Mfa, Ts}</c>, is sent to
+ <c>ProfilerPid</c>. Running processes that is reinserted into the
+ run queue after having been preemptively scheduled out will not trigger this
+ message.
+ </p>
+ </item>
+ <tag><c>runnable_ports</c></tag>
+ <item>
+ <p>If a port is put into or removed from the run queue a message,
+ <c>{profile, Port, State, 0, Ts}</c>, is sent to
+ <c>ProfilerPid</c>.
+ </p>
+ </item>
+ <tag><c>scheduler</c></tag>
+ <item>
+ <p>If a scheduler is put to sleep or awoken a message,
+ <c>{profile, scheduler, Id, State, NoScheds, Ts}</c>, is sent
+ to <c>ProfilerPid</c>.
+ </p>
+ </item>
+ <tag><c>exclusive</c></tag>
+ <item>
+ <p>
+ If a synchronous call to a port from a process is done, the
+ calling process is considered not runnable during the call
+ runtime to the port. The calling process is notified as
+ <c>inactive</c> and subsequently <c>active</c> when the port
+ callback returns.
+ </p>
+ </item>
+ </taglist>
+ <note><p><c>erlang:system_profile</c> is considered experimental and
+ its behaviour may change in the future.</p>
+ </note>
+ </desc>
+ </func>
+
+ <func>
+ <name>term_to_binary(Term) -> ext_binary()</name>
+ <fsummary>Encode a term to an Erlang external term format binary</fsummary>
+ <type>
+ <v>Term = term()</v>
+ </type>
+ <desc>
+ <p>Returns a binary data object which is the result of encoding
+ <c>Term</c> according to the Erlang external term format.</p>
+ <p>This can be used for a variety of purposes, for example
+ writing a term to a file in an efficient way, or sending an
+ Erlang term to some type of communications channel not
+ supported by distributed Erlang.</p>
+ <p>See also
+ <seealso marker="#binary_to_term/1">binary_to_term/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>term_to_binary(Term, [Option]) -> ext_binary()</name>
+ <fsummary>Encode a term to en Erlang external term format binary</fsummary>
+ <type>
+ <v>Term = term()</v>
+ <v>Option = compressed | {compressed,Level} | {minor_version,Version}</v>
+ </type>
+ <desc>
+ <p>Returns a binary data object which is the result of encoding
+ <c>Term</c> according to the Erlang external term format.</p>
+ <p>If the option <c>compressed</c> is provided, the external
+ term format will be compressed. The compressed format is
+ automatically recognized by <c>binary_to_term/1</c> in R7B and later.</p>
+ <p>It is also possible to specify a compression level by giving
+ the option <c>{compressed,Level}</c>, where <c>Level</c> is an
+ integer from 0 through 9. <c>0</c> means that no compression
+ will be done (it is the same as not giving any <c>compressed</c> option);
+ <c>1</c> will take the least time but may not compress as well as
+ the higher levels; <c>9</c> will take the most time and may produce
+ a smaller result. Note the "mays" in the preceding sentence; depending
+ on the input term, level 9 compression may or may not produce a smaller
+ result than level 1 compression.</p>
+ <p>Currently, <c>compressed</c> gives the same result as
+ <c>{compressed,6}</c>.</p>
+ <p>The option <c>{minor_version,Version}</c> can be use to control
+ some details of the encoding. This option was
+ introduced in R11B-4. Currently, the allowed values for <c>Version</c>
+ are <c>0</c> and <c>1</c>.</p>
+ <p><c>{minor_version,1}</c> forces any floats in the term to be encoded
+ in a more space-efficient and exact way (namely in the 64-bit IEEE format,
+ rather than converted to a textual representation). <c>binary_to_term/1</c>
+ in R11B-4 and later is able decode the new representation.</p>
+ <p><c>{minor_version,0}</c> is currently the default, meaning that floats
+ will be encoded using a textual representation; this option is useful if
+ you want to ensure that releases prior to R11B-4 can decode resulting
+ binary.</p>
+ <p>See also
+ <seealso marker="#binary_to_term/1">binary_to_term/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>throw(Any)</name>
+ <fsummary>Throw an exception</fsummary>
+ <type>
+ <v>Any = term()</v>
+ </type>
+ <desc>
+ <p>A non-local return from a function. If evaluated within a
+ <c>catch</c>, <c>catch</c> will return the value <c>Any</c>.</p>
+ <pre>
+> <input>catch throw({hello, there}).</input>
+{hello,there}</pre>
+ <p>Failure: <c>nocatch</c> if not evaluated within a catch.</p>
+ </desc>
+ </func>
+ <func>
+ <name>time() -> {Hour, Minute, Second}</name>
+ <fsummary>Current time</fsummary>
+ <type>
+ <v>Hour = Minute = Second = int()</v>
+ </type>
+ <desc>
+ <p>Returns the current time as <c>{Hour, Minute, Second}</c>.</p>
+ <p>The time zone and daylight saving time correction depend on
+ the underlying OS.</p>
+ <pre>
+> <input>time().</input>
+{9,42,44}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>tl(List1) -> List2</name>
+ <fsummary>Tail of a list</fsummary>
+ <type>
+ <v>List1 = List2 = [term()]</v>
+ </type>
+ <desc>
+ <p>Returns the tail of <c>List1</c>, that is, the list minus
+ the first element.</p>
+ <pre>
+> <input>tl([geesties, guilies, beasties]).</input>
+[guilies, beasties]</pre>
+ <p>Allowed in guard tests.</p>
+ <p>Failure: <c>badarg</c> if <c>List</c> is the empty list [].</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:trace(PidSpec, How, FlagList) -> int()</name>
+ <fsummary>Set trace flags for a process or processes</fsummary>
+ <type>
+ <v>PidSpec = pid() | existing | new | all</v>
+ <v>How = bool()</v>
+ <v>FlagList = [Flag]</v>
+ <v>&nbsp;Flag -- see below</v>
+ </type>
+ <desc>
+ <p>Turns on (if <c>How == true</c>) or off (if
+ <c>How == false</c>) the trace flags in <c>FlagList</c> for
+ the process or processes represented by <c>PidSpec</c>.</p>
+ <p><c>PidSpec</c> is either a pid for a local process, or one of
+ the following atoms:</p>
+ <taglist>
+ <tag><c>existing</c></tag>
+ <item>
+ <p>All processes currently existing.</p>
+ </item>
+ <tag><c>new</c></tag>
+ <item>
+ <p>All processes that will be created in the future.</p>
+ </item>
+ <tag><c>all</c></tag>
+ <item>
+ <p>All currently existing processes and all processes that
+ will be created in the future.</p>
+ </item>
+ </taglist>
+ <p><c>FlagList</c> can contain any number of the following
+ flags (the "message tags" refers to the list of messages
+ following below):</p>
+ <taglist>
+ <tag><c>all</c></tag>
+ <item>
+ <p>Set all trace flags except <c>{tracer, Tracer}</c> and
+ <c>cpu_timestamp</c> that are in their nature different
+ than the others.</p>
+ </item>
+ <tag><c>send</c></tag>
+ <item>
+ <p>Trace sending of messages.</p>
+ <p>Message tags: <c>send</c>,
+ <c>send_to_non_existing_process</c>.</p>
+ </item>
+ <tag><c>'receive'</c></tag>
+ <item>
+ <p>Trace receiving of messages.</p>
+ <p>Message tags: <c>'receive'</c>.</p>
+ </item>
+ <tag><c>procs</c></tag>
+ <item>
+ <p>Trace process related events.</p>
+ <p>Message tags: <c>spawn</c>, <c>exit</c>,
+ <c>register</c>, <c>unregister</c>, <c>link</c>,
+ <c>unlink</c>, <c>getting_linked</c>,
+ <c>getting_unlinked</c>.</p>
+ </item>
+ <tag><c>call</c></tag>
+ <item>
+ <p>Trace certain function calls. Specify which function
+ calls to trace by calling
+ <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <p>Message tags: <c>call</c>, <c>return_from</c>.</p>
+ </item>
+ <tag><c>silent</c></tag>
+ <item>
+ <p>Used in conjunction with the <c>call</c> trace flag.
+ The <c>call</c>, <c>return_from</c> and <c>return_to</c>
+ trace messages are inhibited if this flag is set,
+ but if there are match specs they are executed as normal.</p>
+ <p>Silent mode is inhibited by executing
+ <c>erlang:trace(_, false, [silent|_])</c>,
+ or by a match spec executing the <c>{silent, false}</c>
+ function.</p>
+ <p>The <c>silent</c> trace flag facilitates setting up
+ a trace on many or even all processes in the system.
+ Then the interesting trace can be activated and
+ deactivated using the <c>{silent,Bool}</c>
+ match spec function, giving a high degree
+ of control of which functions with which
+ arguments that triggers the trace.</p>
+ <p>Message tags: <c>call</c>, <c>return_from</c>,
+ <c>return_to</c>. Or rather, the absence of.</p>
+ </item>
+ <tag><c>return_to</c></tag>
+ <item>
+ <p>Used in conjunction with the <c>call</c> trace flag.
+ Trace the actual return from a traced function back to
+ its caller. Only works for functions traced with
+ the <c>local</c> option to
+ <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ <p>The semantics is that a trace message is sent when a
+ call traced function actually returns, that is, when a
+ chain of tail recursive calls is ended. There will be
+ only one trace message sent per chain of tail recursive
+ calls, why the properties of tail recursiveness for
+ function calls are kept while tracing with this flag.
+ Using <c>call</c> and <c>return_to</c> trace together
+ makes it possible to know exactly in which function a
+ process executes at any time.</p>
+ <p>To get trace messages containing return values from
+ functions, use the <c>{return_trace}</c> match_spec
+ action instead.</p>
+ <p>Message tags: <c>return_to</c>.</p>
+ </item>
+ <tag><c>running</c></tag>
+ <item>
+ <p>Trace scheduling of processes.</p>
+ <p>Message tags: <c>in</c>, and <c>out</c>.</p>
+ </item>
+ <tag><c>exiting</c></tag>
+ <item>
+ <p>Trace scheduling of an exiting processes.</p>
+ <p>Message tags: <c>in_exiting</c>, <c>out_exiting</c>, and
+ <c>out_exited</c>.</p>
+ </item>
+ <tag><c>garbage_collection</c></tag>
+ <item>
+ <p>Trace garbage collections of processes.</p>
+ <p>Message tags: <c>gc_start</c>, <c>gc_end</c>.</p>
+ </item>
+ <tag><c>timestamp</c></tag>
+ <item>
+ <p>Include a time stamp in all trace messages. The time
+ stamp (Ts) is of the same form as returned by
+ <c>erlang:now()</c>.</p>
+ </item>
+ <tag><c>cpu_timestamp</c></tag>
+ <item>
+ <p>A global trace flag for the Erlang node that makes all
+ trace timestamps be in CPU time, not wallclock. It is
+ only allowed with <c>PidSpec==all</c>. If the host
+ machine operating system does not support high resolution
+ CPU time measurements, <c>trace/3</c> exits with
+ <c>badarg</c>.</p>
+ </item>
+ <tag><c>arity</c></tag>
+ <item>
+ <p>Used in conjunction with the <c>call</c> trace flag.
+ <c>{M, F, Arity}</c> will be specified instead of
+ <c>{M, F, Args}</c> in call trace messages.</p>
+ </item>
+ <tag><c>set_on_spawn</c></tag>
+ <item>
+ <p>Makes any process created by a traced process inherit
+ its trace flags, including the <c>set_on_spawn</c> flag.</p>
+ </item>
+ <tag><c>set_on_first_spawn</c></tag>
+ <item>
+ <p>Makes the first process created by a traced process
+ inherit its trace flags, excluding
+ the <c>set_on_first_spawn</c> flag.</p>
+ </item>
+ <tag><c>set_on_link</c></tag>
+ <item>
+ <p>Makes any process linked by a traced process inherit its
+ trace flags, including the <c>set_on_link</c> flag.</p>
+ </item>
+ <tag><c>set_on_first_link</c></tag>
+ <item>
+ <p>Makes the first process linked to by a traced process
+ inherit its trace flags, excluding
+ the <c>set_on_first_link</c> flag.</p>
+ </item>
+ <tag><c>{tracer, Tracer}</c></tag>
+ <item>
+ <p>Specify where to send the trace messages. <c>Tracer</c>
+ must be the pid of a local process or the port identifier
+ of a local port. If this flag is not given, trace
+ messages will be sent to the process that called
+ <c>erlang:trace/3</c>.</p>
+ </item>
+ </taglist>
+ <p>The effect of combining <c>set_on_first_link</c> with
+ <c>set_on_link</c> is the same as having
+ <c>set_on_first_link</c> alone. Likewise for
+ <c>set_on_spawn</c> and <c>set_on_first_spawn</c>.</p>
+ <p>If the <c>timestamp</c> flag is not given, the tracing
+ process will receive the trace messages described below.
+ <c>Pid</c> is the pid of the traced process in which
+ the traced event has occurred. The third element of the tuple
+ is the message tag.</p>
+ <p>If the <c>timestamp</c> flag is given, the first element of
+ the tuple will be <c>trace_ts</c> instead and the timestamp
+ is added last in the tuple.</p>
+ <taglist>
+ <tag><c>{trace, Pid, 'receive', Msg}</c></tag>
+ <item>
+ <p>When <c>Pid</c> receives the message <c>Msg</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, send, Msg, To}</c></tag>
+ <item>
+ <p>When <c>Pid</c> sends the message <c>Msg</c> to
+ the process <c>To</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, send_to_non_existing_process, Msg, To}</c></tag>
+ <item>
+ <p>When <c>Pid</c> sends the message <c>Msg</c> to
+ the non-existing process <c>To</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, call, {M, F, Args}}</c></tag>
+ <item>
+ <p>When <c>Pid</c> calls a traced function. The return
+ values of calls are never supplied, only the call and its
+ arguments.</p>
+ <p>Note that the trace flag <c>arity</c> can be used to
+ change the contents of this message, so that <c>Arity</c>
+ is specified instead of <c>Args</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, return_to, {M, F, Arity}}</c></tag>
+ <item>
+ <p>When <c>Pid</c> returns <em>to</em> the specified
+ function. This trace message is sent if both
+ the <c>call</c> and the <c>return_to</c> flags are set,
+ and the function is set to be traced on <em>local</em>
+ function calls. The message is only sent when returning
+ from a chain of tail recursive function calls where at
+ least one call generated a <c>call</c> trace message
+ (that is, the functions match specification matched and
+ <c>{message, false}</c> was not an action).</p>
+ </item>
+ <tag><c>{trace, Pid, return_from, {M, F, Arity}, ReturnValue}</c></tag>
+ <item>
+ <p>When <c>Pid</c> returns <em>from</em> the specified
+ function. This trace message is sent if the <c>call</c>
+ flag is set, and the function has a match specification
+ with a <c>return_trace</c> or <c>exception_trace</c> action.</p>
+ </item>
+ <tag><c>{trace, Pid, exception_from, {M, F, Arity}, {Class, Value}}</c></tag>
+ <item>
+ <p>When <c>Pid</c> exits <em>from</em> the specified
+ function due to an exception. This trace message is sent
+ if the <c>call</c> flag is set, and the function has
+ a match specification with an <c>exception_trace</c> action.</p>
+ </item>
+ <tag><c>{trace, Pid, spawn, Pid2, {M, F, Args}}</c></tag>
+ <item>
+ <p>When <c>Pid</c> spawns a new process <c>Pid2</c> with
+ the specified function call as entry point.</p>
+ <p>Note that <c>Args</c> is supposed to be the argument
+ list, but may be any term in the case of an erroneous
+ spawn.</p>
+ </item>
+ <tag><c>{trace, Pid, exit, Reason}</c></tag>
+ <item>
+ <p>When <c>Pid</c> exits with reason <c>Reason</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, link, Pid2}</c></tag>
+ <item>
+ <p>When <c>Pid</c> links to a process <c>Pid2</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, unlink, Pid2}</c></tag>
+ <item>
+ <p>When <c>Pid</c> removes the link from a process
+ <c>Pid2</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, getting_linked, Pid2}</c></tag>
+ <item>
+ <p>When <c>Pid</c> gets linked to a process <c>Pid2</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, getting_unlinked, Pid2}</c></tag>
+ <item>
+ <p>When <c>Pid</c> gets unlinked from a process <c>Pid2</c>.</p>
+ </item>
+ <tag><c>{trace, Pid, register, RegName}</c></tag>
+ <item>
+ <p>When <c>Pid</c> gets the name <c>RegName</c> registered.</p>
+ </item>
+ <tag><c>{trace, Pid, unregister, RegName}</c></tag>
+ <item>
+ <p>When <c>Pid</c> gets the name <c>RegName</c> unregistered.
+ Note that this is done automatically when a registered
+ process exits.</p>
+ </item>
+ <tag><c>{trace, Pid, in, {M, F, Arity} | 0}</c></tag>
+ <item>
+ <p>When <c>Pid</c> is scheduled to run. The process will
+ run in function <c>{M, F, Arity}</c>. On some rare
+ occasions the current function cannot be determined, then
+ the last element <c>Arity</c> is 0.</p>
+ </item>
+ <tag><c>{trace, Pid, out, {M, F, Arity} | 0}</c></tag>
+ <item>
+ <p>When <c>Pid</c> is scheduled out. The process was
+ running in function {M, F, Arity}. On some rare occasions
+ the current function cannot be determined, then the last
+ element <c>Arity</c> is 0.</p>
+ </item>
+ <tag><c>{trace, Pid, gc_start, Info}</c></tag>
+ <item>
+ <marker id="gc_start"></marker>
+ <p>Sent when garbage collection is about to be started.
+ <c>Info</c> is a list of two-element tuples, where
+ the first element is a key, and the second is the value.
+ You should not depend on the tuples have any defined
+ order. Currently, the following keys are defined:</p>
+ <taglist>
+ <tag><c>heap_size</c></tag>
+ <item>The size of the used part of the heap.</item>
+ <tag><c>heap_block_size</c></tag>
+ <item>The size of the memory block used for storing
+ the heap and the stack.</item>
+ <tag><c>old_heap_size</c></tag>
+ <item>The size of the used part of the old heap.</item>
+ <tag><c>old_heap_block_size</c></tag>
+ <item>The size of the memory block used for storing
+ the old heap.</item>
+ <tag><c>stack_size</c></tag>
+ <item>The actual size of the stack.</item>
+ <tag><c>recent_size</c></tag>
+ <item>The size of the data that survived the previous garbage
+ collection.</item>
+ <tag><c>mbuf_size</c></tag>
+ <item>The combined size of message buffers associated with
+ the process.</item>
+ </taglist>
+ <p>All sizes are in words.</p>
+ </item>
+ <tag><c>{trace, Pid, gc_end, Info}</c></tag>
+ <item>
+ <p>Sent when garbage collection is finished. <c>Info</c>
+ contains the same kind of list as in the <c>gc_start</c>
+ message, but the sizes reflect the new sizes after
+ garbage collection.</p>
+ </item>
+ </taglist>
+ <p>If the tracing process dies, the flags will be silently
+ removed.</p>
+ <p>Only one process can trace a particular process. For this
+ reason, attempts to trace an already traced process will fail.</p>
+ <p>Returns: A number indicating the number of processes that
+ matched <c>PidSpec</c>. If <c>PidSpec</c> is a pid,
+ the return value will be <c>1</c>. If <c>PidSpec</c> is
+ <c>all</c> or <c>existing</c> the return value will be
+ the number of processes running, excluding tracer processes.
+ If <c>PidSpec</c> is <c>new</c>, the return value will be
+ <c>0</c>.</p>
+ <p>Failure: If specified arguments are not supported. For
+ example <c>cpu_timestamp</c> is not supported on all
+ platforms.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:trace_delivered(Tracee) -> Ref</name>
+ <fsummary>Notification when trace has been delivered</fsummary>
+ <type>
+ <v>Tracee = pid() | all</v>
+ <v>Ref = reference()</v>
+ </type>
+ <desc>
+ <p>The delivery of trace messages is dislocated on the time-line
+ compared to other events in the system. If you know that the
+ <c>Tracee</c> has passed some specific point in its execution,
+ and you want to know when at least all trace messages
+ corresponding to events up to this point have reached the tracer
+ you can use <c>erlang:trace_delivered(Tracee)</c>. A
+ <c>{trace_delivered, Tracee, Ref}</c> message is sent to
+ the caller of <c>erlang:trace_delivered(Tracee)</c> when it
+ is guaranteed that all trace messages have been delivered to
+ the tracer up to the point that the <c>Tracee</c> had reached
+ at the time of the call to
+ <c>erlang:trace_delivered(Tracee)</c>.</p>
+ <p>Note that the <c>trace_delivered</c> message does <em>not</em>
+ imply that trace messages have been delivered; instead, it implies
+ that all trace messages that <em>should</em> be delivered have
+ been delivered. It is not an error if <c>Tracee</c> isn't, and
+ hasn't been traced by someone, but if this is the case,
+ <em>no</em> trace messages will have been delivered when the
+ <c>trace_delivered</c> message arrives.</p>
+ <p>Note that <c>Tracee</c> has to refer to a process currently,
+ or previously existing on the same node as the caller of
+ <c>erlang:trace_delivered(Tracee)</c> resides on.
+ The special <c>Tracee</c> atom <c>all</c> denotes all processes
+ that currently are traced in the node.</p>
+ <p>An example: Process <c>A</c> is tracee, port <c>B</c> is
+ tracer, and process <c>C</c> is the port owner of <c>B</c>.
+ <c>C</c> wants to close <c>B</c> when <c>A</c> exits. <c>C</c>
+ can ensure that the trace isn't truncated by calling
+ <c>erlang:trace_delivered(A)</c> when <c>A</c> exits and wait
+ for the <c>{trace_delivered, A, Ref}</c> message before closing
+ <c>B</c>.</p>
+ <p>Failure: <c>badarg</c> if <c>Tracee</c> does not refer to a
+ process (dead or alive) on the same node as the caller of
+ <c>erlang:trace_delivered(Tracee)</c> resides on.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:trace_info(PidOrFunc, Item) -> Res</name>
+ <fsummary>Trace information about a process or function</fsummary>
+ <type>
+ <v>PidOrFunc = pid() | new | {Module, Function, Arity} | on_load</v>
+ <v>&nbsp;Module = Function = atom()</v>
+ <v>&nbsp;Arity = int()</v>
+ <v>Item, Res -- see below</v>
+ </type>
+ <desc>
+ <p>Returns trace information about a process or function.</p>
+ <p>To get information about a process, <c>PidOrFunc</c> should
+ be a pid or the atom <c>new</c>. The atom <c>new</c> means
+ that the default trace state for processes to be created will
+ be returned. <c>Item</c> must have one of the following
+ values:</p>
+ <taglist>
+ <tag><c>flags</c></tag>
+ <item>
+ <p>Return a list of atoms indicating what kind of traces is
+ enabled for the process. The list will be empty if no
+ traces are enabled, and one or more of the followings
+ atoms if traces are enabled: <c>send</c>,
+ <c>'receive'</c>, <c>set_on_spawn</c>, <c>call</c>,
+ <c>return_to</c>, <c>procs</c>, <c>set_on_first_spawn</c>,
+ <c>set_on_link</c>, <c>running</c>,
+ <c>garbage_collection</c>, <c>timestamp</c>, and
+ <c>arity</c>. The order is arbitrary.</p>
+ </item>
+ <tag><c>tracer</c></tag>
+ <item>
+ <p>Return the identifier for process or port tracing this
+ process. If this process is not being traced, the return
+ value will be <c>[]</c>.</p>
+ </item>
+ </taglist>
+ <p>To get information about a function, <c>PidOrFunc</c> should
+ be a three-element tuple: <c>{Module, Function, Arity}</c> or
+ the atom <c>on_load</c>. No wildcards are allowed. Returns
+ <c>undefined</c> if the function does not exist or
+ <c>false</c> if the function is not traced at all. <c>Item</c>
+ must have one of the following values:</p>
+ <taglist>
+ <tag><c>traced</c></tag>
+ <item>
+ <p>Return <c>global</c> if this function is traced on
+ global function calls, <c>local</c> if this function is
+ traced on local function calls (i.e local and global
+ function calls), and <c>false</c> if neither local nor
+ global function calls are traced.</p>
+ </item>
+ <tag><c>match_spec</c></tag>
+ <item>
+ <p>Return the match specification for this function, if it
+ has one. If the function is locally or globally traced but
+ has no match specification defined, the returned value
+ is <c>[]</c>.</p>
+ </item>
+ <tag><c>meta</c></tag>
+ <item>
+ <p>Return the meta trace tracer process or port for this
+ function, if it has one. If the function is not meta
+ traced the returned value is <c>false</c>, and if
+ the function is meta traced but has once detected that
+ the tracer proc is invalid, the returned value is [].</p>
+ </item>
+ <tag><c>meta_match_spec</c></tag>
+ <item>
+ <p>Return the meta trace match specification for this
+ function, if it has one. If the function is meta traced
+ but has no match specification defined, the returned
+ value is <c>[]</c>.</p>
+ </item>
+ <tag><c>call_count</c></tag>
+ <item>
+ <p>Return the call count value for this function or
+ <c>true</c> for the pseudo function <c>on_load</c> if call
+ count tracing is active. Return <c>false</c> otherwise.
+ See also
+ <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern/3</seealso>.</p>
+ </item>
+ <tag><c>all</c></tag>
+ <item>
+ <p>Return a list containing the <c>{Item, Value}</c> tuples
+ for all other items, or return <c>false</c> if no tracing
+ is active for this function.</p>
+ </item>
+ </taglist>
+ <p>The actual return value will be <c>{Item, Value}</c>, where
+ <c>Value</c> is the requested information as described above.
+ If a pid for a dead process was given, or the name of a
+ non-existing function, <c>Value</c> will be <c>undefined</c>.</p>
+ <p>If <c>PidOrFunc</c> is the <c>on_load</c>, the information
+ returned refers to the default value for code that will be
+ loaded.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:trace_pattern(MFA, MatchSpec) -> int()</name>
+ <fsummary>Set trace patterns for global call tracing</fsummary>
+ <desc>
+ <p>The same as
+ <seealso marker="#erlang:trace_pattern/3">erlang:trace_pattern(MFA, MatchSpec, [])</seealso>,
+ retained for backward compatibility.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:trace_pattern(MFA, MatchSpec, FlagList) -> int()</name>
+ <fsummary>Set trace patterns for tracing of function calls</fsummary>
+ <type>
+ <v>MFA, MatchSpec, FlagList -- see below</v>
+ </type>
+ <desc>
+ <p>This BIF is used to enable or disable call tracing for
+ exported functions. It must be combined with
+ <seealso marker="#erlang:trace/3">erlang:trace/3</seealso>
+ to set the <c>call</c> trace flag for one or more processes.</p>
+ <p>Conceptually, call tracing works like this: Inside
+ the Erlang virtual machine there is a set of processes to be
+ traced and a set of functions to be traced. Tracing will be
+ enabled on the intersection of the set. That is, if a process
+ included in the traced process set calls a function included
+ in the traced function set, the trace action will be taken.
+ Otherwise, nothing will happen.</p>
+ <p>Use
+ <seealso marker="#erlang:trace/3">erlang:trace/3</seealso> to
+ add or remove one or more processes to the set of traced
+ processes. Use <c>erlang:trace_pattern/2</c> to add or remove
+ exported functions to the set of traced functions.</p>
+ <p>The <c>erlang:trace_pattern/3</c> BIF can also add match
+ specifications to an exported function. A match specification
+ comprises a pattern that the arguments to the function must
+ match, a guard expression which must evaluate to <c>true</c>
+ and an action to be performed. The default action is to send a
+ trace message. If the pattern does not match or the guard
+ fails, the action will not be executed.</p>
+ <p>The <c>MFA</c> argument should be a tuple like
+ <c>{Module, Function, Arity}</c> or the atom <c>on_load</c>
+ (described below). It can be the module, function, and arity
+ for an exported function (or a BIF in any module).
+ The <c>'_'</c> atom can be used to mean any of that kind.
+ Wildcards can be used in any of the following ways:</p>
+ <taglist>
+ <tag><c>{Module,Function,'_'}</c></tag>
+ <item>
+ <p>All exported functions of any arity named <c>Function</c>
+ in module <c>Module</c>.</p>
+ </item>
+ <tag><c>{Module,'_','_'}</c></tag>
+ <item>
+ <p>All exported functions in module <c>Module</c>.</p>
+ </item>
+ <tag><c>{'_','_','_'}</c></tag>
+ <item>
+ <p>All exported functions in all loaded modules.</p>
+ </item>
+ </taglist>
+ <p>Other combinations, such as <c>{Module,'_',Arity}</c>, are
+ not allowed. Local functions will match wildcards only if
+ the <c>local</c> option is in the <c>FlagList</c>.</p>
+ <p>If the <c>MFA</c> argument is the atom <c>on_load</c>,
+ the match specification and flag list will be used on all
+ modules that are newly loaded.</p>
+ <p>The <c>MatchSpec</c> argument can take any of the following
+ forms:</p>
+ <taglist>
+ <tag><c>false</c></tag>
+ <item>
+ <p>Disable tracing for the matching function(s). Any match
+ specification will be removed.</p>
+ </item>
+ <tag><c>true</c></tag>
+ <item>
+ <p>Enable tracing for the matching function(s).</p>
+ </item>
+ <tag><c>MatchSpecList</c></tag>
+ <item>
+ <p>A list of match specifications. An empty list is
+ equivalent to <c>true</c>. See the ERTS User's Guide
+ for a description of match specifications.</p>
+ </item>
+ <tag><c>restart</c></tag>
+ <item>
+ <p>For the <c>FlagList</c> option <c>call_count</c>:
+ restart the existing counters. The behaviour is undefined
+ for other <c>FlagList</c> options.</p>
+ </item>
+ <tag><c>pause</c></tag>
+ <item>
+ <p>For the <c>FlagList</c> option <c>call_count</c>: pause
+ the existing counters. The behaviour is undefined for
+ other <c>FlagList</c> options.</p>
+ </item>
+ </taglist>
+ <p>The <c>FlagList</c> parameter is a list of options.
+ The following options are allowed:</p>
+ <taglist>
+ <tag><c>global</c></tag>
+ <item>
+ <p>Turn on or off call tracing for global function calls
+ (that is, calls specifying the module explicitly). Only
+ exported functions will match and only global calls will
+ generate trace messages. This is the default.</p>
+ </item>
+ <tag><c>local</c></tag>
+ <item>
+ <p>Turn on or off call tracing for all types of function
+ calls. Trace messages will be sent whenever any of
+ the specified functions are called, regardless of how they
+ are called. If the <c>return_to</c> flag is set for
+ the process, a <c>return_to</c> message will also be sent
+ when this function returns to its caller.</p>
+ </item>
+ <tag><c>meta | {meta, Pid}</c></tag>
+ <item>
+ <p>Turn on or off meta tracing for all types of function
+ calls. Trace messages will be sent to the tracer process
+ or port <c>Pid</c> whenever any of the specified
+ functions are called, regardless of how they are called.
+ If no <c>Pid</c> is specified, <c>self()</c> is used as a
+ default tracer process.</p>
+ <p>Meta tracing traces all processes and does not care
+ about the process trace flags set by <c>trace/3</c>,
+ the trace flags are instead fixed to
+ <c>[call, timestamp]</c>.</p>
+ <p>The match spec function <c>{return_trace}</c> works with
+ meta trace and send its trace message to the same tracer
+ process.</p>
+ </item>
+ <tag><c>call_count</c></tag>
+ <item>
+ <p>Starts (<c>MatchSpec == true</c>) or stops
+ (<c>MatchSpec == false</c>) call count tracing for all
+ types of function calls. For every function a counter is
+ incremented when the function is called, in any process.
+ No process trace flags need to be activated.</p>
+ <p>If call count tracing is started while already running,
+ the count is restarted from zero. Running counters can be
+ paused with <c>MatchSpec == pause</c>. Paused and running
+ counters can be restarted from zero with
+ <c>MatchSpec == restart</c>.</p>
+ <p>The counter value can be read with
+ <seealso marker="#erlang:trace_info/2">erlang:trace_info/2</seealso>.</p>
+ </item>
+ </taglist>
+ <p>The <c>global</c> and <c>local</c> options are mutually
+ exclusive and <c>global</c> is the default (if no options are
+ specified). The <c>call_count</c> and <c>meta</c> options
+ perform a kind of local tracing, and can also not be combined
+ with <c>global</c>. A function can be either globally or
+ locally traced. If global tracing is specified for a
+ specified set of functions; local, meta and call count
+ tracing for the matching set of local functions will be
+ disabled, and vice versa.</p>
+ <p>When disabling trace, the option must match the type of trace
+ that is set on the function, so that local tracing must be
+ disabled with the <c>local</c> option and global tracing with
+ the <c>global</c> option (or no option at all), and so forth.</p>
+ <p>There is no way to directly change part of a match
+ specification list. If a function has a match specification,
+ you can replace it with a completely new one. If you need to
+ change an existing match specification, use the
+ <seealso marker="#erlang:trace_info/2">erlang:trace_info/2</seealso>
+ BIF to retrieve the existing match specification.</p>
+ <p>Returns the number of exported functions that matched
+ the <c>MFA</c> argument. This will be zero if none matched at
+ all.</p>
+ </desc>
+ </func>
+ <func>
+ <name>trunc(Number) -> int()</name>
+ <fsummary>Return an integer by the truncating a number</fsummary>
+ <type>
+ <v>Number = number()</v>
+ </type>
+ <desc>
+ <p>Returns an integer by the truncating <c>Number</c>.</p>
+ <pre>
+> <input>trunc(5.5).</input>
+5</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>tuple_size(Tuple) -> int()</name>
+ <fsummary>Return the size of a tuple</fsummary>
+ <type>
+ <v>Tuple = tuple()</v>
+ </type>
+ <desc>
+ <p>Returns an integer which is the number of elements in <c>Tuple</c>.</p>
+ <pre>
+> <input>tuple_size({morni, mulle, bwange}).</input>
+3</pre>
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>tuple_to_list(Tuple) -> [term()]</name>
+ <fsummary>Convert a tuple to a list</fsummary>
+ <type>
+ <v>Tuple = tuple()</v>
+ </type>
+ <desc>
+ <p>Returns a list which corresponds to <c>Tuple</c>.
+ <c>Tuple</c> may contain any Erlang terms.</p>
+ <pre>
+> <input>tuple_to_list({share, {'Ericsson_B', 163}}).</input>
+[share,{'Ericsson_B',163}]</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:universaltime() -> {Date, Time}</name>
+ <fsummary>Current date and time according to Universal Time Coordinated (UTC)</fsummary>
+ <type>
+ <v>Date = {Year, Month, Day}</v>
+ <v>Time = {Hour, Minute, Second}</v>
+ <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ </type>
+ <desc>
+ <p>Returns the current date and time according to Universal
+ Time Coordinated (UTC), also called GMT, in the form
+ <c>{{Year, Month, Day}, {Hour, Minute, Second}}</c> if
+ supported by the underlying operating system. If not,
+ <c>erlang:universaltime()</c> is equivalent to
+ <c>erlang:localtime()</c>.</p>
+ <pre>
+> <input>erlang:universaltime().</input>
+{{1996,11,6},{14,18,43}}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:universaltime_to_localtime({Date1, Time1}) -> {Date2, Time2}</name>
+ <fsummary>Convert from Universal Time Coordinated (UTC) to local date and time</fsummary>
+ <type>
+ <v>Date1 = Date2 = {Year, Month, Day}</v>
+ <v>Time1 = Time2 = {Hour, Minute, Second}</v>
+ <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ </type>
+ <desc>
+ <p>Converts Universal Time Coordinated (UTC) date and time to
+ local date and time, if this is supported by the underlying
+ OS. Otherwise, no conversion is done, and
+ <c>{Date1, Time1}</c> is returned.</p>
+ <pre>
+> <input>erlang:universaltime_to_localtime({{1996,11,6},{14,18,43}}).</input>
+{{1996,11,7},{15,18,43}}</pre>
+ <p>Failure: <c>badarg</c> if <c>Date1</c> or <c>Time1</c> do
+ not denote a valid date or time.</p>
+ </desc>
+ </func>
+ <func>
+ <name>unlink(Id) -> true</name>
+ <fsummary>Remove a link, if there is one, to another process or port</fsummary>
+ <type>
+ <v>Id = pid() | port()</v>
+ </type>
+ <desc>
+ <p>Removes the link, if there is one, between the calling
+ process and the process or port referred to by <c>Id</c>.</p>
+ <p>Returns <c>true</c> and does not fail, even if there is no
+ link to <c>Id</c>, or if <c>Id</c> does not exist.</p>
+ <p>Once <c>unlink(Id)</c> has returned it is guaranteed that
+ the link between the caller and the entity referred to by
+ <c>Id</c> has no effect on the caller in the future (unless
+ the link is setup again). If caller is trapping exits, an
+ <c>{'EXIT', Id, _}</c> message due to the link might have
+ been placed in the callers message queue prior to the call,
+ though. Note, the <c>{'EXIT', Id, _}</c> message can be the
+ result of the link, but can also be the result of <c>Id</c>
+ calling <c>exit/2</c>. Therefore, it <em>may</em> be
+ appropriate to cleanup the message queue when trapping exits
+ after the call to <c>unlink(Id)</c>, as follow:</p>
+ <code type="none">
+
+ unlink(Id),
+ receive
+\011{'EXIT', Id, _} ->
+\011 true
+ after 0 ->
+\011 true
+ end</code>
+ <note>
+ <p>Prior to OTP release R11B (erts version 5.5) <c>unlink/1</c>
+ behaved completely asynchronous, i.e., the link was active
+ until the "unlink signal" reached the linked entity. This
+ had one undesirable effect, though. You could never know when
+ you were guaranteed <em>not</em> to be effected by the link.</p>
+ <p>Current behavior can be viewed as two combined operations:
+ asynchronously send an "unlink signal" to the linked entity
+ and ignore any future results of the link.</p>
+ </note>
+ </desc>
+ </func>
+ <func>
+ <name>unregister(RegName) -> true</name>
+ <fsummary>Remove the registered name for a process (or port)</fsummary>
+ <type>
+ <v>RegName = atom()</v>
+ </type>
+ <desc>
+ <p>Removes the registered name <c>RegName</c>, associated with a
+ pid or a port identifier.</p>
+ <pre>
+> <input>unregister(db).</input>
+true</pre>
+ <p>Users are advised not to unregister system processes.</p>
+ <p>Failure: <c>badarg</c> if <c>RegName</c> is not a registered
+ name.</p>
+ </desc>
+ </func>
+ <func>
+ <name>whereis(RegName) -> pid() | port() | undefined</name>
+ <fsummary>Get the pid (or port) with a given registered name</fsummary>
+ <desc>
+ <p>Returns the pid or port identifier with the registered name
+ <c>RegName</c>. Returns <c>undefined</c> if the name is not
+ registered.</p>
+ <pre>
+> <input>whereis(db).</input>
+&lt;0.43.0></pre>
+ </desc>
+ </func>
+ <func>
+ <name>erlang:yield() -> true</name>
+ <fsummary>Let other processes get a chance to execute</fsummary>
+ <desc>
+ <p>Voluntarily let other processes (if any) get a chance to
+ execute. Using <c>erlang:yield()</c> is similar to
+ <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 will have a
+ chance to run in another scheduler thread anyway.
+ Using this BIF without a thorough grasp of how the scheduler
+ works may cause performance degradation.</p></warning>
+ </desc>
+ </func>
+ </funcs>
+</erlref>
+
diff --git a/erts/doc/src/erlc.xml b/erts/doc/src/erlc.xml
new file mode 100644
index 0000000000..3859ac8365
--- /dev/null
+++ b/erts/doc/src/erlc.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erlc</title>
+ <prepared>Bj&ouml;rn Gustavsson</prepared>
+ <responsible>Bjarne D&auml;cker</responsible>
+ <docno>1</docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked></checked>
+ <date>97-03-24</date>
+ <rev>A</rev>
+ <file>erlc.xml</file>
+ </header>
+ <com>erlc</com>
+ <comsummary>Compiler</comsummary>
+ <description>
+ <p>The <c><![CDATA[erlc]]></c> program provides a common way to run
+ all compilers in the Erlang system.
+ Depending on the extension of each input file, <c><![CDATA[erlc]]></c>
+ will invoke the appropriate compiler.
+ Regardless of which compiler is used, the same flags are used to provide parameters such as include paths and output directory.</p>
+ <p>The current working directory, <c>"."</c>, will not be included
+ in the code path when running the compiler (to avoid loading
+ Beam files from the current working directory that could potentially
+ be in conflict with the compiler or Erlang/OTP system used by the
+ compiler).</p>
+ </description>
+ <funcs>
+ <func>
+ <name>erlc flags file1.ext file2.ext...</name>
+ <fsummary>Compile files</fsummary>
+ <desc>
+ <p><c><![CDATA[Erlc]]></c> compiles one or more files.
+ The files must include the extension, for example <c><![CDATA[.erl]]></c>
+ for Erlang source code, or <c><![CDATA[.yrl]]></c> for Yecc source code.
+ <c><![CDATA[Erlc]]></c> uses the extension to invoke the correct compiler.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Generally Useful Flags</title>
+ <p>The following flags are supported:
+ </p>
+ <taglist>
+ <tag>-I <em>directory</em></tag>
+ <item>
+ <p>Instructs the compiler to search for include files in
+ the specified directory. When encountering an
+ <c><![CDATA[-include]]></c> or <c><![CDATA[-include_dir]]></c> directive, the
+ compiler searches for header files in the following
+ directories:</p>
+ <list type="ordered">
+ <item>
+ <p><c><![CDATA["."]]></c>, the current working directory of the
+ file server;</p>
+ </item>
+ <item>
+ <p>the base name of the compiled file;</p>
+ </item>
+ <item>
+ <p>the directories specified using the <c><![CDATA[-I]]></c> option.
+ The directory specified last is searched first.</p>
+ </item>
+ </list>
+ </item>
+ <tag>-o <em>directory</em></tag>
+ <item>
+ <p>The directory where the compiler should place the output files.
+ If not specified, output files will be placed in the current working
+ directory.</p>
+ </item>
+ <tag>-D<em>name</em></tag>
+ <item>
+ <p>Defines a macro.</p>
+ </item>
+ <tag>-D<em>name</em>=<em>value</em></tag>
+ <item>
+ <p>Defines a macro with the given value.
+ The value can be any Erlang term.
+ Depending on the platform, the value may need to be
+ quoted if the shell itself interprets certain characters.
+ On Unix, terms which contain tuples and list
+ must be quoted. Terms which contain spaces
+ must be quoted on all platforms.</p>
+ </item>
+ <tag>-W<em>number</em></tag>
+ <item>
+ <p>Sets warning level to <em>number</em>. Default is <c><![CDATA[1]]></c>.
+ Use <c><![CDATA[-W0]]></c> to turn off warnings.</p>
+ </item>
+ <tag>-W</tag>
+ <item>
+ <p>Same as <c><![CDATA[-W1]]></c>. Default.</p>
+ </item>
+ <tag>-v</tag>
+ <item>
+ <p>Enables verbose output.</p>
+ </item>
+ <tag>-b <em>output-type</em></tag>
+ <item>
+ <p>Specifies the type of output file.
+ Generally, <em>output-type</em> is the same as the file extension
+ of the output file but without the period.
+ This option will be ignored by compilers that have a
+ a single output format.</p>
+ </item>
+ <tag>-hybrid</tag>
+ <item>
+ <p>Compile using the hybrid-heap emulator. This is mainly useful
+ for compiling native code, which needs to be compiled with the same
+ run-time system that it should be run on.</p>
+ </item>
+ <tag>-smp</tag>
+ <item>
+ <p>Compile using the SMP emulator. This is mainly useful
+ for compiling native code, which needs to be compiled with the same
+ run-time system that it should be run on.</p>
+ </item>
+ <tag>--</tag>
+ <item>
+ <p>Signals that no more options will follow.
+ The rest of the arguments will be treated as file names,
+ even if they start with hyphens.</p>
+ </item>
+ <tag>+<em>term</em></tag>
+ <item>
+ <p>A flag starting with a plus ('<em>+</em>') rather than a hyphen
+ will be converted to an Erlang term and passed unchanged to
+ the compiler.
+ For instance, the <c><![CDATA[export_all]]></c> option for the Erlang
+ compiler can be specified as follows:</p>
+ <pre>
+erlc +export_all file.erl</pre>
+ <p>Depending on the platform, the value may need to be
+ quoted if the shell itself interprets certain characters.
+ On Unix, terms which contain tuples and list
+ must be quoted. Terms which contain spaces
+ must be quoted on all platforms.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Special Flags</title>
+ <p>The flags in this section are useful in special situations
+ such as re-building the OTP system.</p>
+ <taglist>
+ <tag>-pa <em>directory</em></tag>
+ <item>
+ <p>Appends <em>directory</em> to the front of the code path in
+ the invoked Erlang emulator.
+ This can be used to invoke another
+ compiler than the default one.</p>
+ </item>
+ <tag>-pz <em>directory</em></tag>
+ <item>
+ <p>Appends <em>directory</em> to the code path in
+ the invoked Erlang emulator.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Supported Compilers</title>
+ <taglist>
+ <tag>.erl</tag>
+ <item>
+ <p>Erlang source code. It generates a <c><![CDATA[.beam]]></c> file.</p>
+ <p>The options -P, -E, and -S are equivalent to +'P',
+ +'E', and +'S', except that it is not necessary to include the single quotes to protect them
+ from the shell.</p>
+ <p>Supported options: -I, -o, -D, -v, -W, -b.</p>
+ </item>
+ <tag>.yrl</tag>
+ <item>
+ <p>Yecc source code. It generates an <c><![CDATA[.erl]]></c> file.</p>
+ <p>Use the -I option with the name of a file to use that file
+ as a customized prologue file (the <c><![CDATA[includefile]]></c> option).</p>
+ <p>Supported options: -o, -v, -I, -W (see above).</p>
+ </item>
+ <tag>.mib</tag>
+ <item>
+ <p>MIB for SNMP. It generates a <c><![CDATA[.bin]]></c> file.</p>
+ <p>Supported options: -I, -o, -W.</p>
+ </item>
+ <tag>.bin</tag>
+ <item>
+ <p>A compiled MIB for SNMP. It generates a <c><![CDATA[.hrl]]></c> file.</p>
+ <p>Supported options: -o, -v.</p>
+ </item>
+ <tag>.rel</tag>
+ <item>
+ <p>Script file. It generates a boot file.</p>
+ <p>Use the -I to name directories to be searched for application
+ files (equivalent to the <c><![CDATA[path]]></c> in the option list for
+ <c><![CDATA[systools:make_script/2]]></c>).</p>
+ <p>Supported options: -o.</p>
+ </item>
+ <tag>.asn1</tag>
+ <item>
+ <p>ASN1 file.</p>
+ <p>Creates an <c><![CDATA[.erl]]></c>, <c><![CDATA[.hrl]]></c>, and <c><![CDATA[.asn1db]]></c> file from
+ an <c><![CDATA[.asn1]]></c> file. Also compiles the <c><![CDATA[.erl]]></c> using the Erlang
+ compiler unless the <c><![CDATA[+noobj]]></c> options is given.</p>
+ <p>Supported options: -I, -o, -b, -W.</p>
+ </item>
+ <tag>.idl</tag>
+ <item>
+ <p>IC file.</p>
+ <p>Runs the IDL compiler.</p>
+ <p>Supported options: -I, -o.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Environment Variables</title>
+ <taglist>
+ <tag>ERLC_EMULATOR</tag>
+ <item>The command for starting the emulator.
+ Default is <em>erl</em> in the same directory as the <em>erlc</em> program
+ itself, or if it doesn't exist, <em>erl</em> in any of the directories
+ given in the <em>PATH</em> environment variable.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="erl">erl(1)</seealso>,
+ <seealso marker="compiler:compile">compile(3)</seealso>,
+ <seealso marker="parsetools:yecc">yecc(3)</seealso>,
+ <seealso marker="snmp:snmp">snmp(3)</seealso></p>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml
new file mode 100644
index 0000000000..93db56fc7c
--- /dev/null
+++ b/erts/doc/src/erlsrv.xml
@@ -0,0 +1,405 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1998</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erlsrv</title>
+ <prepared>Patrik Nyblom</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>98-04-29</date>
+ <rev></rev>
+ <file>erlsrv.xml</file>
+ </header>
+ <com>erlsrv</com>
+ <comsummary>Run the Erlang emulator as a service on Windows NT&reg;</comsummary>
+ <description>
+ <p>This utility is specific to Windows NT/2000/XP&reg; (and subsequent versions of Windows) It allows Erlang
+ emulators to run as services on the Windows system, allowing embedded
+ systems to start without any user needing to log in. The
+ emulator started in this way can be manipulated through the
+ Windows&reg; services applet in a manner similar to other
+ services.</p>
+ <p>Note that erlsrv is not a general service utility for Windows, but designed for embedded Erlang systems.</p>
+ <p>As well as being the actual service, erlsrv also provides a
+ command line interface for registering, changing, starting and
+ stopping services.</p>
+ <p>To manipulate services, the logged in user should have
+ Administrator privileges on the machine. The Erlang machine
+ itself is (default) run as the local administrator. This can be
+ changed with the Services applet in Windows &reg;.</p>
+ <p>The processes created by the service can, as opposed to normal
+ services, be "killed" with the task manager. Killing a emulator
+ that is started by a service will trigger the "OnFail" action
+ specified for that service, which may be a reboot.</p>
+ <p>The following parameters may be specified for each Erlang
+ service:</p>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[StopAction]]></c>: This tells <c><![CDATA[erlsrv]]></c> how to stop
+ the Erlang emulator. Default is to kill it (Win32
+ TerminateProcess), but this action can specify any Erlang
+ shell command that will be executed in the emulator to make
+ it stop. The emulator is expected to stop within 30 seconds
+ after the command is issued in the shell. If the emulator is
+ not stopped, it will report a running state to the service
+ manager.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[OnFail]]></c>: This can be either of <c><![CDATA[reboot]]></c>,
+ <c><![CDATA[restart]]></c>, <c><![CDATA[restart_always]]></c> or <c><![CDATA[ignore]]></c> (the
+ default). In case of <c><![CDATA[reboot]]></c>, the NT system is
+ rebooted whenever the emulator stops (a more simple form of
+ watchdog), this could be useful for less critical systems,
+ otherwise use the heart functionality to accomplish
+ this. The restart value makes the Erlang emulator be
+ restarted (with whatever parameters are registered for the
+ service at the occasion) when it stops. If the emulator
+ stops again within 10 seconds, it is not restarted to avoid
+ an infinite loop which could completely hang the NT
+ system. <c><![CDATA[restart_always]]></c> is similar to restart, but
+ does not try to detect cyclic restarts, it is expected that
+ some other mechanism is present to avoid the problem. The
+ default (ignore) just reports the service as stopped to the
+ service manager whenever it fails, it has to be manually
+ restarted.</p>
+ <p>On a system where release handling is
+ used, this should always be set to <c><![CDATA[ignore]]></c>. Use
+ <c><![CDATA[heart]]></c> to restart the service on failure instead.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[Machine]]></c>: The location of the Erlang
+ emulator. The default is the <c><![CDATA[erl.exe]]></c> located in the
+ same directory as erlsrv.exe. Do not specify <c><![CDATA[werl.exe]]></c>
+ as this emulator, it will not work.</p>
+ <p>If the system
+ uses release handling, this should be set to a program
+ similar to <c><![CDATA[start_erl.exe]]></c>.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[Env]]></c>: Specifies an <em>additional</em> environment
+ for the emulator. The environment variables specified
+ here are added to the system wide environment block that is
+ normally present when a service starts up. Variables present
+ in both the system wide environment and in the service
+ environment specification will be set to the value specified
+ in the service.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[WorkDir]]></c>: The working directory for the Erlang
+ emulator, has to be on a local drive (there are no network
+ drives mounted when a service starts). Default working
+ directory for services is <c><![CDATA[%SystemDrive%%SystemPath%]]></c>.
+ Debug log files will be placed in this directory.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[Priority]]></c>: The process priority of the emulator,
+ this can be one of <c><![CDATA[realtime]]></c>, <c><![CDATA[high]]></c>, <c><![CDATA[low]]></c>
+ or <c><![CDATA[default]]></c> (the default). Real-time priority is not
+ recommended, the machine will possibly be inaccessible to
+ interactive users. High priority could be used if two Erlang
+ nodes should reside on one dedicated system and one should
+ have precedence over the other. Low process priority may be
+ used if interactive performance should not be affected by
+ the emulator process.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[SName or Name]]></c>: Specifies the short or long
+ node-name of the Erlang emulator. The Erlang services are
+ always distributed, default is to use the service name as
+ (short) node-name.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[DebugType]]></c>: Can be one of <c><![CDATA[none]]></c> (default),
+ <c><![CDATA[new]]></c>, <c><![CDATA[reuse]]></c> or <c><![CDATA[console]]></c>.
+ Specifies that output from the Erlang shell should be
+ sent to a "debug log". The log file is named
+ &lt;servicename&gt;<c><![CDATA[.debug]]></c> or
+ &lt;servicename&gt;<c><![CDATA[.debug.]]></c>&lt;N&gt;, where &lt;N&gt; is
+ an integer between 1 and 99. The log-file is placed in the
+ working directory of the service (as specified in WorkDir). The
+ <c><![CDATA[reuse]]></c> option always reuses the same log file
+ (&lt;servicename&gt;<c><![CDATA[.debug]]></c>) and the <c><![CDATA[new]]></c> option
+ uses a separate log file for every invocation of the service
+ (&lt;servicename&gt;<c><![CDATA[.debug.]]></c>&lt;N&gt;). The <c><![CDATA[console]]></c>
+ option opens an interactive Windows&reg; console window for
+ the Erlang shell of the service. The <c><![CDATA[console]]></c> option
+ automatically
+ disables the <c><![CDATA[StopAction]]></c> and a service started with an
+ interactive console window will not survive logouts,
+ <c><![CDATA[OnFail]]></c> actions do not work with debug-consoles either.
+ If no <c><![CDATA[DebugType]]></c> is specified (<c><![CDATA[none]]></c>), the
+ output of the Erlang shell is discarded.</p>
+ <p>The <c><![CDATA[console]]></c><c><![CDATA[DebugType]]></c> is <em>not in any way</em>
+ intended for production. It is <em>only</em> a convenient way to
+ debug Erlang services during development. The <c><![CDATA[new]]></c> and
+ <c><![CDATA[reuse]]></c> options might seem convenient to have in a
+ production system, but one has to take into account that the
+ logs will grow indefinitely during the systems lifetime and
+ there is no way, short of restarting the service, to
+ truncate those logs. In short, the <c><![CDATA[DebugType]]></c> is
+ intended for debugging only. Logs during production are
+ better produced with the standard Erlang logging
+ facilities.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[Args]]></c>: Additional arguments passed to the
+ emulator startup program <c><![CDATA[erl.exe]]></c> (or
+ <c><![CDATA[start_erl.exe]]></c>). Arguments that cannot be specified
+ here are <c><![CDATA[-noinput]]></c> (StopActions would not work),
+ <c><![CDATA[-name]]></c> and <c><![CDATA[-sname]]></c> (they are specified in any
+ way. The most common use is for specifying cookies and flags
+ to be passed to init:boot() (<c><![CDATA[-s]]></c>).</p>
+ </item>
+ <item>
+ <p><c><![CDATA[InternalServiceName]]></c>: Specifies the Windows&reg; internal service name (not the display name, which is the one <c>erlsrv</c> uses to identify the service).</p>
+ <p>This internal name can not be changed, it is fixed even if the service is renamed. <c>Erlsrv</c> generates a unique internal name when a service is created, it is recommended to keep to the defaut if release-handling is to be used for the application.</p>
+ <p>The internal service name can be seen in the Windows&reg; service manager if viewing <c>Properties</c> for an erlang service.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[Comment]]></c>: A textual comment describing the service. Not mandatory, but shows up as the service description in the Windows&reg; service manager.</p>
+ </item>
+ </list>
+ <p> <marker id="001"></marker>
+ The naming of the service in a system that
+ uses release handling has to follow the convention
+ <em>NodeName</em>_<em>Release</em>, where <em>NodeName</em> is
+ the first part of the Erlang nodename (up to, but not including
+ the "@") and <em>Release</em> is the current release of the
+ application.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>erlsrv {set | add} &lt;service-name> [&lt;service options>]</name>
+ <fsummary>Add or modify an Erlang service</fsummary>
+ <desc>
+ <p>The set and add commands adds or modifies a Erlang service
+ respectively. The simplest form of an add command would be
+ completely without options in which case all default values
+ (described above) apply. The service name is mandatory.</p>
+ <p>Every option can be given without parameters, in which case
+ the default value is applied. Values to the options are
+ supplied <em>only</em> when the default should not be used
+ (i.e. <c><![CDATA[erlsrv set myservice -prio -arg]]></c> sets the
+ default priority and removes all arguments).</p>
+ <p>The following service options are currently available:</p>
+ <taglist>
+ <tag>-st[opaction] [&lt;erlang shell command&gt;]</tag>
+ <item>Defines the StopAction, the command given to the Erlang
+ shell when the service is stopped. Default is none.</item>
+ <tag>-on[fail] [{reboot | restart | restart_always}]</tag>
+ <item>Specifies the action to take when the Erlang emulator
+ stops unexpectedly. Default is to ignore.</item>
+ <tag>-m[achine] [&lt;erl-command&gt;]</tag>
+ <item>The complete path to the Erlang emulator, never use the
+ werl program for this. Default is the <c><![CDATA[erl.exe]]></c> in the
+ same directory as <c><![CDATA[erlsrv.exe]]></c>. When release handling
+ is used, this should be set to a program similar to
+ <c><![CDATA[start_erl.exe]]></c>.</item>
+ <tag>-e[nv] [&lt;variable&gt;[=&lt;value&gt;]] ...</tag>
+ <item>Edits the environment block for the service. Every
+ environment variable specified will add to the system
+ environment block. If a variable specified here has the same
+ name as a system wide environment variable, the specified
+ value overrides the system wide. Environment variables are
+ added to this list by specifying
+ &lt;variable&gt;=&lt;value&gt; and deleted from the list by
+ specifying &lt;variable&gt; alone. The environment block is
+ automatically sorted. Any number of <c><![CDATA[-env]]></c> options can
+ be specified in one command. Default is to use the system
+ environment block unmodified (except for two additions, see
+ <seealso marker="#002">below</seealso>).</item>
+ <tag>-w[orkdir] [&lt;directory&gt;]</tag>
+ <item>The initial working directory of the Erlang
+ emulator. Default is the system directory.</item>
+ <tag>-p[riority] [{low|high|realtime}]</tag>
+ <item>The priority of the Erlang emulator. The default is the
+ Windows&reg; default priority.</item>
+ <tag>{-sn[ame] | -n[ame]} [&lt;node-name&gt;]</tag>
+ <item>The node-name of the Erlang machine, distribution is
+ mandatory. Default is <c><![CDATA[-sname <service name>]]></c>.
+ </item>
+ <tag>-d[ebugtype] [{new|reuse|console}]</tag>
+ <item>Specifies where shell output should be sent,
+ default is that shell output is discarded.
+ To be used only for debugging.</item>
+ <tag>-ar[gs] [&lt;limited erl arguments&gt;]</tag>
+ <item>Additional arguments to the Erlang emulator, avoid
+ <c><![CDATA[-noinput]]></c>, <c><![CDATA[-noshell]]></c> and
+ <c><![CDATA[-sname]]></c>/<c><![CDATA[-name]]></c>. Default is no additional
+ arguments. Remember that the services cookie file is not
+ necessarily the same as the interactive users. The service
+ runs as the local administrator. All arguments should be given
+ together in one string, use double quotes (") to give an
+ argument string containing spaces and use quoted quotes (\\")
+ to give an quote within the argument string if
+ necessary.</item>
+ <tag>-i[nternalservicename] [&lt;internal name&gt;]</tag>
+ <item><em>Only</em> allowed for <c>add</c>. Specifies a
+ Windows&reg; internal service name for the service, which by
+ default is set to something unique (prefixed with the
+ original service name) by erlsrv when adding a new
+ service. Specifying this is a purely cosmethic action and is
+ <em>not</em> recommended if release handling is to be
+ performed. The internal service name cannot be changed once
+ the service is created. The internal name is <em>not</em> to
+ be confused with the ordinary service name, which is the name
+ used to identify a service to erlsrv.</item>
+ <tag>-c[omment] [&lt;short description&gt;]</tag>
+ <item>Specifies a textual comment describing the
+ service. This comment will show upp as the service description
+ in the Windows&reg; service manager.</item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>erlsrv {start | stop | disable | enable} &lt;service-name></name>
+ <fsummary>Manipulate the current service status.</fsummary>
+ <desc>
+ <p>These commands are only added for convenience, the normal
+ way to manipulate the state of a service is through the
+ control panels services applet. The <c><![CDATA[start]]></c> and
+ <c><![CDATA[stop]]></c> commands communicates
+ with the service manager for stopping and starting a
+ service. The commands wait until the service is actually
+ stopped or started. When disabling a service, it is not
+ stopped, the disabled state will not take effect until the
+ service actually is stopped. Enabling a service sets it in
+ automatic mode, that is started at boot. This command cannot
+ set the service to manual. </p>
+ </desc>
+ </func>
+ <func>
+ <name>erlsrv remove &lt;service-name&gt;</name>
+ <fsummary>Remove the service.</fsummary>
+ <desc>
+ <p>This command removes the service completely with all its registered
+ options. It will be stopped before it is removed.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlsrv list [&lt;service-name&gt;]</name>
+ <fsummary>List all Erlang services or all options for one service.</fsummary>
+ <desc>
+ <p>If no service name is supplied, a brief listing of all Erlang services
+ is presented. If a service-name is supplied, all options for that
+ service are presented.</p>
+ </desc>
+ </func>
+ <func>
+ <name>erlsrv help</name>
+ <fsummary>Display a brief help text</fsummary>
+ </func>
+ </funcs>
+
+ <section>
+ <title>ENVIRONMENT</title>
+ <p> <marker id="002"></marker>
+The environment of an Erlang machine started
+ as a service will contain two special variables,
+ <c><![CDATA[ERLSRV_SERVICE_NAME]]></c>, which is the name of the service that
+ started the machine and <c><![CDATA[ERLSRV_EXECUTABLE]]></c> which is the
+ full path to the <c><![CDATA[erlsrv.exe]]></c> that can be used to manipulate
+ the service. This will come in handy when defining a heart command for
+ your service. A command file for restarting a service will
+ simply look like this:</p>
+ <code type="none"><![CDATA[
+@echo off
+%ERLSRV_EXECUTABLE% stop %ERLSRV_SERVICE_NAME%
+%ERLSRV_EXECUTABLE% start %ERLSRV_SERVICE_NAME% ]]></code>
+ <p>This command file is then set as heart command.</p>
+ <p>The environment variables can also be used to detect that we
+ are running as a service and make port programs react correctly
+ to the control events generated on logout (see below).</p>
+ </section>
+
+ <section>
+ <title>PORT PROGRAMS</title>
+ <p>When a program runs in
+ the service context, it has to handle the control events that is
+ sent to every program in the system when the interactive user
+ logs off. This is done in different ways for programs running in
+ the console subsystem and programs running as window
+ applications. An application which runs in the console subsystem
+ (normal for port programs) uses the win32 function
+ <c><![CDATA[SetConsoleCtrlHandler]]></c> to a control handler that returns
+ TRUE in answer to the <c><![CDATA[CTRL_LOGOFF_EVENT]]></c>. Other
+ applications just forward <c><![CDATA[WM_ENDSESSION]]></c> and
+ <c><![CDATA[WM_QUERYENDSESSION]]></c> to the default window procedure. Here
+ is a brief example in C of how to set the console control
+ handler:</p>
+ <code type="none"><![CDATA[
+#include <windows.h>
+/*
+** A Console control handler that ignores the log off events,
+** and lets the default handler take care of other events.
+*/
+BOOL WINAPI service_aware_handler(DWORD ctrl){
+ if(ctrl == CTRL_LOGOFF_EVENT)
+\011return TRUE;
+ return FALSE;
+}
+
+void initialize_handler(void){
+ char buffer[2];
+ /*
+ * We assume we are running as a service if this
+ * environment variable is defined
+ */
+ if(GetEnvironmentVariable("ERLSRV_SERVICE_NAME",buffer,
+ (DWORD) 2)){
+\011/*
+\011** Actually set the control handler
+\011*/
+\011SetConsoleCtrlHandler(&service_aware_handler, TRUE);
+ }
+} ]]></code>
+ </section>
+
+ <section>
+ <title>NOTES</title>
+ <p>Even though the options are described in a Unix-like format, the case of
+ the options or commands is not relevant, and the "/" character for options
+ can be used as well as the "-" character. </p>
+ <p>Note that the program resides in the emulators
+ <c><![CDATA[bin]]></c>-directory, not in the <c><![CDATA[bin]]></c>-directory directly under
+ the Erlang root. The reasons for this are the subtle problem of
+ upgrading the emulator on a running system, where a new version of
+ the runtime system should not need to overwrite existing (and probably
+ used) executables.</p>
+ <p>To easily manipulate the Erlang services, put
+ the <c><![CDATA[<erlang_root>\\erts-<version>\\bin]]></c> directory in
+ the path instead of <c><![CDATA[<erlang_root>\\bin]]></c>. The erlsrv program
+ can be found from inside Erlang by using the
+ <c><![CDATA[os:find_executable/1]]></c> Erlang function.</p>
+ <p>For release handling to work, use <c><![CDATA[start_erl]]></c> as the Erlang
+ machine. It is also worth mentioning again that the name of the
+ service is significant (see <seealso marker="#001">above</seealso>).</p>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p>start_erl(1), release_handler(3)</p>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
new file mode 100644
index 0000000000..d51e5b3ea4
--- /dev/null
+++ b/erts/doc/src/erts_alloc.xml
@@ -0,0 +1,554 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE cref SYSTEM "cref.dtd">
+
+<cref>
+ <header>
+ <copyright>
+ <year>2002</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>erts_alloc</title>
+ <prepared>Rickard Green</prepared>
+ <docno>1</docno>
+ <date>03-06-11</date>
+ <rev>1</rev>
+ <file>erts_alloc.xml</file>
+ </header>
+ <lib>erts_alloc</lib>
+ <libsummary>An Erlang Run-Time System internal memory allocator library.</libsummary>
+ <description>
+ <p><c>erts_alloc</c> is an Erlang Run-Time System internal memory
+ allocator library. <c>erts_alloc</c> provides the Erlang
+ Run-Time System with a number of memory allocators.</p>
+ </description>
+
+ <section>
+ <title>Allocators</title>
+ <marker id="allocators"></marker>
+ <p>Currently the following allocators are present:</p>
+ <taglist>
+ <tag><c>temp_alloc</c></tag>
+ <item>Allocator used for temporary allocations.</item>
+ <tag><c>eheap_alloc</c></tag>
+ <item>Allocator used for Erlang heap data, such as Erlang process heaps.</item>
+ <tag><c>binary_alloc</c></tag>
+ <item>Allocator used for Erlang binary data.</item>
+ <tag><c>ets_alloc</c></tag>
+ <item>Allocator used for ETS data.</item>
+ <tag><c>driver_alloc</c></tag>
+ <item>Allocator used for driver data.</item>
+ <tag><c>sl_alloc</c></tag>
+ <item>Allocator used for memory blocks that are expected to be
+ short-lived.</item>
+ <tag><c>ll_alloc</c></tag>
+ <item>Allocator used for memory blocks that are expected to be
+ long-lived, for example Erlang code.</item>
+ <tag><c>fix_alloc</c></tag>
+ <item>A very fast allocator used for some fix-sized
+ data. <c>fix_alloc</c> manages a set of memory pools from
+ which memory blocks are handed out. <c>fix_alloc</c>
+ allocates memory pools from <c>ll_alloc</c>. Memory pools
+ that have been allocated are never deallocated.</item>
+ <tag><c>std_alloc</c></tag>
+ <item>Allocator used for most memory blocks not allocated via any of
+ the other allocators described above.</item>
+ <tag><c>sys_alloc</c></tag>
+ <item>This is normally the default <c>malloc</c> implementation
+ used on the specific OS.</item>
+ <tag><c>mseg_alloc</c></tag>
+ <item>A memory segment allocator. <c>mseg_alloc</c> is used by other
+ allocators for allocating memory segments and is currently only
+ available on systems that have the <c>mmap</c> system
+ call. Memory segments that are deallocated are kept for a
+ while in a segment cache before they are destroyed. When
+ segments are allocated, cached segments are used if possible
+ instead of creating new segments. This in order to reduce
+ the number of system calls made.</item>
+ </taglist>
+ <p><c>sys_alloc</c> and <c>fix_alloc</c> are always enabled and
+ cannot be disabled. <c>mseg_alloc</c> is always enabled if it is
+ available and an allocator that uses it is enabled. All other
+ allocators can be <seealso marker="#M_e">enabled or disabled</seealso>.
+ By default all allocators are enabled.
+ When an allocator is disabled, <c>sys_alloc</c>
+ is used instead of the disabled allocator.</p>
+ <p>The main idea with the <c>erts_alloc</c> library is to separate
+ memory blocks that are used differently into different memory
+ areas, and by this achieving less memory fragmentation. By
+ putting less effort in finding a good fit for memory blocks that
+ are frequently allocated than for those less frequently
+ allocated, a performance gain can be achieved.</p>
+ </section>
+
+ <section>
+ <marker id="alloc_util"></marker>
+ <title>The alloc_util framework</title>
+ <p>Internally a framework called <c>alloc_util</c> is used for
+ implementing allocators. <c>sys_alloc</c>, <c>fix_alloc</c>, and
+ <c>mseg_alloc</c> do not use this framework; hence, the
+ following does <em>not</em> apply to them.</p>
+ <p>An allocator manages multiple areas, called carriers, in which
+ memory blocks are placed. A carrier is either placed in a
+ separate memory segment (allocated via <c>mseg_alloc</c>) or in
+ the heap segment (allocated via <c>sys_alloc</c>). Multiblock
+ carriers are used for storage of several blocks. Singleblock
+ carriers are used for storage of one block. Blocks that are
+ larger than the value of the singleblock carrier threshold
+ (<seealso marker="#M_sbct">sbct</seealso>) parameter are placed
+ in singleblock carriers. Blocks smaller than the value of the
+ <c>sbct</c> parameter are placed in multiblock
+ carriers. Normally an allocator creates a "main multiblock
+ carrier". Main multiblock carriers are never deallocated. The
+ size of the main multiblock carrier is determined by the value
+ of the <seealso marker="#M_mmbcs">mmbcs</seealso> parameter.</p>
+ <p> <marker id="mseg_mbc_sizes"></marker>
+
+ Sizes of multiblock carriers allocated via <c>mseg_alloc</c> are
+ decided based on the values of the largest multiblock carrier
+ size (<seealso marker="#M_lmbcs">lmbcs</seealso>), the smallest
+ multiblock carrier size (<seealso marker="#M_smbcs">smbcs</seealso>),
+ and the multiblock carrier growth stages
+ (<seealso marker="#M_smbcs">mbcgs</seealso>) parameters. If
+ <c>nc</c> is the current number of multiblock carriers (the main
+ multiblock carrier excluded) managed by an allocator, the size
+ of the next <c>mseg_alloc</c> multiblock carrier allocated by
+ this allocator will roughly be
+ <c><![CDATA[smbcs+nc*(lmbcs-smbcs)/mbcgs]]></c> when
+ <c><![CDATA[nc <= mbcgs]]></c>,
+ and <c>lmbcs</c> when <c><![CDATA[nc > mbcgs]]></c>. If the value of the
+ <c>sbct</c> parameter should be larger than the value of the
+ <c>lmbcs</c> parameter, the allocator may have to create
+ multiblock carriers that are larger than the value of the
+ <c>lmbcs</c> parameter, though. Singleblock carriers allocated
+ via <c>mseg_alloc</c> are sized to whole pages.</p>
+ <p>Sizes of carriers allocated via <c>sys_alloc</c> are
+ decided based on the value of the <c>sys_alloc</c> carrier size
+ (<seealso marker="#Muycs">ycs</seealso>) parameter. The size of
+ a carrier is the least number of multiples of the value of the
+ <c>ycs</c> parameter that satisfies the request.</p>
+ <p>Coalescing of free blocks are always performed immediately.
+ Boundary tags (headers and footers) in free blocks are used
+ which makes the time complexity for coalescing constant.</p>
+ <p> <marker id="strategy"></marker>
+
+ The memory allocation strategy used for multiblock carriers by an
+ allocator is configurable via the <seealso marker="#M_as">as</seealso>
+ parameter. Currently the following strategies are available:</p>
+ <taglist>
+ <tag>Best fit</tag>
+ <item>
+ <p>Strategy: Find the smallest block that satisfies the
+ requested block size.</p>
+ <p>Implementation: A balanced binary search tree is
+ used. The time complexity is proportional to log N, where
+ N is the number of sizes of free blocks.</p>
+ </item>
+ <tag>Address order best fit</tag>
+ <item>
+ <p>Strategy: Find the smallest block that satisfies the
+ requested block size. If multiple blocks are found, choose
+ the one with the lowest address.</p>
+ <p>Implementation: A balanced binary search tree is
+ used. The time complexity is proportional to log N, where
+ N is the number of free blocks.</p>
+ </item>
+ <tag>Good fit</tag>
+ <item>
+ <p>Strategy: Try to find the best fit, but settle for the best fit
+ found during a limited search.</p>
+ <p>Implementation: The implementation uses segregated free
+ lists with a maximum block search depth (in each list) in
+ order to find a good fit fast. When the maximum block
+ search depth is small (by default 3) this implementation
+ has a time complexity that is constant. The maximum block
+ search depth is configurable via the
+ <seealso marker="#M_mbsd">mbsd</seealso> parameter.</p>
+ </item>
+ <tag>A fit</tag>
+ <item>
+ <p>Strategy: Do not search for a fit, inspect only one free
+ block to see if it satisfies the request. This strategy is
+ only intended to be used for temporary allocations.</p>
+ <p>Implementation: Inspect the first block in a free-list.
+ If it satisfies the request, it is used; otherwise, a new
+ carrier is created. The implementation has a time
+ complexity that is constant.</p>
+ <p>As of erts version 5.6.1 the emulator will refuse to
+ use this strategy on other allocators than <c>temp_alloc</c>.
+ This since it will only cause problems for other allocators.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="flags"></marker>
+ <title>System Flags Effecting erts_alloc</title>
+ <warning>
+ <p>Only use these flags if you are absolutely sure what you are
+ doing. Unsuitable settings may cause serious performance
+ degradation and even a system crash at any time during
+ operation.</p>
+ </warning>
+ <p>Memory allocator system flags have the following syntax:
+ <c><![CDATA[+M<S><P> <V>]]></c>
+ where <c><![CDATA[<S>]]></c> is a letter identifying a subsystem,
+ <c><![CDATA[<P>]]></c> is a parameter, and <c><![CDATA[<V>]]></c> is the
+ value to use. The flags can be passed to the Erlang emulator
+ (<seealso marker="erl">erl</seealso>) as command line
+ arguments.</p>
+ <p>System flags effecting specific allocators have an upper-case
+ letter as <c><![CDATA[<S>]]></c>. The following letters are used for
+ the currently present allocators:</p>
+ <list type="bulleted">
+ <item><c>B: binary_alloc</c></item>
+ <item><c>D: std_alloc</c></item>
+ <item><c>E: ets_alloc</c></item>
+ <item><c>F: fix_alloc</c></item>
+ <item><c>H: eheap_alloc</c></item>
+ <item><c>L: ll_alloc</c></item>
+ <item><c>M: mseg_alloc</c></item>
+ <item><c>R: driver_alloc</c></item>
+ <item><c>S: sl_alloc</c></item>
+ <item><c>T: temp_alloc</c></item>
+ <item><c>Y: sys_alloc</c></item>
+ </list>
+ <p>The following flags are available for configuration of
+ <c>mseg_alloc</c>:</p>
+ <taglist>
+ <tag><c><![CDATA[+MMamcbf <size>]]></c></tag>
+ <item> <marker id="MMamcbf"></marker>
+
+ Absolute max cache bad fit (in kilobytes). A segment in the
+ memory segment cache is not reused if its size exceeds the
+ requested size with more than the value of this
+ parameter. Default value is 4096. </item>
+ <tag><c><![CDATA[+MMrmcbf <ratio>]]></c></tag>
+ <item> <marker id="MMrmcbf"></marker>
+
+ Relative max cache bad fit (in percent). A segment in the
+ memory segment cache is not reused if its size exceeds the
+ requested size with more than relative max cache bad fit
+ percent of the requested size. Default value is 20.</item>
+ <tag><c><![CDATA[+MMmcs <amount>]]></c></tag>
+ <item> <marker id="MMmcs"></marker>
+
+ Max cached segments. The maximum number of memory segments
+ stored in the memory segment cache. Valid range is
+ 0-30. Default value is 5.</item>
+ <tag><c><![CDATA[+MMcci <time>]]></c></tag>
+ <item> <marker id="MMcci"></marker>
+
+ Cache check interval (in milliseconds). The memory segment
+ cache is checked for segments to destroy at an interval
+ determined by this parameter. Default value is 1000.</item>
+ </taglist>
+ <p>The following flags are available for configuration of
+ <c>fix_alloc</c>:</p>
+ <taglist>
+ <tag><c>+MFe true</c></tag>
+ <item> <marker id="MFe"></marker>
+
+ Enable <c>fix_alloc</c>. Note: <c>fix_alloc</c> cannot be disabled.</item>
+ </taglist>
+ <p>The following flags are available for configuration of
+ <c>sys_alloc</c>:</p>
+ <taglist>
+ <tag><c>+MYe true</c></tag>
+ <item> <marker id="MYe"></marker>
+
+ Enable <c>sys_alloc</c>. Note: <c>sys_alloc</c> cannot be disabled.</item>
+ <tag><c>+MYm libc</c></tag>
+ <item> <marker id="MYm"></marker>
+<c>malloc</c> library to use. Currently only
+ <c>libc</c> is available. <c>libc</c> enables the standard
+ <c>libc</c> malloc implementation. By default <c>libc</c> is used.</item>
+ <tag><c><![CDATA[+MYtt <size>]]></c></tag>
+ <item> <marker id="MYtt"></marker>
+
+ Trim threshold size (in kilobytes). This is the maximum amount
+ of free memory at the top of the heap (allocated by
+ <c>sbrk</c>) that will be kept by <c>malloc</c> (not
+ released to the operating system). When the amount of free
+ memory at the top of the heap exceeds the trim threshold,
+ <c>malloc</c> will release it (by calling
+ <c>sbrk</c>). Trim threshold is given in kilobytes. Default
+ trim threshold is 128. <em>Note:</em> This flag will
+ only have any effect when the emulator has been linked with
+ the GNU C library, and uses its <c>malloc</c> implementation.</item>
+ <tag><c><![CDATA[+MYtp <size>]]></c></tag>
+ <item> <marker id="MYtp"></marker>
+
+ Top pad size (in kilobytes). This is the amount of extra
+ memory that will be allocated by <c>malloc</c> when
+ <c>sbrk</c> is called to get more memory from the operating
+ system. Default top pad size is 0. <em>Note:</em> This flag
+ will only have any effect when the emulator has been linked
+ with the GNU C library, and uses its <c>malloc</c>
+ implementation.</item>
+ </taglist>
+ <p>The following flags are available for configuration of allocators
+ based on <c>alloc_util</c>. If <c>u</c> is used as subsystem
+ identifier (i.e., <c><![CDATA[<S> = u]]></c>) all allocators based on
+ <c>alloc_util</c> will be effected. If <c>B</c>, <c>D</c>, <c>E</c>,
+ <c>H</c>, <c>L</c>, <c>R</c>, <c>S</c>, or <c>T</c> is used as
+ subsystem identifier, only the specific allocator identified will be
+ effected:</p>
+ <taglist>
+ <tag><c><![CDATA[+M<S>as bf|aobf|gf|af]]></c></tag>
+ <item> <marker id="M_as"></marker>
+
+ Allocation strategy. Valid strategies are <c>bf</c> (best fit),
+ <c>aobf</c> (address order best fit), <c>gf</c> (good fit),
+ and <c>af</c> (a fit). See
+ <seealso marker="#strategy">the description of allocation strategies</seealso> in "the <c>alloc_util</c> framework" section.</item>
+ <tag><c><![CDATA[+M<S>asbcst <size>]]></c></tag>
+ <item> <marker id="M_asbcst"></marker>
+
+ Absolute singleblock carrier shrink threshold (in
+ kilobytes). When a block located in an
+ <c>mseg_alloc</c> singleblock carrier is shrunk, the carrier
+ will be left unchanged if the amount of unused memory is less
+ than this threshold; otherwise, the carrier will be shrunk.
+ See also <seealso marker="#M_rsbcst">rsbcst</seealso>.</item>
+ <tag><c><![CDATA[+M<S>e true|false]]></c></tag>
+ <item> <marker id="M_e"></marker>
+
+ Enable allocator <c><![CDATA[<S>]]></c>.</item>
+ <tag><c><![CDATA[+M<S>lmbcs <size>]]></c></tag>
+ <item> <marker id="M_lmbcs"></marker>
+
+ Largest (<c>mseg_alloc</c>) multiblock carrier size (in
+ kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
+ on how sizes for mseg_alloc multiblock carriers are decided</seealso>
+ in "the <c>alloc_util</c> framework" section.</item>
+ <tag><c><![CDATA[+M<S>mbcgs <ratio>]]></c></tag>
+ <item> <marker id="M_mbcgs"></marker>
+
+ (<c>mseg_alloc</c>) multiblock carrier growth stages. See
+ <seealso marker="#mseg_mbc_sizes">the description on how sizes for
+ mseg_alloc multiblock carriers are decided</seealso>
+ in "the <c>alloc_util</c> framework" section.</item>
+ <tag><c><![CDATA[+M<S>mbsd <depth>]]></c></tag>
+ <item> <marker id="M_mbsd"></marker>
+
+ Max block search depth. This flag has effect only if the
+ good fit strategy has been selected for allocator
+ <c><![CDATA[<S>]]></c>. When the good fit strategy is used, free
+ blocks are placed in segregated free-lists. Each free list
+ contains blocks of sizes in a specific range. The max block
+ search depth sets a limit on the maximum number of blocks to
+ inspect in a free list during a search for suitable block
+ satisfying the request.</item>
+ <tag><c><![CDATA[+M<S>mmbcs <size>]]></c></tag>
+ <item> <marker id="M_mmbcs"></marker>
+
+ Main multiblock carrier size. Sets the size of the main
+ multiblock carrier for allocator <c><![CDATA[<S>]]></c>. The main
+ multiblock carrier is allocated via <c><![CDATA[sys_alloc]]></c> and is
+ never deallocated.</item>
+ <tag><c><![CDATA[+M<S>mmmbc <amount>]]></c></tag>
+ <item> <marker id="M_mmmbc"></marker>
+
+ Max <c>mseg_alloc</c> multiblock carriers. Maximum number of
+ multiblock carriers allocated via <c>mseg_alloc</c> by
+ allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
+ new multiblock carriers will be allocated via
+ <c>sys_alloc</c>.</item>
+ <tag><c><![CDATA[+M<S>mmsbc <amount>]]></c></tag>
+ <item> <marker id="M_mmsbc"></marker>
+
+ Max <c>mseg_alloc</c> singleblock carriers. Maximum number of
+ singleblock carriers allocated via <c>mseg_alloc</c> by
+ allocator <c><![CDATA[<S>]]></c>. When this limit has been reached,
+ new singleblock carriers will be allocated via
+ <c>sys_alloc</c>.</item>
+ <tag><c><![CDATA[+M<S>ramv <bool>]]></c></tag>
+ <item> <marker id="M_ramv"></marker>
+
+ Realloc always moves. When enabled, reallocate operations will
+ more or less be translated into an allocate, copy, free sequence.
+ This often reduce memory fragmentation, but costs performance.
+ </item>
+ <tag><c><![CDATA[+M<S>rmbcmt <ratio>]]></c></tag>
+ <item> <marker id="M_rmbcmt"></marker>
+
+ Relative multiblock carrier move threshold (in percent). When
+ a block located in a multiblock carrier is shrunk,
+ the block will be moved if the ratio of the size of the returned
+ memory compared to the previous size is more than this threshold;
+ otherwise, the block will be shrunk at current location.</item>
+ <tag><c><![CDATA[+M<S>rsbcmt <ratio>]]></c></tag>
+ <item> <marker id="M_rsbcmt"></marker>
+
+ Relative singleblock carrier move threshold (in percent). When
+ a block located in a singleblock carrier is shrunk to
+ a size smaller than the value of the
+ <seealso marker="#M_sbct">sbct</seealso> parameter,
+ the block will be left unchanged in the singleblock carrier if
+ the ratio of unused memory is less than this threshold;
+ otherwise, it will be moved into a multiblock carrier. </item>
+ <tag><c><![CDATA[+M<S>rsbcst <ratio>]]></c></tag>
+ <item> <marker id="M_rsbcst"></marker>
+
+ Relative singleblock carrier shrink threshold (in
+ percent). When a block located in an <c>mseg_alloc</c>
+ singleblock carrier is shrunk, the carrier will be left
+ unchanged if the ratio of unused memory is less than this
+ threshold; otherwise, the carrier will be shrunk.
+ See also <seealso marker="#M_asbcst">asbcst</seealso>.</item>
+ <tag><c><![CDATA[+M<S>sbct <size>]]></c></tag>
+ <item> <marker id="M_sbct"></marker>
+
+ Singleblock carrier threshold. Blocks larger than this
+ threshold will be placed in singleblock carriers. Blocks
+ smaller than this threshold will be placed in multiblock
+ carriers.</item>
+ <tag><c><![CDATA[+M<S>smbcs <size>]]></c></tag>
+ <item> <marker id="M_smbcs"></marker>
+
+ Smallest (<c>mseg_alloc</c>) multiblock carrier size (in
+ kilobytes). See <seealso marker="#mseg_mbc_sizes">the description
+ on how sizes for mseg_alloc multiblock carriers are decided</seealso>
+ in "the <c>alloc_util</c> framework" section.</item>
+ <tag><c><![CDATA[+M<S>t true|false|<amount>]]></c></tag>
+ <item> <marker id="M_t"></marker>
+
+ Multiple, thread specific instances of the allocator.
+ This option will only have any effect on the runtime system
+ with SMP support. Default behaviour on the runtime system with
+ SMP support (<c>N</c> equals the number of scheduler threads):
+ <taglist>
+ <tag><c>temp_alloc</c></tag>
+ <item><c>N + 1</c> instances.</item>
+ <tag><c>ll_alloc</c></tag>
+ <item><c>1</c> instance.</item>
+ <tag>Other allocators</tag>
+ <item><c>N</c> instances when <c>N</c> is less than or equal to
+ <c>16</c>. <c>16</c> instances when <c>N</c> is greater than
+ <c>16</c>.</item>
+ </taglist>
+ <c>temp_alloc</c> will always use <c>N + 1</c> instances when
+ this option has been enabled regardless of the amount passed.
+ Other allocators will use the same amount of instances as the
+ amount passed as long as it isn't greater than <c>N</c>.
+ </item>
+ </taglist>
+ <p>Currently the following flags are available for configuration of
+ <c>alloc_util</c>, i.e. all allocators based on <c>alloc_util</c>
+ will be effected:</p>
+ <taglist>
+ <tag><c><![CDATA[+Muycs <size>]]></c></tag>
+ <item> <marker id="Muycs"></marker>
+<c>sys_alloc</c> carrier size. Carriers allocated via
+ <c>sys_alloc</c> will be allocated in sizes which are
+ multiples of the <c>sys_alloc</c> carrier size. This is not
+ true for main multiblock carriers and carriers allocated
+ during a memory shortage, though.</item>
+ <tag><c><![CDATA[+Mummc <amount>]]></c></tag>
+ <item> <marker id="Mummc"></marker>
+
+ Max <c>mseg_alloc</c> carriers. Maximum number of carriers
+ placed in separate memory segments. When this limit has been
+ reached, new carriers will be placed in memory retrieved from
+ <c>sys_alloc</c>.</item>
+ </taglist>
+ <p>Instrumentation flags:</p>
+ <taglist>
+ <tag><c>+Mim true|false</c></tag>
+ <item> <marker id="Mim"></marker>
+
+ A map over current allocations is kept by the emulator. The
+ allocation map can be retrieved via the <c>instrument</c>
+ module. <c>+Mim true</c> implies <c>+Mis true</c>.
+ <c>+Mim true</c> is the same as
+ <seealso marker="erl#instr">-instr</seealso>.</item>
+ <tag><c>+Mis true|false</c></tag>
+ <item> <marker id="Mis"></marker>
+
+ Status over allocated memory is kept by the emulator. The
+ allocation status can be retrieved via the <c>instrument</c>
+ module.</item>
+ <tag><c>+Mit X</c></tag>
+ <item> <marker id="Mit"></marker>
+
+ Reserved for future use. Do <em>not</em> use this flag.</item>
+ </taglist>
+ <note>
+ <p>When instrumentation of the emulator is enabled, the emulator
+ uses more memory and runs slower.</p>
+ </note>
+ <p>Other flags:</p>
+ <taglist>
+ <tag><c>+Mea min|max|r9c|r10b|r11b|config</c></tag>
+ <item> <marker id="Mea"></marker>
+ <taglist>
+ <tag><c>min</c></tag>
+ <item>
+ Disables all allocators that can be disabled.
+ </item>
+
+ <tag><c>max</c></tag>
+ <item>
+ Enables all allocators (currently default).
+ </item>
+
+ <tag><c>r9c|r10b|r11b</c></tag>
+ <item>
+ Configures all allocators as they were configured in respective
+ OTP release. These will eventually be removed.
+ </item>
+
+ <tag><c>config</c></tag>
+ <item>
+ Disables features that cannot be enabled while creating an
+ allocator configuration with
+ <seealso marker="runtime_tools:erts_alloc_config">erts_alloc_config(3)</seealso>.
+ Note, this option should only be used while running
+ <c>erts_alloc_config</c>, <em>not</em> when using the created
+ configuration.
+ </item>
+ </taglist>
+ </item>
+ </taglist>
+ <p>Only some default values have been presented
+ here.
+ <seealso marker="erts:erlang#system_info_allocator">erlang:system_info(allocator)</seealso>,
+ and
+ <seealso marker="erts:erlang#system_info_allocator_tuple">erlang:system_info({allocator, Alloc})</seealso>
+ can be used in order to obtain currently used settings and current
+ status of the allocators.</p>
+ <note>
+ <p>Most of these flags are highly implementation dependent, and they
+ may be changed or removed without prior notice.</p>
+ <p><c>erts_alloc</c> is not obliged to strictly use the settings that
+ have been passed to it (it may even ignore them).</p>
+ </note>
+ <p><seealso marker="runtime_tools:erts_alloc_config">erts_alloc_config(3)</seealso>
+ is a tool that can be used to aid creation of an
+ <c>erts_alloc</c> configuration that is suitable for a limited
+ number of runtime scenarios.</p>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="runtime_tools:erts_alloc_config">erts_alloc_config(3)</seealso>,
+ <seealso marker="erl">erl(1)</seealso>,
+ <seealso marker="tools:instrument">instrument(3)</seealso>,
+ <seealso marker="erts:erlang">erlang(3)</seealso></p>
+ </section>
+</cref>
+
diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml
new file mode 100644
index 0000000000..8df179b3e2
--- /dev/null
+++ b/erts/doc/src/escript.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>2007</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>escript</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>escript.xml</file>
+ </header>
+ <com>escript</com>
+ <comsummary>Erlang scripting support</comsummary>
+ <description>
+ <p><c><![CDATA[escript]]></c> provides support for running short Erlang programs
+ without having to compile them first and an easy way to retrieve the
+ command line arguments.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>script-name script-arg1 script-arg2...</name>
+ <name>escript escript-flags script-name script-arg1 script-arg2...</name>
+ <fsummary>Run a script written in Erlang</fsummary>
+ <desc>
+ <p><c><![CDATA[escript]]></c> runs a script written in Erlang.</p>
+ <p>Here follows an example.</p>
+ <pre>
+$ <input>cat factorial</input>
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -smp enable -sname factorial -mnesia debug verbose
+main([String]) ->
+ try
+\011N = list_to_integer(String),
+\011F = fac(N),
+\011io:format("factorial ~w = ~w\
+", [N,F])
+ catch
+\011_:_ ->
+\011 usage()
+ end;
+main(_) ->
+ usage().
+
+usage() ->
+ io:format("usage: factorial integer\
+"),
+ halt(1).
+
+fac(0) -> 1;
+fac(N) -> N * fac(N-1).
+$ <input>factorial 5</input>
+factorial 5 = 120
+$ <input>factorial</input>
+usage: factorial integer
+$ <input>factorial five</input>
+usage: factorial integer </pre>
+ <p>The header of the Erlang script in the example differs from
+ a normal Erlang module. The first line is intended to be the
+ interpreter line, which invokes
+ <c><![CDATA[escript]]></c>. However if you invoke the
+ <c><![CDATA[escript]]></c> like this</p>
+ <pre>
+$ <input>escript factorial 5</input> </pre>
+ <p>the contents of the first line does not matter, but it
+ cannot contain Erlang code as it will be ignored.</p>
+ <p>The second line in the example, contains an optional
+ directive to the <c>Emacs</c> editor which causes it to
+ enter the major mode for editing Erlang source files. If the
+ directive is present it must be located on the second
+ line.</p>
+ <p>On the third line (or second line depending on the presence
+ of the Emacs directive), it is possible to give arguments to
+ the emulator, such as </p>
+ <pre>
+%%! -smp enable -sname factorial -mnesia debug verbose</pre>
+ <p>Such an argument line must start with <c>%%!</c> and the
+ rest of the line will interpreted as arguments to the emulator.</p>
+ <p>If you know the location of the <c><![CDATA[escript]]></c> executable, the first
+ line can directly give the path to <c><![CDATA[escript]]></c>. For instance:</p>
+ <pre>
+#!/usr/local/bin/escript </pre>
+ <p>As any other kind of scripts, Erlang scripts will not work on
+ Unix platforms if the execution bit for the script file is not set.
+ (Use <c><![CDATA[chmod +x script-name]]></c> to turn on the execution bit.)
+ </p>
+
+ <p>The rest of the Erlang script file may either contain
+ Erlang <c>source code</c>, an <c>inlined beam file</c> or an
+ <c>inlined archive file</c>.</p>
+
+ <p>An Erlang script file must always contain the function
+ <em>main/1</em>. When the script is run, the
+ <c><![CDATA[main/1]]></c> function will be called with a list
+ of strings representing the arguments given to the script (not
+ changed or interpreted in any way).</p>
+
+ <p>If the <c><![CDATA[main/1]]></c> function in the script returns successfully,
+ the exit status for the script will be 0. If an exception is generated
+ during execution, a short message will be printed and the script terminated
+ with exit status 127.</p>
+
+ <p>To return your own non-zero exit code, call <c><![CDATA[halt(ExitCode)]]></c>;
+ for instance:</p>
+ <pre>
+halt(1).</pre>
+
+ <p>Call <c><![CDATA[escript:script_name/0]]></c> from your to
+ script to retrieve the pathname of the script (the pathname
+ is usually, but not always, absolute).</p>
+
+ <p>If the file contains source code (as in the example above),
+ it will be processed by the preprocessor <c>epp</c>. This
+ means that you for example may use pre-defined macros (such as
+ <c><![CDATA[?MODULE]]></c>) as well as include directives like
+ the <c><![CDATA[-include_lib]]></c> directive. For instance, use</p>
+ <pre>
+-include_lib("kernel/include/file.hrl"). </pre>
+ <p>to include the record definitions for the records used by the
+ <c><![CDATA[file:read_link_info/1]]></c> function.</p>
+
+ <p>The script will be checked for syntactic and semantic
+ correctness before being run. If there are warnings (such as
+ unused variables), they will be printed and the script will
+ still be run. If there are errors, they will be printed and
+ the script will not be run and its exit status will be
+ 127.</p>
+
+ <p>Both the module declaration and the export declaration of
+ the <c><![CDATA[main/1]]></c> function are optional.</p>
+
+ <p>By default, the script will be interpreted. You can force
+ it to be compiled by including the following line somewhere
+ in the script file:</p><pre>
+-mode(compile).</pre>
+
+ <p>Execution of interpreted code is slower than compiled code.
+ If much of the execution takes place in interpreted code it
+ may be worthwhile to compile it, even though the compilation
+ itself will take a little while.</p>
+
+ <p>As mentioned earlier, it is possible to have a script which
+ contains precompiled <c>beam</c> code. In a precompiled
+ script, the interpretation of the script header is exactly
+ the same as in a script containing source code. That means
+ that you can make a <c>beam</c> file executable by
+ prepending the file with the lines starting with <c>#!</c>
+ and <c>%%!</c> mentioned above. In a precompiled script, the
+ function
+ <c>main/1</c> must be exported.</p>
+
+ <p>As yet another option it is possible to have an entire
+ Erlang archive in the script. In a archive script, the
+ interpretation of the script header is exactly the same as
+ in a script containing source code. That means that you can
+ make an archive file executable by prepending the file with
+ the lines starting with <c>#!</c> and <c>%%!</c> mentioned
+ above. In an archive script, the function <c>main/1</c> must
+ be exported. By default the <c>main/1</c> function in the
+ module with the same name as the basename of the
+ <c>escript</c> file will be invoked. This behavior can be
+ overridden by setting the flag <c>-escript main Module</c>
+ as one of the emulator flags. The <c>Module</c> must be the
+ name of a module which has an exported <c>main/1</c>
+ function. See <seealso marker="kernel:code">code(3)</seealso>
+ for more information about archives and code loading.</p>
+
+ <p>In many cases it is very convenient to have a header in
+ the escript, especially on Unix platforms. But the header is
+ in fact optional. This means that you directly can "execute"
+ an Erlang module, beam file or archive file without adding
+ any header to them. But then you have to invoke the script
+ like this:</p>
+ <pre>
+$ <input>escript factorial.erl 5</input>
+factorial 5 = 120
+$ <input>escript factorial.beam 5</input>
+factorial 5 = 120
+$ <input>escript factorial.zip 5</input>
+factorial 5 = 120
+</pre>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Options accepted by escript</title>
+ <taglist>
+ <tag>-c</tag>
+ <item>Compile the escript regardless of the value of the mode attribute.
+ </item>
+
+ <tag>-d</tag>
+ <item>Debug the escript. Starts the debugger, loads the module
+ containing the <c>main/1</c> function into the debugger, sets a
+ breakpoint in <c>main/1</c> and invokes <c>main/1</c>. If the
+ module is precompiled, it must be explicitly compiled with the
+ <c>debug_info</c> option.
+ </item>
+
+ <tag>-i</tag>
+ <item>Interpret the escript regardless of the value of the mode attribute.
+ </item>
+
+ <tag>-s</tag>
+ <item>Only perform a syntactic and semantic check of the script file.
+ Warnings and errors (if any) are written to the standard output, but
+ the script will not be run. The exit status will be 0 if there were
+ no errors, and 127 otherwise.</item>
+ </taglist>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/fascicules.xml b/erts/doc/src/fascicules.xml
new file mode 100644
index 0000000000..cae197a516
--- /dev/null
+++ b/erts/doc/src/fascicules.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
+
+<fascicules>
+ <fascicule file="part" href="part_frame.html" entry="no">
+ ERTS User's Guide
+ </fascicule>
+ <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
+ ERTS Reference Manual
+ </fascicule>
+ <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
+ Release Notes
+ </fascicule>
+ <fascicule file="" href="../../../doc/print.html" entry="no">
+ Off-Print
+ </fascicule>
+</fascicules>
+
diff --git a/erts/doc/src/inet_cfg.xml b/erts/doc/src/inet_cfg.xml
new file mode 100644
index 0000000000..18cf65759a
--- /dev/null
+++ b/erts/doc/src/inet_cfg.xml
@@ -0,0 +1,397 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2004</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Inet configuration</title>
+ <prepared>Peter Andersson</prepared>
+ <docno></docno>
+ <date>2004-03-02</date>
+ <rev>PA1</rev>
+ <file>inet_cfg.xml</file>
+ </header>
+
+ <section>
+ <title>Introduction</title>
+ <p>This chapter tells you how the Erlang runtime system is configured
+ for IP communication. It also explains how you may configure it
+ for your own particular needs by means of a configuration file.
+ The information here is mainly intended for users with special
+ configuration needs or problems. There should normally be no need
+ for specific settings for Erlang to function properly on a correctly
+ IP configured platform. </p>
+ <p>When Erlang starts up it will read the kernel variable
+ <c><![CDATA[inetrc]]></c> which, if defined, should specify the location and
+ name of a user configuration file. Example:</p>
+ <p><c><![CDATA[% erl -kernel inetrc '"./cfg_files/erl_inetrc"']]></c></p>
+ <p>Note that the usage of a <c><![CDATA[.inetrc]]></c> file, which was
+ supported in earlier Erlang versions, is now obsolete.</p>
+ <p>A second way to specify the configuration file is to set the
+ environment variable <c><![CDATA[ERL_INETRC]]></c> to the full name of the file. Example (bash):</p>
+ <p><c><![CDATA[% export ERL_INETRC=./cfg_files/erl_inetrc]]></c></p>
+ <p>Note that the kernel variable <c><![CDATA[inetrc]]></c> overrides this environment variable.</p>
+ <p>If no user configuration file is specified and Erlang is started
+ in non-distributed or short name distributed mode, Erlang will use
+ default configuration settings and a native lookup method that should
+ work correctly under most circumstances. Erlang
+ will not read any information from system inet configuration files
+ (like /etc/host.conf, /etc/nsswitch.conf, etc) in these modes,
+ except for /etc/resolv.conf and /etc/hosts that is read and monitored
+ for changes on Unix platforms for the internal DNS client
+ <seealso marker="kernel:inet_res">inet_res</seealso>.</p>
+ <p>If Erlang is started in long name distributed mode, it needs to
+ get the domain name from somewhere and will read system inet
+ configuration files for this information. Any hosts and resolver
+ information found then is also recorded, but not
+ used as long as Erlang is configured for native lookups. (The
+ information becomes useful if the lookup method is changed to
+ <c><![CDATA['file']]></c> or <c><![CDATA['dns']]></c>, see below).</p>
+ <p>Native lookup (system calls) is always the default resolver method. This
+ is true for all platforms except VxWorks and OSE Delta where <c><![CDATA['file']]></c>
+ or <c><![CDATA['dns']]></c> is used (in that order of priority).</p>
+ <p>On Windows platforms, Erlang will search the system registry rather than
+ look for configuration files when started in long name distributed mode. </p>
+ </section>
+
+ <section>
+ <title>Configuration Data</title>
+ <p>Erlang records the following data in a local database if found in system
+ inet configuration files (or system registry):</p>
+ <list type="bulleted">
+ <item>Host names and addresses</item>
+ <item>Domain name</item>
+ <item>Nameservers</item>
+ <item>Search domains</item>
+ <item>Lookup method</item>
+ </list>
+ <p>This data may also be specified explicitly in the user
+ configuration file. The configuration file should contain lines
+ of configuration parameters (each terminated with a full
+ stop). Some parameters add data to the configuration (e.g. host
+ and nameserver), others overwrite any previous settings
+ (e.g. domain and lookup). The user configuration file is always
+ examined last in the configuration process, making it possible
+ for the user to override any default values or previously made
+ settings. Call <c><![CDATA[inet:get_rc()]]></c> to view the state of the
+ inet configuration database.</p>
+ <p>These are the valid configuration parameters:</p>
+ <p></p>
+ <taglist>
+ <tag><em><c><![CDATA[{file, Format, File}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Format = atom()]]></c></p>
+ <p><c><![CDATA[File = string()]]></c></p>
+ <p></p>
+ <p>Specify a system file that Erlang should read configuration
+ data from. <c><![CDATA[Format]]></c> tells the parser how the file should be
+ interpreted: <c><![CDATA[resolv]]></c> (Unix resolv.conf), <c><![CDATA[host_conf_freebsd]]></c>
+ (FreeBSD host.conf), <c><![CDATA[host_conf_bsdos]]></c> (BSDOS host.conf),
+ <c><![CDATA[host_conf_linux]]></c> (Linux host.conf), <c><![CDATA[nsswitch_conf]]></c>
+ (Unix nsswitch.conf) or <c><![CDATA[hosts]]></c> (Unix hosts). <c><![CDATA[File]]></c> should
+ specify the name of the file with full path.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{resolv_conf, File}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[File = string()]]></c></p>
+ <p></p>
+ <p>Specify a system file that Erlang should read resolver
+ configuration from for the internal DNS client
+ <seealso marker="kernel:inet_res">inet_res</seealso>,
+ and monitor for changes, even if it does not exist.
+ The path must be absolute.</p>
+ <p>This may override the configuration parameters
+ <c><![CDATA[nameserver]]></c> and
+ <c><![CDATA[search]]></c> depending on the contents
+ of the specified file. They may also change any time in the future
+ reflecting the file contents.</p>
+ <p>If the file is specified as an empty string "",
+ no file is read nor monitored in the future. This emulates
+ the old behaviour of not configuring the DNS client when
+ the node is started in short name distributed mode.</p>
+ <p>If this parameter is not specified it defaults to
+ <c><![CDATA[/etc/resolv.conf]]></c> unless the environment variable
+ <c><![CDATA[ERL_INET_ETC_DIR]]></c> is set which defines
+ the directory for this file to some maybe other than
+ <c><![CDATA[/etc]]></c>.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{hosts_file, File}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[File = string()]]></c></p>
+ <p></p>
+ <p>Specify a system file that Erlang should read resolver
+ configuration from for the internal hosts file resolver
+ and monitor for changes, even if it does not exist.
+ The path must be absolute.</p>
+ <p>These host entries are searched after all added with
+ <c>{file, hosts, File}</c> above or
+ <c>{host, IP, Aliases}</c> below when the lookup option
+ <c>file</c> is used.</p>
+ <p>If the file is specified as an empty string "",
+ no file is read nor monitored in the future. This emulates
+ the old behaviour of not configuring the DNS client when
+ the node is started in short name distributed mode.</p>
+ <p>If this parameter is not specified it defaults to
+ <c><![CDATA[/etc/hosts]]></c> unless the environment variable
+ <c><![CDATA[ERL_INET_ETC_DIR]]></c> is set which defines
+ the directory for this file to some maybe other than
+ <c><![CDATA[/etc]]></c>.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{registry, Type}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Type = atom()]]></c></p>
+ <p></p>
+ <p>Specify a system registry that Erlang should read configuration
+ data from. Currently, <c><![CDATA[win32]]></c> is the only valid option.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{host, IP, Aliases}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[IP = tuple()]]></c></p>
+ <p><c><![CDATA[Aliases = [string()]]]></c></p>
+ <p></p>
+ <p>Add host entry to the hosts table.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{domain, Domain}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Domain = string()]]></c></p>
+ <p></p>
+ <p>Set domain name.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{nameserver, IP [,Port]}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[IP = tuple()]]></c></p>
+ <p><c><![CDATA[Port = integer()]]></c></p>
+ <p></p>
+ <p>Add address (and port, if other than default) of primary
+ nameserver to use for
+ <seealso marker="kernel:inet_res">inet_res</seealso>.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{alt_nameserver, IP [,Port]}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[IP = tuple()]]></c></p>
+ <p><c><![CDATA[Port = integer()]]></c></p>
+ <p></p>
+ <p>Add address (and port, if other than default) of secondary
+ nameserver for
+ <seealso marker="kernel:inet_res">inet_res</seealso>.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{search, Domains}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Domains = [string()]]]></c></p>
+ <p></p>
+ <p>Add search domains for
+ <seealso marker="kernel:inet_res">inet_res</seealso>.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{lookup, Methods}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Methods = [atom()]]]></c></p>
+ <p></p>
+ <p>Specify lookup methods and in which order to try them.
+ The valid methods are: <c><![CDATA[native]]></c> (use system calls),
+ <c><![CDATA[file]]></c> (use host data retrieved from
+ system configuration files and/or
+ the user configuration file) or <c><![CDATA[dns]]></c>
+ (use the Erlang DNS client
+ <seealso marker="kernel:inet_res">inet_res</seealso>
+ for nameserver queries).</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{cache_size, Size}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Size = integer()]]></c></p>
+ <p></p>
+ <p>Set size of resolver cache. Default is 100 DNS records.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{cache_refresh, Time}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Time = integer()]]></c></p>
+ <p></p>
+ <p>Set how often (in millisec)
+ the resolver cache for
+ <seealso marker="kernel:inet_res">inet_res</seealso>.
+ is refreshed (i.e. expired DNS records are deleted).
+ Default is 1 h.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{timeout, Time}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Time = integer()]]></c></p>
+ <p></p>
+ <p>Set the time to wait until retry (in millisec) for DNS queries
+ made by
+ <seealso marker="kernel:inet_res">inet_res</seealso>.
+ Default is 2 sec.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{retry, N}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[N = integer()]]></c></p>
+ <p></p>
+ <p>Set the number of DNS queries
+ <seealso marker="kernel:inet_res">inet_res</seealso>
+ will try before giving up.
+ Default is 3.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{inet6, Bool}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Bool = true | false]]></c></p>
+ <p></p>
+ <p>Tells the DNS client
+ <seealso marker="kernel:inet_res">inet_res</seealso>
+ to look up IPv6 addresses. Default is false.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{usevc, Bool}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Bool = true | false]]></c></p>
+ <p></p>
+ <p>Tells the DNS client
+ <seealso marker="kernel:inet_res">inet_res</seealso>
+ to use TCP (Virtual Circuit) instead of UDP. Default is false.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{edns, Version}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Version = false | 0]]></c></p>
+ <p></p>
+ <p>Sets the EDNS version that
+ <seealso marker="kernel:inet_res">inet_res</seealso>
+ will use. The only allowed is zero. Default is false
+ which means to not use EDNS.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{udp_payload_size, Size}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[N = integer()]]></c></p>
+ <p></p>
+ <p>Sets the allowed UDP payload size
+ <seealso marker="kernel:inet_res">inet_res</seealso>
+ will advertise in EDNS queries. Also sets the limit
+ when the DNS query will be deemed too large for UDP
+ forcing a TCP query instead, which is not entirely
+ correct since the advertised UDP payload size of the
+ individual nameserver is what should be used,
+ but this simple strategy will do until a more intelligent
+ (probing, caching) algorithm need be implemented.
+ The default is 1280 which stems from the
+ standard Ethernet MTU size.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{udp, Module}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Module = atom()]]></c></p>
+ <p></p>
+ <p>Tell Erlang to use other primitive UDP module than inet_udp.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[{tcp, Module}.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p><c><![CDATA[Module = atom()]]></c></p>
+ <p></p>
+ <p>Tell Erlang to use other primitive TCP module than inet_tcp.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[clear_hosts.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p>Clear the hosts table.</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[clear_ns.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p>Clear the list of recorded nameservers (primary and secondary).</p>
+ <p></p>
+ </item>
+ <tag><em><c><![CDATA[clear_search.]]></c></em></tag>
+ <item>
+ <p></p>
+ <p>Clear the list of search domains.</p>
+ <p></p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>User Configuration Example</title>
+ <p>Here follows a user configuration example.</p>
+ <p>Assume a user does not want Erlang to use the native lookup method,
+ but wants Erlang to read all information necessary from start and use
+ that for resolving names and addresses. In case lookup fails, Erlang
+ should request the data from a nameserver (using the Erlang
+ DNS client, set to use EDNS allowing larger responses).
+ The resolver configuration will be updated when
+ its configuration file changes, furthermore, DNS records
+ should never be cached. The user configuration file
+ (in this example named <c><![CDATA[erl_inetrc]]></c>, stored
+ in directory <c><![CDATA[./cfg_files]]></c>) could then look like this
+ (Unix):</p>
+ <pre>
+ %% -- ERLANG INET CONFIGURATION FILE --
+ %% read the hosts file
+ {file, hosts, "/etc/hosts"}.
+ %% add a particular host
+ {host, {134,138,177,105}, ["finwe"]}.
+ %% do not monitor the hosts file
+ {hosts_file, ""}.
+ %% read and monitor nameserver config from here
+ {resolv_conf, "/usr/local/etc/resolv.conf"}.
+ %% enable EDNS
+ {edns,0}.
+ %% disable caching
+ {cache_size, 0}.
+ %% specify lookup method
+ {lookup, [file, dns]}.</pre>
+ <p>And Erlang could, for example, be started like this:</p>
+ <p><c><![CDATA[% erl -sname my_node -kernel inetrc '"./cfg_files/erl_inetrc"']]></c></p>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml
new file mode 100644
index 0000000000..33364c709a
--- /dev/null
+++ b/erts/doc/src/init.xml
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>init</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>init.xml</file>
+ </header>
+ <module>init</module>
+ <modulesummary>Coordination of System Startup</modulesummary>
+ <description>
+ <p>The <c>init</c> module is pre-loaded and contains the code for
+ the <c>init</c> system process which coordinates the start-up of
+ the system. The first function evaluated at start-up is
+ <c>boot(BootArgs)</c>, where <c>BootArgs</c> is a list of command
+ line arguments supplied to the Erlang runtime system from
+ the local operating system. See
+ <seealso marker="erts:erl">erl(1)</seealso>.</p>
+ <p><c>init</c> reads the boot script which contains instructions on
+ how to initiate the system. See
+ <seealso marker="sasl:script">script(4)</seealso> for more
+ information about boot scripts.</p>
+ <p><c>init</c> also contains functions to restart, reboot, and stop
+ the system.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>boot(BootArgs) -> void()</name>
+ <fsummary>Start the Erlang runtime system</fsummary>
+ <type>
+ <v>BootArgs = [binary()]</v>
+ </type>
+ <desc>
+ <p>Starts the Erlang runtime system. This function is called
+ when the emulator is started and coordinates system start-up.</p>
+ <p><c>BootArgs</c> are all command line arguments except
+ the emulator flags, that is, flags and plain arguments. See
+ <seealso marker="erts:erl">erl(1)</seealso>.</p>
+ <p><c>init</c> itself interprets some of the flags, see
+ <seealso marker="#flags">Command Line Flags</seealso> below.
+ The remaining flags ("user flags") and plain arguments are
+ passed to the <c>init</c> loop and can be retrieved by calling
+ <c>get_arguments/0</c> and <c>get_plain_arguments/0</c>,
+ respectively.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_args() -> [Arg]</name>
+ <fsummary>Get all non-flag command line arguments</fsummary>
+ <type>
+ <v>Arg = atom()</v>
+ </type>
+ <desc>
+ <p>Returns any plain command line arguments as a list of atoms
+ (possibly empty). It is recommended that
+ <c>get_plain_arguments/1</c> is used instead, because of
+ the limited length of atoms.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_argument(Flag) -> {ok, Arg} | error</name>
+ <fsummary>Get the values associated with a command line user flag</fsummary>
+ <type>
+ <v>Flag = atom()</v>
+ <v>Arg = [Values]</v>
+ <v>&nbsp;Values = [string()]</v>
+ </type>
+ <desc>
+ <p>Returns all values associated with the command line user flag
+ <c>Flag</c>. If <c>Flag</c> is provided several times, each
+ <c>Values</c> is returned in preserved order.</p>
+ <pre>
+% <input>erl -a b c -a d</input>
+...
+1> <input>init:get_argument(a).</input>
+{ok,[["b","c"],["d"]]}</pre>
+ <p>There are also a number of flags, which are defined
+ automatically and can be retrieved using this function:</p>
+ <taglist>
+ <tag><c>root</c></tag>
+ <item>
+ <p>The installation directory of Erlang/OTP, <c>$ROOT</c>.</p>
+ <pre>
+2> <input>init:get_argument(root).</input>
+{ok,[["/usr/local/otp/releases/otp_beam_solaris8_r10b_patched"]]}</pre>
+ </item>
+ <tag><c>progname</c></tag>
+ <item>
+ <p>The name of the program which started Erlang.</p>
+ <pre>
+3> <input>init:get_argument(progname).</input>
+{ok,[["erl"]]}</pre>
+ </item>
+ <tag><c>home</c></tag>
+ <item>
+ <p>The home directory.</p>
+ <pre>
+4> <input>init:get_argument(home).</input>
+{ok,[["/home/harry"]]}</pre>
+ </item>
+ </taglist>
+ <p>Returns <c>error</c> if there is no value associated with
+ <c>Flag</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_arguments() -> Flags</name>
+ <fsummary>Get all command line user flags</fsummary>
+ <type>
+ <v>Flags = [{Flag, Values}]</v>
+ <v>&nbsp;Flag = atom()</v>
+ <v>&nbsp;Values = [string()]</v>
+ </type>
+ <desc>
+ <p>Returns all command line flags, as well as the system
+ defined flags, see <c>get_argument/1</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_plain_arguments() -> [Arg]</name>
+ <fsummary>Get all non-flag command line arguments</fsummary>
+ <type>
+ <v>Arg = string()</v>
+ </type>
+ <desc>
+ <p>Returns any plain command line arguments as a list of strings
+ (possibly empty).</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_status() -> {InternalStatus, ProvidedStatus}</name>
+ <fsummary>Get system status information</fsummary>
+ <type>
+ <v>InternalStatus = starting | started | stopping</v>
+ <v>ProvidedStatus = term()</v>
+ </type>
+ <desc>
+ <p>The current status of the <c>init</c> process can be
+ inspected. During system startup (initialization),
+ <c>InternalStatus</c> is <c>starting</c>, and
+ <c>ProvidedStatus</c> indicates how far the boot script has
+ been interpreted. Each <c>{progress, Info}</c> term
+ interpreted in the boot script affects <c>ProvidedStatus</c>,
+ that is, <c>ProvidedStatus</c> gets the value of <c>Info</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>reboot() -> void()</name>
+ <fsummary>Take down and restart an Erlang node smoothly</fsummary>
+ <desc>
+ <p>All applications are taken down smoothly, all code is
+ unloaded, and all ports are closed before the system
+ terminates. If the <c>-heart</c> command line flag was given,
+ the <c>heart</c> program will try to reboot the system. Refer
+ to <c>heart(3)</c> for more information.</p>
+ <p>To limit the shutdown time, the time <c>init</c> is allowed
+ to spend taking down applications, the <c>-shutdown_time</c>
+ command line flag should be used.</p>
+ </desc>
+ </func>
+ <func>
+ <name>restart() -> void()</name>
+ <fsummary>Restart the running Erlang node</fsummary>
+ <desc>
+ <p>The system is restarted <em>inside</em> the running Erlang
+ node, which means that the emulator is not restarted. All
+ applications are taken down smoothly, all code is unloaded,
+ and all ports are closed before the system is booted again in
+ the same way as initially started. The same <c>BootArgs</c>
+ are used again.</p>
+ <p>To limit the shutdown time, the time <c>init</c> is allowed
+ to spend taking down applications, the <c>-shutdown_time</c>
+ command line flag should be used.</p>
+ </desc>
+ </func>
+ <func>
+ <name>script_id() -> Id</name>
+ <fsummary>Get the identity of the used boot script</fsummary>
+ <type>
+ <v>Id = term()</v>
+ </type>
+ <desc>
+ <p>Get the identity of the boot script used to boot the system.
+ <c>Id</c> can be any Erlang term. In the delivered boot
+ scripts, <c>Id</c> is <c>{Name, Vsn}</c>. <c>Name</c> and
+ <c>Vsn</c> are strings.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop() -> void()</name>
+ <fsummary>Take down an Erlang node smoothly</fsummary>
+ <desc>
+ <p>All applications are taken down smoothly, all code is
+ unloaded, and all ports are closed before the system
+ terminates. If the <c>-heart</c> command line flag was given,
+ the <c>heart</c> program is terminated before the Erlang node
+ terminates. Refer to <c>heart(3)</c> for more information.</p>
+ <p>To limit the shutdown time, the time <c>init</c> is allowed
+ to spend taking down applications, the <c>-shutdown_time</c>
+ command line flag should be used.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop(Status) -> void()</name>
+ <fsummary>Take down an Erlang node smoothly</fsummary>
+ <type>
+ <v>Status = int()>=0 | string()</v>
+ </type>
+ <desc>
+ <p>All applications are taken down smoothly, all code is
+ unloaded, and all ports are closed before the system
+ terminates by calling <c>halt(Status)</c>. If the
+ <c>-heart</c> command line flag was given, the <c>heart</c>
+ program is terminated before the Erlang node
+ terminates. Refer to <c>heart(3)</c> for more
+ information.</p>
+ <p>To limit the shutdown time, the time <c>init</c> is allowed
+ to spend taking down applications, the <c>-shutdown_time</c>
+ command line flag should be used.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <marker id="flags"></marker>
+ <title>Command Line Flags</title>
+ <warning><p>The support for loading of code from archive files is
+ experimental. The sole purpose of releasing it before it is ready
+ is to obtain early feedback. The file format, semantics,
+ interfaces etc. may be changed in a future release. The
+ <c>-code_path_choice</c> flag is also experimental.</p></warning>
+
+ <p>The <c>init</c> module interprets the following command line
+ flags:</p>
+
+ <taglist>
+ <tag><c>--</c></tag>
+ <item>
+ <p>Everything following <c>--</c> up to the next flag is
+ considered plain arguments and can be retrieved using
+ <c>get_plain_arguments/0</c>.</p>
+ </item>
+ <tag><c>-code_path_choice Choice</c></tag>
+ <item>
+ <p>This flag can be set to <c>strict</c> or <c>relaxed</c>. It
+ controls whether each directory in the code path should be
+ interpreted strictly as it appears in the <c>boot script</c> or if
+ <c>init</c> should be more relaxed and try to find a suitable
+ directory if it can choose from a regular ebin directory and
+ an ebin directory in an archive file. This flag is particular
+ useful when you want to elaborate with code loading from
+ archives without editing the <c>boot script</c>. See <seealso
+ marker="sasl:script">script(4)</seealso> for more information
+ about interpretation of boot scripts. The flag does also have
+ a similar affect on how the code server works. See <seealso
+ marker="kernel:code">code(3)</seealso>.</p>
+
+ </item>
+ <tag><c>-eval Expr</c></tag>
+ <item>
+ <p>Scans, parses and evaluates an arbitrary expression
+ <c>Expr</c> during system initialization. If any of these
+ steps fail (syntax error, parse error or exception during
+ evaluation), Erlang stops with an error message. Here is an
+ example that seeds the random number generator:</p>
+ <pre>
+% <input>erl -eval '{X,Y,Z}' = now(), random:seed(X,Y,Z).'</input></pre>
+ <p>This example uses Erlang as a hexadecimal calculator:</p>
+ <pre>
+% <input>erl -noshell -eval 'R = 16#1F+16#A0, io:format("~.16B~n", [R])' \\</input>
+<input>-s erlang halt</input>
+BF</pre>
+ <p>If multiple <c>-eval</c> expressions are specified, they
+ are evaluated sequentially in the order specified.
+ <c>-eval</c> expressions are evaluated sequentially with
+ <c>-s</c> and <c>-run</c> function calls (this also in
+ the order specified). As with <c>-s</c> and <c>-run</c>, an
+ evaluation that does not terminate, blocks the system
+ initialization process.</p>
+ </item>
+ <tag><c>-extra</c></tag>
+ <item>
+ <p>Everything following <c>-extra</c> is considered plain
+ arguments and can be retrieved using
+ <c>get_plain_arguments/0</c>.</p>
+ </item>
+ <tag><c>-run Mod [Func [Arg1, Arg2, ...]]</c></tag>
+ <item>
+ <p>Evaluates the specified function call during system
+ initialization. <c>Func</c> defaults to <c>start</c>. If no
+ arguments are provided, the function is assumed to be of arity
+ 0. Otherwise it is assumed to be of arity 1, taking the list
+ <c>[Arg1,Arg2,...]</c> as argument. All arguments are passed
+ as strings. If an exception is raised, Erlang stops with an
+ error message.</p>
+ <p>Example:</p>
+ <pre>
+% <input>erl -run foo -run foo bar -run foo bar baz 1 2</input></pre>
+ <p>This starts the Erlang runtime system and evaluates
+ the following functions:</p>
+ <code type="none">
+foo:start()
+foo:bar()
+foo:bar(["baz", "1", "2"]).</code>
+ <p>The functions are executed sequentially in an initialization
+ process, which then terminates normally and passes control to
+ the user. This means that a <c>-run</c> call which does not
+ return will block further processing; to avoid this, use
+ some variant of <c>spawn</c> in such cases.</p>
+ </item>
+ <tag><c>-s Mod [Func [Arg1, Arg2, ...]]</c></tag>
+ <item>
+ <p>Evaluates the specified function call during system
+ initialization. <c>Func</c> defaults to <c>start</c>. If no
+ arguments are provided, the function is assumed to be of arity
+ 0. Otherwise it is assumed to be of arity 1, taking the list
+ <c>[Arg1,Arg2,...]</c> as argument. All arguments are passed
+ as atoms. If an exception is raised, Erlang stops with an
+ error message.</p>
+ <p>Example:</p>
+ <pre>
+% <input>erl -s foo -s foo bar -s foo bar baz 1 2</input></pre>
+ <p>This starts the Erlang runtime system and evaluates
+ the following functions:</p>
+ <code type="none">
+foo:start()
+foo:bar()
+foo:bar([baz, '1', '2']).</code>
+ <p>The functions are executed sequentially in an initialization
+ process, which then terminates normally and passes control to
+ the user. This means that a <c>-s</c> call which does not
+ return will block further processing; to avoid this, use
+ some variant of <c>spawn</c> in such cases.</p>
+ <p>Due to the limited length of atoms, it is recommended that
+ <c>-run</c> be used instead.</p>
+ </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Example</title>
+ <pre>
+% <input>erl -- a b -children thomas claire -ages 7 3 -- x y</input>
+...
+
+1> <input>init:get_plain_arguments().</input>
+["a","b","x","y"]
+2> <input>init:get_argument(children).</input>
+{ok,[["thomas","claire"]]}
+3> <input>init:get_argument(ages).</input>
+{ok, [["7","3"]]}
+4> <input>init:get_argument(silly).</input>
+error</pre>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p><seealso marker="erl_prim_loader">erl_prim_loader(3)</seealso>,
+ <seealso marker="kernel:heart">heart(3)</seealso></p>
+ </section>
+</erlref>
+
diff --git a/erts/doc/src/make.dep b/erts/doc/src/make.dep
new file mode 100644
index 0000000000..98bac78235
--- /dev/null
+++ b/erts/doc/src/make.dep
@@ -0,0 +1,32 @@
+# ----------------------------------------------------
+# >>>> Do not edit this file <<<<
+# This file was automaticly generated by
+# /home/gandalf/otp/bin/docdepend
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# TeX files that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: absform.tex alt_dist.tex book.tex crash_dump.tex \
+ driver.tex driver_entry.tex epmd.tex erl.tex \
+ erl_dist_protocol.tex erl_driver.tex erl_ext_dist.tex \
+ erl_prim_loader.tex erl_set_memory_block.tex \
+ erlang.tex erlc.tex erlsrv.tex erts_alloc.tex \
+ escript.tex inet_cfg.tex init.tex match_spec.tex \
+ part.tex ref_man.tex run_erl.tex start.tex \
+ start_erl.tex tty.tex werl.tex zlib.tex
+
+# ----------------------------------------------------
+# Source inlined when transforming from source to LaTeX
+# ----------------------------------------------------
+
+book.tex: ref_man.xml
+
+# ----------------------------------------------------
+# Pictures that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: erl_ext_fig.ps
+
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
new file mode 100644
index 0000000000..26480473d2
--- /dev/null
+++ b/erts/doc/src/match_spec.xml
@@ -0,0 +1,564 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1999</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Match specifications in Erlang</title>
+ <prepared>Patrik Nyblom</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>1999-06-01</date>
+ <rev>PA1</rev>
+ <file>match_spec.xml</file>
+ </header>
+ <p>A "match specification" (match_spec) is an Erlang term describing a
+ small "program" that will try to match something (either the
+ parameters to a function as used in the <c><![CDATA[erlang:trace_pattern/2]]></c>
+ BIF, or the objects in an ETS table.).
+ The match_spec in many ways works like a small function in Erlang, but is
+ interpreted/compiled by the Erlang runtime system to something much more
+ efficient than calling an Erlang function. The match_spec is also
+ very limited compared to the expressiveness of real Erlang functions.</p>
+ <p>Match specifications are given to the BIF <c><![CDATA[erlang:trace_pattern/2]]></c> to
+ execute matching of function arguments as well as to define some actions
+ to be taken when the match succeeds (the <c><![CDATA[MatchBody]]></c> part). Match
+ specifications can also be used in ETS, to specify objects to be
+ returned from an <c><![CDATA[ets:select/2]]></c> call (or other select
+ calls). The semantics and restrictions differ slightly when using
+ match specifications for tracing and in ETS, the differences are
+ defined in a separate paragraph below.</p>
+ <p>The most notable difference between a match_spec and an Erlang fun is
+ of course the syntax. Match specifications are Erlang terms, not
+ Erlang code. A match_spec also has a somewhat strange concept of
+ exceptions. An exception (e.g., <c><![CDATA[badarg]]></c>) in the <c><![CDATA[MatchCondition]]></c>
+ part,
+ which resembles an Erlang guard, will generate immediate failure,
+ while an exception in the <c><![CDATA[MatchBody]]></c> part, which resembles the body of an
+ Erlang function, is implicitly caught and results in the single atom
+ <c><![CDATA['EXIT']]></c>.
+ </p>
+
+ <section>
+ <title>Grammar</title>
+ <p>A match_spec can be described in this <em>informal</em> grammar:</p>
+ <list type="bulleted">
+ <item>MatchExpression ::= [ MatchFunction, ... ]
+ </item>
+ <item>MatchFunction ::= { MatchHead, MatchConditions, MatchBody }
+ </item>
+ <item>MatchHead ::= MatchVariable | <c><![CDATA['_']]></c> | [ MatchHeadPart, ... ]
+ </item>
+ <item>MatchHeadPart ::= term() | MatchVariable | <c><![CDATA['_']]></c></item>
+ <item>MatchVariable ::= '$&lt;number&gt;'
+ </item>
+ <item>MatchConditions ::= [ MatchCondition, ...] | <c><![CDATA[[]]]></c></item>
+ <item>MatchCondition ::= { GuardFunction } |
+ { GuardFunction, ConditionExpression, ... }
+ </item>
+ <item>BoolFunction ::= <c><![CDATA[is_atom]]></c> | <c><![CDATA[is_constant]]></c> |
+ <c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> | <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_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
+ </item>
+ <item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
+ <c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c></item>
+ <item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
+ <c><![CDATA[[]]]></c> | [ConditionExpression, ...] | NonCompositeTerm | Constant
+ </item>
+ <item>NonCompositeTerm ::= term() (not list or tuple)
+ </item>
+ <item>Constant ::= {<c><![CDATA[const]]></c>, term()}
+ </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[round]]></c> | <c><![CDATA[size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
+ <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
+ <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> | <c><![CDATA['bor']]></c> | <c><![CDATA['bxor']]></c> |
+ <c><![CDATA['bnot']]></c> | <c><![CDATA['bsl']]></c> | <c><![CDATA['bsr']]></c> | <c><![CDATA['>']]></c> |
+ <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></item>
+ <item>MatchBody ::= [ ActionTerm ]
+ </item>
+ <item>ActionTerm ::= ConditionExpression | ActionCall
+ </item>
+ <item>ActionCall ::= {ActionFunction} |
+ {ActionFunction, ActionTerm, ...}
+ </item>
+ <item>ActionFunction ::= <c><![CDATA[set_seq_token]]></c> |
+ <c><![CDATA[get_seq_token]]></c> | <c><![CDATA[message]]></c> |
+ <c><![CDATA[return_trace]]></c> | <c><![CDATA[exception_trace]]></c> | <c><![CDATA[process_dump]]></c> |
+ <c><![CDATA[enable_trace]]></c> | <c><![CDATA[disable_trace]]></c> | <c><![CDATA[trace]]></c> |
+ <c><![CDATA[display]]></c> | <c><![CDATA[caller]]></c> | <c><![CDATA[set_tcw]]></c> |
+ <c><![CDATA[silent]]></c></item>
+ </list>
+ </section>
+
+ <section>
+ <title>Function descriptions</title>
+
+ <section>
+ <title>Functions allowed in all types of match specifications</title>
+ <p>The different functions allowed in <c><![CDATA[match_spec]]></c> work like this:
+ </p>
+ <p><em>is_atom, is_constant, is_float, is_integer, is_list, is_number, is_pid, is_port, is_reference, is_tuple, is_binary, is_function: </em> Like the corresponding guard tests in
+ Erlang, return <c><![CDATA[true]]></c> or <c><![CDATA[false]]></c>.
+ </p>
+ <p><em>is_record: </em>Takes an additional parameter, which SHALL
+ be the result of <c><![CDATA[record_info(size, <record_type>)]]></c>,
+ like in <c><![CDATA[{is_record, '$1', rectype, record_info(size, rectype)}]]></c>.
+ </p>
+ <p><em>'not': </em>Negates its single argument (anything other
+ than <c><![CDATA[false]]></c> gives <c><![CDATA[false]]></c>).
+ </p>
+ <p><em>'and': </em>Returns <c><![CDATA[true]]></c> if all its arguments
+ (variable length argument list) evaluate to <c><![CDATA[true]]></c>, else
+ <c><![CDATA[false]]></c>. Evaluation order is undefined.
+ </p>
+ <p><em>'or': </em>Returns <c><![CDATA[true]]></c> if any of its arguments
+ evaluates to <c><![CDATA[true]]></c>. Variable length argument
+ list. Evaluation order is undefined.
+ </p>
+ <p><em>andalso: </em>Like <c><![CDATA['and']]></c>, but quits evaluating its
+ arguments as soon as one argument evaluates to something else
+ than true. Arguments are evaluated left to right.
+ </p>
+ <p><em>orelse: </em>Like <c><![CDATA['or']]></c>, but quits evaluating as soon
+ as one of its arguments evaluates to <c><![CDATA[true]]></c>. Arguments are
+ evaluated left to right.
+ </p>
+ <p><em>'xor': </em>Only two arguments, of which one has to be true
+ and the other false to return <c><![CDATA[true]]></c>; otherwise
+ <c><![CDATA['xor']]></c> returns false.
+ </p>
+ <p><em>abs, element, hd, length, node, round, size, tl, trunc, '+', '-', '*', 'div', 'rem', 'band', 'bor', 'bxor', 'bnot', 'bsl', 'bsr', '>', '>=', '&lt;', '=&lt;', '=:=', '==', '=/=', '/=', self: </em>Work as the corresponding Erlang bif's (or
+ operators). In case of bad arguments, the result depends on
+ the context. In the <c><![CDATA[MatchConditions]]></c> part of the
+ expression, the test fails immediately (like in an Erlang
+ guard), but in the <c><![CDATA[MatchBody]]></c>, exceptions are implicitly
+ caught and the call results in the atom <c><![CDATA['EXIT']]></c>.</p>
+ </section>
+
+ <section>
+ <title>Functions allowed only for tracing</title>
+ <p><em>is_seq_trace: </em>Returns <c><![CDATA[true]]></c> if a sequential
+ trace token is set for the current process, otherwise <c><![CDATA[false]]></c>.
+ </p>
+ <p><em>set_seq_token:</em> Works like
+ <c><![CDATA[seq_trace:set_token/2]]></c>, but returns <c><![CDATA[true]]></c> on success
+ and <c><![CDATA['EXIT']]></c> on error or bad argument. Only allowed in the
+ <c><![CDATA[MatchBody]]></c> part and only allowed when tracing.
+ </p>
+ <p><em>get_seq_token:</em> Works just like
+ <c><![CDATA[seq_trace:get_token/0]]></c>, and is only allowed in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.
+ </p>
+ <p><em>message:</em> Sets an additional message appended to the
+ trace message sent. One can only set one additional message in
+ the body; subsequent calls will replace the appended message. As
+ a special case, <c><![CDATA[{message, false}]]></c> disables sending of
+ trace messages ('call' and 'return_to')
+ for this function call, just like if the match_spec had not matched,
+ which can be useful if only the side effects of
+ the <c><![CDATA[MatchBody]]></c> are desired.
+ Another special case is <c><![CDATA[{message, true}]]></c> which
+ sets the default behavior, as if the function had no match_spec,
+ trace message is sent with no extra
+ information (if no other calls to <c><![CDATA[message]]></c> are placed
+ before <c><![CDATA[{message, true}]]></c>, it is in fact a "noop").
+ </p>
+ <p>Takes one argument, the message. Returns <c><![CDATA[true]]></c> and can
+ only be used in the <c><![CDATA[MatchBody]]></c> part and when tracing.
+ </p>
+ <p><em>return_trace:</em> Causes a <c><![CDATA[return_from]]></c> trace
+ message to be sent upon return from the current function.
+ Takes no arguments, returns <c><![CDATA[true]]></c> and can only be used
+ in the <c><![CDATA[MatchBody]]></c> part when tracing.
+ If the process trace flag <c><![CDATA[silent]]></c>
+ is active the <c><![CDATA[return_from]]></c> trace message is inhibited.
+ </p>
+ <p>NOTE! If the traced function is tail recursive, this match
+ spec function destroys that property.
+ Hence, if a match spec executing this function is used on a
+ perpetual server process, it may only be active for a limited
+ time, or the emulator will eventually use all memory in the host
+ machine and crash. If this match_spec function is inhibited
+ using the <c><![CDATA[silent]]></c> process trace flag
+ tail recursiveness still remains.
+ </p>
+ <p><em>exception_trace:</em> Same as <em>return_trace</em>,
+ plus; if the traced function exits due to an exception,
+ an <c><![CDATA[exception_from]]></c> trace message is generated,
+ whether the exception is caught or not.
+ </p>
+ <p><em>process_dump:</em> Returns some textual information about
+ the current process as a binary. Takes no arguments and is only
+ allowed in the <c><![CDATA[MatchBody]]></c> part when tracing.
+ </p>
+ <p><em>enable_trace:</em> With one parameter this function turns
+ on tracing like the Erlang call <c><![CDATA[erlang:trace(self(), true, [P2])]]></c>, where <c><![CDATA[P2]]></c> is the parameter to
+ <c><![CDATA[enable_trace]]></c>. With two parameters, the first parameter
+ should be either a process identifier or the registered name of
+ a process. In this case tracing is turned on for the designated
+ process in the same way as in the Erlang call <c><![CDATA[erlang:trace(P1, true, [P2])]]></c>, where P1 is the first and P2 is the second
+ argument. The process <c><![CDATA[P1]]></c> gets its trace messages sent to the same
+ tracer as the process executing the statement uses. <c><![CDATA[P1]]></c>
+ can <em>not</em> be one of the atoms <c><![CDATA[all]]></c>, <c><![CDATA[new]]></c> or
+ <c><![CDATA[existing]]></c> (unless, of course, they are registered names).
+ <c><![CDATA[P2]]></c> can <em>not</em> be <c><![CDATA[cpu_timestamp]]></c> nor
+ <c><![CDATA[{tracer,_}]]></c>.
+ Returns <c><![CDATA[true]]></c> and may only be used in
+ the <c><![CDATA[MatchBody]]></c> part when tracing.
+ </p>
+ <p><em>disable_trace:</em> With one parameter this function
+ disables tracing like the Erlang call <c><![CDATA[erlang:trace(self(), false, [P2])]]></c>, where <c><![CDATA[P2]]></c> is the parameter to
+ <c><![CDATA[disable_trace]]></c>. With two parameters it works like the
+ Erlang call <c><![CDATA[erlang:trace(P1, false, [P2])]]></c>, where P1 can
+ be either a process identifier or a registered name and is given
+ as the first argument to the match_spec function.
+ <c><![CDATA[P2]]></c> can <em>not</em> be <c><![CDATA[cpu_timestamp]]></c> nor
+ <c><![CDATA[{tracer,_}]]></c>. Returns
+ <c><![CDATA[true]]></c> and may only be used in the <c><![CDATA[MatchBody]]></c> part
+ when tracing.
+ </p>
+ <p><em>trace:</em> With two parameters this function takes a list
+ of trace flags to disable as first parameter and a list
+ of trace flags to enable as second parameter. Logically, the
+ disable list is applied first, but effectively all changes
+ are applied atomically. The trace flags
+ are the same as for <c><![CDATA[erlang:trace/3]]></c> not including
+ <c><![CDATA[cpu_timestamp]]></c> but including <c><![CDATA[{tracer,_}]]></c>. 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 spec is
+ used. With three parameters to this function the first is
+ either a process identifier or the registered name of a
+ process to set trace flags on, the second is the disable
+ list, and the third is the enable list. Returns
+ <c><![CDATA[true]]></c> if any trace property was changed for the
+ trace target process or <c><![CDATA[false]]></c> if not. It may only
+ be used in the <c><![CDATA[MatchBody]]></c> part when tracing.
+ </p>
+ <p><em>caller:</em>
+ Returns the calling function as a tuple {Module,
+ Function, Arity} or the atom <c><![CDATA[undefined]]></c> if the calling
+ function cannot be determined. May only be used in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.
+ </p>
+ <p>Note that if a "technically built in function" (i.e. a
+ function not written in Erlang) is traced, the <c><![CDATA[caller]]></c>
+ function will sometimes return the atom <c><![CDATA[undefined]]></c>. The calling
+ Erlang function is not available during such calls.
+ </p>
+ <p><em>display:</em> For debugging purposes only; displays the
+ single argument as an Erlang term on stdout, which is seldom
+ what is wanted. Returns <c><![CDATA[true]]></c> and may only be used in the
+ <c><![CDATA[MatchBody]]></c> part when tracing.
+ </p>
+ <p> <marker id="get_tcw"></marker>
+<em>get_tcw:</em>
+ Takes no argument and returns the value of the node's trace
+ control word. The same is done by
+ <c><![CDATA[erlang:system_info(trace_control_word)]]></c>.
+ </p>
+ <p>The trace control word is a 32-bit unsigned integer intended for
+ generic trace control. The trace control word can be tested and
+ set both from within trace match specifications and with BIFs.
+ This call is only allowed when tracing.
+ </p>
+ <p> <marker id="set_tcw"></marker>
+<em>set_tcw:</em>
+ Takes one unsigned integer argument, sets the value of
+ the node's trace control word to the value of the argument
+ and returns the previous value. The same is done by
+ <c><![CDATA[erlang:system_flag(trace_control_word, Value)]]></c>. It is only
+ allowed to use <c><![CDATA[set_tcw]]></c> in the <c><![CDATA[MatchBody]]></c> part
+ when tracing.
+ </p>
+ <p><em>silent:</em>
+ Takes one argument. If the argument is <c><![CDATA[true]]></c>, the call
+ trace message mode for the current process is set to silent
+ for this call and all subsequent, i.e call trace messages
+ are inhibited even if <c><![CDATA[{message, true}]]></c> is called in the
+ <c><![CDATA[MatchBody]]></c> part for a traced function.
+ </p>
+ <p>This mode can also be activated with the <c><![CDATA[silent]]></c> flag
+ to <c><![CDATA[erlang:trace/3]]></c>.
+ </p>
+ <p>If the argument is <c><![CDATA[false]]></c>, the call trace message mode
+ for the current process is set to normal (non-silent) for
+ this call and all subsequent.
+ </p>
+ <p>If the argument is neither <c><![CDATA[true]]></c> nor <c><![CDATA[false]]></c>,
+ the call trace message mode is unaffected.</p>
+ </section>
+ <p><em>Note</em> that all "function calls" have to be tuples,
+ even if they take no arguments. The value of <c><![CDATA[self]]></c> is
+ the atom() <c><![CDATA[self]]></c>, but the value of <c><![CDATA[{self}]]></c> is
+ the pid() of the current process.</p>
+ </section>
+
+ <section>
+ <title>Variables and literals</title>
+ <p>Variables take the form <c><![CDATA['$<number>']]></c> where
+ <c><![CDATA[<number>]]></c> is an integer between 0 (zero) and
+ 100000000 (1e+8), the behavior if the number is outside these
+ limits is <em>undefined</em>. In the <c><![CDATA[MatchHead]]></c> part, the special
+ variable <c><![CDATA['_']]></c> matches anything, and never gets bound (like
+ <c><![CDATA[_]]></c> in Erlang). In the <c><![CDATA[MatchCondition/MatchBody]]></c>
+ parts, no unbound variables are allowed, why <c><![CDATA['_']]></c> is
+ interpreted as itself (an atom). Variables can only be bound in
+ the <c><![CDATA[MatchHead]]></c> part. In the <c><![CDATA[MatchBody]]></c> and
+ <c><![CDATA[MatchCondition]]></c> parts, only variables bound previously may
+ be used. As a special case, in the
+ <c><![CDATA[MatchCondition/MatchBody]]></c> parts, the variable <c><![CDATA['$_']]></c>
+ expands to the whole expression which matched the
+ <c><![CDATA[MatchHead]]></c> (i.e., the whole parameter list to the possibly
+ traced function or the whole matching object in the ets table)
+ and the variable <c><![CDATA['$$']]></c> expands to a list
+ of the values of all bound variables in order
+ (i.e. <c><![CDATA[['$1','$2', ...]]]></c>).
+ </p>
+ <p>In the <c><![CDATA[MatchHead]]></c> part, all literals (except the variables
+ noted above) are interpreted as is. In the
+ <c><![CDATA[MatchCondition/MatchBody]]></c> parts, however, the
+ interpretation is in some ways different. Literals in the
+ <c><![CDATA[MatchCondition/MatchBody]]></c> can either be written as is,
+ which works for all literals except tuples, or by using the
+ special form <c><![CDATA[{const, T}]]></c>, where <c><![CDATA[T]]></c> is any Erlang
+ term. For tuple literals in the match_spec, one can also use
+ double tuple parentheses, i.e., construct them as a tuple of
+ arity one containing a single tuple, which is the one to be
+ constructed. The "double tuple parenthesis" syntax is useful to
+ construct tuples from already bound variables, like in
+ <c><![CDATA[{{'$1', [a,b,'$2']}}]]></c>. Some examples may be needed:
+ </p>
+ <table>
+ <row>
+ <cell align="left" valign="middle">Expression\011\011</cell>
+ <cell align="left" valign="middle">Variable bindings\011\011</cell>
+ <cell align="left" valign="middle">Result\011</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{{'$1','$2'}}\011\011</cell>
+ <cell align="left" valign="middle">'$1' = a, '$2' = b</cell>
+ <cell align="left" valign="middle">{a,b}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{const, {'$1', '$2'}}\011</cell>
+ <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">{'$1', '$2'}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">a\011\011\011</cell>
+ <cell align="left" valign="middle">doesn't matter\011\011\011</cell>
+ <cell align="left" valign="middle">a</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">'$1'\011\011\011</cell>
+ <cell align="left" valign="middle">'$1' = []\011\011\011</cell>
+ <cell align="left" valign="middle">[]</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">['$1']\011\011\011</cell>
+ <cell align="left" valign="middle">'$1' = []\011\011\011</cell>
+ <cell align="left" valign="middle">[[]]</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">[{{a}}]\011\011\011</cell>
+ <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">[{a}]</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">42\011\011\011</cell>
+ <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">42</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">"hello"\011\011\011</cell>
+ <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">"hello"</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">$1\011\011\011</cell>
+ <cell align="left" valign="middle">doesn't matter</cell>
+ <cell align="left" valign="middle">49 (the ASCII value for the character '1')</cell>
+ </row>
+ <tcaption>Literals in the MatchCondition/MatchBody parts of a match_spec</tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>Execution of the match</title>
+ <p>The execution of the match expression, when the runtime system
+ decides whether a trace message should be sent, goes as follows:
+ </p>
+ <p>For each tuple in the <c><![CDATA[MatchExpression]]></c> list and while no
+ match has succeeded:</p>
+ <list type="bulleted">
+ <item>Match the <c><![CDATA[MatchHead]]></c> part against the arguments to the
+ function,
+ binding the <c><![CDATA['$<number>']]></c> variables (much like in
+ <c><![CDATA[ets:match/2]]></c>).
+ If the <c><![CDATA[MatchHead]]></c> cannot match the arguments, the match fails.
+ </item>
+ <item>Evaluate each <c><![CDATA[MatchCondition]]></c> (where only
+ <c><![CDATA['$<number>']]></c> variables previously bound in the
+ <c><![CDATA[MatchHead]]></c> can occur) and expect it to return the atom
+ <c><![CDATA[true]]></c>. As soon as a condition does not evaluate to
+ <c><![CDATA[true]]></c>, the match fails. If any BIF call generates an
+ exception, also fail.
+ </item>
+ <item>
+ <list type="bulleted">
+ <item><em>If the match_spec is executing when tracing:</em><br></br>
+ Evaluate each <c><![CDATA[ActionTerm]]></c> in the same way as the
+ <c><![CDATA[MatchConditions]]></c>, but completely ignore the return
+ values. Regardless of what happens in this part, the match has
+ succeeded.</item>
+ <item><em>If the match_spec is executed when selecting objects from an ETS table:</em><br></br>
+ Evaluate the expressions in order and return the value of
+ the last expression (typically there is only one expression
+ in this context)</item>
+ </list>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Differences between match specifications in ETS and tracing</title>
+ <p>ETS match specifications are there to produce a return
+ value. Usually the expression contains one single
+ <c><![CDATA[ActionTerm]]></c> which defines the return value without having
+ any side effects. Calls with side effects are not allowed in the
+ ETS context.</p>
+ <p>When tracing there is no return value to produce, the
+ match specification either matches or doesn't. The effect when the
+ expression matches is a trace message rather then a returned
+ term. The <c><![CDATA[ActionTerm]]></c>'s are executed as in an imperative
+ language, i.e. for their side effects. Functions with side effects
+ are also allowed when tracing.</p>
+ <p>In ETS the match head is a <c><![CDATA[tuple()]]></c> (or a single match
+ variable) while it is a list (or a single match variable) when
+ tracing.</p>
+ </section>
+
+ <section>
+ <title>Examples</title>
+ <p>Match an argument list of three where the first and third arguments
+ are equal:</p>
+ <code type="none"><![CDATA[
+[{['$1', '_', '$1'],
+ [],
+ []}]
+ ]]></code>
+ <p>Match an argument list of three where the second argument is
+ a number greater than three:</p>
+ <code type="none"><![CDATA[
+[{['_', '$1', '_'],
+ [{ '>', '$1', 3}],
+ []}]
+ ]]></code>
+ <p>Match an argument list of three, where the third argument
+ is a tuple containing argument one and two <em>or</em> a list
+ beginning with argument one and two (i. e. <c><![CDATA[[a,b,[a,b,c]]]]></c> or
+ <c><![CDATA[[a,b,{a,b}]]]></c>):
+ </p>
+ <code type="none"><![CDATA[
+[{['$1', '$2', '$3'],
+ [{orelse,
+ {'=:=', '$3', {{'$1','$2'}}},
+ {'and',
+ {'=:=', '$1', {hd, '$3'}},
+ {'=:=', '$2', {hd, {tl, '$3'}}}}}],
+ []}]
+ ]]></code>
+ <p>The above problem may also be solved like this:</p>
+ <code type="none"><![CDATA[
+[{['$1', '$2', {'$1', '$2}], [], []},
+ {['$1', '$2', ['$1', '$2' | '_']], [], []}]
+ ]]></code>
+ <p>Match two arguments where the first is a tuple beginning with
+ a list which in turn begins with the second argument times
+ two (i. e. [{[4,x],y},2] or [{[8], y, z},4])</p>
+ <code type="none"><![CDATA[
+[{['$1', '$2'],\011[{'=:=', {'*', 2, '$2'}, {hd, {element, 1, '$1'}}}],
+ []}]\011
+ ]]></code>
+ <p>Match three arguments. When all three are equal and are
+ numbers, append the process dump to the trace message, else
+ let the trace message be as is, but set the sequential trace
+ token label to 4711.</p>
+ <code type="none"><![CDATA[
+[{['$1', '$1', '$1'],
+ [{is_number, '$1'}],
+ [{message, {process_dump}}]},
+ {'_', [], [{set_seq_token, label, 4711}]}]
+ ]]></code>
+ <p>As can be noted above, the parameter list can be matched
+ against a single <c><![CDATA[MatchVariable]]></c> or an <c><![CDATA['_']]></c>. To replace the
+ whole
+ parameter list with a single variable is a special case. In all
+ other cases the <c><![CDATA[MatchHead]]></c> has to be a <em>proper</em> list.
+ </p>
+ <p>Match all objects in an ets table where the first element is
+ the atom 'strider' and the tuple arity is 3 and return the whole
+ object.</p>
+ <code type="none"><![CDATA[
+[{{strider,'_'.'_'},
+ [],
+ ['$_']}]
+ ]]></code>
+ <p>Match all objects in an ets table with arity &gt; 1 and the first
+ element is 'gandalf', return element 2.</p>
+ <code type="none"><![CDATA[
+[{'$1',
+ [{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
+ [{element,2,'$1'}]}]
+ ]]></code>
+ <p>In the above example, if the first element had been the key,
+ it's much more efficient to match that key in the <c><![CDATA[MatchHead]]></c>
+ part than in the <c><![CDATA[MatchConditions]]></c> part. The search space of
+ the tables is restricted with regards to the <c><![CDATA[MatchHead]]></c> so
+ that only objects with the matching key are searched.
+ </p>
+ <p>Match tuples of 3 elements where the second element is either
+ 'merry' or 'pippin', return the whole objects.</p>
+ <code type="none"><![CDATA[
+[{{'_',merry,'_'},
+ [],
+ ['$_']},
+ {{'_',pippin,'_'},
+ [],
+ ['$_']}]
+ ]]></code>
+ <p>The function <c><![CDATA[ets:test_ms/2]]></c> 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
new file mode 100644
index 0000000000..2252358e0d
--- /dev/null
+++ b/erts/doc/src/notes.xml
@@ -0,0 +1,5439 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2004</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>ERTS Release Notes</title>
+ <prepared>otp_appnotes</prepared>
+ <docno>nil</docno>
+ <date>nil</date>
+ <rev>nil</rev>
+ <file>notes.xml</file>
+ </header>
+ <p>This document describes the changes made to the ERTS application.</p>
+
+<section><title>Erts 5.7.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ An insufficient stack allocation was made when reading
+ CPU information on BSD operating systems. (Thanks Michael
+ Turner and Akira Kitada)</p>
+ <p>
+ Own Id: OTP-8207</p>
+ </item>
+ <item>
+ <p>
+ A bug when supplying an argument without a dash directly
+ after the program name when starting erlang could prevent
+ distribution to start. This is now corrected.</p>
+ <p>
+ Own Id: OTP-8209</p>
+ </item>
+ <item>
+ <p>
+ A ticker process could potentially be blocked
+ indefinitely trying to send a tick to a node not
+ responding. If this happened, the connection would not be
+ brought down as it should.</p>
+ <p>
+ Own Id: OTP-8218</p>
+ </item>
+ <item>
+ <p>
+ Using certain firewalls (i.e. MS IAS Client and certain
+ versions of COMODO) could expose an undocumented
+ behaviour in the Win32 socket interface causing the name
+ resolution calls to hang infinitely. This is now worked
+ around by adding possibilities for port programs under
+ Windows to use overlapped I/O on their standard
+ input/output file handles.</p>
+ <p>
+ Own Id: OTP-8230</p>
+ </item>
+ <item>
+ <p>
+ Fixed bug on ETS tables with <c>write_concurrency</c>.
+ The emulator could crash when doing a <c>select</c> or
+ <c>match</c> with a bound key without finding any object.</p>
+ <p>
+ Own Id: OTP-8242</p>
+ </item>
+ <item>
+ <p>The <c>information-request</c> /
+ <c>information-response</c>, and
+ <c>group-leader-change-request</c> /
+ <c>group-leader-changed-response</c> signal pairs
+ described below did not always adhere to the signal order
+ guarantees of Erlang's signal model in the runtime system
+ with SMP support. These signals could for example
+ sometimes pass exit signals.</p>
+ <p>The following BIFs behaviors can be modeled as if an
+ asynchronous <c>information-request</c> signal is sent to
+ <c>Pid</c>. If <c>Pid</c> is alive, it responds with an
+ asynchronous <c>information-response</c> signal;
+ otherwise, the runtime system responds with a
+ <c>no-such-process</c> signal. When the response is
+ received, the caller transforms it into the result of the
+ BIF.</p> <list> <item><c>is_process_alive(Pid)</c></item>
+ <item><c>erlang:process_display(Pid, Type)</c></item>
+ <item><c>process_info(Pid)</c></item>
+ <item><c>process_info(Pid, ItemSpec)</c></item> </list>
+ <p>When <c>Pid</c> resides on the same node as the caller
+ of <c>group_leader(GroupLeader, Pid)</c>, the
+ <c>group_leader/2</c> BIFs behavior can be modeled as if
+ an asynchronous <c>group-leader-change-request</c> signal
+ is sent to <c>Pid</c>. If <c>Pid</c> is alive, it
+ responds with an asynchronous
+ <c>group-leader-changed-response</c> signal; otherwise,
+ the runtime system responds with a <c>no-such-process</c>
+ signal. When the response is received, the caller
+ transforms it into the result of the BIF. The distributed
+ case which only consists of an asynchronous
+ <c>group-leader-change-request</c> signal and no response
+ is not effected.</p>
+ <p>
+ Own Id: OTP-8245</p>
+ </item>
+ <item>
+ <p>
+ Errors in the <c>system_profile</c> documentation has
+ been corrected.</p>
+ <p>
+ Own Id: OTP-8257</p>
+ </item>
+ <item>
+ <p>
+ Low watermark socket option modified high watermark
+ instead of low watermark in the inet_driver. (Thanks to
+ Feng Yu and Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-8279</p>
+ </item>
+ <item>
+ <p>
+ A race condition could cause the runtime system with SMP
+ support to end up in a completely unresponsive state.</p>
+ <p>
+ Own Id: OTP-8297</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The use of <c>pthread_cond_timedwait()</c> have been
+ completely removed from the runtime system. This since
+ its behavior is unpredictable when the system clock is
+ suddenly changed. The previous use of it was harmless.</p>
+ <p>
+ Own Id: OTP-8193</p>
+ </item>
+ <item>
+ <p>
+ The documentation is now built with open source tools
+ (xsltproc and fop) that exists on most platforms. One
+ visible change is that the frames are removed.</p>
+ <p>
+ Own Id: OTP-8201</p>
+ </item>
+ <item>
+ <p>
+ A new garbage collecting strategy for binaries which is
+ more aggressive than the previous implementation.
+ Binaries now has a virtual binary heap tied to each
+ process. When binaries are created or received to a
+ process it will check if the heap limit has been reached
+ and if a reclaim should be done. This imitates the
+ behavior of ordinary Erlang terms. The virtual heaps are
+ grown and shrunk like ordinary heaps. This will lessen
+ the memory footprint of binaries in a system.</p>
+ <p>
+ Own Id: OTP-8202</p>
+ </item>
+ <item>
+ <p>
+ The <c>ErlDrvTermData</c> term types used by
+ <c>driver_output_term()</c> and <c>driver_send_term()</c>
+ have been extended with the term types
+ <c>ERL_DRV_INT64</c>, and <c>ERL_DRV_UINT64</c> for
+ passing 64-bit integers. Also the 64-bit integer data
+ types <c>ErlDrvSInt64</c> and <c>ErlDrvUInt64</c> have
+ been introduced.</p>
+ <p>
+ For more information see the <seealso
+ marker="erl_driver">erl_driver(3)</seealso>
+ documentation.</p>
+ <p>
+ Own Id: OTP-8205</p>
+ </item>
+ <item>
+ <p>
+ [escript] The restriction that the first line in escripts
+ must begin with <c>#!</c> has been removed.</p>
+ <p>
+ [escript] Some command line options to the escript
+ executable has now been documented. For example you can
+ run an escript in the debugger by just adding a command
+ line option.</p>
+ <p>
+ [escript] The documentation of the escript header syntax
+ has been clarified. For example the header is optional.
+ This means that it is possible to directly "execute"
+ <c>.erl</c>, <c>.beam</c> and<c>.zip</c> files.</p>
+ <p>
+ Own Id: OTP-8215</p>
+ </item>
+ <item>
+ <p>
+ The instruction for building OTP on Windows was outdated
+ and incomplete, the document is updated.</p>
+ <p>
+ Also the otp_build script required windows drives to show
+ up in Cygwin using the /cygdrive prefix. That requirement
+ is now removed.</p>
+ <p>
+ Own Id: OTP-8219</p>
+ </item>
+ <item>
+ <p>
+ A module can have native implemented functions (NIFs)
+ that are dynamically loaded by calling
+ <c>erlang:load_nif/2</c>. This is an experimental feature
+ that is not yet intended for production systems. It is
+ released with intention to get some early feedback on the
+ interfaces before they are carved in stone.</p>
+ <p>
+ Own Id: OTP-8220</p>
+ </item>
+ <item>
+ <p>
+ The <c>float/1</c> BIF would always force a garbage
+ collection. The BIFs <c>size/1</c>, <c>byte_size/1</c>,
+ <c>bit_size/1</c>, <c>abs/1</c>, and <c>round/1</c> would
+ force a garbage-collection if the result was not a
+ sufficiently small integer.</p>
+ <p>
+ Own Id: OTP-8221</p>
+ </item>
+ <item>
+ <p>
+ The <seealso
+ marker="erlang#erlang:port_command/3">erlang:port_command/3</seealso>
+ BIF has been added. <c>erlang:port_command/3</c> is
+ currently not auto imported, but it is planned to be auto
+ imported in OTP R14. For more information see the
+ <seealso marker="erlang">erlang(3)</seealso>
+ documentation.</p>
+ <p>
+ Own Id: OTP-8225</p>
+ </item>
+ <item>
+ <p>
+ '<c>configure --enable-darwin-64bit</c>' would fail if
+ Snow Leopard had been booted with the 64-bit kernel.
+ (Thanks to Ryan M. Graham.)</p>
+ <p>
+ Own Id: OTP-8236</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ On Windows, open_port({spawn,Command},Opts) could not run
+ executables with spaces in the path or filename,
+ regardless of quoting efforts. While
+ open_port({spawn_executable,Exec},Opts) can run any
+ executable, it was still impossible to use 'spawn' to do
+ the same thing. This is now corrected.</p>
+ <p>
+ Own Id: OTP-8055</p>
+ </item>
+ <item>
+ <p>
+ The scheduler bind type <c>processor_spread</c> spread
+ schedulers too much on large NUMA systems.</p>
+ <p>
+ The new scheduler bind type <c>spread</c> spreads
+ schedulers as much as possible, and behaves as
+ <c>processor_spread</c> previously did. For more
+ information see the documentation of the <c>+sbt</c>
+ command line argument in the <c>erl(1)</c> documentation,
+ and the documentation of
+ <c>erlang:system_flag(scheduler_bind_type,
+ SchedulerBindType)</c>.</p>
+ <p>
+ Own Id: OTP-8063</p>
+ </item>
+ <item>
+ <p>
+ Automatically detected CPU topology on Linux system could
+ erroneously contain logical processors with <c>-1</c> as
+ identifiers. This happened when
+ <c>sysconf(_SC_NPROCESSORS_CONF)</c> returned a value
+ larger than the amount of logical processors found.</p>
+ <p>
+ Own Id: OTP-8064</p>
+ </item>
+ <item>
+ <p>
+ When the minimal term [] (end of list) was sent as the
+ complete message to a process on another node, and
+ received there, it could not be decoded. This bug is now
+ corrected. Fortunately [] is uncommon as the complete
+ message in real applications but it is a serious bug
+ anyway.</p>
+ <p>
+ Own Id: OTP-8092</p>
+ </item>
+ <item>
+ <p>A bug when the floating point exception pointer was
+ not initialized has been corrected. It manifested itself
+ on CentOS 5.1 sometimes when a floating point value was
+ sent to a remote node. Bug reported and patch suggested
+ by David Reiss, confirmed by Mikael Pettersson.</p>
+ <p>Some build problems on IRIX was also corrected.
+ Problem reported by Patrick Baggett, patch by Mikael
+ Pettersson.</p>
+ <p>
+ Own Id: OTP-8095</p>
+ </item>
+ <item>
+ <p>
+ A terminating process could erroneously unregister a name
+ for another process. This could occur under the following
+ conditions: The name of the terminating process was
+ unregistered and then registered for another process
+ simultaneously as the process that first had the name was
+ terminating.</p>
+ <p>
+ Own Id: OTP-8099 Aux Id: seq11344 </p>
+ </item>
+ <item>
+ <p>
+ Running erlc in a very deep directory (with a path length
+ of more 256 or more characters) would cause the emulator
+ to crash in a call to <c>list_to_atom/1</c>. (Thanks to
+ Chris Newcombe.)</p>
+ <p>
+ Own Id: OTP-8124</p>
+ </item>
+ <item>
+ <p>
+ A deadlock of the runtime system could occur when
+ unregistering the name of a port.</p>
+ <p>
+ Own Id: OTP-8145</p>
+ </item>
+ <item>
+ <p>
+ <c>Makefile.in</c> has been updated to use the LDFLAGS
+ environment variable (if set). (Thanks to Davide
+ Pesavento.)</p>
+ <p>
+ Own Id: OTP-8157</p>
+ </item>
+ <item>
+ <p>
+ The pthread rwlock implemention on Linux could cause
+ starvation of writers. We, therefore, now use our own
+ rwlock implementation on Linux.</p>
+ <p>
+ Own Id: OTP-8158</p>
+ </item>
+ <item>
+ <p>
+ Open source Erlang builds are updated to work well on
+ Snow Leopard (MacOS X 10.6)</p>
+ <p>
+ Own Id: OTP-8168</p>
+ </item>
+ <item>
+ <p>
+ A call to <c>erlang:system_info(schedulers_online)</c>
+ could end up in an infinite loop. This happened if the
+ amount of schedulers was larger than one, the amount of
+ schedulers online was one, and someone was blocking
+ multi-scheduling.</p>
+ <p>
+ Own Id: OTP-8169</p>
+ </item>
+ <item>
+ <p>
+ An error in erlang:system_profile/2 could cause
+ timestamped messages to arrive out of order in the SMP
+ case. This has now been fixed.</p>
+ <p>
+ Own Id: OTP-8171</p>
+ </item>
+ <item>
+ <p>
+ <c>binary_to_atom/2</c> and
+ <c>binary_to_existing_atom/2</c> would leak memory if the
+ binary contained unaligned data.</p>
+ <p>
+ Own Id: OTP-8192</p>
+ </item>
+ <item>
+ <p>
+ The async thread pool in the runtime system without SMP
+ support used a memory allocator that was not thread safe
+ for async jobs.</p>
+ <p>
+ Own Id: OTP-8194</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Processor internal NUMA nodes are now supported in the
+ ERTS internal CPU topology representation. For more
+ information see the documentation of the <c>+sct</c>
+ command line argument in the <c>erl(1)</c> documentation,
+ and the documentation of
+ <c>erlang:system_info(cpu_topology)</c>.</p>
+ <p>
+ Own Id: OTP-8041</p>
+ </item>
+ <item>
+ <p>
+ Documentation for ets improved about concurrency.</p>
+ <p>
+ Own Id: OTP-8050</p>
+ </item>
+ <item>
+ <p>
+ Emulator flags in an escript were earlier inherited to
+ emulators started from from the emulator running the
+ escript. For example when an escript invoked
+ <c>os:cmd("erl")</c>, the new emulator were given
+ erroneous emulator flags. This bug has now been fixed</p>
+ <p>
+ Escript filenames may now contain dots.</p>
+ <p>
+ Own Id: OTP-8060</p>
+ </item>
+ <item>
+ <p>
+ Made some BIFs non-recursive (relational operators,hash
+ and phash) to limit internal stack usage.</p>
+ <p>
+ Own Id: OTP-8065</p>
+ </item>
+ <item>
+ <p>
+ Fixed Windows specific bug in erl_prim_loader. Now it
+ handles the root directory (e.g. c:/) better. This bug
+ affected the directory listing in the debugger.</p>
+ <p>
+ Own Id: OTP-8080</p>
+ </item>
+ <item>
+ <p>
+ A TCP socket with option <c>{packet,4}</c> could crash
+ the emulator if it received a packet header with a very
+ large size value (>2Gb). The same bug caused
+ <c>erlang:decode_packet/3</c> to return faulty values.
+ (Thanks to Georgos Seganos.)</p>
+ <p>
+ Own Id: OTP-8102</p>
+ </item>
+ <item>
+ <p>
+ The maximum size of the export table has been raised from
+ 65536 to 524288 entries.</p>
+ <p>
+ Own Id: OTP-8104 Aux Id: seq11345 </p>
+ </item>
+ <item>
+ <p>
+ The file module has now a read_line/1 function similar to
+ the io:get_line/2, but with byte oriented semantics. The
+ function file:read_line/1 works for raw files as well,
+ but for good performance it is recommended to use it
+ together with the 'read_ahead' option for raw file
+ access.</p>
+ <p>
+ Own Id: OTP-8108</p>
+ </item>
+ <item>
+ <p>
+ Fixed bug causing emulator crash when reading a term in
+ external format containing a corrupt list with a negative
+ length.</p>
+ <p>
+ Own Id: OTP-8117</p>
+ </item>
+ <item>
+ <p>
+ New emulator flag <c>+sss</c>, to set stack size of
+ scheduler threads.</p>
+ <p>
+ Own Id: OTP-8119</p>
+ </item>
+ <item>
+ <p>
+ The Windows utility Erlsrv, run in interactive mode now
+ accepts options for registering internal service name and
+ description field of Windows registry database.</p>
+ <p>
+ Own Id: OTP-8132</p>
+ </item>
+ <item>
+ <p>
+ <c>erlang:demonitor(Mon, [flush])</c> has been optimized.
+ Previously it always searched the message queue of the
+ caller for a <c>'DOWN'</c> message. Current
+ implementation only search the message queue when
+ necessary. It is quite common that the search is not
+ necessary.</p>
+ <p>
+ A new option <c>info</c> has been added to
+ <c>erlang:demonitor/2</c>. For more information see the
+ <c>erlang(3)</c> documentation.</p>
+ <p>
+ Own Id: OTP-8143</p>
+ </item>
+ <item>
+ <p>
+ I/O tasks could unnecessarily be rescheduled. This was
+ harmless, but not useful work.</p>
+ <p>
+ Own Id: OTP-8148</p>
+ </item>
+ <item>
+ <p>
+ Minor improvements of <c>erlang:memory/[1,2]</c>.</p>
+ <p>
+ Own Id: OTP-8152</p>
+ </item>
+ <item>
+ <p>
+ New configuration option to enable use of shared zlib.</p>
+ <p>
+ Own Id: OTP-8155</p>
+ </item>
+ <item>
+ <p>
+ Fixed smp bug in ETS that could cause emulator crash when
+ table with more than 1000 objects accessed by several
+ processes, including calls to variants of <c>select</c>
+ or <c>match</c> combined with concurrent object deletion.</p>
+ <p>
+ Own Id: OTP-8166 Aux Id: seq11392 </p>
+ </item>
+ <item>
+ <p>
+ The code path interpretation is now more relaxed. The
+ flag -code_path_choice now defaults to relaxed instead of
+ strict. See the documentation of code and init for more
+ info.</p>
+ <p>
+ Own Id: OTP-8170</p>
+ </item>
+ <item>
+ <p>
+ Load balancing of run queues and check for I/O are
+ triggered more often than before in situations where
+ processes are scheduled often but are doing very little
+ work each time they execute.</p>
+ <p>
+ Own Id: OTP-8172</p>
+ </item>
+ <item>
+ <p>
+ Call tracing binary comprehensions would cause an
+ emulator crash. (Thanks to Paul Mineiro.)</p>
+ <p>
+ Own Id: OTP-8179</p>
+ </item>
+ <item>
+ <p>
+ <c>binary_to_term/1</c> would crash the emulator instead
+ of generating a <c>badarg</c> exception when given
+ certain invalid terms. (Thanks to Scott Lystig Fritchie.)</p>
+ <p>
+ Own Id: OTP-8180</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Crash dumps should now cause less problems for the
+ crashdump_viewer application. (For processes where arity
+ was non-zero, the arguments are now longer printed - they
+ used to be printed in a format that was not parseable.)</p>
+ <p>
+ Own Id: OTP-7472 Aux Id: seq11019, 11292 </p>
+ </item>
+ <item>
+ <p>
+ Processes could potentially get stuck on an offline
+ scheduler.</p>
+ <p>
+ Own Id: OTP-7990</p>
+ </item>
+ <item>
+ <p>
+ <c>binary_to_atom/2</c> and
+ <c>binary_to_existing_atom/2</c> could leak memory if
+ they caused a <c>badarg</c> exception.</p>
+ <p>
+ Own Id: OTP-7997</p>
+ </item>
+ <item>
+ <p>
+ A process could under very rare circumstances erroneously
+ be resumed.</p>
+ <p>
+ Own Id: OTP-8000</p>
+ </item>
+ <item>
+ <p>
+ Load balancing between schedulers could under rare
+ circumstances cause an emulator crash.</p>
+ <p>
+ Own Id: OTP-8008</p>
+ </item>
+ <item>
+ <p>
+ <c>erlang:memory(processes_used)</c> always returned
+ <c>0</c> instead of the correct value. (Thanks to Geoff
+ Cant)</p>
+ <p>
+ Own Id: OTP-8022</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Major improvements of the Erlang distribution for Erlang
+ runtime systems with SMP support. Previously distribution
+ port locks were heavily contended, and all encoding and
+ decoding for a specific distribution channel had to be
+ done in sequence. Lock contention due to the distribution
+ is now negligible and both encoding and decoding of
+ Erlang messages can be done in parallel.</p>
+ <p>
+ The old atom cache protocol used by the Erlang
+ distribution has been dropped since it effectively
+ prevented all parallel encoding and decoding of messages
+ passed over the same distribution channel.</p>
+ <p>
+ A new atom cache protocol has been introduced which
+ isolates atom cache accesses and makes parallel encoding
+ and decoding of messages passed over the same
+ distribution channel possible. The new atom cache
+ protocol also use an atom cache size 8 times larger than
+ before. The new atom cache protocol is documented in the
+ ERTS users guide.</p>
+ <p>
+ Erlang messages received via the distribution are now
+ decoded by the receiving Erlang processes without holding
+ any distribution channel specific locks. Erlang messages
+ and signals sent over the distribution are as before
+ encoded by the sending Erlang process, but now without
+ holding any distribution channel specific locks during
+ the encoding. That is, both encoding and decoding can be
+ and are done in parallel regardless of distribution
+ channel used.</p>
+ <p>
+ The part that cannot be parallelized is the atom cache
+ updates. Atom cache updates are therefore now scheduled
+ on the distribution port. Since it is only one entity per
+ distribution channel doing this work there is no lock
+ contention due to the atom cache updates.</p>
+ <p>
+ The new runtime system does not understand the old atom
+ cache protocol. New and old runtime systems can however
+ still communicate, but no atom cache will be used.</p>
+ <p>
+ Own Id: OTP-7774</p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug that caused error logging from
+ <c>driver_select</c> sometimes with additional symptoms
+ such as failing IP communications or even an emulator
+ crash.</p>
+ <p>
+ Own Id: OTP-7898 Aux Id: seq11304 </p>
+ </item>
+ <item>
+ <p>
+ Improved SMP concurrency for ETS tables. Several mutating
+ operations can now be performed truly concurrent on
+ different records of the same table. To support this, the
+ table has to be created with option
+ <c>write_concurrency</c>, as it is achieved at the
+ expense of some execution and memory overhead.
+ <c>ets:select</c> and <c>select_count</c> has also been
+ improved for all tables to not acquire exclusive table
+ lock during the iteration.</p>
+ <p>
+ Own Id: OTP-7922</p>
+ </item>
+ <item>
+ <p>
+ erl (that is erl.exe and dyn_erl) and erlexec has been
+ made more dynamic so no hard coded paths needs to added
+ at installation time to erl (that is erl.ini and erl).
+ Reltool will make use of this in a future release.</p>
+ <p>
+ Own Id: OTP-7952</p>
+ </item>
+ <item>
+ <p>
+ Added functionality to get higher resolution timestamp
+ from system. The erlang:now function returns a timestamp
+ that's not always consistent with the actual operating
+ system time (due to resilience against large time changes
+ in the operating system). The function os:timestamp/0 is
+ added to get a similar timestamp as the one being
+ returned by erlang:now, but untouched by Erlangs time
+ correcting and smoothing algorithms. The timestamp
+ returned by os:timestamp is always consistent with the
+ operating systems view of time, like the calendar
+ functions for getting wall clock time, but with higher
+ resolution. Example of usage can be found in the os
+ manual page.</p>
+ <p>
+ Own Id: OTP-7971</p>
+ </item>
+ <item>
+ <p>
+ Two new options are added to open_port - spawn_executable
+ which runs external executables in a controlled way, and
+ spawn_driver which only opens port to loaded Erlang
+ drivers. See the erlang manual page for details.</p>
+ <p>
+ Own Id: OTP-7995</p>
+ </item>
+ <item>
+ <p>
+ New functionality in ETS to transfer the ownership of a
+ table. A table can either change owner be declaring an
+ "heir", another process that will inherit the table if
+ the owner terminates. A table can also change owner by
+ calling a new function <c>ets:give_away</c>.</p>
+ <p>
+ Own Id: OTP-8006</p>
+ </item>
+ <item>
+ <p>
+ Updates to Tilera build environment.</p>
+ <p>
+ Own Id: OTP-8009</p>
+ </item>
+ <item>
+ <p>
+ A stack trace was unnecessarily saved during process
+ termination.</p>
+ <p>
+ Own Id: OTP-8014</p>
+ </item>
+ <item>
+ <p>
+ User defined CPU topology and scheduler bind type can now
+ be set from the command line when starting an emulator.
+ For more information see the documentation of the
+ <c>+sct</c>, and the <c>+sbt</c> emulator flags in the
+ <c>erl(1)</c> documentation.</p>
+ <p>
+ The CPU topologies returned from
+ <c>erlang:system_info/1</c> and
+ <c>erlang:system_flag/2</c> now always contain the
+ <c>processor</c> level, also when not strictly necessary.</p>
+ <p>
+ Own Id: OTP-8030</p>
+ </item>
+ <item>
+ <p>
+ Various fixes in ETS: <c>ets:first</c> could return a
+ deleted key in a fixated table. <c>ets:lookup</c> could
+ return objects out of order if a deleted object was
+ re-inserted into a fixed bag. <c>ets:delete_object</c>
+ could fail to delete duplicate objects in a
+ duplicate_bag.</p>
+ <p>
+ Own Id: OTP-8040</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a bug on Windows that could make
+ <c>gen_tcp:send</c> hang trying to send an iolist of more
+ than 16 binaries.</p>
+ <p>
+ Own Id: OTP-7816</p>
+ </item>
+ <item>
+ <p>
+ The runtime system could under rare circumstances crash
+ during load balancing.</p>
+ <p>
+ Own Id: OTP-7908 Aux Id: otp-7500 </p>
+ </item>
+ <item>
+ <p>
+ <c>run_erl</c> uses fallback if Unix98 pseudo-terminal is
+ not present on host.</p>
+ <p>
+ Own Id: OTP-7916 Aux Id: seq11249 </p>
+ </item>
+ <item>
+ <p>
+ A message buffer memory leak in the runtime system
+ without smp support has been fixed.</p>
+ <p>
+ Own Id: OTP-7941</p>
+ </item>
+ <item>
+ <p>Attempting to append a binary of 16Mb or greater to
+ another binary using the bit syntax would cause a
+ <c>system_limit</c> exception. There was also several
+ cases when constructing binaries when a <c>badarg</c>
+ exception was generated when it should have been
+ <c>system_limit</c>.</p>
+ <p>
+ Own Id: OTP-7942</p>
+ </item>
+ <item>
+ <p>
+ The runtime system with SMP support failed to terminate
+ the caller of <c>link(RemotePid)</c> properly, if
+ <c>RemotePid</c> was the pid of a process on an
+ unreachable node. The calling process was in this case
+ marked as exiting, but never terminated.</p>
+ <p>
+ Own Id: OTP-7946</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Rudimentary support for cross compiling is added to the
+ source release. The support is still in its infancy and
+ has only been used to cross compile on Linux for a
+ different cpu architecture and a different Linux version,
+ but should be extendible to support other platforms as
+ well. The cross configuration files with examples are
+ placed in $ERL_TOP/xcomp/. View README.xcomp and run
+ $ERL_TOP/otp_build -help for further information.</p>
+ <p>
+ Own Id: OTP-7854</p>
+ </item>
+ <item>
+ <p>The escape sequence <c>\{</c> which was given a new
+ interpretation in R13A has retained its old meaning (the
+ ASCII code for <c>{</c>), which means that codes greater
+ than 255 have to be stated using hexadecimal characters
+ (for example, <c>\x{AAA}</c>). The escape sequence
+ <c>\xH</c> where H is a hexadecimal character followed by
+ something else but a hexadecimal character is no longer
+ valid (incompatibility with R13A). Character codes less
+ than 256 can be stated using two hexadecimal characters
+ (for example, <c>\x0D</c>).</p>
+ <p>
+ Own Id: OTP-7891 Aux Id: OTP-7855 </p>
+ </item>
+ <item>
+ <p>The <c>term_to_binary/1</c> BIF used to be implemented
+ with recursive C code, which could cause the Erlang
+ emulator to terminate because of a stack overflow.</p>
+ <p>Also fixed some minor issues in
+ <c>term_to_binary/1</c> and <c>binary_to_term/1</c>
+ pointed out by Matthew Dempsky.</p>
+ <p>
+ Own Id: OTP-7894</p>
+ </item>
+ <item>
+ <p>
+ Several glitches and performance issues in the Unicode
+ and I/O-system implementation of R13A have been
+ corrected.</p>
+ <p>
+ Own Id: OTP-7896 Aux Id: OTP-7648 OTP-7887 </p>
+ </item>
+ <item>
+ <p>
+ Minor documentation improvements of the
+ <c>scheduler_bind_type</c> argument of
+ <c>erlang:system_flag/2</c>, and the
+ <c>scheduler_bind_type</c>, and the
+ <c>scheduler_bindings</c> arguments of
+ <c>erlang:system_info/1</c>.</p>
+ <p>
+ Own Id: OTP-7901 Aux Id: OTP-7777 </p>
+ </item>
+ <item>
+ <p>
+ There is a new BIF <c>erlang:make_tuple/3</c>.</p>
+ <p>
+ Own Id: OTP-7913</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Erts 5.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p><em>OpenSource:</em></p>
+ <p>FreeBSD leap-seconds are handled according to patch
+ submitted by OpenSource user Kenji Rikitake. No test case
+ covers this functionality (unsupported platform).</p>
+ <p>
+ Own Id: OTP-7609</p>
+ </item>
+ <item>
+ <p>
+ A corrected bug in <c>ets</c> for <c>bag</c> and
+ <c>duplicate_bag</c>. A <c>delete/2</c> or
+ <c>lookup_element/3</c> could miss objects in a fixed
+ table if one or more objects with the same key had
+ already been deleted.</p>
+ <p>
+ Own Id: OTP-7665</p>
+ </item>
+ <item>
+ <p>
+ A new driver call-back <c>stop_select</c> is introduced
+ to allow drivers to de-select and then close a file
+ descriptor in a safe way in a SMP emulator. The old way
+ was not strictly according to posix standard and could in
+ some rare cases lead to unexpected behavior. A new flag
+ <c>ERL_DRV_USE</c> can be passed to
+ <c>driver_select()</c> to tell it that the descriptor
+ should be closed. <c>stop_select</c> is then called when
+ it is safe to do so. Old drivers will however still work
+ as before.</p>
+ <p>
+ Own Id: OTP-7670</p>
+ </item>
+ <item>
+ <p>
+ A bug fixed for TCP sockets with option
+ <c>{packet,http}</c>. An HTTP request with an absolute
+ URI was returned with a corrupt path string. This bug did
+ only exist in R12B-4 and R12B-5.</p>
+ <p>
+ Own Id: OTP-7682 Aux Id: OTP-7647 </p>
+ </item>
+ <item>
+ <p>
+ run_erl did in some cases fail to extract control
+ sequences from to_erl (like: winsize=X,Y) and did instead
+ send them to be interpreted by the erlang shell.</p>
+ <p>
+ Own Id: OTP-7688</p>
+ </item>
+ <item>
+ <p>
+ A bug in the installer on Windows not updating file
+ associations properly is now corrected.</p>
+ <p>
+ Own Id: OTP-7746</p>
+ </item>
+ <item>
+ <p>More space than necessary could be allocated in
+ binaries when appending to a binary (also in a binary
+ comprehension) and the data appended did not consist of
+ wholes bytes (e.g. 13 bits).</p>
+ <p>
+ Own Id: OTP-7747</p>
+ </item>
+ <item>
+ <p>
+ The gen_sctp option sctp_peer_addr_params,
+ #sctp_paddrparams{address={IP,Port} was erroneously
+ decoded in the inet driver. This bug has now been
+ corrected.</p>
+ <p>
+ Own Id: OTP-7755</p>
+ </item>
+ <item>
+ <p>
+ Outstanding async driver jobs leaked memory if the
+ issuing port died before the async jobs completed.</p>
+ <p>
+ Own Id: OTP-7784</p>
+ </item>
+ <item>
+ <p>A bug in the dynamic library loading affecting, among
+ others, OpenSolaris is now corrected. (Thanks to Paul
+ Fisher.)</p>
+ <p>
+ Own Id: OTP-7796</p>
+ </item>
+ <item>
+ <p>
+ run_erl compile errors fixed for FreeBSD</p>
+ <p>
+ Own Id: OTP-7817</p>
+ </item>
+ <item>
+ <p>
+ A bug in the inet driver for SCTP on Solaris showing for
+ e.g gen_sctp:abort/1 and gen_sctp:eof/1 has been
+ corrected. Patch suggestion by Simon Cornish.</p>
+ <p>
+ Own Id: OTP-7866</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The order of objects visited in select for ordered_set is
+ now documented.</p>
+ <p>
+ Own Id: OTP-7339</p>
+ </item>
+ <item>
+ <p>
+ The runtime system with SMP support now uses multiple,
+ scheduler specific run queues, instead of one globally
+ shared run queue.</p>
+ <p>
+ The lock protecting the shared run queue was heavily
+ contended, and the shared run queue also caused Erlang
+ processes to randomly migrate between schedulers with
+ negative cache effects as a result.</p>
+ <p>
+ With the current scheduler specific run queue solution,
+ lock contention due to run queue protection has been
+ reduced, and Erlang processes are only migrated when
+ needed to balance the load between the schedulers. The
+ reduced amount of migration also reduce lock contention
+ on locks protecting the scheduler specific instances of
+ the erts internal memory allocators.</p>
+ <p>
+ The scheduler specific run queues are also a necessity
+ for a lot of future planned NUMA (Non-Uniform Memory
+ Access) specific optimizations.</p>
+ <p>
+ Own Id: OTP-7500</p>
+ </item>
+ <item>
+ <p>Support for Unicode is implemented as described in
+ EEP10. Formatting and reading of unicode data both from
+ terminals and files is supported by the io and io_lib
+ modules. Files can be opened in modes with automatic
+ translation to and from different unicode formats. The
+ module 'unicode' contains functions for conversion
+ between external and internal unicode formats and the re
+ module has support for unicode data. There is also
+ language syntax for specifying string and character data
+ beyond the ISO-latin-1 range.</p>
+ <p>The interactive shell will support input and output of
+ unicode characters when the terminal and operating system
+ supports it.</p>
+ <p>Please see the EEP and the io/io_lib manual pages as
+ well as the stdlib users guide for details.</p>
+ <p><em>I/O-protocol incompatibilities:</em></p>
+ <p>The io_protocol between io_Server and client is
+ updated to handle protocol data in unicode formats. The
+ updated protocol is now documented. The specification
+ resides in the stdlib <em>users manual</em>, which is a
+ new part of the manual.</p>
+ <p><em>io module incompatibilities:</em></p>
+ <p>The io:put_chars, io:get_chars and io:get_line all
+ handle and return unicode data. In the case where
+ binaries can be provided (as to io:put_chars), they shall
+ be encoded in UTF-8. When binaries are returned (as by
+ io:get_line/get_chars when the io_server is set in
+ <em>binary mode</em>) the returned data is also
+ <em>always</em> encoded as UTF-8. The file module however
+ still returns byte-oriented data, why file:read can be
+ used instead of io:get_chars to read binary data in
+ ISO-latin-1.</p>
+ <p><em>io_lib module incompatibilities:</em></p>
+ <p>io_lib:format can, given new format directives (i.e
+ "~ts" and "~tc"), return lists containing integers larger
+ than 255. </p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7648 Aux Id: OTP-7580 OTP-7514 OTP-7494
+ OTP-7443 OTP-7181 EEP10 EEP11 </p>
+ </item>
+ <item>
+ <p>
+ The format of the string returned by
+ <c>erlang:system_info(system_version)</c> (as well as the
+ first message when Erlang is started) has changed. The
+ string now contains the both the OTP version number as
+ well as the erts version number.</p>
+ <p>
+ Own Id: OTP-7649</p>
+ </item>
+ <item>
+ <p>
+ Message passing has been further optimized for parallel
+ execution. Serial message passing is slightly more
+ expensive than before, but parallel send to a common
+ receiver is much cheaper.</p>
+ <p>
+ Own Id: OTP-7659</p>
+ </item>
+ <item>
+ <p>
+ Lock contention on the atom table lock when decoding
+ Erlang terms on the external format has been drastically
+ reduced.</p>
+ <p>
+ Own Id: OTP-7660</p>
+ </item>
+ <item>
+ <p>
+ The undocumented, unsupported, and deprecated guard BIF
+ <c>is_constant/1</c> has been removed.</p>
+ <p>
+ *** INCOMPATIBILITY with R12B ***</p>
+ <p>
+ Own Id: OTP-7673</p>
+ </item>
+ <item>
+ <p>
+ The Erlang process lock implementation has been improved
+ by Mat Hostetter at Tilera Corporation.</p>
+ <p>
+ Own Id: OTP-7692</p>
+ </item>
+ <item>
+ <p>
+ A <c>{nodedown, Node}</c> message passed by the
+ <c>net_kernel:monitor_nodes/X</c> functionality is now
+ guaranteed to be sent after <c>Node</c> has been removed
+ from the result returned by <c>erlang:nodes/Y</c>.</p>
+ <p>
+ Own Id: OTP-7725</p>
+ </item>
+ <item>
+ <p>The short-circuit operators <c>andalso</c> and
+ <c>orelse</c> no longer guarantees that their second
+ argument is either <c>true</c> or <c>false</c>. As a
+ consequence, <c>andalso</c>/<c>orelse</c> are now
+ tail-recursive.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7748</p>
+ </item>
+ <item>
+ <p>
+ A new BIF, <c>lists:keyfind/3</c>, has been added. It
+ works like <c>lists:keysearch/3</c> except that it does
+ not wrap the returned tuple in a <c>value</c> tuple in
+ case of success. (Thanks to James Hague for suggesting
+ this function.)</p>
+ <p>
+ Own Id: OTP-7752</p>
+ </item>
+ <item>
+ <p>
+ Optimization for drivers by creating small binaries
+ direct on process heap.</p>
+ <p>
+ Own Id: OTP-7762</p>
+ </item>
+ <item>
+ <p><c>I bsl N</c> could cause the Erlang virtual machine
+ to run of memory instead generating a <c>system_limit</c>
+ if N was absurdly huge. (Thanks to Daniel Hedlund.)</p>
+ <p>There would always be a garbage collection when
+ evaluating <c>I bsl N</c> or <c>I bsr N</c> if <c>I</c>
+ was a bignum.</p>
+ <p>If <c>I</c> is an integer and <c>N</c> a bignum, <c>I
+ bsl N</c> will now cause the correct <c>system_limit</c>
+ exception instead of <c>bad_arith</c> as in earlier
+ releases.</p>
+ <p>If <c>I</c> is an integer and <c>N</c> a bignum, <c>I
+ bsr N</c> will return either 0 or -1 depending on the
+ sign of <c>I</c> instead of causing a <c>bad_arith</c>
+ exception as in earlier releases.</p>
+ <p>
+ Own Id: OTP-7764</p>
+ </item>
+ <item>
+ <p>
+ Scheduler threads can now be bound to logical processors
+ on newer Linux and Solaris systems. More systems will be
+ supported in the future.</p>
+ <p>
+ In some cases performance has increased drastically when
+ binding schedulers. Schedulers are not bound by default,
+ though. This since it might cause a performance
+ degradation if multiple programs have bound to
+ processors, e.g. multiple Erlang runtime systems. For
+ more information see the documentation of
+ <c>erlang:system_flag/2</c>.</p>
+ <p>
+ In order to bind scheduler threads the CPU topology need
+ to be known. On some newer Linux and Solaris systems the
+ runtime system automatically detects the CPU topology. If
+ the emulator isn't able to automatically detect the CPU
+ topology, the CPU topology can be defined. For more
+ information see the documentation of
+ <c>erlang:system_flag/2</c>.</p>
+ <p>
+ Own Id: OTP-7777</p>
+ </item>
+ <item>
+ <p>The compiler will refuse to a compile file where the
+ module name in the file differs from the output file
+ name.</p>
+ <p>When compiling using <c>erlc</c>, the current working
+ directory will no be included in the code path (unless
+ explicitly added using "-pa .").</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7793</p>
+ </item>
+ <item>
+ <p>
+ The BIFs <c>atom_to_binary/2</c>,
+ <c>binary_to_atom/2</c>, and
+ <c>binary_to_existing_atom/2</c> have been added.</p>
+ <p>
+ Own Id: OTP-7804</p>
+ </item>
+ <item>
+ <p>
+ The amount of schedulers online can now be changed during
+ operation. The amount of schedulers online defaults to
+ the same amount as available logical processors. For more
+ information see the documentation of
+ <c>erlang:system_flag/2</c> and <c>erl</c>.</p>
+ <p>
+ Own Id: OTP-7811</p>
+ </item>
+ <item>
+ <p>The deprecated functions <c>erlang:fault/1</c>,
+ <c>erlang:fault/2</c>, and <c>file:rawopen/2</c> have
+ been removed.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7812</p>
+ </item>
+ <item>
+ <p>
+ Erts internal dynamically allocated process and port
+ specific data for rarely used data. This is used to
+ reduce memory usage of processes and ports that do not
+ use specific functionality. More functionality will be
+ moved to process and port specific data in future
+ releases.</p>
+ <p>
+ Own Id: OTP-7818</p>
+ </item>
+ <item>
+ <p>
+ New packet type <c>http_bin</c> for gen_tcp sockets and
+ <c>erlang:decode_packet</c>. It works like <c>http</c>
+ except that strings are returned as binaries instead of
+ lists.</p>
+ <p>
+ Own Id: OTP-7821</p>
+ </item>
+ <item>
+ <p>
+ The obsolete wd_keeper program for embedded Solaris
+ systems has been removed.</p>
+ <p>
+ Own Id: OTP-7822</p>
+ </item>
+ <item>
+ <p>
+ Nodes belonging to different independent clusters can now
+ co-exist on the same host with the help of a new
+ environment variable setting ERL_EPMD_PORT.</p>
+ <p>
+ Own Id: OTP-7826</p>
+ </item>
+ <item>
+ <p>There are new functions <c>erlang:min/2</c> and
+ <c>erlang:max/2</c> to calculate the minimum and maximum
+ of two terms, respectively. Note that the functions are
+ not auto-imported, so they need to be imported explicitly
+ or the <c>erlang</c> prefix must be used when calling
+ them.</p>
+ <p>
+ Own Id: OTP-7841</p>
+ </item>
+ <item>
+ <p>The copyright notices have been updated.</p>
+ <p>
+ Own Id: OTP-7851</p>
+ </item>
+ <item>
+ <p>Enhanced build environment for cross compilation to
+ Tilera Tile architecture.</p>
+ <p>Support for native ethread atomics on Tilera
+ Tile64/TilePro (Thanks to Tilera Corporation).</p>
+ <p>
+ Own Id: OTP-7852</p>
+ </item>
+ <item>
+ <p>The escape sequences <c>\x</c> and <c>\{</c> have been
+ assigned new interpretations (they used to return the
+ ASCII code for <c>x</c> and <c>{</c> respectively). One
+ or more octal characters inside curly brackets after a
+ leading backslash is from now on an alternative to the
+ existing syntax <c>\NNN</c>, but can also be used for
+ codes greater than 255. In a similar fashion, one or more
+ hexadecimal characters can be put inside curly brackets
+ after a leading <c>\x</c>. Furthermore, the escape
+ sequences <c>\xH</c> and <c>\xHH</c>, where N is a
+ hexadecimal character, can be used for codes less than
+ 256.</p>
+ <p>NOTE: These new escape sequences are still considered
+ experimental and may be changed in the R13B release.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7855</p>
+ </item>
+ <item>
+ <p>
+ The PCRE library's exported function names are now
+ prefixed with erts_ in the erlang emulator to avoid
+ clashes with dynamically loaded drivers.</p>
+ <p>
+ Own Id: OTP-7861</p>
+ </item>
+ <item>
+ <p>
+ A runtime system with SMP support will now be built by
+ default on most platforms if a usable posix thread
+ library or native windows threads are found.</p>
+ <p>
+ For more information see the top README file.</p>
+ <p>
+ Own Id: OTP-7872</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Erts 5.6.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A corrected bug in <c>ets</c> for <c>bag</c> and
+ <c>duplicate_bag</c>. A <c>delete/2</c> or
+ <c>lookup_element/3</c> could miss objects in a fixed
+ table if one or more objects with the same key had
+ already been deleted.</p>
+ <p>
+ Own Id: OTP-7665</p>
+ </item>
+ <item>
+ <p>
+ A bug fixed for TCP sockets with option
+ <c>{packet,http}</c>. An HTTP request with an absolute
+ URI was returned with a corrupt path string. This bug did
+ only exist in R12B-4 and R12B-5.</p>
+ <p>
+ Own Id: OTP-7682 Aux Id: OTP-7647 </p>
+ </item>
+ <item>
+ <p>
+ Calling <c>gen_tcp:send()</c> from several processes on
+ socket with option <c>send_timeout</c> could lead to much
+ longer timeout than specified. The solution is a new
+ socket option <c>{send_timeout_close,true}</c> that will
+ do automatic close on timeout. Subsequent calls to send
+ will then immediately fail due to the closed connection.</p>
+ <p>
+ Own Id: OTP-7731 Aux Id: seq11161 </p>
+ </item>
+ <item>
+ <p>
+ A process being garbage collected via the
+ <c>garbage_collect/1</c> BIF or the
+ <c>check_process_code/2</c> BIF didn't handle message
+ receive and resume correctly during the garbage collect.
+ When this occurred, the process returned to the state it
+ had before the garbage collect instead of entering the
+ new state.</p>
+ <p>
+ Own Id: OTP-7738</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A bug in inet_drv concerning gen_tcp:connect has been
+ corrected. A connect towards a non-open port through open
+ firewalls could sometimes erroneously be successful. Any
+ subsequent operation would fail, though.</p>
+ <p>
+ Own Id: OTP-6542</p>
+ </item>
+ <item>
+ <p>
+ Floating point arithmetics in drivers could cause a
+ runtime system crash and/or unexpected results on runtime
+ systems with floating point exceptions enabled. Floating
+ point exceptions are disabled unless explicitly enabled
+ or if hipe is enabled.</p>
+ <p>
+ Own Id: OTP-7237</p>
+ </item>
+ <item>
+ <p>
+ A bug when many sockets got signalled simultaneously
+ causing the emulator to panic with the message
+ "Inconsistent, why isnt io reported?" is now corrected.</p>
+ <p>
+ Own Id: OTP-7420</p>
+ </item>
+ <item>
+ <p>
+ Starting erl with option "-detached" now disconnects
+ correctly from terminal session on Unix.</p>
+ <p>
+ Own Id: OTP-7461</p>
+ </item>
+ <item>
+ <p>
+ Mended gdb etp-commands for ETS access.</p>
+ <p>
+ Own Id: OTP-7538</p>
+ </item>
+ <item>
+ <p>
+ <c>erlang:decode_packet/3</c> allows white space between
+ HTTP header tag and colon according to RFC2616.</p>
+ <p>
+ Own Id: OTP-7543</p>
+ </item>
+ <item>
+ <p>
+ An emulator compiled for SCTP now starts even if the
+ dynamic libraries are not present. The SCTP driver is
+ then of course not loaded.</p>
+ <p>
+ Own Id: OTP-7551</p>
+ </item>
+ <item>
+ <p>To build on Mac OS X, 10.3.0 or later is now required
+ because of fixes for two problems:</p>
+ <p>There would be a resource leak when <c>erl_ddl</c>
+ attempted to unload a driver. This problem has been
+ corrected by using <c>dlopen()</c> (which works on all
+ modern Unix-like platforms) instead of the Mac OS X
+ specific API calls.</p>
+ <p>Signal handling in the run-time system for HiPE has
+ been updated to work on later versions of Mac OS X than
+ 10.2.x. Therefore, <c>--enable-hipe</c> now works on Mac
+ OS X with Intel CPUs.</p>
+ <p>Thanks to Geoff Cant for the patches.</p>
+ <p>
+ Own Id: OTP-7562</p>
+ </item>
+ <item>
+ <p>Corrected some information about the protocol between
+ EPMD and Erlang nodes. (Thanks to Michael Regen.)</p>
+ <p>
+ Own Id: OTP-7594</p>
+ </item>
+ <item>
+ <p>
+ When using
+ <c>erlang:system_monitor(Pid,{long_gc,Time})</c>, and the
+ GC time exceeded 1 second, it sometimes erroneously
+ showed up as about 4300 seconds. (This bug was corrected
+ in R9C, but re-introduced in R12B.) (Thanks to Chris
+ Newcombe.)</p>
+ <p>
+ Own Id: OTP-7622 Aux Id: OTP-4903, seq8379 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The driver entry of a dynamically loaded driver is now
+ copied when loaded which enables some internal
+ optimizations. Note that drivers that modify the driver
+ entry during execution will not work anymore. Such a
+ miss-use of the driver interface is however not
+ supported.</p>
+ <p>
+ Own Id: OTP-6900</p>
+ </item>
+ <item>
+ <p>
+ The split function is now added to the re library.
+ Exceptions and errors from both run, replace and split
+ are made more consistent.</p>
+ <p>
+ Own Id: OTP-7514 Aux Id: OTP-7494 </p>
+ </item>
+ <item>
+ <p>
+ Fixed harmless compiler warnings when building the
+ emulator and minor build changes in order to avoid
+ unnecessary rebuilds.</p>
+ <p>
+ Own Id: OTP-7530</p>
+ </item>
+ <item>
+ <p>
+ There is now experimental support for loading of code
+ from archive files. See the documentation of <c>code</c>,
+ <c>init</c>, <c>erl_prim_loader </c> and <c>escript</c>
+ for more info.</p>
+ <p>
+ The error handling of <c>escripts</c> has been improved.</p>
+ <p>
+ An <c>escript</c> may now set explicit arguments to the
+ emulator, such as <c>-smp enabled</c>.</p>
+ <p>
+ An <c>escript</c> may now contain a precompiled beam
+ file.</p>
+ <p>
+ An <c>escript</c> may now contain an archive file
+ containing one or more applications (experimental).</p>
+ <p>
+ The internal module <c>code_aux</c> has been removed.</p>
+ <p>
+ Own Id: OTP-7548 Aux Id: otp-6622 </p>
+ </item>
+ <item>
+ <p>
+ The reallocation functionality part of the ERTS internal
+ memory allocators, now consider current block in
+ combination with surrounding free blocks as an
+ alternative location for a reallocation.</p>
+ <p>
+ Own Id: OTP-7555</p>
+ </item>
+ <item>
+ <p>There could remain false references from a process to
+ a module that has been called earlier, so that the
+ process would be killed if the module was reloaded.
+ (Thanks to Richard Carlsson.)</p>
+ <p>Also, the fix for this bug also made it possible to
+ make stack backtraces (as returned from
+ <c>erlang:get_stacktrace/0</c> and other functions) more
+ correct in that the immediate caller is always included
+ in the stack backtrace (it could sometimes be
+ missing).</p>
+ <p>
+ Own Id: OTP-7559</p>
+ </item>
+ <item>
+ <p>
+ Improved locking in IO-handling for better smp
+ performance.</p>
+ <p>
+ Own Id: OTP-7560</p>
+ </item>
+ <item>
+ <p>
+ Improved BIF rescheduling functionality.</p>
+ <p>
+ Own Id: OTP-7587</p>
+ </item>
+ <item>
+ <p>
+ Loading a module compiled with Erlang/OTP R9C and calling
+ <c>module_info/0</c> in the module would crash the
+ emulator. The emulator now refuses to load any module
+ compiled with R9C or earlier. (Note: only trivial modules
+ compiled with R10B or earlier could be loaded anyway.)
+ (Thanks to Martin Kjellin.)</p>
+ <p>
+ Own Id: OTP-7590</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A process calling one of the following BIFs could under
+ very rare conditions deadlock in the runtime system with
+ SMP support: <c>check_process_code/2</c>,
+ <c>garbage_collect/1</c>, <c>process_info/[1,2]</c>,
+ <c>system_flag/2</c>, and
+ <c>erlang:suspend_process/[1,2]</c>.</p>
+ <p>
+ Own Id: OTP-7582</p>
+ </item>
+ <item>
+ <p>
+ A couple of statistics variables were not managed in a
+ thread safe manner in the runtime system with SMP
+ support.</p>
+ <p>
+ Own Id: OTP-7583</p>
+ </item>
+ <item>
+ <p>
+ An extremely rare race condition when terminating a
+ process could potentially cause a runtime system crash.</p>
+ <p>
+ Own Id: OTP-7584</p>
+ </item>
+ <item>
+ <p>
+ Under certain conditions and when using run_erl/to_erl,
+ the terminal Erlang driver (ttsl_drv) could crash the
+ emulator by doing a division by zero due to incorrect
+ handling of terminals reporting a zero width. For
+ terminals reporting zero width, the driver now fallbacks
+ to a default width of 80 and a default height of 24
+ (vt100), as a fallback behaviour. This fixes the crashes
+ and also makes output on "dumb" terminals much more
+ readable.</p>
+ <p>
+ Own Id: OTP-7592 Aux Id: seq11073 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.4.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ A new <c>erts_alloc</c> parameter
+ <c>+M&lt;S&gt;rmbcmt</c> (relative multiblock carrier
+ move threshold) has been added. It determines when to
+ force a moving realloc in a multiblock carrier when a
+ block is shrunk. For more information see the
+ <c>erts_alloc(3)</c> documentation.</p>
+ <p>
+ Own Id: OTP-7540</p>
+ </item>
+ <item>
+ <p>The new option <c>+d</c> can be given to <c>erl</c> to
+ suppress the crash dump generation if an internal error
+ is detected. As a result, a more useful core dump is
+ produced.</p>
+ <p>
+ Own Id: OTP-7578 Aux Id: seq11052 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Double backslashes in format string passed to the erts
+ internal printf implementation produced erroneous
+ results. No such format strings were passed to the erts
+ internal printf implementation, i.e., the bug was
+ therefore completely harmless. (Thanks to Perry Smith.)</p>
+ <p>
+ Own Id: OTP-7408</p>
+ </item>
+ <item>
+ <p>
+ Large files are now handled on Windows, where the
+ filesystem supports it.</p>
+ <p>
+ Own Id: OTP-7410</p>
+ </item>
+ <item>
+ <p>
+ Bug fixed for <c>{packet,http}</c> when space follows
+ http headers.</p>
+ <p>
+ Own Id: OTP-7458</p>
+ </item>
+ <item>
+ <p>
+ The trace option <c>running</c> could cause an emulator
+ crash if the current function couldn't be determined.</p>
+ <p>
+ Own Id: OTP-7484</p>
+ </item>
+ <item>
+ <p>
+ Using 16#ffffFFFF as a timeout value in receive...after
+ would often cause a timeout almost at once due to an
+ 32-bit integer overflow. (Thanks to Serge Aleynikov and
+ Matthias Lang.)</p>
+ <p>
+ Own Id: OTP-7493</p>
+ </item>
+ <item>
+ <p>
+ For the process that an escript runs in, the
+ <c>trap_exit</c> process flag is now <c>false</c> instead
+ of <c>true</c> (as in previous releases). Scripts that
+ depend on the previous (counter-intuitive) behaviour
+ might not work. (Thanks to Bengt Kleberg.)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7517</p>
+ </item>
+ <item>
+ <p>
+ A bug in the <c>string:to_integer/1</c> builtin made the
+ emulator unstable. This is now corrected. (Thanks to Lev
+ Walkin.)</p>
+ <p>
+ Own Id: OTP-7526</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Performance for ETS intensive applications should now
+ be better in the SMP emulator. Also, ETS table
+ identifiers (as returned by <c>ets:new/2</c>) are now
+ spread out in wider range than before (using 28 bits in a
+ 32-bit emulator) to make sure that the table identifier
+ for a deleted table will not be quickly re-used.</p>
+ <p>NOTE: Table identifiers can now be negative integers.
+ Programs that (incorrectly) assume that table identifiers
+ can only be positive integers might stop to work. (The
+ type of a table identifier is intentionally not
+ documented, and may change in a future release.)</p>
+ <p>
+ Own Id: OTP-7348</p>
+ </item>
+ <item>
+ <p>
+ New BIF <c>erlang:decode_packet/3</c> that extracts a
+ protocol packet from a binary. Similar to the socket
+ option <c>{packet, Type}</c>. Also documented the socket
+ packet type <c>http</c> and made it official.
+ <em>NOTE</em>: The tuple format for <c>http</c> packets
+ sent from an active socket has been changed in an
+ incompatible way.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7404</p>
+ </item>
+ <item>
+ <p>
+ The source code for the documentation for some
+ applications (erts, kernel, stdlib, and several others)
+ are now included in the source tar ball. There is
+ currently no Makefile support for building HTML files
+ from the source (such support will be included in a
+ future release).</p>
+ <p>
+ Own Id: OTP-7406</p>
+ </item>
+ <item>
+ <p>
+ A lot of frequently accessed memory counters (erts
+ internal) have been removed. This since they hurt
+ performance on the runtime system with SMP support. As a
+ result <c>erlang:memory/[0,1]</c> will only deliver a
+ result if all <c>erts_alloc(3)</c> allocators are enabled
+ (default). The result delivered when all
+ <c>erts_alloc(3)</c> allocators are enabled are both more
+ accurate and less accurate than before. More memory than
+ before are included in the result, but the different
+ parts that are summed are not gathered atomically. A call
+ to <c>erlang:memory/[0,1]</c> is much cheaper for the
+ system than before. This since the information isn't
+ gathered atomically anymore which was very expensive.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7468</p>
+ </item>
+ <item>
+ <p>
+ Pre-allocators used for, for example, timers, and
+ messages have been rewritten to be scheduler specific.
+ That is, different schedulers will now allocate from
+ different pools which reduces lock contention.</p>
+ <p>
+ Own Id: OTP-7470</p>
+ </item>
+ <item>
+ <p>
+ On Mac OS X, file:sync/1 now guarantees that all
+ filesystem buffers are written to the disk by using the
+ fcntl() with F_FULLFSYNC option. Previously, file:sync/1
+ called fsync(), which only guaranteed that the data had
+ been transferred to the disk drive. (Thanks to Jan
+ Lehnardt.)</p>
+ <p>
+ Own Id: OTP-7471</p>
+ </item>
+ <item>
+ <p>
+ Termination of a process that takes a long time can now
+ be preempted, i.e., the terminating process will be
+ rescheduled for later continuation of termination so that
+ other processes can execute. Termination of a process
+ that owns many and/or large ets tables typically takes a
+ long time.</p>
+ <p>
+ Own Id: OTP-7477</p>
+ </item>
+ <item>
+ <p>
+ A new trace option <c>exiting</c> has been added. The
+ <c>exiting</c> trace is similar to the <c>running</c>
+ trace, but for exiting processes. For more information
+ see the erlang(3) documentation.</p>
+ <p>
+ The <c>erlang:trace/3</c> bif now doesn't block other
+ scheduler threads if only one tracee is specified in the
+ call to <c>erlang:trace/3</c>.</p>
+ <p>
+ Own Id: OTP-7481</p>
+ </item>
+ <item>
+ <p>
+ The re module is extended with repetitive matches (global
+ option) and replacement function.</p>
+ <p>
+ Own Id: OTP-7494 Aux Id: OTP-7181 </p>
+ </item>
+ <item>
+ <p>
+ In the section about binary construction, the reference
+ manual now mentions what happens when an integer value
+ does not fit into an integer segment of size N (namely,
+ that the N least significant bits will be put into into
+ the binary and that the most significant bits will be
+ silently discarded). (Thanks to Edwin Fine.)</p>
+ <p>
+ Own Id: OTP-7506</p>
+ </item>
+ <item>
+ <p>
+ Setting the <c>{active,once}</c> for a socket (using
+ inets:setopts/2) is now specially optimized (because the
+ <c>{active,once}</c> option is typically used much more
+ frequently than other options).</p>
+ <p>
+ Own Id: OTP-7520</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ Floating point arithmetics in drivers can cause a runtime
+ system crash and/or unexpected results on runtime systems
+ with floating point exceptions enabled. Floating point
+ exceptions are disabled unless explicitly enabled or if
+ hipe is enabled.</p>
+ <p>
+ Own Id: OTP-7237</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.3.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Binary construction with an integer field of size 0 at
+ the end of the constructed binary (and the size given in
+ a variable), would cause a write of one byte outside the
+ memory reserved for the binary, which in turn could cause
+ an emulator crash.</p>
+ <p>
+ Own Id: OTP-7422</p>
+ </item>
+ <item>
+ <p>
+ A race condition in the dynamic driver implementation
+ could cause an emulator crash. (Thanks to Paul Fisher)</p>
+ <p>
+ Own Id: OTP-7464</p>
+ </item>
+ <item>
+ <p>
+ Calls to <c>erlang:system_info(allocated_areas)</c> could
+ cause the runtime system with SMP support to crash.</p>
+ <p>
+ Own Id: OTP-7474</p>
+ </item>
+ <item>
+ <p>
+ The <c>env</c> option to <c>open_port()</c> could cause
+ the runtime system with SMP support to crash.</p>
+ <p>
+ Own Id: OTP-7475</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Operations that needed to block other threads in the
+ runtime system with SMP support unnecessarily waited for
+ async threads to block. Most important the
+ <c>erlang:memory/[0,1]</c> bif, code loading, and the
+ <c>erlang:trace/3</c> bif.</p>
+ <p>
+ Own Id: OTP-7480</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.3.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Calls to <c>erlang:memory/[0,1]</c> could cause the
+ runtime system with SMP support to crash.</p>
+ <p>
+ Own Id: OTP-7415</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Doing local call trace on bit syntax matching code that
+ has been optimized with delayed sub-binary creation could
+ crash the emulator.</p>
+ <p>
+ Own Id: OTP-7399 Aux Id: seq10978 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Only one to_erl process at a time is allowed to connect
+ to the same run_erl pipe. Prevents buggy behaviour when
+ IO from several to_erl's get interleaved.</p>
+ <p>
+ Own Id: OTP-5107</p>
+ </item>
+ <item>
+ <p>
+ IPv6 name resolving has now been fixed to use
+ getaddrinfo() patch (thoroughly reworked) courtesy of Love
+ H�rnquist-�strand submitted by Fredrik Thulin. It also
+ can use gethostname2() patch (also reworked) courtesy of
+ Mikael Magnusson for debian submitted by Sergei Golovan.</p>
+ <p>
+ Own Id: OTP-5382</p>
+ </item>
+ <item>
+ <p>
+ Improved error handling in run_erl</p>
+ <p>
+ Own Id: OTP-7252</p>
+ </item>
+ <item>
+ <p>A permanent fix for the deadlock issue temporarily
+ fixed by OTP-7260.</p> <taglist><tag>OTP-7260</tag><item>
+ The runtime system with SMP support could under rare
+ circumstances deadlock when a distribution channel was
+ taken down while multiple simultaneous operations were
+ performed on it. </item></taglist>
+ <p>
+ Own Id: OTP-7267 Aux Id: OTP-7260 </p>
+ </item>
+ <item>
+ <p>
+ ./configure has been improved to find 64-bit OpenSSL
+ libraries.</p>
+ <p>
+ Own Id: OTP-7270</p>
+ </item>
+ <item>
+ <p>
+ A terminating process could under very rare circumstances
+ trigger a bug which could crash the runtime system with
+ SMP support.</p>
+ <p>
+ Own Id: OTP-7272</p>
+ </item>
+ <item>
+ <p>
+ SCTP_ADDR_CONFIRMED events are now handled by gen_sctp.</p>
+ <p>
+ Own Id: OTP-7276</p>
+ </item>
+ <item>
+ <p>
+ binary_to_term/1 would crash the emulator if the binary
+ data contained an external fun with non-atom module
+ and/or function. Corrected to generate a badarg
+ exception.</p>
+ <p>
+ Own Id: OTP-7281</p>
+ </item>
+ <item>
+ <p>
+ On Mac OS 10.5 (Leopard), sending to socket which the
+ other end closes could cause the emulator to consume 100%
+ CPU time. (Thanks to Matthias Radestock.)</p>
+ <p>
+ Own Id: OTP-7289</p>
+ </item>
+ <item>
+ <p>
+ The vanilla driver used on Windows could crash the
+ emulator and sometimes produced corrupt files. The
+ vanilla driver is the driver that is used when one only
+ pass a filename as first argument to <c>open_port/2</c>.
+ <em>NOTE</em>: This use of <c>open_port/2</c> is
+ <em>obsolete</em>, and the documentation of this use has
+ previously been removed. The functionality is only
+ present for backward compatibility reasons and
+ <em>will</em> eventually be removed.</p>
+ <p>
+ Own Id: OTP-7301</p>
+ </item>
+ <item>
+ <p>
+ Faulty matching in binaries larger than 512Mb on 64bit
+ machines fixed.(On 32bit, the size limit for binaries is
+ still 512Mb). Thanks to Edwin Fine and Per Gustafsson for
+ finding fault and fix.</p>
+ <p>
+ Own Id: OTP-7309</p>
+ </item>
+ <item>
+ <p>
+ crypto:start() on Windows caused emulator to hang on
+ error popup window if openssl DLL was not found. Windows
+ error popups now suppressed.</p>
+ <p>
+ Own Id: OTP-7325</p>
+ </item>
+ <item>
+ <p>
+ Configuration option <c>without-termcap</c> can be used to
+ disable the use of termcap libraries for terminal cursor
+ control in the shell.</p>
+ <p>
+ Own Id: OTP-7338</p>
+ </item>
+ <item>
+ <p>
+ to_erl reports its terminal window size to run_erl in
+ order to get output formatted accordingly</p>
+ <p>
+ Own Id: OTP-7342</p>
+ </item>
+ <item>
+ <p>
+ On Solaris, the <c>compressed</c> option for file
+ operations did not work if the file descriptor happened
+ to be greater than 255 (a problem with fopen() and
+ friends in Solaris itself).</p>
+ <p>
+ Own Id: OTP-7343 Aux Id: seq10949 </p>
+ </item>
+ <item>
+ <p>
+ A race condition in the runtime system with SMP support
+ causing an erroneous removal of a newly created ets table
+ has been fixed.</p>
+ <p>
+ The race occurred when a process removed a table during
+ termination simultaneously as another process removed the
+ same table via <c>ets:delete/1</c> and a third process
+ created a table that accidentaly got the same internal
+ table index as the table being removed.</p>
+ <p>
+ Own Id: OTP-7349</p>
+ </item>
+ <item>
+ <p>
+ <c>zlib:inflate</c> failed when the size of the inflated
+ data was an exact multiple of the internal buffer size
+ (4000 bytes by default).</p>
+ <p>
+ Own Id: OTP-7359</p>
+ </item>
+ <item>
+ <p>
+ If the total number of allowed atoms is exceeded, there
+ will now be a controlled termination of the emulator with
+ a crash dump file. The emulator used to simply crash.
+ (Thanks Howard Yeh and Thomas Lindgren.)</p>
+ <p>
+ Own Id: OTP-7372</p>
+ </item>
+ <item>
+ <p>
+ The break handler in werl on Windows could cause the
+ emulator to hang or crash, that is now corrected.</p>
+ <p>
+ Own Id: OTP-7394 Aux Id: seq10969 </p>
+ </item>
+ <item>
+ <p>
+ The configure script now tests for an serious
+ optimization bug in gcc-4.3.0. If the bug is present, the
+ configure script will abort (if this happens, the only
+ way to build Erlang/OTP is to change to another version
+ of gcc). (Thanks to Mikael Pettersson.)</p>
+ <p>
+ Own Id: OTP-7397</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ On Unix, the emulator now notices when the width of the
+ terminal has changed. (Thanks to Matthew Dempsky and
+ Patrick Mahoney.)</p>
+ <p>
+ Own Id: OTP-7290</p>
+ </item>
+ <item>
+ <p>
+ There is a new function <c>init:stop/1</c> which can be
+ used to shutdown the system cleanly AND generate a
+ non-zero exit status or crash dump. (Thanks to Magnus
+ Froberg.)</p>
+ <p>
+ Own Id: OTP-7308</p>
+ </item>
+ <item>
+ <p>
+ process_info(Pid, garbage_collection) now returns more
+ information</p>
+ <p>
+ Own Id: OTP-7311</p>
+ </item>
+ <item>
+ <p>
+ The <c>hide</c> option for <c>open_port/2</c> is now
+ documented. (Thanks to Richard Carlsson.)</p>
+ <p>
+ Own Id: OTP-7358</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ Floating point arithmetics in drivers can cause a runtime
+ system crash on runtime systems with floating point
+ exceptions enabled. Floating point exceptions are
+ disabled unless explicitly enabled or if hipe is enabled.</p>
+ <p>
+ Own Id: OTP-7237</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Erts 5.6.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The maximum length of an atom of 255 characters is now
+ strictly enforced. <c>binary_to_term/1</c> will now fail
+ with a badarg if an encoded term contains an atom longer
+ than 255 characters. Atoms created by drivers will now be
+ truncated to 255 characters if necessary. (Thanks to
+ Matthew Dempsky.)</p>
+ <p>
+ Own Id: OTP-7147</p>
+ </item>
+ <item>
+ <p>
+ A bug in "bignum handling" on some 64bit architectures
+ could cause rem and div operations on large numbers to
+ hang indefinitely. Rem operations involving the smallest
+ negative number representable in 28 bits or 60 bits could
+ also cause access violation and emulator crash. Both
+ errors are corrected.</p>
+ <p>
+ Own Id: OTP-7177</p>
+ </item>
+ <item>
+ <p>
+ When doing the initial garbage collection after waking a
+ hibernated process, a fullsweep garbage collection was
+ unnecessarily triggered.</p>
+ <p>
+ Own Id: OTP-7212</p>
+ </item>
+ <item>
+ <p>The beta testing module <c>gen_sctp</c> now supports
+ active mode as stated in the documentation. Active mode
+ is still rather untested, and there are some issues about
+ what should be the right semantics for
+ <c>gen_sctp:connect/5</c>. In particular: should it be
+ blocking or non-blocking or choosable. There is a high
+ probability it will change semantics in a (near) future
+ patch.</p> <p>Try it, give comments and send in bug
+ reports!</p>
+ <p>
+ Own Id: OTP-7225</p>
+ </item>
+ <item>
+ <p>
+ Invalid arguments to <c>ets:update_counter/3</c> were not
+ handled correctly. A tuple position (<c>Pos</c>) less
+ than 1 caused the element directly following the key to
+ be updated (as if no position at all had been specified).
+ All invalid values for <c>Pos</c> will now fail with
+ <c>badarg</c>.</p>
+ <p>
+ Own Id: OTP-7226</p>
+ </item>
+ <item>
+ <p>
+ The runtime system with SMP support could under rare
+ circumstances deadlock when a distribution channel was
+ taken down while multiple simultaneous operations were
+ performed on it.</p>
+ <p>
+ Own Id: OTP-7260</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ More checksum/hash algorithms from the zlib library are
+ now available as built in functions (like md5 hashes has
+ been for a long time).</p>
+ <p>
+ Own Id: OTP-7128</p>
+ </item>
+ <item>
+ <p>
+ Minor improvements in the garbage collector.</p>
+ <p>
+ Own Id: OTP-7139 Aux Id: OTP-7132 </p>
+ </item>
+ <item>
+ <p>
+ The switch "-detached" to the windows werl program now
+ can create an erlang virtual machine without any main
+ window and without a temporary console showing.</p>
+ <p>
+ Own Id: OTP-7142</p>
+ </item>
+ <item>
+ <p><c>erlang:system_info/1</c> now accepts the
+ <c>logical_processors</c>, and <c>debug_compiled</c>
+ arguments. For more info see the, <c>erlang(3)</c>
+ documentation.</p> <p>The scale factor returned by
+ <c>test_server:timetrap_scale_factor/0</c> is now also
+ effected if the emulator uses a larger amount of
+ scheduler threads than the amount of logical processors
+ on the system. </p>
+ <p>
+ Own Id: OTP-7175</p>
+ </item>
+ <item>
+ <p>
+ A new BIF ets:update_element/3. To update individual
+ elements within an ets-tuple, without having to read,
+ update and write back the entire tuple.</p>
+ <p>
+ Own Id: OTP-7200</p>
+ </item>
+ <item>
+ <p>
+ A process executing the <c>processes/0</c> BIF can now be
+ preempted by other processes during its execution. This
+ in order to disturb the rest of the system as little as
+ possible. The returned result is, of course, still a
+ consistent snapshot of existing processes at a time
+ during the call to <c>processes/0</c>.</p>
+ <p>
+ The documentation of the <c>processes/0</c> BIF and the
+ <c>is_process_alive/1</c> BIF have been updated in order
+ to clarify the difference between an existing process and
+ a process that is alive.</p>
+ <p>
+ Own Id: OTP-7213</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Erts 5.6.1.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Not enough parameters were passed when sending an error
+ report in erl_check_io.c (Thanks to Matthew Dempsky).</p>
+ <p>
+ Own Id: OTP-7176</p>
+ </item>
+ <item>
+ <p>
+ In rare circumstances, complex binary matching code could
+ cause the emulator to crash or not match when it should.
+ (Thanks to Rory Byrne.)</p>
+ <p>
+ Own Id: OTP-7198</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The <c>{allocator_sizes, Alloc}</c> and
+ <c>alloc_util_allocators</c> arguments are now accepted
+ by <c>erlang:system_info/1</c>. For more information see
+ the <c>erlang(3)</c> documentation.</p>
+ <p>
+ Own Id: OTP-7167</p>
+ </item>
+ <item>
+ <p>
+ The finishing reallocation of the heap block when
+ hibernating a process is now always moving the heap block
+ since it drastically reduces memory fragmentation when
+ hibernating large amounts of processes.</p>
+ <p>
+ Own Id: OTP-7187</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The SMP emulator on sparc64 erroneously used the sparc32
+ atomic and the sparc32 spinlock implementations which
+ caused it to crash.</p>
+ <p>
+ Own Id: OTP-7006</p>
+ </item>
+ <item>
+ <p>
+ Call tracing the new guard BIFs <c>byte_size</c>,
+ <c>bit_size</c>, or <c>tuple_size</c> and the loading a
+ module that uses one of those functions, could cause the
+ emulator to terminate.</p>
+ <p>
+ Own Id: OTP-7008</p>
+ </item>
+ <item>
+ <p>
+ configuring --enable-darwin-universal or
+ --enable-darwin-64bit on MacOSX could result in a non
+ optimized emulator. Top level configure script now
+ corrected.</p>
+ <p>
+ Own Id: OTP-7014</p>
+ </item>
+ <item>
+ <p>
+ configuring --with-gd did not produce correct include
+ flags for percept.</p>
+ <p>
+ Own Id: OTP-7015</p>
+ </item>
+ <item>
+ <p>
+ Environment variables weren't handled in thread safe
+ manner in the runtime system with SMP support on Windows.</p>
+ <p>
+ <c>erl_drv_putenv()</c>, and <c>erl_drv_getenv()</c> has
+ been introduced for use in drivers. Do <em>not</em> use
+ putenv(), or getenv() directly in drivers. For more
+ information see the <c>erl_driver</c> documentation.</p>
+ <p>
+ Own Id: OTP-7035</p>
+ </item>
+ <item>
+ <p>
+ HIPE: Corrected the choice of interface to the send/3 and
+ setnode/3 BIFs for native-compiled code. Using the
+ incorrect interface could, in unusual circumstances, lead
+ to random runtime errors.</p>
+ <p>
+ Own Id: OTP-7067</p>
+ </item>
+ <item>
+ <p>
+ Garbage collections could become extremely slow when
+ there were many keys in the process dictionary. (Thanks
+ to Fredrik Svahn.)</p>
+ <p>
+ Own Id: OTP-7068</p>
+ </item>
+ <item>
+ <p>
+ The duplicate documentation directory in the windows
+ installation is removed.</p>
+ <p>
+ Own Id: OTP-7070</p>
+ </item>
+ <item>
+ <p>Documentation bugfixes and clarifications.</p> (Thanks
+ to Joern ([email protected]), Matthias Lang, and Richard
+ Carlsson.)
+ <p>
+ Own Id: OTP-7079</p>
+ </item>
+ <item>
+ <p>
+ The runtime system with SMP support <em>not</em> using
+ the native atomic integer implementation part of OTP
+ could deadlock when run on a system with more than one
+ logical processor. That is, only the runtime system with
+ SMP support on <em>other</em> hardware platforms than
+ x86, x86_64, sparc32, and powerpc32 were effected by this
+ bug.</p>
+ <p>
+ Own Id: OTP-7080</p>
+ </item>
+ <item>
+ <p>
+ The break handling code (run when Ctrl-C is hit) could
+ could potentially deadlock the runtime system with SMP
+ support.</p>
+ <p>
+ Own Id: OTP-7104</p>
+ </item>
+ <item>
+ <p>
+ The sctp driver has been updated to work against newer
+ lksctp packages e.g 1.0.7 that uses the API spelling
+ change adaption -> adaptation. Older lksctp (1.0.6) still
+ work. The erlang API in gen_sctp.erl and inet_sctp.hrl
+ now spells 'adaptation' regardless of the underlying C
+ API.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7120</p>
+ </item>
+ <item>
+ <p>A bug in <c>erlang:phash2/1</c> on 64-bit platforms
+ has been fixed. (Thanks to Scott Lystig Fritchie.)</p>
+ <p>
+ Own Id: OTP-7127</p>
+ </item>
+ <item>
+ <p>
+ The emulator could under rare circumstances crash while
+ garbage collecting.</p>
+ <p>
+ Own Id: OTP-7132</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation has been updated so as to reflect
+ the last updates of the Erlang shell as well as the minor
+ modifications of the control sequence <c>p</c> of the
+ <c>io_lib</c> module.</p> <p>Superfluous empty lines have
+ been removed from code examples and from Erlang shell
+ examples.</p>
+ <p>
+ Own Id: OTP-6944 Aux Id: OTP-6554, OTP-6911 </p>
+ </item>
+ <item>
+ <p>
+ Bit syntax construction with a small integer in a
+ non-byte aligned field wider than the CPU's word size
+ could cause garbage bits in the beginning of the field.</p>
+ <p>
+ Own Id: OTP-7085</p>
+ </item>
+ <item>
+ <p>
+ All Windows versions older than Windows 2000 are now
+ <em>not supported</em> by the Erlang runtime system. This
+ since there was a need for usage of features introduced
+ in Windows 2000.</p>
+ <p>
+ Own Id: OTP-7086</p>
+ </item>
+ <item>
+ <p>Memory management improvements especially for the
+ runtime system with SMP support:</p> <list> <item> The
+ runtime system with SMP support can now use multiple,
+ thread specific instances of most memory allocators. This
+ improves performance since it reduces lock contention in
+ the memory allocators. It may however increase memory
+ usage for some applications. The runtime system with SMP
+ support will by default enable this feature on most
+ allocators. The amount of instances used can be
+ configured. </item> <item> <c>driver_alloc()</c>,
+ <c>driver_realloc()</c>, and <c>driver_free()</c> now use
+ their own erts specific memory allocator instead of the
+ default <c>malloc()</c> implementation on the system.
+ </item> <item> The default configuration of some
+ allocators have been changed to fit applications that use
+ much memory better. </item> <item> Some new
+ <c>erts_alloc</c> configuration parameters have been
+ added. </item> <item> <c>erts_alloc_config</c> has been
+ modified to be able to create configurations suitable for
+ multiple instances of allocators. </item> <item> The
+ returned value from <c>erlang:system_info({allocator,
+ Alloc})</c> has been changed. This since an allocator may
+ now run in multiple instances. </item> </list> <p>If you
+ for some reason want the memory allocators to be
+ configured as before, you can pass the <c>+Mea r11b</c>
+ command-line argument to <c>erl</c>.</p> <p>For more
+ information see the <c>erts_alloc(3)</c>, the
+ <c>erts_alloc_config(3)</c>, and the <c>erlang(3)</c>
+ documentation.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-7100</p>
+ </item>
+ <item>
+ <p>
+ On Unix, denormalized floating point numbers could not be
+ created using <c>list_to_float/1</c> or
+ <c>binary_to_term/1</c>. (Thanks to Matthew Dempsky.)</p>
+ <p>
+ Own Id: OTP-7122</p>
+ </item>
+ <item>
+ <p>
+ Native atomic integers and spin-locks are now also
+ available for the runtime system with SMP support on
+ sparc64.</p>
+ <p>
+ Own Id: OTP-7130</p>
+ </item>
+ <item>
+ <p>
+ FP exceptions support for sparc64 userspace on Linux has
+ been added. Note that FP exception support is now turned
+ off by default, so to actually enable it you need to do
+ '<c>./configure --enable-fp-exceptions</c>'.</p>
+ <p>
+ Own Id: OTP-7131</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A bug for raw files when reading 0 bytes returning 'eof'
+ instead of empty data has been corrected.</p>
+ <p>
+ Own Id: OTP-6291 Aux Id: OTP-6967 </p>
+ </item>
+ <item>
+ <p>
+ All exported functions in gzio.c have now been renamed to
+ avoid conflict with drivers that are indirectly linked
+ with an external zlib library.</p>
+ <p>
+ Own Id: OTP-6816 Aux Id: OTP-6591 </p>
+ </item>
+ <item>
+ <p>
+ On the 64-bit Erlang emulator, bit syntax construction
+ with integers containing more than 60 bits ("big
+ numbers") into fields with more than 60 bits could
+ produce incorrect results.</p>
+ <p>
+ Own Id: OTP-6833</p>
+ </item>
+ <item>
+ <p>
+ When the runtime system failed to allocate memory for
+ binaries, it could dead lock while writing the
+ <c>erl_crash.dump</c>.</p>
+ <p>
+ Own Id: OTP-6848</p>
+ </item>
+ <item>
+ <p>
+ The runtime system with SMP support could deadlock if a
+ process called the <c>erlang:suspend_process(Pid)</c> BIF
+ or the <c>erlang:garbage_collect(Pid)</c> BIF while the
+ process identified by <c>Pid</c> was currently running
+ and the process calling the BIFs was terminated during
+ the call to the BIFs.</p>
+ <p>
+ Processes suspending each other via the
+ <c>erlang:suspend_process/1</c> BIF or garbage collecting
+ each other via the <c>erlang:garbage_collect/1</c> BIF
+ could deadlock each other when the runtime system with
+ SMP support was used.</p>
+ <p>
+ Own Id: OTP-6920</p>
+ </item>
+ <item>
+ <p>
+ <c>dbg</c> could leave traced processes in a suspended
+ state if the tracer process was killed with exit reason
+ <c>kill</c>.</p>
+ <p>
+ <c>erlang:suspend_process/2</c> has been introduced which
+ accepts an option list as second argument. For more
+ information see the <c>erlang(3)</c> documentation.</p>
+ <p>
+ Processes suspended via
+ <c>erlang:suspend_process/[1,2]</c> will now be
+ automatically resumed if the process that called
+ <c>erlang:suspend_process/[1,2]</c> terminates.</p>
+ <p>
+ Processes could previously be suspended by one process
+ and resumed by another unless someone was tracing the
+ suspendee. This is <em>not</em> possible anymore. The
+ process resuming a process <em>has</em> to be the one
+ that suspended it.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-6946</p>
+ </item>
+ <item>
+ <p>file:write_file/3, file:write/2 and file:read/2 could
+ crash (contrary to documentation) for odd enough file
+ system problems, e.g write to full file system. This bug
+ has now been corrected.</p> <p>In this process the file
+ module has been rewritten to produce better error codes.
+ Posix error codes now originate from the OS file system
+ calls or are generated only for very similar causes (for
+ example 'enomem' is generated if a memory allocation
+ fails, and 'einval' is generated if the file handle in
+ Erlang is a file handle but currently invalid).</p>
+ <p>More Erlang-ish error codes are now generated. For
+ example <c>{error,badarg}</c> is now returned from
+ <c>file:close/1</c> if the argument is not of a file
+ handle type. See file(3).</p> <p>The possibility to write
+ a single byte using <c>file:write/2</c> instead of a list
+ or binary of one byte, contradictory to the
+ documentation, has been removed.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-6967 Aux Id: OTP-6597 OTP-6291 </p>
+ </item>
+ <item>
+ <p>
+ Monitor messages produced by the system monitor
+ functionality, and garbage collect trace messages could
+ contain erroneous heap and/or stack sizes when the actual
+ heaps and/or stacks were huge.</p>
+ <p>
+ As of erts version 5.6 the <c>large_heap</c> option to
+ <c>erlang:system_monitor/[1,2]</c> has been modified. The
+ monitor message is sent if the sum of the sizes of all
+ memory blocks allocated for all heap generations is equal
+ to or larger than the specified size. Previously the
+ monitor message was sent if the memory block allocated
+ for the youngest generation was equal to or larger than
+ the specified size.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-6974 Aux Id: seq10796 </p>
+ </item>
+ <item>
+ <p>
+ <c>inet:getopts/2</c> returned random values on Windows
+ Vista.</p>
+ <p>
+ Own Id: OTP-7003</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The emulator internal process lock implementation has
+ been rewritten and optimized. A slight risk of starvation
+ existed in the previous implementation. This risk has
+ also been eliminated in the new implementation.</p>
+ <p>
+ Own Id: OTP-6500</p>
+ </item>
+ <item>
+ <p>
+ Bitstrings (bit-level) binaries and binary comprehensions
+ are now part of the language. See the Reference Manual.</p>
+ <p>
+ Own Id: OTP-6558</p>
+ </item>
+ <item>
+ <p>
+ The windows version of erlang now has SMP support. The
+ SMP emulator is run by default on machines which shows
+ more than one virtual or physical processor.</p>
+ <p>
+ Own Id: OTP-6560 Aux Id: OTP-6925 </p>
+ </item>
+ <item>
+ <p>
+ The details of the compressed term format has been
+ documented in erl_ext_dist.txt. (Thanks to Daniel
+ Goertzen.)</p>
+ <p>
+ Own Id: OTP-6755</p>
+ </item>
+ <item>
+ <p>
+ The runtime system with SMP support is now started by
+ default if more than one logical processor are detected.
+ For more information, see the <c>erl(3)</c>
+ documentation.</p>
+ <p>
+ Own Id: OTP-6756</p>
+ </item>
+ <item>
+ <p>
+ The external format for Erlang terms and the distribution
+ protocol are now documented in ERTS User's Guide.</p>
+ <p>
+ Own Id: OTP-6779</p>
+ </item>
+ <item>
+ <p>
+ New BIF's erlang:system_profile/1 and
+ erlang:system_profile/2. These BIF's controls concurrency
+ profiling options for processes, ports and schedulers.</p>
+ <p>
+ Own Id: OTP-6783 Aux Id: OTP-6285 </p>
+ </item>
+ <item>
+ <p>
+ The <c>ErlDrvTermData</c> term types used by
+ <c>driver_output_term()</c> and <c>driver_send_term()</c>
+ have been extended with the term types
+ <c>ERL_DRV_BUF2BINARY</c>, <c>ERL_DRV_EXT2TERM</c>, and
+ <c>ERL_DRV_UINT</c>. <c>ERL_DRV_BUF2BINARY</c> is used
+ for passing and creating a binary,
+ <c>ERL_DRV_EXT2TERM</c> is used for passing terms encoded
+ with the external term format, and <c>ERL_DRV_UINT</c> is
+ used for passing unsigned integers.</p>
+ <p>
+ Also the data types <c>ErlDrvUInt</c> and
+ <c>ErlDrvSInt</c> have been added which makes it more
+ obvious how arguments to term types are interpreted with
+ regards to width and signedness.</p>
+ <p>
+ The incorrect data types <c>ErlDriverTerm</c>,
+ <c>ErlDriverBinary</c>, and <c>ErlDriverPort</c> in the
+ <c>erl_driver(3)</c> documentation have been replaced
+ with the correct data types <c>ErlDrvTermData</c>,
+ <c>ErlDrvBinary</c>, and <c>ErlDrvPort</c>.</p>
+ <p>
+ For more information see the <c>erl_driver(3)</c>
+ documentation.</p>
+ <p>
+ Own Id: OTP-6823</p>
+ </item>
+ <item>
+ <p>
+ Miscellaneous improvements of the erts internal thread
+ library.</p>
+ <p>
+ It now support optimized atomic operations and spin-locks
+ on windows.</p>
+ <p>
+ Fall-backs based on mutexes and/or spin-locks for missing
+ optimized atomic operations, spin-locks, or rwlocks has
+ been implemented. This makes it possible to compile the
+ runtime system with SMP support on a lot more platforms.</p>
+ <p>
+ Default stack size on OpenBSD has been increased to 256
+ kilo-words.</p>
+ <p>
+ Own Id: OTP-6831 Aux Id: OTP-6560 </p>
+ </item>
+ <item>
+ <p>Many bit syntax operations, both construction and
+ matching, are faster. For further information, see the
+ Efficiency Guide.</p>
+ <p>
+ Own Id: OTP-6838</p>
+ </item>
+ <item>
+ <p>Literal lists, tuples, and binaries are no longer
+ constructed at run-time as they used to be, but are
+ stored in a per-module constant pool. Literals that are
+ used more than once are stored only once.</p>
+ <p>This is not a change to the language, only in the
+ details of its implementation. Therefore, the
+ implications of this change is described in the
+ Efficiency Guide.</p>
+ <p>Example 1: In the expression <c>element(BitNum-1,
+ {1,2,4,8,16,32,64,128})</c>, the tuple used to be
+ constructed every time the expression was executed, which
+ could be detrimental to performance in two ways if the
+ expression was executed in a loop: the time to build the
+ tuple itself and the time spent in garbage collections
+ because the heap filled up with garbage faster.</p>
+ <p>Example 2: Literal strings, such as <c>"abc"</c>, used
+ to be stored in the compiled code compactly as a byte
+ string and expanded to a list at run-time. Now all
+ strings will be stored expanded to lists (such as
+ <c>[$a,$b,$c]</c>) in the constant pool. That means that
+ the string will be faster to use at run-time, but that it
+ will require more space even when not used. If space is
+ an issue, you might want to use binary literals (that is,
+ <c>&lt;&lt;"abc"&gt;&gt;</c>) instead of string literals for
+ infrequently used long strings (such as error
+ messages).</p>
+ <p>
+ Own Id: OTP-6850</p>
+ </item>
+ <item>
+ <p>The Erlang driver API has been extended with a
+ portable POSIX thread like API for multi-threading. The
+ Erlang driver thread API provides:</p> <list>
+ <item>Threads</item> <item>Mutexes</item> <item>Condition
+ variables</item> <item>Read/Write locks</item>
+ <item>Thread specific data</item> </list> <p>For more
+ information see the <c>erl_driver(3)</c>
+ documentation.</p>
+ <p>
+ Own Id: OTP-6857</p>
+ </item>
+ <item>
+ <p>
+ Recursive calls now usually consume less stack than in
+ R11B. See the Efficiency Guide.</p>
+ <p>
+ Own Id: OTP-6862 Aux Id: seq10746 </p>
+ </item>
+ <item>
+ <p>
+ The deprecated BIFs <c>erlang:old_binary_to_term/1</c>
+ and <c>erlang:info/1</c> have been removed.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-6876</p>
+ </item>
+ <item>
+ <p>
+ Calls to driver call-backs triggered by external events
+ are now scheduled and interleaved with execution of
+ Erlang processes also on the runtime system without SMP
+ support.</p>
+ <p>
+ Own Id: OTP-6878</p>
+ </item>
+ <item>
+ <p>
+ Faster arithmetic of integers of more than 27 bits signed
+ (or 60 bits signed on an 64-bit CPU), and also faster
+ integer multiplication. (Thanks to Tony Rogvall.)</p>
+ <p>
+ Own Id: OTP-6891</p>
+ </item>
+ <item>
+ <p>Significant improvements of the <c>process_info</c>
+ BIFs:</p> <list> <item> <c>process_info/2</c> can now be
+ called with a list of items as second argument in order
+ to atomically retrieve information about multiple items.
+ </item> <item> <c>process_info/[1,2]</c> has been
+ optimized in the runtime system with SMP support. The
+ whole scheduler could previously be blocked for a
+ significant period of time in <c>process_info/[1,2]</c>
+ waiting for a lock on the process being inspected. The
+ Erlang process calling <c>process_info/[1,2]</c> can
+ still be blocked for a significant period of time waiting
+ for the lock, but the scheduler will now be able to run
+ other processes while the process calling
+ <c>process_info/[1,2]</c> waits for the lock. </item>
+ <item> <c>process_info/2</c> now accept a few more items
+ than before. </item> <item> The documentation of
+ <c>process_info/[1,2]</c> has been improved. </item>
+ </list> <p>For more information see the <c>erlang(3)</c>
+ documentation.</p>
+ <p>
+ Own Id: OTP-6899</p>
+ </item>
+ <item>
+ <p>
+ <c>open_port({}, [])</c> could crash the emulator.
+ (Thanks to Matthew Dempsky.)</p>
+ <p>
+ Own Id: OTP-6901</p>
+ </item>
+ <item>
+ <p>Two new guard BIFs have been introduced as a
+ recommended replacement for <c>size/1</c>. (The
+ <c>size/1</c> BIF will be removed no earlier than in
+ R14B.) The BIFs are <c>tuple_size/1</c> to calculate the
+ size of a tuple and <c>byte_size/1</c> to calculate the
+ number of bytes needed for the contents of the binary or
+ bitstring (rounded up to the nearest number of bytes if
+ necessary).</p>
+ <p>There is also a new <c>bit_size/1</c> BIF that returns
+ the exact number of bits that a binary or bitstring
+ contains.</p>
+ <p>
+ Own Id: OTP-6902</p>
+ </item>
+ <item>
+ <p>The <c>ets:fixtable/2</c> function, which has been
+ deprecated for several releases, has been removed.</p>
+ <p>The <c>ets:info/1</c> function has been reimplemented
+ as a BIF, which guarantees that information returned is
+ consistent.</p>
+ <p>The <c>ets:info/2</c> function now fails with reason
+ <c>badarg</c> if the second argument is invalid.
+ (Dialyzer can be used to find buggy code where the second
+ argument is misspelled.)</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-6906</p>
+ </item>
+ <item>
+ <p>
+ As the linux kernel may generate a minor fault when
+ tracing with CPU timestamps, and there exists no patch to
+ the Linux kernel that fixes the problem, cpu timestamps
+ are disabled on Linux for now.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-6922</p>
+ </item>
+ <item>
+ <p>The functions io:columns/0, io:columns/1, io:rows/0
+ and io:rows/1 are added to allow the user to get
+ information about the terminal geometry. The shell takes
+ some advantage of this when formatting output. For
+ regular files and other io-devices where height and width
+ are not applicable, the functions return
+ {error,enotsup}.</p>
+ <p>Potential incompatibility: If one has written a custom
+ io-handler, the handler has to either return an error or
+ take care of io-requests regarding terminal height and
+ width. Usually that is no problem as io-handlers, as a
+ rule of thumb, should give an error reply when receiving
+ unknown io-requests, instead of crashing.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-6933</p>
+ </item>
+ <item>
+ <p>
+ <c>driver_caller()</c> can now also be used from the
+ <c>start</c> callback of a driver.</p>
+ <p>
+ Own Id: OTP-6951</p>
+ </item>
+ <item>
+ <p>
+ The emulator can now be compiled for 64bit intel, as well
+ as a 32bit universal binary on darwin/MacOSX 10.4 and
+ 10.5.</p>
+ <p>
+ Own Id: OTP-6961</p>
+ </item>
+ <item>
+ <p>
+ If <c>open_port</c> fails because all available ports are
+ already in use, it will now throw a <c>system_limit</c>
+ exception instead of an <c>enfile</c> exception.
+ (<c>enfile</c> might still be thrown if the operating
+ system would return ENFILE.)</p>
+ <p>
+ Own Id: OTP-6968</p>
+ </item>
+ <item>
+ <p>
+ The <c>spawn_monitor/1</c> and <c>spawn_monitor/3</c> BIFs
+ are now auto-imported (i.e. they no longer need an
+ <c>erlang:</c> prefix).</p>
+ <p>
+ Own Id: OTP-6975</p>
+ </item>
+ <item>
+ <p>
+ On Windows, the werl window now handles resize, so that
+ the whole window can be utilized. Text selection is also
+ updated to be line oriented instead of rectangle oriented
+ as in earlier versions.</p>
+ <p>
+ Own Id: OTP-6994 Aux Id: OTP-6933 </p>
+ </item>
+ <item>
+ <p>
+ Kqueue support (kernel-poll) has been enabled on FreeBSD.
+ The problem with kqueue not detecting writes on a pipe on
+ FreeBSD was actually not a kqueue issue, but a writev on
+ pipes issue. Neither poll(), nor select() detected the
+ write when the bug hit. NetBSD and DragonFlyBSD probably
+ have or have had the same bug. This bug should have been
+ fixed in FreeBSD 6.3 and FreeBSD 7.0 thanks to
+ Jean-Sebastien Pedron.</p>
+ <p>
+ Own Id: OTP-7001</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Erts 5.5.5.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Hanging writes on temporarily unavailable NFS
+ filesystems could cause the execution of (not file
+ related) erlang code to get blocked even though I/O
+ threads were used. This is now corrected.</p>
+ <p>
+ Own Id: OTP-6907 Aux Id: seq10771 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.5.5.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Data passed to a driver via <c>erlang:port_call</c> could
+ be corrupted when the runtime system with SMP support was
+ used. (Thanks to YAMASHINA Hio.)</p>
+ <p>
+ Own Id: OTP-6879</p>
+ </item>
+ <item>
+ <p>
+ In the SMP emulator, if several processes called
+ ets:update_counter/3 (even for different tables) when the
+ counter values exceeded 27 bits, the counter values could
+ be corrupted or the emulator could crash.</p>
+ <p>
+ Own Id: OTP-6880 Aux Id: seq10760 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+<section><title>Erts 5.5.5.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Creating a named table using <c>ets:new/2</c> or
+ renaming a named table using <c>ets:rename/2</c> could in
+ rare circumstances succeed, meaning that there would be
+ two or more tables with the same name. Now such call will
+ fail with a <c>badarg</c> exception as it is supposed to
+ do.</p>
+ <p><c>ets:delete/1</c> used on a named table now removes
+ the name immediately so that a new table with the same
+ name can be created.</p>
+ <p>Turning on call trace on the internal BIF that
+ implements <c>ets:delete/1</c> would crash the
+ emulator.</p>
+ <p>SMP emulator only: Using <c>ets:rename/2</c> on a
+ table that <c>ets:safe_fixtable/2</c> has been used on
+ could cause an emulator crash or undefined behaviour
+ because of a missing lock.</p>
+ <p>
+ Own Id: OTP-6872 Aux Id: seq10756, seq10757 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.5.5.2</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ ets:select/3 on ordered_set and with a chunksize a
+ multiple of 1000 gave all elements instead of just 1000.
+ Also ets:slot/2 on ordered set could give unexpected
+ results on SMP emulator. Both problems are corrected.</p>
+ <p>
+ Own Id: OTP-6842</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Erts 5.5.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ All exported functions in gzio.c have now been renamed to
+ avoid conflict with drivers that are indirectly linked
+ with an external zlib library.</p>
+ <p>
+ Own Id: OTP-6816 Aux Id: OTP-6591 </p>
+ </item>
+ <item>
+ <p>
+ Calling binary_to_term/1 with certain invalid binaries
+ would crash the emulator.</p>
+ <p>
+ Own Id: OTP-6817</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Restored speed of bit-syntax matching of 32 bits
+ integers.</p>
+ <p>
+ Own Id: OTP-6789 Aux Id: seq10688 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+ <section>
+ <title>Erts 5.5.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The functions in gzio.c have been renamed to avoid
+ conflict with drivers that indirectly linked with an
+ external zlib library.</p>
+ <p>Own Id: OTP-6591</p>
+ </item>
+ <item>
+ <p>The emulator without SMP support dumped core if an
+ async-thread finished a job after the emulator had begun
+ writing an <c><![CDATA[erl_crash.dump]]></c>. </p>
+ <p>Own Id: OTP-6685</p>
+ </item>
+ <item>
+ <p>In bit syntax matching, integer fields with greater
+ size than 16Mb would fail to match. (Thanks to Bertil
+ Karlsson and Francesco Pierfederici.)</p>
+ <p>Matching out a 32-bit integer not aligned on a byte
+ boundary from a binary could cause an heap overflow (and
+ subsequent termination of the emulator).</p>
+ <p>A module that contained bit syntax construction with a
+ literal field size greater than 16Mb would fail to
+ load.</p>
+ <p>Several other similar bugs having to do with huge
+ field sizes were eliminated.</p>
+ <p>Attempting to construct a binary longer than 536870911
+ bytes will now fail with a <c><![CDATA[system_limit]]></c> exception
+ (rather than fail in mysterious ways or construct an
+ binary with incorrect contents). Similarily, attempting
+ to match a binary longer than 536870911 bytes will now
+ fail (instead of producing an incorrect result). This
+ limitation has been documented in the Efficiency Guide.
+ (The limit is in the 32-bit emulator; use the 64-bit
+ emulator if you need to handle larger binaries than
+ 536870911.)</p>
+ <p>Own Id: OTP-6686</p>
+ </item>
+ <item>
+ <p>Bugs in rem and div of very large numbers are corrected.</p>
+ <p>Own Id: OTP-6692</p>
+ </item>
+ <item>
+ <p><c><![CDATA[erlang:system_info({allocator, Alloc})]]></c> didn't
+ allocate enough heap when a bignum was part of the result
+ which could cause an emulator crash.</p>
+ <p>Own Id: OTP-6693</p>
+ </item>
+ <item>
+ <p>It was previously not possible to pass
+ <c><![CDATA[erts_alloc]]></c> the same configuration via the
+ command-line, as used by default. </p>
+ <p>A <c><![CDATA[+M*]]></c> command-line argument that configure a
+ size of some sort can now be passed a value that equals
+ the size of the address space. The value used, in this
+ case, will be <c><![CDATA["the size of the address space" - 1]]></c>.</p>
+ <p>Own Id: OTP-6699</p>
+ </item>
+ <item>
+ <p><c><![CDATA[SysIOVec* driver_peekq(ErlDrvPort port, int *vlen)]]></c> did not update <c><![CDATA[*vlen]]></c> if <c><![CDATA[port]]></c> was
+ invalid. <c><![CDATA[*vlen]]></c> is now set to <c><![CDATA[-1]]></c> if the
+ <c><![CDATA[port]]></c> is invalid.</p>
+ <p>The <c><![CDATA[efile]]></c> driver
+ expects <c><![CDATA[*vlen]]></c> to be updated also when the
+ <c><![CDATA[port]]></c> is invalid. This situation occurs seldom, but
+ when the runtime system has async-threads enabled and
+ ports are killed it can. When it occurred the runtime
+ system crashed.</p>
+ <p>Own Id: OTP-6729</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>For scripts written using <c><![CDATA[escript]]></c>, there is a new
+ function <c><![CDATA[escript:script_name/0]]></c>, which can be used
+ to retrieve the pathame of the script. The documentation
+ has been clarified regarding pre-defined macros such as
+ ?MODULE and the module name.</p>
+ <p>Own Id: OTP-6593</p>
+ </item>
+ <item>
+ <p>The section Guards in the chapter The Abstract Format
+ of the ERTS User's Guide has been updated.</p>
+ <p>Own Id: OTP-6600</p>
+ </item>
+ <item>
+ <p>Corrected protocol layer flue for socket options
+ SO_LINGER, SO_SNDBUF and SO_RCVBUF, for SCTP.</p>
+ <p>Own Id: OTP-6625 Aux Id: OTP-6336 </p>
+ </item>
+ <item>
+ <p>The behaviour of the inet option {active,once} on peer
+ close is improved and documented.</p>
+ <p>Own Id: OTP-6681</p>
+ </item>
+ <item>
+ <p>The inet option send_timeout for connection oriented
+ sockets is added to allow for timeouts in communicating
+ send requests to the underlying TCP stack.</p>
+ <p>Own Id: OTP-6684 Aux Id: seq10637 OTP-6681 </p>
+ </item>
+ <item>
+ <p>The command line flag <c><![CDATA[-args_file FileName]]></c>, and
+ the environment variables <c><![CDATA[ERL_AFLAGS]]></c>, and
+ <c><![CDATA[ERL_ZFLAGS]]></c> for the <c><![CDATA[erl]]></c> command have been
+ added. For more information see the <c><![CDATA[erl(1)]]></c>
+ documentation.</p>
+ <p>Own Id: OTP-6697</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[is_constant/1]]></c> type test has been deprecated.
+ <c><![CDATA[is_constant/1]]></c> is improperly named and almost
+ entirely undocumented.</p>
+ <p>Own Id: OTP-6731</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.4.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[process_flag(trap_exit, Bad)]]></c> where <c><![CDATA[Bad]]></c>
+ was a term not equal to <c><![CDATA[true]]></c> or <c><![CDATA[false]]></c>,
+ didn't fail with <c><![CDATA[badarg]]></c> as it should; instead, the
+ failure was silently ignored. This bug was introduced in
+ <c><![CDATA[erts-5.5.2]]></c>.</p>
+ <p>Own Id: OTP-6627 Aux Id: OTP-6160 </p>
+ </item>
+ <item>
+ <p>The minimum and default stack size for async-threads has
+ been increased to 16 kilowords. This since the previous
+ minimum and default stack size of 8 kilowords proved to
+ be too small (introduced in <c><![CDATA[erts-5.5.4.2]]></c>).</p>
+ <p>Own Id: OTP-6628 Aux Id: OTP-6580, Seq10633 </p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>process_flag/2 accepts the new flag <c><![CDATA[sensitive]]></c>.</p>
+ <p>Own Id: OTP-6592 Aux Id: seq10555 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.4.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>When a port steals control over a file descriptor from
+ another port, the stealing port tests if the other port
+ is alive. This in order to be able to give an accurate
+ error message. In the runtime system with SMP support,
+ this test was done without appropriate locks held. This
+ could in worst case lead to an erroneous error message;
+ therefore, this bug is to be considered harmless.</p>
+ <p>Own Id: OTP-6602</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The default stack size for threads in the async-thread
+ pool has been shrunk to 8 kilowords, i.e., 32 KB on
+ 32-bit architectures. This small default size has been
+ chosen since the amount of async-threads might be quite
+ large. The default stack size is enough for drivers
+ delivered with Erlang/OTP, but might not be sufficiently
+ large for other dynamically linked in drivers that use
+ the <c><![CDATA[driver_async()]]></c> functionality. A suggested
+ stack size for threads in the async-thread pool can be
+ configured via the <c><![CDATA[+a]]></c> command line argument of
+ <c><![CDATA[erl(1)]]></c>.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-6580</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.4.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Setting the time on the system while using heart on a
+ linux machine where the emulator was built with
+ clock_gettime support (default from Linux 2.6/erts-5.5.4
+ and upwards), could make the heart command fire. This was
+ due to bug in the heart executable which is now
+ corrected.</p>
+ <p>Own Id: OTP-6598 Aux Id: seq10614 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Corrected misspelling of '<c><![CDATA[-pz]]></c>' in the help text
+ for <c><![CDATA[erlc]]></c>. (Thanks to Ulf Wiger.)</p>
+ <p>Own Id: OTP-6433</p>
+ </item>
+ <item>
+ <p>The MD5 calculation of a BEAM file done by
+ <c><![CDATA[code:module_md5/1]]></c>, <c><![CDATA[beam_lib:md5/1]]></c>, and by
+ the compiler for the default value of the <c><![CDATA[vsn]]></c>
+ attribute have all been changed so that its result will
+ be the same on all platforms; modules containing funs
+ could get different MD5s on different platforms.</p>
+ <p>Own Id: OTP-6459</p>
+ </item>
+ <item>
+ <p>The emulator could dump core while writing an
+ <c><![CDATA[erl_crash.dump]]></c> file if there were funs with a
+ large terms in its environment. Since there is no way to
+ inspect a fun's environment in the crashdump_viewer
+ application anyway, a variables in the environment are
+ now set to [] before dumping the fun. (Thanks to
+ Jean-Sebastien Pedron.)</p>
+ <p>Own Id: OTP-6504</p>
+ </item>
+ <item>
+ <p><c><![CDATA[{Port, {exit_status, S}}]]></c> messages from ports
+ opened with the <c><![CDATA[exit_status]]></c> option could under
+ rare circumstances be delayed. This bug was present on
+ Erlang runtime systems without SMP support on all unix
+ operating systems other than SunOS.</p>
+ <p>Own Id: OTP-6528</p>
+ </item>
+ <item>
+ <p>A bug in linuxthreads could cause the emulator to dump
+ core when dlerror() was called before the first call to
+ dlopen(). As a workaround the emulator always makes a
+ call to dlopen() on initialization when linuxthreads is
+ used as thread library.</p>
+ <p>Own Id: OTP-6530</p>
+ </item>
+ <item>
+ <p>file:sync/1 did not do anything on Windows. Now it calls
+ the system function for flushing buffers
+ (FlushFileBuffers()). (Thanks to Matthew Sackman.)</p>
+ <p>Own Id: OTP-6531</p>
+ </item>
+ <item>
+ <p><c><![CDATA[open_port/2]]></c> could on the runtime system with SMP
+ support fail with the wrong exit reason when a port
+ couldn't be created. When this happened the exit reason
+ was typically <c><![CDATA[eintr]]></c>, or <c><![CDATA[ebusy]]></c> instead of
+ <c><![CDATA[eagain]]></c>.</p>
+ <p>Own Id: OTP-6536</p>
+ </item>
+ <item>
+ <p>The file driver (efile_drv) did not flush data written
+ using the option 'delayed_write' after the set timeout
+ time, rather at the next file operation. This bug has now
+ been corrected.</p>
+ <p>Own Id: OTP-6538</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>An interface towards the SCTP Socket API Extensions
+ has been implemented.It is an Open Source patch courtesy
+ of Serge Aleynikov and Leonid Timochouk. The Erlang code
+ parts has been adapted by the OTP team, changing the
+ Erlang API somewhat.</p>
+ <p>The Erlang interface consists of the module
+ <c><![CDATA[gen_sctp]]></c> and an include file
+ <c><![CDATA[-include_lib("kernel/include/inet_sctp.hrl").]]></c> for
+ option record definitions. The <c><![CDATA[gen_sctp]]></c> module is
+ documented.</p>
+ <p>The delivered Open Source patch, before the OTP team
+ rewrites, was written according to
+ http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13
+ and was claimed to work fine, tested on Linux Fedora Core
+ 5.0 (kernel 2.6.15-2054 or later) and on Solaris 10 and
+ 11. The OTP team rewrites used the same standard document
+ but might have accidentally broken some functionality. If
+ so it will soon be patched to working state. The tricky
+ parts in C and the general design has essentially not
+ changed. During the rewrites the code was hand tested on
+ SuSE Linux Enterprise Server 10, and briefly on Solaris
+ 10. Feedbach on code and docs is very much
+ appreciated.</p>
+ <p>The SCTP interface is in beta state. It has only been
+ hand tested and has no automatic test suites in OPT
+ meaning everything is most certainly not tested. Socket
+ active mode is broken. IPv6 is not tested. The
+ documentation has been reworked due to the API changes,
+ but has not been proofread after this.</p>
+ <p>Thank you from the OTP team to Serge Aleynikov and
+ Leonid Timochouk for a valuable contribution. We hope we
+ have not messed it up too much.</p>
+ <p>Own Id: OTP-6336</p>
+ </item>
+ <item>
+ <p>A <c><![CDATA[{minor_version,Version}]]></c> option is now recognized
+ by <c><![CDATA[term_to_binary/2]]></c>. {minor_version,1} will cause
+ floats to be encoded in an exact and more space-efficient
+ way compared to the previous encoding.</p>
+ <p>Own Id: OTP-6434</p>
+ </item>
+ <item>
+ <p>There is a new <c><![CDATA[escript]]></c> program that can be used
+ for writing scripts in Erlang. Erlang scripts don't need
+ to be compiled and any arguments can be passed to them
+ without risk that they are interpreted by the Erlang
+ system.</p>
+ <p>Own Id: OTP-6505</p>
+ </item>
+ <item>
+ <p>Setting and getting socket options in a "raw" fashion is
+ now allowed. Using this feature will inevitably produce
+ non portable code, but will allow setting ang getting
+ arbitrary uncommon options on TCP stacks that do have
+ them.</p>
+ <p>Own Id: OTP-6519</p>
+ </item>
+ <item>
+ <p>Miscellaneous signal handling improvements on the Erlang
+ runtime system with SMP support.</p>
+ <p>The fallback implementation of spin locks and atomic
+ operations are now implemented using pthread spin locks
+ when pthread spin locks are found on the system.</p>
+ <p>The Erlang runtime system with SMP support can now run on
+ Linux systems that has Linuxthreads instead of NPTL
+ (Native POSIX Thread Library). Note that the SMP support
+ hasn't been as thoroughly tested with Linuxthreads as
+ with NPTL. A runtime system with SMP support will
+ therefore not be built by default on Linux when NPTL
+ isn't found. In order to force a build of the runtime
+ system with SMP support, pass <c><![CDATA[--enable-smp-support]]></c>
+ to <c><![CDATA[configure]]></c> when building OTP.</p>
+ <p>Own Id: OTP-6525</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.3.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[erlang:system_flag(multi_scheduling, block)]]></c> could
+ cause the emulator with SMP support to deadlock.</p>
+ <p>Own Id: OTP-6431 Aux Id: OTP-6403 </p>
+ </item>
+ <item>
+ <p>The runtime system with SMP support failed to call the
+ driver timeout callback of ports in state closing. This
+ could cause ports to fail flushing their I/O queues.</p>
+ <p>Own Id: OTP-6432</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[{Port, closed}]]></c> message from a closed port
+ could arrive at the port owner before <c><![CDATA[Port]]></c> had
+ been removed from the result of <c><![CDATA[erlang:ports/0]]></c> in
+ the runtime system with SMP support.</p>
+ <p>Own Id: OTP-6437</p>
+ </item>
+ <item>
+ <p>The async id of async jobs created via
+ <c><![CDATA[driver_async]]></c> wasn't created in a thread safe
+ manner in the runtime system with SMP support. This could
+ in worst case cause <c><![CDATA[driver_async_cancel()]]></c> to
+ cancel another async job than intended.</p>
+ <p>Own Id: OTP-6438</p>
+ </item>
+ <item>
+ <p>Under rare circumstances a terminating connection between
+ two nodes could cause an instantaneous reconnect between
+ the two nodes to fail on the runtime system with SMP
+ support.</p>
+ <p>Own Id: OTP-6447</p>
+ </item>
+ <item>
+ <p>In the documentation of the driver entry field
+ <c><![CDATA[extended_marker]]></c> of erts version 5.5.3
+ (<c><![CDATA[driver_entry(3)]]></c>), the following is stated: "The
+ following fields are ignored if this field is equal to
+ <c><![CDATA[0]]></c>". This is a documentation bug and has been
+ changed to: "If this field is equal to <c><![CDATA[0]]></c>, all the
+ fields following this field also <em>have</em> to be
+ <c><![CDATA[0]]></c>, or <c><![CDATA[NULL]]></c> in case it is a pointer field".</p>
+ <p>The runtime check for detection of old incompatible
+ drivers made when loading drivers has been improved. The
+ emulator can, however, not make sure that a driver that
+ doesn't use the extended driver interface isn't
+ incompatible. Therefore, when loading a driver that
+ doesn't use the extended driver interface, there is a
+ risk that it will be loaded also when the driver is
+ incompatible. When the driver use the extended driver
+ interface, the emulator can verify that it isn't of an
+ incompatible driver version. You are therefore advised to
+ use the extended driver interface.</p>
+ <p>For more information see the <c><![CDATA[erl_driver(3)]]></c> and
+ <c><![CDATA[driver_entry(3)]]></c> documentation.</p>
+ <p>Own Id: OTP-6452 Aux Id: OTP-6330 </p>
+ </item>
+ <item>
+ <p>When terminating ports on the runtime system with SMP
+ support, removal of links to processes was done without
+ locking the link lock on processes. This could cause an
+ emulator crash.</p>
+ <p>Own Id: OTP-6475</p>
+ </item>
+ <item>
+ <p>The emulator with SMP support could crash when a port
+ flushed its I/O queue by calling <c><![CDATA[driver_async()]]></c>
+ from the timeout driver callback.</p>
+ <p>Own Id: OTP-6479</p>
+ </item>
+ <item>
+ <p>Large exit reasons could under rare circumstances cause
+ the runtime system with SMP support to crash.</p>
+ <p>Own Id: OTP-6521</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Faster system calls for keeping the time accurate are
+ used on newer Linux kernels, which can result in a
+ significant speed-up of the emulator on those systems.</p>
+ <p>Own Id: OTP-6430</p>
+ </item>
+ <item>
+ <p>Added number of async threads and number of scheduler
+ threads to the system information that can be retrieved
+ via <c><![CDATA[driver_system_info()]]></c>. For more information see
+ the <c><![CDATA[erl_driver(3)]]></c> documentation.</p>
+ <p>Own Id: OTP-6440</p>
+ </item>
+ <item>
+ <p>When <c><![CDATA[SIGUSR1]]></c> is received by the runtime system
+ with SMP support, the <c><![CDATA[erl_crash.dump]]></c> is now
+ written by a special thread, instead of as before
+ directly from the signal handler.</p>
+ <p>Own Id: OTP-6465</p>
+ </item>
+ <item>
+ <p>term_to_binary/2 with compression is now faster.</p>
+ <p></p>
+ <p>term_to_binary/2 now accepts the option
+ '<c><![CDATA[{compressed,Level}]]></c>' for specifying the
+ compression level. <c><![CDATA[Level]]></c> must be in the range 0
+ (no compression) through 9 (highest compression level).
+ Default is 6.</p>
+ <p>Future compatibility bugfix: binary_to_term/1 did not
+ handle the <c><![CDATA[Uniq]]></c> and <c><![CDATA[Index]]></c> fields
+ correctly.</p>
+ <p>Own Id: OTP-6494</p>
+ </item>
+ <item>
+ <p>Removed unnecessary reallocation when initializing
+ kernel-poll set.</p>
+ <p>Own Id: OTP-6516</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Node and fun table entries could under rare circumstances
+ be deallocated multiple times on the emulator with SMP
+ support.</p>
+ <p>Own Id: OTP-6369</p>
+ </item>
+ <item>
+ <p>epoll_wait() can repeat entries for the same file
+ descriptor in the result array. This could cause the
+ ready_input, ready_output, or event callbacks of a driver
+ to unintentionally be called multiple times. We have only
+ noted repeated entries when an error condition has
+ occurred on the file descriptor. In this case, the
+ repeated entries should normally not be a problem for the
+ driver since it should detect the error and de-select the
+ file descriptor. Therefore this bug should be considered
+ harmless. The emulator now coalesce repeated entries into
+ one.</p>
+ <p>You are only affected by this bug if you are using
+ erts-5.5.2.* and the kernel-poll feature on linux.</p>
+ <p>Own Id: OTP-6376 Aux Id: OTP-6222 </p>
+ </item>
+ <item>
+ <p>If a process that was waiting in gen_tcp:accept/1 was
+ killed, calling gen_tcp:accept/1 again on the same listen
+ socket would fail with '<c><![CDATA[{error,einval}]]></c>'.</p>
+ <p>Own Id: OTP-6381 Aux Id: seq10535 </p>
+ </item>
+ <item>
+ <p>The emulator failed to start on Solaris 10 when
+ kernel-poll support was enabled and the maximum number of
+ filedescriptors configured was less than or equal to 256.</p>
+ <p>Own Id: OTP-6384 Aux Id: OTP-6222 </p>
+ </item>
+ <item>
+ <p>The R10B compiler could generate unsafe
+ <c><![CDATA[bs_save/bs_restore]]></c> instructions that could cause
+ memory corruption. (The R11B compiler does not have that
+ problem.) The erlang emulator will now refuse to load
+ R10B-compiled modules that contain such unsafe
+ <c><![CDATA[bs_save/bs_restore]]></c> instructions. In addition, the
+ beam_validator module in the compiler will also reject
+ such instructions (in case it is used to validate R10B
+ code). (Thanks to Matthew Reilly.)</p>
+ <p>Own Id: OTP-6386</p>
+ </item>
+ <item>
+ <p>Process and port timers could fail to work properly on
+ the runtime system with SMP support. Many thanks to
+ Dmitriy Kargapolov and Serge Aleynikov who tracked down
+ this bug.</p>
+ <p>Own Id: OTP-6387</p>
+ </item>
+ <item>
+ <p>Bit syntax code compiled by an R10B compiler that matched
+ out a floating point number would not properly check that
+ the floating point number was valid; if the float was,
+ for instance, NaN the emulator could crash.</p>
+ <p>Own Id: OTP-6395</p>
+ </item>
+ <item>
+ <p>statistics(runtime) on Windows used to return the elapsed
+ system time for the process, instead of the user time.
+ Corrected. (Thanks to Robert Virding.)</p>
+ <p>Own Id: OTP-6407</p>
+ </item>
+ <item>
+ <p>A loadable driver (loaded by erl_ddll) which used
+ driver_async() would cause the emulator to crash. (Thanks
+ to Dmitriy Kargapolov.)</p>
+ <p>Own Id: OTP-6410</p>
+ </item>
+ <item>
+ <p>Under rare circumstances the emulator on unix platforms
+ could fail to terminate the Erlang port corresponding to
+ a port program opened with the <c><![CDATA[exit_status]]></c> option.</p>
+ <p>Own Id: OTP-6411</p>
+ </item>
+ <item>
+ <p>A link removed via <c><![CDATA[unlink/1]]></c> could under rare
+ circumstances transfer exit signals for a short period of
+ time after the call to <c><![CDATA[unlink/1]]></c> had returned when
+ the runtime system with SMP support was used.</p>
+ <p>Own Id: OTP-6425 Aux Id: OTP-6160 </p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>In the runtime system with SMP support, ports are now
+ being scheduled on the scheduler threads interleaved with
+ processes instead of being run in a separate I/O thread.</p>
+ <p>Own Id: OTP-6262</p>
+ </item>
+ <item>
+ <p>More interfaces are added in erl_ddll, to support
+ different usage scenarios.</p>
+ <p>Own Id: OTP-6307 Aux Id: OTP-6234 </p>
+ </item>
+ <item>
+ <p>In the runtime system with SMP support, the global
+ I/O lock has been replaced with a more fine grained port
+ locking scheme. Port locking is either done on driver
+ level, i.e., all ports executing the same driver share a
+ lock, or on port level, i.e., each port has its own lock.
+ Currently the inet driver, the efile driver, and the
+ spawn driver use port level locking and all other
+ statically linked in drivers use driver level locking. By
+ default dynamically linked in drivers will use locking on
+ driver level. For more information on how to enable port
+ level locking see the <c><![CDATA[erl_driver(3)]]></c> and the
+ <c><![CDATA[driver_entry(3)]]></c> man pages. </p>
+ <p>As of erts
+ version 5.5.3 the driver interface has been extended. The
+ extended interface introduce version management, the
+ possibility to pass capability flags to the runtime
+ system at driver initialization, and some new driver API
+ functions. For example, the <c><![CDATA[driver_system_info()]]></c>
+ function which can be used to determine if the driver is
+ run in a runtime system with SMP support or not. The
+ extended interface doesn't have to be used, <em>but</em>
+ dynamically linked in driver <em>have</em> to be
+ recompiled. For information see the <c><![CDATA[erl_driver(3)]]></c>
+ and the <c><![CDATA[driver_entry(3)]]></c> man pages. </p>
+ <p><em>NOTE:</em> Dynamically linked in drivers
+ <em>have</em> to be recompiled. </p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-6330 Aux Id: OTP-6262 </p>
+ </item>
+ <item>
+ <p>A test and debug feature which modifies the timing of the
+ runtime system has been added. For more information, see
+ documentation of the <c><![CDATA[+T<Level>]]></c> command line
+ argument of <c><![CDATA[erl(1)]]></c>.</p>
+ <p>Own Id: OTP-6382</p>
+ </item>
+ <item>
+ <p>The version of zlib (http://zlib.net) linked into
+ run-time system has been updated to version 1.2.3.</p>
+ <p>Own Id: OTP-6394</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[erlc]]></c> program now passes on the <c><![CDATA[-smp]]></c>
+ and <c><![CDATA[-hybrid]]></c> options to the Erlang emulator it
+ starts. This is mainly useful for compiling native code,
+ because native code must be compiled with same type of
+ run-time system as in which it will be run.</p>
+ <p>If the <c><![CDATA[-s]]></c> option is given, <c><![CDATA[erlc]]></c> now
+ prints a warning that it is deprecated and that it will
+ be removed in R12B.</p>
+ <p>Own Id: OTP-6398</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[schedulers]]></c> option of
+ <c><![CDATA[erlang:system_flag/2]]></c> has been removed, i.e., the
+ number of scheduler threads cannot be changed after
+ emulator boot time any more.</p>
+ <p>A <c><![CDATA[multi_scheduling]]></c> option has been added to
+ <c><![CDATA[erlang:system_flag/2]]></c>. This option can be used for
+ blocking and unblocking multi-scheduling. For more
+ information see the <c><![CDATA[erlang(3)]]></c> documentation.</p>
+ <p>Own Id: OTP-6403</p>
+ </item>
+ <item>
+ <p>A port program that had been started with the
+ <c><![CDATA[exit_status]]></c> option and closed one of the pipes
+ used for communication with the emulator caused the
+ emulator to continuously poll for termination of the port
+ program. This only became a problem when the emulator
+ didn't have other things to do and the port program
+ closed a pipe much earlier than it terminated. When the
+ emulator had other things to do, such as running Erlang
+ processes, the emulator polled for termination in between
+ scheduling of processes.</p>
+ <p>Now the emulator doesn't poll for termination of the port
+ program at all; instead, it waits for the child signal
+ from the terminated port program to arrive and then
+ schedules the Erlang port for termination.</p>
+ <p>The termination of any port programs have also been
+ optimized. Previously the termination of any port program
+ did always cause a scan of a table of the size equal to
+ maximum number of file descriptors. If the maximum number
+ of file descriptors was large, this scan could be quite
+ expensive. Now the search have been reduced to the set of
+ ports started with the <c><![CDATA[exit_status]]></c> option.</p>
+ <p>Note, all of the above only applies to Erlang emulators
+ on Unix platforms.</p>
+ <p>Own Id: OTP-6412 Aux Id: seq10194 </p>
+ </item>
+ <item>
+ <p>* BEAM: added support for floating-point exceptions on
+ FreeBSD (32-bit x86)</p>
+ <p>* SMP: made locking procedures work even when native
+ lock operations aren't implemented</p>
+ <p>* SMP: improved timing accuracy in the timer thread
+ (if enabled)</p>
+ <p>Own Id: OTP-6424</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.2.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A bug in the kernel poll implementation could cause the
+ emulator to omit polling for events on file descriptors.
+ The bug was only present when using the kernel poll
+ implementation based on epoll or kqueue. This bug was
+ introduced in erts-5.5.2.</p>
+ <p>Own Id: OTP-6344 Aux Id: OTP-6222 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.2.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The run_erl program now acquires its pseudo-ttys using
+ openpty(3), so that it will work on newer Linux
+ distributions that don't have the traditional pseudo-tty
+ devices in the file system. On platforms that don't have
+ openpty(3), run_erl will still search for pseudo-tty
+ devices in the file system.</p>
+ <p>The run_erl program will now wait using waitpid(3) to
+ prevent the program it spawned to become defunct. run_erl
+ will also terminate after a delay of 5 seconds (to allow
+ any pending output to be written to the log file) if the
+ spawned program terminates even if some child of it still
+ holds stdin and/or stdout open.</p>
+ <p>Own Id: OTP-6225 Aux Id: seq10500 </p>
+ </item>
+ <item>
+ <p>A bug in ordered_set ETS datatyp caused ets:select (and
+ match) to return faulty results when the table contained
+ process id's from another node.</p>
+ <p>Own Id: OTP-6338</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>erlc: A typo in the help text for '-pa path' was
+ corrected.</p>
+ <p>Own Id: OTP-6218</p>
+ </item>
+ <item>
+ <p>Failure in port command/control driver callbacks could
+ crash the non-SMP emulator. This bug was introduced in
+ the 5.5 version of erts.</p>
+ <p>Own Id: OTP-6224</p>
+ </item>
+ <item>
+ <p>Erroneous "<c><![CDATA[Input driver gone away without deselecting!]]></c>" error reports could sometimes occur
+ when a driver instance terminated in the ready_output()
+ callback of the driver. This bug was only present in
+ emulators that used poll(). Note, that this bug was
+ harmless, the only effect it had was the erroneous error
+ report.</p>
+ <p>Own Id: OTP-6229 Aux Id: OTP-3993, Seq5266, Seq7247,
+ OTP-4307 </p>
+ </item>
+ <item>
+ <p>The emulator could cause a type assertion failure while
+ writing an erl_crash.dump, causing the erl_crash.dump to
+ be terminated and a core dump generated.</p>
+ <p>Own Id: OTP-6235 Aux Id: seq10444 </p>
+ </item>
+ <item>
+ <p>The registered name of a process is now the last
+ observable resource removed before links and monitors are
+ triggered when a process terminates.</p>
+ <p>Previously ets tables were removed after the registered
+ name. This could cause problems on the runtime system
+ with SMP support for code that expected that ets tables
+ owned by a specific process had been removed if the name
+ of the process had been removed.</p>
+ <p>Own Id: OTP-6237</p>
+ </item>
+ <item>
+ <p>Failure to fork() a new (os) process could cause the
+ emulator to deadlock. This bug affect all emulators with
+ SMP support, and emulators with async thread support on
+ SunOS.</p>
+ <p>Own Id: OTP-6241 Aux Id: OTP-3906 </p>
+ </item>
+ <item>
+ <p>Fprof traces could become truncated for the SMP emulator.
+ This bug has now been corrected.</p>
+ <p>Own Id: OTP-6246</p>
+ </item>
+ <item>
+ <p>The undocumented functions inet:getiflist/0,1
+ inet:ifget/2,3 and inet:getif/1 were completely broken on
+ Windows. That has been fixed.</p>
+ <p>Own Id: OTP-6255</p>
+ </item>
+ <item>
+ <p>Behavior in case of disappeared nodes when using the
+ dist_auto_connect once got changed in R11B-1. The
+ timeouts regarding normal distributed operations is now
+ reverted to the old (pre R11B-1).</p>
+ <p>Own Id: OTP-6258 Aux Id: OTP-6200, seq10449 </p>
+ </item>
+ <item>
+ <p>The bsl and bsr operators could cause the emulator to
+ crash if given invalid arguments. (Thanks to datacompboy
+ and Per Gustafsson.)</p>
+ <p>Own Id: OTP-6259</p>
+ </item>
+ <item>
+ <p>driver_cancel_timer() could under certain circumstances
+ fail to cancel the timer on the runtime system with SMP
+ support.</p>
+ <p>Own Id: OTP-6261</p>
+ </item>
+ <item>
+ <p>A call to erlang:system_info(info) could deadlock the
+ runtime system with SMP support.</p>
+ <p>Own Id: OTP-6268</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Exit signals are now truly asynchronous in the runtime
+ system with SMP support. This simplifies locking in bifs
+ a lot, and makes process termination cheaper.</p>
+ <p>Own Id: OTP-6160</p>
+ </item>
+ <item>
+ <p>When tracing on the runtime system with SMP support it
+ can be difficult to know when a trace has been delivered
+ to the tracer. A new built in function
+ <c><![CDATA[erlang:trace_delivered/1]]></c> has been introduced in
+ order to make it easier to know when the trace has been
+ delivered. See the erlang(3) man page for more
+ information.</p>
+ <p>Own Id: OTP-6205 Aux Id: OTP-6269 </p>
+ </item>
+ <item>
+ <p>Kernel poll support can now be combined with SMP support.
+ Currently the following kernel poll versions exist:
+ <c><![CDATA[/dev/poll]]></c>, <c><![CDATA[epoll]]></c>, and <c><![CDATA[kqueue]]></c>. Linux
+ <c><![CDATA[kpoll]]></c> has been replaced with <c><![CDATA[epoll]]></c>. Some
+ time in the future there will also be a kernel poll
+ version using Solaris event ports.</p>
+ <p>The "check io" implementation for unix has been
+ completely rewritten. The current kernel poll
+ implementation reduce the amount of system calls needed
+ compared to the old kernel poll implementation.</p>
+ <p>When <c><![CDATA[epoll]]></c> or <c><![CDATA[kqueue]]></c> is used either
+ <c><![CDATA[poll]]></c> or <c><![CDATA[select]]></c> is used as fallback.
+ Previously only <c><![CDATA[poll]]></c> could be used as fallback.
+ Since <c><![CDATA[select]]></c> now can be used as fallback, kernel
+ poll support is now also available on newer MacOSX. Note
+ however, when <c><![CDATA[select]]></c> is used as fallback, the
+ maximum number of file descriptors is limited to
+ <c><![CDATA[FD_SETSIZE]]></c>. </p>
+ <p>Kernel poll support is now enabled by default if
+ <c><![CDATA[/dev/poll]]></c>, <c><![CDATA[epoll]]></c>, or <c><![CDATA[kqueue]]></c> is found
+ when building OTP, i.e. you do not have to pass the
+ <c><![CDATA[--enable-kernel-poll]]></c> argument to <c><![CDATA[configure]]></c>.
+ As before, kernel poll is disabled by default in the
+ runtime system. In order to enable it, pass the
+ <c><![CDATA[+Ktrue]]></c> command line argument to <c><![CDATA[erl]]></c>.</p>
+ <p>Note: <c><![CDATA[configure]]></c> will refuse to enable kernel poll
+ support on FreeBSD since <c><![CDATA[kqueue]]></c> have problems with
+ (at least) pipes on all version of FreeBSD that we have
+ tested.</p>
+ <p>Own Id: OTP-6222 Aux Id: seq10380 </p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[erl_ddll]]></c> module and the code in the emulator
+ have been completely rewritten; several bugs were fixed.</p>
+ <p>Own Id: OTP-6234</p>
+ </item>
+ <item>
+ <p>The SMP emulator now avoids locking for the following
+ operations (thus making them as fast as in the UP
+ emulator): <c><![CDATA[atom_to_list/1]]></c>, atom comparison, atom
+ hashing, <c><![CDATA[erlang:apply/3]]></c>.</p>
+ <p>Own Id: OTP-6252</p>
+ </item>
+ <item>
+ <p>There are new BIFs <c><![CDATA[erlang:spawn_monitor/1,3]]></c>,
+ and the new option <c><![CDATA[monitor]]></c> for
+ <c><![CDATA[spawn_opt/2,3,4,5]]></c>.</p>
+ <p>The <c><![CDATA[observer_backend]]></c> module has been updated to
+ handle the new BIFs.</p>
+ <p>Own Id: OTP-6281</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.1.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>There is now an option read_packets for UDP sockets that
+ sets the maximum number of UDP packets that will be read
+ for each invocation of the socket driver.</p>
+ <p>Own Id: OTP-6249 Aux Id: seq10452 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Erts 5.5.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Complex pattern matching of strings would fail in the 64
+ bits emulator because of a bug in the loader. (Thanks to
+ Igor Goryachev.)</p>
+ <p>Own Id: OTP-6142</p>
+ </item>
+ <item>
+ <p><c><![CDATA[-134217728 div 134217728]]></c> and <c><![CDATA[-134217728 rem 134217728]]></c> would be calculated incorrectly.
+ <c><![CDATA[abs(-2147483648)]]></c> could in unlucky circumstances
+ cause a heap overflow, as could size(Binary) when size of
+ the binary was larger than 128Mb.</p>
+ <p>Own Id: OTP-6154</p>
+ </item>
+ <item>
+ <p>erlang:display/1 displayed erroneous values for negative
+ integers.</p>
+ <p>Big integers (both positive and negative) were previously
+ displayed in hexadecimal form while small integers were
+ displayed in decimal form. All integers are now displayed
+ in decimal form.</p>
+ <p>NOTE: erlang:display/1 should only be used for debugging.</p>
+ <p>Own Id: OTP-6156</p>
+ </item>
+ <item>
+ <p>A call to erlang:trace/3 with erroneous flags caused the
+ SMP emulator to deadlock instead of exiting the calling
+ process with badarg.</p>
+ <p>Own Id: OTP-6175</p>
+ </item>
+ <item>
+ <p>A bug causing the emulator to hang when exiting a process
+ that is exception traced has been fixed.</p>
+ <p>Own Id: OTP-6180</p>
+ </item>
+ <item>
+ <p>ets:rename/1 could deadlock, or crash the SMP emulator
+ when the table wasn't a named table.</p>
+ <p>ets:next/2, and ets:prev/2 could return erroneous results
+ on the SMP emulator.</p>
+ <p>Own Id: OTP-6198 Aux Id: seq10392, seq10415 </p>
+ </item>
+ <item>
+ <p>A memory allocation bug could cause the SMP emulator to
+ crash when a process had executed a <c><![CDATA[receive after]]></c>
+ with a larger timeout than 10 minutes.</p>
+ <p>Own Id: OTP-6199</p>
+ </item>
+ <item>
+ <p>The runtime system with SMP support did not slowly adjust
+ it's view of time when the system time suddenly changed.</p>
+ <p>Timeouts could sometimes timeout too early on the runtime
+ system with SMP support.</p>
+ <p>Own Id: OTP-6202</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The smp runtime system now automatically detects the
+ number of logical processors on MacOSX (darwin) and
+ OpenBSD.</p>
+ <p>The smp runtime system is now built by default on MacOSX
+ (darwin) on x86.</p>
+ <p>Own Id: OTP-6119</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[-smp]]></c> command line argument now take the
+ following options: <c><![CDATA[enable]]></c>, <c><![CDATA[auto]]></c>, or
+ <c><![CDATA[disable]]></c>.</p>
+ <p>Especially the <c><![CDATA[-smpauto]]></c> argument is useful since
+ it starts the Erlang runtime system with SMP support if
+ it is available and more than one logical processor are
+ detected; otherwise, it starts the Erlang runtime system
+ without SMP support. For more information see the
+ <c><![CDATA[erl(1)]]></c> man page.</p>
+ <p>Own Id: OTP-6126</p>
+ </item>
+ <item>
+ <p>Increased the reduction cost for sending messages in the
+ SMP emulator so it behaves more like the non-SMP
+ emulator.</p>
+ <p>Own Id: OTP-6196</p>
+ </item>
+ <item>
+ <p>A port running a dynamically linked-in driver that exits
+ due to the driver being unloaded now exits with exit
+ reason <c><![CDATA[driver_unloaded]]></c>. Previously the port exited
+ with exit reason <c><![CDATA[-1]]></c>.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-6204</p>
+ </item>
+ <item>
+ <p>Changed name of the <c><![CDATA[erlang:system_info/1]]></c> argument
+ <c><![CDATA[scheduler]]></c> to <c><![CDATA[scheduler_id]]></c>. This since the
+ <c><![CDATA[scheduler]]></c> argument so easily could be mixed up
+ with the <c><![CDATA[schedulers]]></c> argument (both returning
+ integers).</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-6208</p>
+ </item>
+ <item>
+ <p>The changes below were made by Mikael Pettersson, HiPE.</p>
+ <p>HiPE runtime system:</p>
+ <p>Reduce overheads in the HiPE runtime system's BIF glue
+ code.</p>
+ <p>Fix bug when exceptions are thrown from BEAM to HiPE.</p>
+ <p>Support SPARC on Linux.</p>
+ <p>Support x86 on FreeBSD.</p>
+ <p>Floating-point exceptions:</p>
+ <p>Reduce overheads in checking results of floating-point
+ operations.</p>
+ <p>Minor bug fix in SSE2 floating-point exception
+ handling.</p>
+ <p>Support SSE2 floating-point exceptions on 32-bit x86
+ machines.</p>
+ <p>Make FP exceptions work in the SMP runtime system on
+ FreeBSD/x86.</p>
+ <p>Support floating-point exceptions on SPARCs running
+ Linux.</p>
+ <p>Runtime system:</p>
+ <p>Minor scheduler optimisation in the non-SMP runtime
+ system.</p>
+ <p>Substantial reduction of I/O thread overheads in the
+ SMP runtime system if the separate timer thread is used.
+ (In R11B-1, the separate timer thread is not used.)</p>
+ <p>Own Id: OTP-6211</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Previously <c><![CDATA[unlink/1]]></c> and <c><![CDATA[erlang:demonitor/2]]></c>
+ behaved completely asynchronous. This had one undesirable
+ effect, though. You could never know when you were
+ guaranteed <em>not</em> to be affected by a link that you
+ had unlinked or a monitor that you had demonitored.</p>
+ <p>The new behavior of <c><![CDATA[unlink/1]]></c> and
+ <c><![CDATA[erlang:demonitor/2]]></c> can be viewed as two operations
+ performed atomically. Asynchronously send an unlink
+ signal or a demonitor signal, and ignore any future
+ results of the link or monitor.</p>
+ <p><em>NOTE</em>: This change can cause some obscure code
+ to fail which previously did not. For example, the
+ following code might hang:</p>
+ <code type="none"><![CDATA[
+ Mon = erlang:monitor(process, Pid),
+\011 %% ...
+\011 exit(Pid, bang),
+ erlang:demonitor(Mon),
+\011 receive
+\011 {'DOWN', Mon , process, Pid, _} -> ok
+\011 %% We were previously guaranteed to get a down message
+\011 %% (since we exited the process ourself), so we could
+\011 %% in this case leave out:
+\011 %% after 0 -> ok
+\011 end,
+ ]]></code>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-5772</p>
+ </item>
+ <item>
+ <p>Two bugs fixed: If the environment variable <c><![CDATA[ERL_FLAGS]]></c>
+ was set, its contents would be appended to the end of the
+ command line even if the command line had an <c><![CDATA[-extra]]></c>
+ options. Changed to place the options from <c><![CDATA[ERL_FLAGS]]></c>
+ just before <c><![CDATA[-extra]]></c>. Also, the <c><![CDATA[-smp]]></c> and
+ <c><![CDATA[-hybrid]]></c> flags no longer have any effect if placed
+ after <c><![CDATA[-extra]]></c>.</p>
+ <p>Own Id: OTP-6054</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation for writing drivers in the ERTS User's
+ Guide has been expanded and updated.</p>
+ <p>Own Id: OTP-5192</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[andalso]]></c> and <c><![CDATA[orelse]]></c> operators are
+ now allowed to be used in guards. That also applies to
+ match specifications.</p>
+ <p>Own Id: OTP-5894 Aux Id: OTP-5149 </p>
+ </item>
+ <item>
+ <p>There is a new trace match spec function
+ <c><![CDATA[{exception_trace}]]></c> and a corresponding trace
+ message <c><![CDATA[exception_from]]></c> that can be used to trace
+ on any exit from a function, both normal function return
+ and exception return. See the documentation for
+ details.</p>
+ <p>The <c><![CDATA[return_to]]></c> trace message is now also
+ generated when the execution returns to a function due to
+ catching an exception.</p>
+ <p>Own Id: OTP-5956</p>
+ </item>
+ <item>
+ <p>Erlang runtime system with SMP (symmetric multi processing)
+ support.</p>
+ <p>The runtime system with SMP support is in this release
+ focused on stability and there are a number of steps
+ with optimizations to follow before it will take
+ full advantage of multi processor systems.
+ The released system is however truly multi threaded
+ and you will notice increased performance
+ for many applications already.
+ We recommend that you evaluate your application on
+ the SMP version of the runtime system and wait for some
+ more optimizations before you use it in a real product.
+ You will then discover if there are any problems in
+ your application that needs to be fixed in order for
+ it to work properly in a multi threaded environment.
+ More optimized versions of the runtime system
+ with SMP support will be included in the R11B
+ maintenance releases.</p>
+ <p>The SMP enabled runtime system will be started if
+ the <c><![CDATA[-smp]]></c> command line argument is passed to
+ the <c><![CDATA[erl]]></c> command. In order to make use of more than
+ one processor core, multiple scheduler threads are used. By
+ default, the number of scheduler threads will equal
+ the number of processor cores. The number of scheduler
+ threads can be set with the <c><![CDATA[+S]]></c> command line argument.
+ For more information see the <c><![CDATA[erl(1)]]></c> man page.</p>
+ <p>A runtime system with SMP support is by default built on
+ the following platforms if posix threads, and a gcc
+ compiler of at least version 2.95 is found:</p>
+ <list type="bulleted">
+ <item>
+ <p>Linux with at least kernel version 2.6 and the Native
+ POSIX Thread Library on x86, x86_64, and 32-bits
+ PowerPC.</p>
+ </item>
+ <item>
+ <p>Solaris of at least version 8 on 32-bits SPARC-V9.</p>
+ </item>
+ <item>
+ <p>MacOSX of at least version 10.4 (Darwin 8.0) on
+ 32-bits PowerPC.</p>
+ </item>
+ </list>
+ <p>The runtime system with SMP support is known <em>not</em>
+ to build on:</p>
+ <list type="bulleted">
+ <item>
+ <p>Windows.</p>
+ </item>
+ <item>
+ <p>Linux with kernel versions less than 2.4, or without
+ the Native POSIX Thread Library.</p>
+ </item>
+ <item>
+ <p>Other hardware platforms than x86, x86_64, 32-bits
+ SPARC-V9 and 32-bits PowerPC.</p>
+ </item>
+ </list>
+ <p>Windows will be supported in a future release.</p>
+ <p>The runtime system with SMP support might build on other
+ operating systems in combination with supported hardware.
+ In order to force a build of a runtime system with SMP
+ support, pass the <c><![CDATA[--enable-smp-support]]></c> command line
+ argument to configure. Note, however, that it is not enough
+ that it builds. The underlying thread library and operating
+ system has to provide SMP support as well. If the thread
+ library does not distribute scheduler threads over multiple
+ processor cores then the runtime system will only seemingly
+ provide SMP support. If the runtime system is not built by
+ default on a specific platform, we have <em>not</em> tested
+ it on that platform.</p>
+ <p><em>NOTE</em>: The design of SMP support for drivers is
+ ongoing. There will probably be incompatible driver
+ changes (only affecting drivers run on the runtime system
+ with SMP support) released as patches for R11B.</p>
+ <p><em>Potential incompatibility</em>: Previously, specific
+ driver call-backs were always called from the same thread.
+ This is <em>not</em> true in the runtime system with SMP
+ support. Calls to call-backs will be made from different
+ threads, e.g., two consecutive calls to exactly the same
+ call-back can be made from two different threads. This
+ will in <em>most</em> cases not be a problem. All calls
+ to call-backs are synchronized, i.e., only one call-back
+ will be called at a time.</p>
+ <p>In the future the default behavior will <em>probably</em>
+ be the following: Calls to call-backs will, as now, be
+ made from different threads. Calls to call-backs in the
+ same driver <em>instance</em> will be synchronized. It
+ will probably be possible to configure so that all calls
+ to call-backs in all driver instances of a specific
+ driver type will be synchronized. It may be possible to
+ configure so that all calls to call-backs of a driver
+ instance or a of a specific driver type will be made from
+ the same thread.</p>
+ <p>Parallelism in the Erlang code executed is a necessity
+ for the Erlang runtime system to be able to take
+ advantage of multi-core or multi-processor hardware.
+ There need to be at least as many Erlang processes
+ runnable as processor cores for the Erlang runtime system
+ to be able to take advantage of all processor cores.</p>
+ <p>An Erlang runtime system with SMP support with only one
+ Erlang process runnable all the time will almost always be
+ slower than the same Erlang runtime system without SMP
+ support. This is due to thread synchronization overhead.</p>
+ <p>Known major bottleneck in the Erlang runtime system:</p>
+ <list type="bulleted">
+ <item>
+ <p>Currently the I/O system uses one "big lock", i.e. only
+ one thread can do I/O at a time (with the exception of
+ async threads and threads created by users own linked-in
+ drivers). This is high on the list of things to
+ optimize. Note, code that does not do I/O can be executed
+ at the same time as one thread does I/O.</p>
+ </item>
+ </list>
+ <p>Some pitfalls which might cause Erlang programs that work on
+ the non-SMP runtime system to fail on the SMP runtime
+ system:</p>
+ <list type="bulleted">
+ <item>
+ <p>A newly spawned process will often begin executing
+ immediately. Code that expects that the parent process
+ will be able to execute for a while before the child
+ process begins executing is likely to fail.</p>
+ </item>
+ <item>
+ <p>High priority processes could previously provide
+ mutual exclusion (bad programming style) by preventing
+ normal and low priority processes from being run. High
+ priority processes cannot be used this way to provide
+ mutual exclusion.</p>
+ </item>
+ <item>
+ <p><c><![CDATA[erlang:yield()]]></c> could be used to provide some
+ kind of temporary mutual exclusion (also bad programming
+ style). <c><![CDATA[erlang:yield()]]></c> cannot be used to provide
+ any kind of mutual exclusion.</p>
+ </item>
+ <item>
+ <p>Obscure pitfall, only if a process being traced also
+ sends normal messages to the tracer:<br></br>
+ &nbsp;&nbsp;The order between trace messages and normal
+ messages is undefined. I.e. the order between normal
+ messages sent from a tracee to a tracer and the trace
+ messages generated from the same tracee to the same
+ tracer is undefined. The internal order of normal
+ messages and the internal order of trace messages will,
+ of course, be preserved as before.</p>
+ </item>
+ </list>
+ <p>The kernel poll feature is currently not supported by
+ the runtime system with SMP support. It will probably be
+ supported in a future release.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-6006 Aux Id: OTP-6095 </p>
+ </item>
+ <item>
+ <p>Linked-in driver modifications.</p>
+ <list type="bulleted">
+ <item>
+ <p>Linked-in drivers must be recompiled.</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[refc]]></c> field in the <c><![CDATA[ErlDrvBinary]]></c> type
+ has been removed. The reference count can be accessed
+ via API functions. For more information see
+ the <c><![CDATA[erl_driver(1)]]></c> man page.</p>
+ </item>
+ </list>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-6095 Aux Id: OTP-6006 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.13</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Large files (more than 2 GBytes) are now handled on
+ Solaris 8.</p>
+ <p>Own Id: OTP-5849 Aux Id: seq10157 </p>
+ </item>
+ <item>
+ <p>A failing bit syntax construction could fail with the
+ PREVIOUS exception reason that had occurred in the process
+ (instead of with <c><![CDATA[badarg]]></c>).</p>
+ <p>Own Id: OTP-5911</p>
+ </item>
+ <item>
+ <p>When building OTP, the Kernel application was built in
+ both the primary and secondary bootstrap steps, which
+ would cause problems if OTP including its bootstrap is
+ checked into a version control system (such as CVS).
+ (Thanks to Sebastian Strollo.)</p>
+ <p>Own Id: OTP-5921</p>
+ </item>
+ <item>
+ <p><c><![CDATA[binary_to_term(<<131,109,255,255,255,255)]]></c> and
+ similar expressions used to crash the emulator instead of
+ causing a <c><![CDATA[badarg]]></c> exception. (Thanks to Matthias
+ Lang.)</p>
+ <p>Own Id: OTP-5933</p>
+ </item>
+ <item>
+ <p><c><![CDATA[erlang:hibernate/3]]></c> could sometimes crash the emulator
+ when no heap was needed.</p>
+ <p>Own Id: OTP-5940</p>
+ </item>
+ <item>
+ <p>Execution of match specs could under rare circumstances
+ cause the emulator to dump core.</p>
+ <p>Execution of match specs could cause memory leaks in the
+ hybrid emulator.</p>
+ <p>Own Id: OTP-5955</p>
+ </item>
+ <item>
+ <p>A bug in <c><![CDATA[erlang:trace_info/2]]></c> when getting info for a
+ function in a deleted module resulting in an emulator
+ crash, has been corrected.</p>
+ <p>Own Id: OTP-5957</p>
+ </item>
+ <item>
+ <p>Different (and old) <c><![CDATA[config.guess]]></c> files in the
+ ERTS and Erl_Interface applications would cause build
+ problems on the new Intel-based iMacs.
+ (Thanks to Sebastion Strollo.)</p>
+ <p>Own Id: OTP-5967</p>
+ </item>
+ <item>
+ <p>pthread header and library mismatch on Linux systems (at
+ least some SuSE and Debian) with both NPTL and
+ Linuxthreads libraries installed.</p>
+ <p>Own Id: OTP-5981</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The driver_set_timer did not change the previous timeout
+ if called a second time. Now it works as specified,
+ changing the timeout.</p>
+ <p>Own Id: OTP-5942</p>
+ </item>
+ <item>
+ <p>The undocumented <c><![CDATA[{packet,http}]]></c> option (for the
+ <c><![CDATA[gen_tcp]]></c> module) did not not work correctly when
+ there were multiple continuation lines. (Thanks to Per
+ Hedeland.)</p>
+ <p>Own Id: OTP-5945</p>
+ </item>
+ <item>
+ <p>The setuid_socket_wrap program was corrected to work for
+ C compilers that treat the <c><![CDATA[char]]></c> type as unsigned.
+ (Thanks to Magnus Henoch.)</p>
+ <p>Own Id: OTP-5946</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.12</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Fixed a minor build problem on Windows.</p>
+ <p>Own Id: OTP-5819 Aux Id: OTP-5382 OTP-5540 OTP-5577 </p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[delay_send]]></c> option for <c><![CDATA[gen_tcp]]></c> was
+ broken on Windows.</p>
+ <p>Own Id: OTP-5822</p>
+ </item>
+ <item>
+ <p>If there were user-defined variables in the boot
+ script, and their values were not provided using the
+ <c><![CDATA[-boot_var]]></c> option, the emulator would refuse to
+ start with a confusing error message. Corrected to show a
+ clear, understandable message.</p>
+ <p>The <c><![CDATA[prim_file]]></c> module was modified to not depend
+ on the <c><![CDATA[lists]]></c> module, to make it possible to start
+ the emulator using a user-defined loader. (Thanks to
+ Martin Bjorklund.)</p>
+ <p>Own Id: OTP-5828 Aux Id: seq10151 </p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The HiPE compiler identifies more leaf functions,
+ giving slightly faster code.</p>
+ <p>Corrected problems in HiPE's coalescing register
+ allocating that would cause it to fail when compiling
+ very large functions (e.g. some of parse modules in the
+ Megaco application).</p>
+ <p>Own Id: OTP-5853</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.11</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Timers could sometimes timeout too early. This bug has
+ now been fixed.</p>
+ <p>Automatic cancellation of timers created by
+ <c><![CDATA[erlang:send_after(Time,pid(),Msg)]]></c> and
+ <c><![CDATA[erlang:start_timer(Time,pid(),Msg)]]></c> has been
+ introduced. Timers created with the receiver specified by a
+ pid, will automatically be cancelled when the receiver
+ exits. For more information see the <c><![CDATA[erlang(3)]]></c> man
+ page.</p>
+ <p>In order to be able to maintain a larger amount of timers
+ without increasing the maintenance cost, the internal
+ timer wheel and bif timer table have been enlarged.</p>
+ <p>Also a number of minor bif timer optimizations have been
+ implemented.</p>
+ <p>Own Id: OTP-5795 Aux Id: OTP-5090, seq8913, seq10139,
+ OTP-5782 </p>
+ </item>
+ <item>
+ <p><c><![CDATA[erlang:monitor(process,Pid)]]></c> hanged if <c><![CDATA[Pid]]></c>
+ referred to a process on a non-existing node with the same
+ nodename as the nodename of node on which the call was made.
+ This bug has now been fixed.</p>
+ <p>Own Id: OTP-5827</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>By setting Unix environment variables, the priority for
+ the emulator can be lowered when it is writing crash
+ dumps and the time allowed for finishing writing a crash
+ dump can be set to a certain number of seconds. See the
+ documentation for <c><![CDATA[erl]]></c> in the ERTS application.
+ (Also, a few other previously undocumented environment
+ variables are now documented.)</p>
+ <p>Own Id: OTP-5818</p>
+ </item>
+ <item>
+ <p>Documentation improvements:</p>
+ <p>- documentation for <c><![CDATA[erlang:link/1]]></c> corrected</p>
+ <p>- command line flag <c><![CDATA[-code_path_cache]]></c> added</p>
+ <p>- <c><![CDATA[erl]]></c> command line flags clarifications</p>
+ <p>- <c><![CDATA[net_kernel(3)]]></c> clarifications</p>
+ <p>Own Id: OTP-5847</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.10</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>-D_GNU_SOURCE is now always passed on the compile command
+ line on linux. This in order to ensure that all included
+ system headers see _GNU_SOURCE defined.</p>
+ <p>_GNU_SOURCE is now also defined on linux in configure
+ when looking for features.</p>
+ <p>Some minor (harmless) configure bugs were also fixed.</p>
+ <p>Own Id: OTP-5749</p>
+ </item>
+ <item>
+ <p>Some compiler warnings and Dialyzer warnings were
+ eliminated in the Tools application.</p>
+ <p>When tracing to a port (which <c><![CDATA[fprof]]></c> does),
+ there could be fake schedule out/schedule in messages
+ sent for a process that had exited.</p>
+ <p>Own Id: OTP-5757</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The BIFs <c><![CDATA[iolist_size/1]]></c> and <c><![CDATA[iolist_to_binary/1]]></c>
+ has been added.</p>
+ <p>The BIF <c><![CDATA[list_to_existing_atom/1]]></c> has been added.</p>
+ <p>Minor bug fix: The exception reason could be changed
+ to <c><![CDATA[error]]></c> inside nested try/catch constructs if the
+ <c><![CDATA[erlang:raise/3]]></c> BIF was called with an empty
+ stacktrace. (Calling <c><![CDATA[erlang:raise/3]]></c> with an empty
+ stacktrace is NOT recommended.)</p>
+ <p>Minor bugfix: On Windows, <c><![CDATA[file:open/2]]></c> will now
+ return the documented error reason <c><![CDATA[{error,eisdir}]]></c>
+ if the filename refers to a directory (it used to return
+ <c><![CDATA[{error,eacces}]]></c>).</p>
+ <p>The message in the documentation for
+ <c><![CDATA[erlang:system_monitor/2]]></c>, description of
+ <c><![CDATA[busy_dist_port]]></c>, was corrected.</p>
+ <p>Own Id: OTP-5709 Aux Id: seq10100 </p>
+ </item>
+ <item>
+ <p>The previously undocumented and UNSUPPORTED <c><![CDATA[zlib]]></c>
+ module has been updated in an incompatible way and many
+ bugs have been corrected. It is now also documented.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-5715</p>
+ </item>
+ <item>
+ <p>New socket options <c><![CDATA[priority]]></c> and <c><![CDATA[tos]]></c> for
+ platforms that support them (currently only Linux).</p>
+ <p>Own Id: OTP-5756</p>
+ </item>
+ <item>
+ <p>Only the emulator is now linked with termcap library in
+ order to decrease library dependencies for other otp
+ programs.</p>
+ <p>Own Id: OTP-5758</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.9.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The native resolver has gotten an control API for
+ extended debugging and soft restart. It is:
+ <c><![CDATA[inet_gethost_native:control(Control)]]></c><br></br><c><![CDATA[Control = {debug_level,Level} | soft_restart]]></c><br></br><c><![CDATA[Level = integer() in the range 0-4]]></c>.</p>
+ <p>Own Id: OTP-5751 Aux Id: EABln25013 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.9.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>On VxWorks, epmd did not handle file descriptors with
+ higher numbers than 63. Also, if epmd should get a file
+ descriptor with a number &gt;= FD_SETSIZE, it will close a
+ the file descriptor and write a message to the log
+ (instead of mysteriously fail); the Erlang node that
+ tried to register will fail with a duplicate_name error
+ (unfortunately, epmd has no way to indicate to the Erlang
+ node why the register attempt failed).</p>
+ <p>Own Id: OTP-5716 Aux Id: seq10070 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.9</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Timezone data is now initialized better. (was a problem
+ at least on NetBSD 2.0.2) Thanks to Rich Neswold.</p>
+ <p>Own Id: OTP-5621</p>
+ </item>
+ <item>
+ <p>The hybrid-heap emulator ('erl -hybrid') is much more
+ stable. We have corrected all known bugs that caused it
+ to dump core while running our test suites.</p>
+ <p>Own Id: OTP-5634</p>
+ </item>
+ <item>
+ <p>Fixed rare memory leaks in <c><![CDATA[erlang:demonitor/1]]></c> when
+ distributed monitors were removed.</p>
+ <p>Own Id: OTP-5692</p>
+ </item>
+ <item>
+ <p>Processes were sometimes unnecessarily garbage collected
+ when terminating. These unnecessary garbage collections
+ have now been eliminated.</p>
+ <p>Own Id: OTP-5693</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The <c><![CDATA[c:i/0]]></c> function will now run in a paged mode if
+ there are more than 100 processes in the system. (Thanks
+ to Ulf Wiger.)</p>
+ <p><c><![CDATA[erlang:system_info(process_count)]]></c> has
+ been optimized and does now return exactly the same value
+ as <c><![CDATA[length(processes())]]></c>. Previously
+ <c><![CDATA[erlang:system_info(process_count)]]></c> did not include
+ exiting processes which are included in
+ <c><![CDATA[length(processes())]]></c>.</p>
+ <p>The <c><![CDATA[+P]]></c> flag for <c><![CDATA[erl]]></c>, which sets the maximum
+ number of processes allowed to exist at the same, no longer
+ accepts values higher than 134217727. (You will still
+ probably run out of memory before you'll be able to reach
+ that limit.)</p>
+ <p>Own Id: OTP-5645 Aux Id: seq9984 </p>
+ </item>
+ <item>
+ <p>The term-building driver functions
+ <c><![CDATA[driver_output_term()]]></c> and <c><![CDATA[driver_send_term()]]></c>
+ have been updated:</p>
+ <p>The ERL_DRV_FLOAT type has been added.</p>
+ <p>For the ERL_DRV_BINARY type, the length and offset are
+ now validated against the length of the driver binary.</p>
+ <p>The ERL_DRV_PID type is now implemented (it was
+ documented, but not implemented).</p>
+ <p>Own Id: OTP-5674</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.8</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[ets:delete/1]]></c> now allows other Erlang process to run
+ when a large table is being deleted.</p>
+ <p>Own Id: OTP-5572</p>
+ </item>
+ <item>
+ <p>A bug regarding tcp sockets which results in hanging
+ <c><![CDATA[gen_tcp:send/2]]></c> has been corrected. To encounter
+ this bug you needed one process that read from a socket,
+ one that wrote more date than the reader read out so the
+ sender got suspended, and then the reader closed the
+ socket. (Reported and diagnosed by Alexey Shchepin.)</p>
+ <p>Corrected a bug in the (undocumented and unsupported)
+ option <c><![CDATA[{packet,http}]]></c> for <c><![CDATA[gen_tcp.]]></c>
+ (Thanks to Claes Wikstrom and Luke Gorrie.)</p>
+ <p>Updated the documentation regarding the second argument to
+ <c><![CDATA[gen_tcp:recv/2]]></c>, the <c><![CDATA[Length]]></c> to receive.</p>
+ <p>Own Id: OTP-5582 Aux Id: seq9839 </p>
+ </item>
+ <item>
+ <p>Erlang/OTP will now build on Mac OS X 10.4 "Tiger" (the
+ problem was that 10.4 has a partially implemented poll()
+ function that can't handle devices). Also, on Mac OS X
+ 10.3 "Panther", Erlang/OTP will now use select() instead
+ of poll() (because poll() on Mac OS X 10.3 is implemented
+ using select()).</p>
+ <p>Own Id: OTP-5595</p>
+ </item>
+ <item>
+ <p>A bug in the file driver when opening a file in
+ compressed mode, and the returned allocated pointer from
+ the compressing library was in very high memory (&gt;= 2GB),
+ causing e.g. <c><![CDATA[file:read/2]]></c> to return
+ <c><![CDATA[{error,ebadf}]]></c>, has been corrected.</p>
+ <p>Own Id: OTP-5618</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The new fun <c><![CDATA[M:F/A]]></c> construct creates a fun that
+ refers to the latest version of <c><![CDATA[M:F/A.]]></c> This syntax is
+ meant to replace tuple funs <c><![CDATA[{M,F}]]></c> which have many
+ problems.</p>
+ <p>The new type test <c><![CDATA[is_function(Fun,A)]]></c> (which may be
+ used in guards) test whether <c><![CDATA[Fun]]></c> is a fun that can be
+ applied with <c><![CDATA[A]]></c> arguments. (Currently, <c><![CDATA[Fun]]></c>
+ can also be a tuple fun.)</p>
+ <p>Own Id: OTP-5584</p>
+ </item>
+ <item>
+ <p>In the HiPE application, there's a new experimental
+ register allocator (optimistic coalescing), and the
+ linear scan register allocator is now also available on
+ ppc. Plus lots of cleanups.</p>
+ <p>Minor hybrid heap corrections.</p>
+ <p>The maximum size of a heap used to be artificially
+ limited so that the size of a heap would fit in 28 bits;
+ that limitation could cause the emulator to terminate in
+ a garbage collection even if there still was available
+ memory. Now the largest heap size for a 32 bit CPU is
+ 1,699,221,830 bytes. (Thanks to Jesper Wilhelmsson.)</p>
+ <p>Also removed the undocumented <c><![CDATA[+H]]></c> emulator option.</p>
+ <p>Own Id: OTP-5596</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.7</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[to_erl]]></c> could close unexpectedly on Linux systems.
+ Also, output from the emulator could be lost. Corrected.</p>
+ <p>Own Id: OTP-5561</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The <c><![CDATA[cpu_timestamp]]></c> option for <c><![CDATA[erlang:trace/3]]></c>
+ is now also supported on Linux.</p>
+ <p>Own Id: OTP-5532 Aux Id: seq9813 </p>
+ </item>
+ <item>
+ <p>The last known <c><![CDATA[werl]]></c> window size/position is now saved
+ correctly when <c><![CDATA[werl]]></c> is stopped with the window
+ minimized. A problem with the placement not being saved if
+ the emulator is halted or stopped from the JCL menu has also
+ been fixed.</p>
+ <p>Own Id: OTP-5544 Aux Id: OTP-5522 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.6</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Some math libraries do not always throw floating-point
+ exceptions on errors. In order to be able to use these
+ libraries, floating-point errors are now more thoroughly
+ checked.</p>
+ <p>Misc floating-point fixes for Linux and MacOSX.</p>
+ <p>Own Id: OTP-5467</p>
+ </item>
+ <item>
+ <p>An internal buffer was sometimes not cleared which caused
+ garbage to appear in error messages sent to the error
+ logger.</p>
+ <p><c><![CDATA[errno]]></c> was sometimes clobbered which caused erroneous
+ error reports about <c><![CDATA[poll()]]></c> errors.</p>
+ <p>Only emulators on unix platforms were affected by these
+ bugs.</p>
+ <p>Own Id: OTP-5492</p>
+ </item>
+ <item>
+ <p>The ethread library now works on OpenBSD.</p>
+ <p>Own Id: OTP-5515</p>
+ </item>
+ <item>
+ <p>Corrected a bug in the (undocumented and unsupported)
+ option <c><![CDATA[{packet,http}]]></c> for <c><![CDATA[gen_tcp]]></c>.
+ (Thanks to Claes Wikstrom and Luke Gorrie.)</p>
+ <p>Own Id: OTP-5519</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[binary_to_term/1]]></c> could cause the emulator to crash
+ when given invalid pids or funs.</p>
+ <p>Own Id: OTP-5484 Aux Id: seq9801 </p>
+ </item>
+ <item>
+ <p>Some more stability problems were fixed in the
+ hybrid-heap emulator.</p>
+ <p>Own Id: OTP-5489</p>
+ </item>
+ <item>
+ <p>After <c><![CDATA[werl]]></c> was closed with the window minimized, it
+ was not possible to restart <c><![CDATA[werl]]></c> with an open
+ window. A temporary solution has so far been implemented
+ that restores the initial window settings every time
+ <c><![CDATA[werl]]></c> is started.</p>
+ <p>Own Id: OTP-5522</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>If a process had node links (created by
+ <c><![CDATA[monitor_node/2]]></c>), executing
+ <c><![CDATA[process_info(Pid,memory)]]></c> for that process would
+ crash the emulator.</p>
+ <p>Own Id: OTP-5420</p>
+ </item>
+ <item>
+ <p>Minor corrections to the help text printed by <c><![CDATA[erlc -help]]></c>. The documentation for <c><![CDATA[erlc]]></c> was also
+ slightly updated.</p>
+ <p>Own Id: OTP-5428</p>
+ </item>
+ <item>
+ <p>32-bit words were used for offsets in the garbage
+ collector. This caused the emulator to crash on 64-bit
+ machines when heaps were moved more than 4 GB during
+ garbage collection.</p>
+ <p>Own Id: OTP-5430</p>
+ </item>
+ <item>
+ <p><c><![CDATA[is_boolean(42.5)]]></c> failed to load if optimization was
+ explicitly turned off.</p>
+ <p>Own Id: OTP-5448</p>
+ </item>
+ <item>
+ <p>If there was a call to <c><![CDATA[Module:foo/X]]></c> from any loaded
+ module, the returned by <c><![CDATA[M:module_info(exports)]]></c> would
+ always include <c><![CDATA[{foo,X}]]></c> (even though
+ <c><![CDATA[Module:foo/X]]></c> if was not defined).</p>
+ <p>Own Id: OTP-5450 Aux Id: seq9722 </p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The <c><![CDATA[c]]></c> option for the <c><![CDATA[+B]]></c> flag has been
+ introduced which makes it possible to use Ctrl-C
+ (Ctrl-Break on Windows) to interrupt the shell process
+ rather than to invoke the emulator break handler. All new
+ <c><![CDATA[+B]]></c> options are also supported on Windows
+ (<c><![CDATA[werl]]></c>) as of now. Furthermore, Ctrl-C on Windows has
+ now been reserved for copying text (what Ctrl-Ins was used
+ for previously). Ctrl-Break should be used for break
+ handling. Lastly, the documentation of the system flags has
+ been updated.</p>
+ <p>Own Id: OTP-5388</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The function <c><![CDATA[erlang:float/1]]></c> can now be used in
+ match specifications and is recognized by
+ <c><![CDATA[dbg:fun2ms/1]]></c> and <c><![CDATA[ets:fun2ms/1]]></c>. This
+ addition is part of the work to "harmonize" match
+ specification guards with Erlang guards.</p>
+ <p>Own Id: OTP-5297 Aux Id: OTP-4927 </p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[register/2]]></c> BIF would return <c><![CDATA[true]]></c> even if
+ the second argument was not a pid for living process.
+ Corrected to cause an exception.</p>
+ <p>Own Id: OTP-5324 Aux Id: seq9698 </p>
+ </item>
+ <item>
+ <p>In the 'bag' type of ets tables, elements having the same
+ key were supposed to be order in insertion order. The
+ would be wrong if a rehash occurred.</p>
+ <p>Own Id: OTP-5340 Aux Id: seq9704 </p>
+ </item>
+ <item>
+ <p>Linked in drivers in the Crypto and Asn1 applications
+ are now compiled with the <c><![CDATA[-D_THREAD_SAFE]]></c> and
+ <c><![CDATA[-D_REENTRANT]]></c> switches on unix when the emulator has
+ thread support enabled.</p>
+ <p>Linked in drivers on MacOSX are not compiled with the
+ undocumented <c><![CDATA[-lbundle1.o]]></c> switch anymore. Thanks to
+ Sean Hinde who sent us a patch.</p>
+ <p>Linked in driver in Crypto, and port programs in SSL, now
+ compiles on OSF1.</p>
+ <p>Minor makefile improvements in Runtime_Tools.</p>
+ <p>Own Id: OTP-5346</p>
+ </item>
+ <item>
+ <p>Fixed a bug in the hybrid heap in distributed send
+ operations.</p>
+ <p>Own Id: OTP-5361</p>
+ </item>
+ <item>
+ <p>A BIF <c><![CDATA[erlang:raise/3]]></c> has been added. See the manual
+ for details. It is intended for internal system programming
+ only, advanced error handling.</p>
+ <p>Own Id: OTP-5376 Aux Id: OTP-5257 </p>
+ </item>
+ <item>
+ <p>Mikael Pettersson (HiPE) corrected a few bugs in the
+ emulator that caused problems when compiled with the
+ experimental gcc-4.0.0.</p>
+ <p>Own Id: OTP-5386</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Minor update of the internal documentation of
+ the <c><![CDATA[epmd]]></c> protocol.</p>
+ <p>The listen port of <c><![CDATA[epmd]]></c> has now been registered at
+ IANA:
+ <url href="http://www.iana.org/assignments/port-numbers">http://www.iana.org/assignments/port-numbers</url>.</p>
+ <p>Own Id: OTP-5234</p>
+ </item>
+ <item>
+ <p><c><![CDATA[run_erl.c]]></c> now works on Mac OS X and FreeBSD.</p>
+ <p>Own Id: OTP-5384</p>
+ </item>
+ <item>
+ <p>A few bugs were corrected in the HiPE application.</p>
+ <p>Own Id: OTP-5385</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Font and color preferences for <c><![CDATA[werl.exe]]></c> now can be
+ saved even after the first time you run <c><![CDATA[werl.exe]]></c>.
+ The window position and size is also saved. Patch from
+ James Hague who did all the hard work.</p>
+ <p>Own Id: OTP-5250</p>
+ </item>
+ <item>
+ <p>OTP archive libraries, e.g. the <c><![CDATA[erl_interface]]></c>
+ library, on MacOSX could not be used without first
+ rerunning <c><![CDATA[ranlib]]></c> on them. This bug has now been
+ fixed.</p>
+ <p>Own Id: OTP-5274</p>
+ </item>
+ <item>
+ <p>Bugs in <c><![CDATA[erlang:hash/2]]></c> and <c><![CDATA[erlang:phash/2]]></c> on
+ 64-bit platforms have been fixed.</p>
+ <p>Own Id: OTP-5292</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Corrected a crash in the 64-bits emulator.</p>
+ <p>Corrected a problem in the hybrid heap emulator.</p>
+ <p>In the chapter about the abstract format in the ERTS User's
+ Guide, updated the last section about how the abstract
+ format is stored in BEAM files.</p>
+ <p>Own Id: OTP-5262</p>
+ </item>
+ <item>
+ <p>The maximum number of concurrent threads in the internal
+ ethread thread package has been limited to 2048.</p>
+ <p>Own Id: OTP-5280</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.2.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>If Erlang/OTP was installed in a short directory name,
+ such as <c><![CDATA[C:\\Program\\erl5.4.2]]></c>, the emulator would not
+ start.</p>
+ <p>Own Id: OTP-5254</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>If one used <c><![CDATA[select/3]]></c> and <c><![CDATA[select/1]]></c> on a
+ non-fixed ETS table and deleted objects simultaneously,
+ the emulator could crash. Note that the result of such
+ simultaneous operations on tables that are not in a fixed
+ state is still undefined, but the emulator crash is,
+ needless to say, fixed.</p>
+ <p>Own Id: OTP-5209 Aux Id: seq9198 </p>
+ </item>
+ <item>
+ <p>Arithmetic with big numbers could crash the emulator.</p>
+ <p>The HiPE native code compiler and run-time code in the
+ emulator has been updated. (Note: Native code is still
+ not supported.)</p>
+ <p>Eliminated a few bugs that could crash the hybrid emulator
+ (which is not supported).</p>
+ <p>Own Id: OTP-5233 Aux Id: seq9587 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.4.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The ethread library was unnecessarily rebuilt multiple
+ times during the build process, also a debug version of
+ the library was build during the install phase. These
+ unnecessary builds have now been removed. Note, the
+ content of the installed Erlang/OTP system is not
+ effected at all by this change.</p>
+ <p>Own Id: OTP-5203</p>
+ </item>
+ <item>
+ <p>The emulator could fail to clear the memory segment
+ cache. This could potentially cause memory allocation to
+ unnecessarily fail when memory usage was close to its
+ maximum. This bug has now been fixed.</p>
+ <p>Own Id: OTP-5211</p>
+ </item>
+ <item>
+ <p>std_alloc (std short for standard) was sometimes called
+ def_alloc (def short for default). std_alloc is now
+ everywhere referred to as std_alloc.</p>
+ <p>Own Id: OTP-5216</p>
+ </item>
+ <item>
+ <p>A documentation bug has been corrected in
+ the <c><![CDATA[erts_alloc(3)]]></c> documentation. It was stated that
+ some of the memory allocators present were by default
+ disabled. This is true for Erlang/OTP R9C, but is not true
+ for Erlang/OTP R10B. In R10B all memory allocators present
+ are enabled by default.</p>
+ <p>Own Id: OTP-5217</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The emulator now close all open files and sockets
+ immediately after receiving an USR1 signal. This causes
+ the emulator to unregister at <c><![CDATA[epmd]]></c> as early as
+ possible.</p>
+ <p>Own Id: OTP-5221 Aux Id: OTP-4985, seq9514 </p>
+ </item>
+ <item>
+ <p>Try/catch support in the emulator slightly updated.</p>
+ <p>Own Id: OTP-5229</p>
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/notes_history.xml b/erts/doc/src/notes_history.xml
new file mode 100644
index 0000000000..cc3b938c86
--- /dev/null
+++ b/erts/doc/src/notes_history.xml
@@ -0,0 +1,503 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2006</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>ERTS Release Notes History</title>
+ <prepared>otp_appnotes</prepared>
+ <docno>nil</docno>
+ <date>nil</date>
+ <rev>nil</rev>
+ <file>notes_history.xml</file>
+ </header>
+
+ <section>
+ <title>ERTS 5.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The BIF <c><![CDATA[is_record(Record,RecordTag)]]></c> has been added to
+ the run-time system. It checks that <c><![CDATA[Record]]></c> is a tuple
+ whose first element is the atom <c><![CDATA[RecordTag.]]></c> No check
+ is made of the size of the tuple (because the run-time
+ system doesn't know anything about records).</p>
+ <p>Note that normally the compiler translates calls to
+ <c><![CDATA[is_record/2]]></c> to code that also verify the size of the
+ tuple, in addition to verifying the first element. The
+ BIF version will be used <c><![CDATA[is_record/2]]></c> is applied or
+ if the second argument is not a literal atom (e.g. a
+ variable or another term type, in which case the BIF will
+ generate a <c><![CDATA[badarg]]></c> exception).</p>
+ <p>Own Id: OTP-4812</p>
+ </item>
+ <item>
+ <p>Guards of mach specifications are corrected to resemble
+ the semantics of guards in real code more closely. The
+ implementation now corresponds to the documentation in
+ ERTS User's Guide. The following things are corrected:</p>
+ <list type="bulleted">
+ <item>Guard semantics was wrong when it came to logical
+ operators and exceptions.
+ <c><![CDATA[{'or',{'is_integer','$1'},{'or','$1','$1'}}]]></c>
+ evaluated to <c><![CDATA[true]]></c> with <c><![CDATA['$1']]></c> bound to an
+ integer.</item>
+ <item>Unary + and - was not implemented.</item>
+ <item>Calling operators as Bif's was not supported by
+ <c><![CDATA[ets/dbg:fun2ms]]></c> (<c><![CDATA[erlang:'or'(A,B)]]></c> etc).</item>
+ <item>Old typetests (like <c><![CDATA[integer(X)]]></c> instead of
+ <c><![CDATA[is_integer(X))]]></c> was not supported by
+ <c><![CDATA[ets/dbg:fun2ms]]></c>.</item>
+ <item>Semicolon (;) in guards was not supported by
+ <c><![CDATA[ets/dbg:fun2ms]]></c>.</item>
+ </list>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-4927</p>
+ </item>
+ <item>
+ <p>A potential initialization failure when using threads and
+ elib_malloc has been removed.</p>
+ <p>Own Id: OTP-5125</p>
+ </item>
+ <item>
+ <p>Several problems in the 64-bit emulator has been
+ corrected. For instance, the emulator could crash while
+ running the Debugger.</p>
+ <p>Own Id: OTP-5146</p>
+ </item>
+ <item>
+ <p>The match spec parse transform <c><![CDATA[ms_transform]]></c> no
+ longer accepts the <c><![CDATA[andalso]]></c> and <c><![CDATA[orelse]]></c>
+ constructs in guards for consistency with the standard
+ Erlang language. A future release of Erlang/OTP may allow
+ <c><![CDATA[andalso]]></c> and <c><![CDATA[orelse]]></c> in guards.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-5149</p>
+ </item>
+ <item>
+ <p>In rare circumstances in a process that has caught
+ exceptions and uses funs, the process would be killed
+ when changing code because the code server would think
+ that the process still held references to the funs.</p>
+ <p>Own Id: OTP-5153</p>
+ </item>
+ <item>
+ <p><c><![CDATA[erlang:system_monitor/2]]></c> no longer sends any
+ monitoring messages to the system monitor process from
+ itself. This behavior is more consistent with other trace
+ functionality.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-5183</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation stated that <c><![CDATA[ets:safe_fixtable/2]]></c>
+ could return <c><![CDATA[true]]></c> or <c><![CDATA[false,]]></c> that was wrong,
+ it always returns <c><![CDATA[true]]></c>.</p>
+ <p>Own Id: OTP-4830</p>
+ </item>
+ <item>
+ <p>The unary '+' operator has been changed to throw an
+ <c><![CDATA[badarith]]></c> exception if its argument is not numeric (or
+ fail in a guard). It used its argument unchanged whatever
+ the type. Given the new meaning, unary '+' can now be
+ used to test whether a term is numeric.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-4928</p>
+ </item>
+ <item>
+ <p>Process identifiers and port identifiers have been
+ made more unique. Previously 18 bits were used as id in
+ the internal representation of process and port
+ identifiers. Now 28 bits are used.</p>
+ <p>The maximum limit on the number of concurrently existing
+ processes due to the representation of pids has been
+ increased to 268435456 processes. The same is true for
+ ports. This limit will at least on a 32-bit architecture be
+ impossible to reach due to memory shortage.</p>
+ <p><em>NOTE:</em> By default, the <c><![CDATA[ERTS]]></c>, and the
+ <c><![CDATA[erl_interface]]></c>, <c><![CDATA[ei]]></c>, and <c><![CDATA[jinterface]]></c>
+ libraries are now only guaranteed to be compatible with
+ other Erlang/OTP components from the same release. It is
+ possible to set each component in compatibility mode of
+ an earlier release, though. See the documentation for
+ respective component on how to set it in compatibility
+ mode.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-4968 Aux Id: OTP-4196 </p>
+ </item>
+ <item>
+ <p>A new internal thread library for the ERTS has been
+ added.</p>
+ <p>Own Id: OTP-5048</p>
+ </item>
+ <item>
+ <p>The system's performance could degrade severely if one
+ process held numerous links or monitors. The issue is
+ resolved.</p>
+ <p>Own Id: OTP-5079</p>
+ </item>
+ <item>
+ <p>A new function, <c><![CDATA[string:to_integer/1]]></c>, has been added.</p>
+ <p>Own Id: OTP-5081 Aux Id: OTP-5136 </p>
+ </item>
+ <item>
+ <p>A new function, <c><![CDATA[string:to_float/1]]></c>, has been added.</p>
+ <p>Own Id: OTP-5136 Aux Id: OTP-5081 </p>
+ </item>
+ <item>
+ <p>The exception code for calling a fun with wrong number of
+ arguments has been changed from simply <c><![CDATA[badarity]]></c> to
+ <c><![CDATA[{badarity,{Fun,Args}}]]></c>.</p>
+ <p>*** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>Own Id: OTP-5139</p>
+ </item>
+ <item>
+ <p>The long-awaited <c><![CDATA[try]]></c>...<c><![CDATA[catch]]></c> construction
+ is included in this release. However, its use in
+ production code is not yet supported as there are several
+ known cases of legal code crashing the compiler. We plan
+ to release a patch to the compiler (including the
+ documentation) and at that time <c><![CDATA[try]]></c>...<c><![CDATA[catch]]></c>
+ will be supported.</p>
+ <p>Own Id: OTP-5150</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.6.6</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A bug that caused an emulator crash when using system
+ monitor of long GC has been fixed.</p>
+ <p>Own Id: OTP-5123</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.6.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p><c><![CDATA[erlang:memory(ets)]]></c> and <c><![CDATA[c:memory(ets)]]></c>
+ sometimes reported erroneous values. This bug has now been
+ fixed.</p>
+ <p>Own Id: OTP-5115 Aux Id: seq9063 </p>
+ </item>
+ <item>
+ <p>There is now a packet size limit option for <c><![CDATA[gen_tcp]]></c>
+ sockets. See the manual for <c><![CDATA[inet:setopts/2]]></c>.</p>
+ <p>The ASN.1 BER packet decoding for <c><![CDATA[gen_tcp]]></c> sockets
+ can now decode indefinite length packets.</p>
+ <p>Own Id: OTP-5128</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Port index was unnecessarily incremented by port table
+ size when port table got full. This unnecessary increment
+ has now been removed.</p>
+ <p>Own Id: OTP-5119</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.6.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Resolved a build problem on Mac OS 10.3 ("Panther").
+ Because of a conflict with the zlib sources included in
+ the Erlang run-time system and the zlib library included
+ in Panther, linking would fail.</p>
+ <p>Minor optimization on all Unix systems: caching the
+ system name returned from the uname() system call.
+ (Thanks to David N. Welton.)</p>
+ <p>Own Id: OTP-5069</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The ability to set system wide options for TCP sockets is
+ added through the kernel application variables
+ <c><![CDATA[inet_default_listen_options]]></c> and
+ <c><![CDATA[inet_default_connect_options]]></c>, see the <c><![CDATA[inet]]></c>
+ manual page for details.</p>
+ <p>Own Id: OTP-5080</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.6.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A few portability enhancements for the R9C-1 Open Source
+ release: The installer for Windows can now be built with
+ NSIS 2.0 (as well as with the NSIS 2.0b3). The driver
+ header files updated to allowed drivers to be built which
+ the MinGW compiler on Windows. Minor portability
+ enhancement in <c><![CDATA[io_lib:fread]]></c>.</p>
+ <p>Own Id: OTP-4789</p>
+ </item>
+ <item>
+ <p>Conversion of extremely small floating point numbers in
+ the external format (distribution) could sometimes fail
+ leading to unexpected closing of distribution channels,
+ i.e. generating nodedowns for healthy nodes.</p>
+ <p>Own Id: OTP-5026 Aux Id: seq8631 EABln12478 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.6.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Conversion of extremely small floating point numbers in
+ the external format (distribution) could sometimes fail
+ leading to unexpected closing of distribution channels,
+ i.e. generating nodedowns for healthy nodes.</p>
+ <p>Own Id: OTP-5026 Aux Id: seq8631 EABln12478 </p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Remote spawn on a nonreachable node now gives warning
+ instead of error in the error_log.</p>
+ <p>Own Id: OTP-5030 Aux Id: seq8663] </p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Known Bugs and Problems</title>
+ <list type="bulleted">
+ <item>
+ <p>Emulator with elib_malloc enabled could hang when many
+ I/O threads were in use.</p>
+ <p>Own Id: OTP-5028 Aux Id: EABln13041, EABln12253 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.6</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Distributed monitoring in combination with nodes
+ restarting did not behave correctly in rare
+ circumstances.</p>
+ <p>Own Id: OTP-4914</p>
+ </item>
+ <item>
+ <p>A module containing code similar to <c><![CDATA[receive after 4.1]]></c>
+ could not be loaded.</p>
+ <p>Own Id: OTP-4963 Aux Id: seq8344 </p>
+ </item>
+ <item>
+ <p>Problems fixed in <c><![CDATA[file:open/2]]></c>: <c><![CDATA["/dev/null"]]></c>
+ can now be opened. Opening a FIFO will now return an error
+ instead of hanging the emulator. The documentation has been
+ updated to point out that <c><![CDATA[file:open/2]]></c> returns
+ the error code <c><![CDATA[eisdir]]></c> when the pathname is not a
+ regular file (the pathname is not necessarily a directory).</p>
+ <p>Own Id: OTP-4992</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The Solaris kernel poll feature was changed from a
+ compile time option to a runtime option. The kernel poll
+ feature can be enabled, by passing the command-line
+ argument <c><![CDATA[+K true]]></c> to an emulator (see <c><![CDATA[erl(1)]]></c>)
+ that have kernel poll support, i.e. an emulator for
+ Solaris 8. By default the kernel poll feature is disabled.</p>
+ <p>Own Id: OTP-4979 Aux Id: seq8478 </p>
+ </item>
+ <item>
+ <p>Before the Erlang emulator writes an <c><![CDATA[erl_crash.dump]]></c>
+ file (for any reason), it will close all open files and
+ sockets.</p>
+ <p>Own Id: OTP-4985 Aux Id: EABln10730, EABln11277,
+ EABln11279 </p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[+c]]></c> switch has been added to disable time
+ correction in the runtime system, this should be used on
+ systems where one is certain no dramatic wall clock time
+ changes will occur and the time correction algorithm is too
+ costly (namely very fast Linux systems where loads of
+ <c><![CDATA[erlang:now()]]></c> are executed).</p>
+ <p>Own Id: OTP-4986</p>
+ </item>
+ <item>
+ <p>The <c><![CDATA[process_flag/2,3]]></c> BIFs now take a flag
+ <c><![CDATA[min_heap_size]]></c> that allows changing an existing
+ process's minimum heap size. The actual size will only be
+ changed when the next garbage collection occurs.</p>
+ <p>Own Id: OTP-4991 Aux Id: seq8515, OTP-4987 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.4</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>A possibility to make distribution messages be qued up
+ during running of erlang code, so that larger packages is
+ sent over the network is added.</p>
+ <p>Own Id: OTP-4916</p>
+ </item>
+ <item>
+ <p>When code loading failed it was impossible to know
+ exactly what caused it, only <c><![CDATA[{undef,[{M,F,A}|...]}]]></c>
+ would be reported. Now the primitive loader lets the
+ error logger print an error report if a file operation
+ fails. All file errors except <c><![CDATA[enoent]]></c> and
+ <c><![CDATA[enotdir]]></c> are reported this way.</p>
+ <p>Own Id: OTP-4925 Aux Id: OTP-4952 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The driver for dynamically linked in drivers has been
+ fixed to delete loaded drivers when its Erlang server
+ dies. The Erlang server has also been updated to improve
+ the start-on-demand behaviour.</p>
+ <p>Own Id: OTP-4876 Aux Id: OTP-4855 seq8272 </p>
+ </item>
+ <item>
+ <p><c><![CDATA[erlang:register/2]]></c> does no longer generate an ERROR
+ REPORT to the error logger when the name already is
+ registered. If the name is already registered the process
+ function will crash with <c><![CDATA[{'EXIT',Reason}]]></c> and that is
+ enough. It is up to the caller to decide if it is an
+ error that the name is already registered.</p>
+ <p>Own Id: OTP-4892</p>
+ </item>
+ <item>
+ <p>When using <c><![CDATA[erlang:system_monitor(Pid,{long_gc,Time})]]></c>,
+ and the GC time exceeded 1 second, it sometimes erroneously
+ showed up as about 4300 seconds. This bug has now been
+ corrected.</p>
+ <p>Own Id: OTP-4903 Aux Id: seq8379 </p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Starting Erlang with the <c><![CDATA[+Bi]]></c> flag (to ignore ^C), now
+ also disables the quit ('q') option in the JCL menu.</p>
+ <p>Own Id: OTP-4897</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>ERTS 5.3.2</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>The elib_malloc alternative dynamic memory allocator has
+ been improved to use an address order best fit strategy.
+ The instrumented emulator has been improved to be able to
+ catch memory allocations done by external libraries. The
+ emulator flag <c><![CDATA[+r]]></c> (stands for "relocate") makes
+ <c><![CDATA[ets]]></c> updates always result in an object relocation,
+ which significantly lessens the memory fragmentation in
+ certain systems. The <c><![CDATA[erlang:system_info/1]]></c> bif can
+ now be called with the argument <c><![CDATA[ets_realloc_moves]]></c>
+ and will return <c><![CDATA[true]]></c> if the <c><![CDATA[+r]]></c> emulator flag
+ is in effect, <c><![CDATA[false]]></c> otherwise.</p>
+ <p>Own Id: OTP-4838 Aux Id: seq8156 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml
new file mode 100644
index 0000000000..e27b722721
--- /dev/null
+++ b/erts/doc/src/part.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>ERTS User's Guide</title>
+ <prepared>Catrin Granbom</prepared>
+ <docno></docno>
+ <date>1997-05-15</date>
+ <rev>4.5.2</rev>
+ <file>part.xml</file>
+ </header>
+ <description>
+ <p>The Erlang Runtime System Application <em>ERTS</em>.</p>
+ </description>
+ <xi:include href="match_spec.xml"/>
+ <xi:include href="crash_dump.xml"/>
+ <xi:include href="alt_dist.xml"/>
+ <xi:include href="absform.xml"/>
+ <xi:include href="tty.xml"/>
+ <xi:include href="driver.xml"/>
+ <xi:include href="inet_cfg.xml"/>
+ <xi:include href="erl_ext_dist.xml"/>
+ <xi:include href="erl_dist_protocol.xml"/>
+</part>
+
diff --git a/erts/doc/src/part_notes.xml b/erts/doc/src/part_notes.xml
new file mode 100644
index 0000000000..4f183999e6
--- /dev/null
+++ b/erts/doc/src/part_notes.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2004</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>ERTS Release Notes</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>2004-09-07</date>
+ <rev>1.0</rev>
+ </header>
+ <description>
+ <p>The Erlang Runtime System application <em>ERTS</em>.</p>
+ <p>For information about older versions, see
+ <url href="part_notes_history_frame.html">Release Notes History</url>.</p>
+ </description>
+ <xi:include href="notes.xml"/>
+</part>
+
diff --git a/erts/doc/src/part_notes_history.xml b/erts/doc/src/part_notes_history.xml
new file mode 100644
index 0000000000..1b9bcca773
--- /dev/null
+++ b/erts/doc/src/part_notes_history.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2006</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>ERTS Release Notes History</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <description>
+ <p>The Erlang Runtime System application <em>ERTS</em>.</p>
+ </description>
+ <xi:include href="notes_history.xml"/>
+</part>
+
diff --git a/erts/doc/src/ref_man.xml b/erts/doc/src/ref_man.xml
new file mode 100644
index 0000000000..2042cf28bd
--- /dev/null
+++ b/erts/doc/src/ref_man.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE application SYSTEM "application.dtd">
+
+<application xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>ERTS Reference Manual</title>
+ <prepared>Lars Thors&eacute;n</prepared>
+ <docno></docno>
+ <date>1997-05-15</date>
+ <rev>4.5.2</rev>
+ <file>application.xml</file>
+ </header>
+ <description>
+ <p>The Erlang Runtime System Application <em>ERTS</em>.</p>
+ <note>
+ <p>By default, the <c><![CDATA[erts]]></c> is only guaranteed to be compatible
+ with other Erlang/OTP components from the same release as
+ the <c><![CDATA[erts]]></c> itself. See the documentation of the system flag
+ <seealso marker="erl#compat_rel">+R</seealso> on how to communicate
+ with Erlang/OTP components from earlier releases.</p>
+ </note>
+ </description>
+ <xi:include href="erl_prim_loader.xml"/>
+ <xi:include href="erlang.xml"/>
+ <xi:include href="init.xml"/>
+ <xi:include href="zlib.xml"/>
+ <xi:include href="epmd.xml"/>
+ <xi:include href="erl.xml"/>
+ <xi:include href="erlc.xml"/>
+ <xi:include href="werl.xml"/>
+ <xi:include href="escript.xml"/>
+ <xi:include href="erlsrv.xml"/>
+ <xi:include href="start_erl.xml"/>
+ <xi:include href="erl_set_memory_block.xml"/>
+ <xi:include href="run_erl.xml"/>
+ <xi:include href="start.xml"/>
+ <xi:include href="erl_driver.xml"/>
+ <xi:include href="driver_entry.xml"/>
+ <xi:include href="erts_alloc.xml"/>
+ <xi:include href="erl_nif.xml"/>
+</application>
+
diff --git a/erts/doc/src/run_erl.xml b/erts/doc/src/run_erl.xml
new file mode 100644
index 0000000000..7bf7f559c5
--- /dev/null
+++ b/erts/doc/src/run_erl.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1999</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>run_erl</title>
+ <prepared>Kent Boortz</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>99-12-15</date>
+ <rev></rev>
+ <file>run_erl.xml</file>
+ </header>
+ <com>run_erl</com>
+ <comsummary>Redirect Erlang input and output streams on Solaris&reg;</comsummary>
+ <description>
+ <p>This describes the <c><![CDATA[run_erl]]></c> program specific to
+ Solaris/Linux. This program redirect the standard input and standard
+ output streams so that all output can be logged. It also let the
+ program <c><![CDATA[to_erl]]></c> connect to the Erlang console making it
+ possible to monitor and debug an embedded system remotely.</p>
+ <p>You can read more about the use in the <c><![CDATA[Embedded System User's Guide]]></c>.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>run_erl [-daemon] pipe_dir/ log_dir "exec command [command_arguments]"</name>
+ <fsummary>Start the Erlang emulator without attached terminal</fsummary>
+ <desc>
+ <p>The <c><![CDATA[run_erl]]></c> program arguments are:</p>
+ <taglist>
+ <tag>-daemon</tag>
+ <item>This option is highly recommended. It makes run_erl run in
+ the background completely detached from any controlling
+ terminal and the command returns to the caller immediately.
+ Without this option, run_erl must be started using several
+ tricks in the shell to detach it completely from the
+ terminal in use when starting it. The option must be the
+ first argument to run_erl on the command line.</item>
+ <tag>pipe_dir</tag>
+ <item>This is where to put the named pipe, usually
+ <c><![CDATA[/tmp/]]></c>. It shall be suffixed by a <c><![CDATA[/]]></c> (slash),
+ i.e. not <c><![CDATA[/tmp/epipies]]></c>, but <c><![CDATA[/tmp/epipes/]]></c>. </item>
+ <tag>log_dir</tag>
+ <item>This is where the log files are written. There will be one
+ log file, <c><![CDATA[run_erl.log]]></c> that log progress and
+ warnings from the <c><![CDATA[run_erl]]></c> program itself and there
+ will be up to five log files at maximum 100KB each (both
+ number of logs and sizes can be
+ changed by environment variables, see below) with
+ the content of the standard streams from and to the
+ command. When the logs are full <c><![CDATA[run_erl]]></c> will delete
+ and reuse the oldest log file.</item>
+ <tag>"exec command [command_arguments]"</tag>
+ <item>In the third argument <c><![CDATA[command]]></c> is the to execute
+ where everything written to stdin and stdout is logged to
+ <c><![CDATA[log_dir]]></c>.</item>
+ </taglist>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Notes concerning the log files</title>
+ <p>While running, run_erl (as stated earlier) sends all output,
+ uninterpreted, to a log file. The file is called
+ <c><![CDATA[erlang.log.N]]></c>, where N is a number. When the log is "full",
+ default after 100KB, run_erl starts to log in file
+ <c><![CDATA[erlang.log.(N+1)]]></c>, until N reaches a certain number (default
+ 5), where after N starts at 1 again and the oldest files start
+ getting overwritten. If no output comes from the erlang shell, but
+ the erlang machine still seems to be alive, an "ALIVE" message is
+ written to the log, it is a timestamp and is written, by default,
+ after 15 minutes of inactivity. Also, if output from erlang is
+ logged but it's been more than 5 minutes (default) since last time
+ we got anything from erlang, a timestamp is written in the
+ log. The "ALIVE" messages look like this:</p>
+ <code type="none"><![CDATA[
+ ===== ALIVE <date-time-string>
+ ]]></code>
+ <p>while the other timestamps look like this:</p>
+ <code type="none"><![CDATA[
+ ===== <date-time-string>
+ ]]></code>
+ <p>The <c><![CDATA[date-time-string]]></c> is the date and time the message is
+ written, default in local time (can be changed to GMT if one wants
+ to) and is formatted with the ANSI-C function <c><![CDATA[strftime]]></c>
+ using the format string <c><![CDATA[%a %b %e %T %Z %Y]]></c>, which produces
+ messages on the line of <c><![CDATA[===== ALIVE Thu May 15 10:13:36 MEST 2003]]></c>, this can be changed, see below.</p>
+ </section>
+
+ <section>
+ <title>Environment variables</title>
+ <p>The following environment variables are recognized by run_erl
+ and change the logging behavior. Also see the notes above to get
+ more info on how the log behaves.</p>
+ <taglist>
+ <tag>RUN_ERL_LOG_ALIVE_MINUTES</tag>
+ <item>How long to wait for output (in minutes) before writing an
+ "ALIVE" message to the log. Default is 15, can never be less
+ than 1.</item>
+ <tag>RUN_ERL_LOG_ACTIVITY_MINUTES</tag>
+ <item>How long erlang need to be inactive before output will be
+ preceded with a timestamp. Default is
+ RUN_ERL_LOG_ALIVE_MINUTES div 3, but never less than 1.</item>
+ <tag>RUN_ERL_LOG_ALIVE_FORMAT</tag>
+ <item>Specifies another format string to be used in the strftime
+ C library call. i.e specifying this to <c><![CDATA["%e-%b-%Y, %T %Z"]]></c>
+ will give log messages with timestamps looking like
+ <c><![CDATA[15-May-2003, 10:23:04 MET]]></c> etc. See the documentation
+ for the C library function strftime for more
+ information. Default is <c><![CDATA["%a %b %e %T %Z %Y"]]></c>.</item>
+ <tag>RUN_ERL_LOG_ALIVE_IN_UTC</tag>
+ <item>If set to anything else than "0", it will make all
+ times displayed by run_erl to be in UTC (GMT,CET,MET, without
+ DST), rather than
+ in local time. This does not affect data coming from erlang,
+ only the logs output directly by run_erl. The application
+ <c><![CDATA[sasl]]></c> can be modified accordingly by setting the erlang
+ application variable <c><![CDATA[utc_log]]></c> to <c><![CDATA[true]]></c>.</item>
+ <tag>RUN_ERL_LOG_GENERATIONS</tag>
+ <item>Controls the number of log files written before older
+ files are being reused. Default is 5, minimum is 2, maximum is 1000.</item>
+ <tag>RUN_ERL_LOG_MAXSIZE</tag>
+ <item>The size (in bytes) of a log file before switching to a
+ new log file. Default is 100000, minimum is 1000 and maximum is
+ approximately 2^30.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p>start(1), start_erl(1)</p>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/start.xml b/erts/doc/src/start.xml
new file mode 100644
index 0000000000..5dc33deb2a
--- /dev/null
+++ b/erts/doc/src/start.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1999</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>start</title>
+ <prepared>Kent Boortz</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>99-12-15</date>
+ <rev></rev>
+ <file>start.xml</file>
+ </header>
+ <com>start</com>
+ <comsummary>OTP start script example for Unix</comsummary>
+ <description>
+ <p>This describes the <c><![CDATA[start]]></c> script that is an example script on
+ how to startup the Erlang system in embedded mode on Unix.</p>
+ <p>You can read more about the use in the <c><![CDATA[Embedded System User's Guide]]></c>.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>start [ data_file ]</name>
+ <fsummary>This is an example script on how to startup the Erlang system in embedded mode on Unix.</fsummary>
+ <desc>
+ <p>In the example there is one argument</p>
+ <taglist>
+ <tag>data_file</tag>
+ <item>Optional, specifies what <c><![CDATA[start_erl.data]]></c> file
+ to use.</item>
+ </taglist>
+ <p>There is also an environment variable <c><![CDATA[RELDIR]]></c> that can
+ be set prior to calling this example that set the directory
+ where to find the release files.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p>run_erl(1), start_erl(1)</p>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/start_erl.xml b/erts/doc/src/start_erl.xml
new file mode 100644
index 0000000000..21cc901f52
--- /dev/null
+++ b/erts/doc/src/start_erl.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1998</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>start_erl</title>
+ <prepared>Patrik Nyblom</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>98-08-05</date>
+ <rev></rev>
+ <file>start_erl.xml</file>
+ </header>
+ <com>start_erl</com>
+ <comsummary>Start Erlang for embedded systems on Windows NT&reg;</comsummary>
+ <description>
+ <p>This describes the <c><![CDATA[start_erl]]></c> program specific to Windows
+ NT. Although there exists programs with the same name on other
+ platforms, their functionality is not the same.</p>
+ <p>The <c><![CDATA[start_erl]]></c> program is distributed both in compiled
+ form (under &lt;Erlang root&gt;\\erts-&lt;version&gt;\\bin) and
+ in source form (under &lt;Erlang
+ root&gt;\\erts-&lt;version&gt;\\src).
+ The purpose of the source code is to make it possible to easily
+ customize the program for local needs, such as cyclic restart
+ detection etc. There is also a "make"-file, written for the
+ <c><![CDATA[nmake]]></c> program distributed with Microsoft&reg; Visual
+ C++&reg;. The program can however be compiled with
+ any Win32 C compiler (possibly with slight modifications).</p>
+ <p>The purpose of the program is to aid release handling on
+ Windows NT&reg;. The program should be called by the
+ <c><![CDATA[erlsrv]]></c> program, read up the release data file
+ start_erl.data and start Erlang. Certain options to start_erl
+ are added and removed by the release handler during upgrade with
+ emulator restart (more specifically the <c><![CDATA[-data]]></c> option).</p>
+ </description>
+ <funcs>
+ <func>
+ <name>start_erl [&lt;erl options>] ++ [&lt;start_erl options>]</name>
+ <fsummary>Start the Erlang emulator with the correct release data</fsummary>
+ <desc>
+ <p>The <c><![CDATA[start_erl]]></c> program in its original form
+ recognizes the following options:</p>
+ <taglist>
+ <tag>++</tag>
+ <item>Mandatory, delimits start_erl options from normal Erlang
+ options. Everything on the command line <em>before</em> the
+ <c><![CDATA[++]]></c> is interpreted as options to be sent to the
+ <c><![CDATA[erl]]></c> program. Everything <em>after</em><c><![CDATA[++]]></c> is
+ interpreted as options to <c><![CDATA[start_erl]]></c> itself.</item>
+ <tag>-reldir &lt;release root&gt;</tag>
+ <item>Mandatory if the environment variable <c><![CDATA[RELDIR]]></c> is not
+ specified. Tells start_erl where the root of the
+ release tree is placed in the file-system
+ (like &lt;Erlang root&gt;\\releases). The
+ <c><![CDATA[start_erl.data]]></c> file is expected to be placed in
+ this directory (if not otherwise specified).</item>
+ <tag>-data &lt;data file name&gt;</tag>
+ <item>Optional, specifies another data file than start_erl.data
+ in the &lt;release root&gt;. It is specified relative to the
+ &lt;release root&gt; or absolute (including drive letter
+ etc.). This option is used by the release handler during
+ upgrade and should not be used during normal
+ operation. The release data file should not normally be
+ named differently.</item>
+ <tag>-bootflags &lt;boot flags file name&gt;</tag>
+ <item>Optional, specifies a file name relative to actual release
+ directory (that is the subdirectory of &lt;release
+ root&gt; where the <c><![CDATA[.boot]]></c> file etc. are placed).
+ The contents of this file is appended to the command line
+ when Erlang is started. This makes it easy to start the
+ emulator with different options for different releases.</item>
+ </taglist>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>NOTES</title>
+ <p>As the source code is distributed, it can easily be modified to
+ accept other options. The program must still accept the
+ <c><![CDATA[-data]]></c> option with the semantics described above for the
+ release handler to work correctly.</p>
+ <p>The Erlang emulator is found by examining the registry keys for
+ the emulator version specified in the release data file. The new
+ emulator needs to be properly installed before the upgrade for
+ this to work.</p>
+ <p>Although the program is located together with files specific to
+ emulator version, it is not expected to be specific to the
+ emulator version. The release handler does <em>not</em> change the
+ <c><![CDATA[-machine]]></c> option to <c><![CDATA[erlsrv]]></c> during emulator restart.
+ Place the (possibly customized) <c><![CDATA[start_erl]]></c> program so that
+ it is not overwritten during upgrade. </p>
+ <p>The <c><![CDATA[erlsrv]]></c> program's default options are not
+ sufficient for release handling. The machine <c><![CDATA[erlsrv]]></c>
+ starts should be specified as the <c><![CDATA[start_erl]]></c> program and
+ the arguments should contain the <c><![CDATA[++]]></c> followed by desired
+ options.</p>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p>erlsrv(1), release_handler(3)</p>
+ </section>
+</comref>
+
diff --git a/erts/doc/src/tty.xml b/erts/doc/src/tty.xml
new file mode 100644
index 0000000000..23694e5965
--- /dev/null
+++ b/erts/doc/src/tty.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>tty - A command line interface</title>
+ <prepared>ETX/B/SFP C. Granbom</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved>EPK/TE (K. Boortz)</approved>
+ <checked></checked>
+ <date>1996-11-01</date>
+ <rev>A</rev>
+ <file>tty.xml</file>
+ </header>
+ <p><c><![CDATA[tty]]></c> is a simple command line interface program where keystrokes are collected and interpreted. Completed lines are sent to the shell for interpretation. There is a simple history mechanism, which saves previous lines. These can be edited before sending them to the shell.
+ <c><![CDATA[tty]]></c> is started when Erlang is started with the command:<br></br></p>
+ <p><em>erl</em></p>
+ <p><c><![CDATA[tty]]></c> operates in one of two modes:<br></br></p>
+ <list type="bulleted">
+ <item>
+ <p><em>normal mode</em>, in which lines of text can be edited and sent to the shell.</p>
+ </item>
+ <item>
+ <p><em>shell break</em> mode, which allows the user to kill the current shell, start multiple shells etc. Shell break mode is started by typing <em>Control G</em>.</p>
+ </item>
+ </list>
+
+ <section>
+ <title>Normal Mode</title>
+ <p>In normal mode keystrokes from the user are collected and interpreted by <c><![CDATA[tty]]></c>. Most of the <em>emacs</em> line editing commands are supported. The following is a complete list of the supported line editing commands.<br></br></p>
+ <p><em>Note:</em>\011The notation <c><![CDATA[C-a]]></c> means pressing the control key and the letter <c><![CDATA[a]]></c> simultaneously. <c><![CDATA[M-f]]></c> means pressing the <c><![CDATA[ESC]]></c> key followed by the letter <c><![CDATA[f]]></c>.
+ </p>
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>Key Sequence</em></cell>
+ <cell align="left" valign="middle"><em>Function</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-a</cell>
+ <cell align="left" valign="middle">Beginning of line</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-b</cell>
+ <cell align="left" valign="middle">Backward character</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">M-b</cell>
+ <cell align="left" valign="middle">Backward word</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-d</cell>
+ <cell align="left" valign="middle">Delete character</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">M-d</cell>
+ <cell align="left" valign="middle">Delete word</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-e</cell>
+ <cell align="left" valign="middle">End of line</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-f</cell>
+ <cell align="left" valign="middle">Forward character</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">M-f</cell>
+ <cell align="left" valign="middle">Forward word</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-g</cell>
+ <cell align="left" valign="middle">Enter shell break mode</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-k</cell>
+ <cell align="left" valign="middle">Kill line</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-l</cell>
+ <cell align="left" valign="middle">Redraw line</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-n</cell>
+ <cell align="left" valign="middle">Fetch next line from the history buffer</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-p</cell>
+ <cell align="left" valign="middle">Fetch previous line from the history buffer</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-t</cell>
+ <cell align="left" valign="middle">Transpose characters</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">C-y</cell>
+ <cell align="left" valign="middle">Insert previously killed text</cell>
+ </row>
+ <tcaption>tty text editing</tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>Shell Break Mode</title>
+ <p><em>tty</em> enters <em>shell</em> break mode when you type <em>Control G</em>. In this mode you can:<br></br></p>
+ <list type="bulleted">
+ <item>
+ <p>Kill or suspend the current shell</p>
+ </item>
+ <item>
+ <p>Connect to a suspended shell</p>
+ </item>
+ <item>
+ <p>Start a new shell</p>
+ </item>
+ </list>
+ </section>
+</chapter>
+
diff --git a/erts/doc/src/werl.xml b/erts/doc/src/werl.xml
new file mode 100644
index 0000000000..1494d91da8
--- /dev/null
+++ b/erts/doc/src/werl.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE comref SYSTEM "comref.dtd">
+
+<comref>
+ <header>
+ <copyright>
+ <year>1998</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>werl</title>
+ <prepared>Bj&ouml;rn Gustavsson</prepared>
+ <responsible>Bjarne D&auml;cker</responsible>
+ <docno>1</docno>
+ <approved>Bjarne D&auml;cker</approved>
+ <checked></checked>
+ <date>98-01-26</date>
+ <rev>A</rev>
+ <file>werl.xml</file>
+ </header>
+ <com>werl</com>
+ <comsummary>The Erlang Emulator</comsummary>
+ <description>
+ <p>On Windows, the preferred way to start the Erlang system for interactive use is:</p>
+ <p><c><![CDATA[werl <arguments>]]></c></p>
+
+ <p>This will start Erlang in its own window, with fully
+ functioning command-line editing and scrollbars. All flags
+ except <c><![CDATA[-oldshell]]></c> work as they do for
+ the <seealso marker="erl">erl</seealso> command.</p>
+
+ <p>Ctrl-C is reserved for copying text to the clipboard (Ctrl-V to paste).
+ To interrupt the runtime system or the shell process (depending on what
+ has been specified with the +B system flag), you should use Ctrl-Break.</p>
+ <p>In cases where you want to redirect standard input and/or
+ standard output or use Erlang in a pipeline, the <c>werl</c> is
+ not suitable, and the <c>erl</c> program should be used instead.</p>
+
+ <p>The <c>werl</c> window is in many ways modelled after the <c>xterm</c>
+ window present on other platforms, as the <c>xterm</c> model
+ fits well with line oriented command based interaction. This
+ means that selecting text is line oriented rather than rectangle
+ oriented.</p>
+
+ <p>To select text in the <c>werl</c> window , simply press and hold
+ the left mouse button and drag the mouse over the text you want
+ to select. If the selection crosses line boundaries, the
+ selected text will consist of complete lines where applicable
+ (just like in a word processor). To select more text than fits
+ in the window, start by selecting a small portion in the
+ beginning of the text you want, then use the scrollbar
+ to view the end of the desired selection, point to it and press
+ the <em>right</em> mouse-button. The whole area between your
+ first selection and the point where you right-clicked will be
+ included in the selection.</p>
+
+ <p>The selected text is copied to the clipboard by either
+ pressing <c>Ctrl-C</c>, using the menu or pressing the copy
+ button in the toolbar.</p>
+
+ <p>Pasted text is always inserted at the current prompt position
+ and will be interpreted by Erlang as usual keyboard input.</p>
+
+ <p>Previous command lines can be retrieved by pressing the <c>Up
+ arrow</c> or by pressing <c>Ctrl-P</c>. There is also a drop
+ down box in the toolbar containing the command
+ history. Selecting a command in the drop down box will insert it
+ at the prompt, just as if you used the keyboard to retrieve the
+ command.</p>
+
+ <p>Closing the <c>werl</c> window will stop the Erlang emulator.</p>
+
+ </description>
+</comref>
+
diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml
new file mode 100644
index 0000000000..9f39ac657a
--- /dev/null
+++ b/erts/doc/src/zlib.xml
@@ -0,0 +1,606 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2005</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>zlib</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>zlib.xml</file>
+ </header>
+ <module>zlib</module>
+ <modulesummary>Zlib Compression interface.</modulesummary>
+ <description>
+ <p>The zlib module provides an API for the zlib library
+ (http://www.zlib.org).
+ It is used to compress and decompress data. The
+ data format is described by RFCs 1950 to 1952.</p>
+ <p>A typical (compress) usage looks like:</p>
+ <pre>
+Z = zlib:open(),
+ok = zlib:deflateInit(Z,default),
+
+Compress = fun(end_of_data, _Cont) -> [];
+ (Data, Cont) ->
+ [zlib:deflate(Z, Data)|Cont(Read(),Cont)]
+ end,
+Compressed = Compress(Read(),Compress),
+Last = zlib:deflate(Z, [], finish),
+ok = zlib:deflateEnd(Z),
+zlib:close(Z),
+list_to_binary([Compressed|Last])</pre>
+ <p>In all functions errors, <c>{'EXIT',{Reason,Backtrace}}</c>,
+ might be thrown, where <c>Reason</c> describes the
+ error. Typical reasons are:</p>
+ <taglist>
+ <tag><c>badarg</c></tag>
+ <item>
+ <p>Bad argument</p>
+ </item>
+ <tag><c>data_error</c></tag>
+ <item>
+ <p>The data contains errors</p>
+ </item>
+ <tag><c>stream_error</c></tag>
+ <item>
+ <p>Inconsistent stream state</p>
+ </item>
+ <tag><c>einval</c></tag>
+ <item>
+ <p>Bad value or wrong function called</p>
+ </item>
+ <tag><c>{need_dictionary,Adler32}</c></tag>
+ <item>
+ <p>See <c>inflate/2</c></p>
+ </item>
+ </taglist>
+ </description>
+
+ <section>
+ <title>DATA TYPES</title>
+ <code type="none">
+iodata = iolist() | binary()
+
+iolist = [char() | binary() | iolist()]
+ a binary is allowed as the tail of the list
+
+zstream = a zlib stream, see open/0</code>
+ </section>
+ <funcs>
+ <func>
+ <name>open() -> Z </name>
+ <fsummary>Open a stream and return a stream reference</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>Open a zlib stream.</p>
+ </desc>
+ </func>
+ <func>
+ <name>close(Z) -> ok</name>
+ <fsummary>Close a stream</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>Closes the stream referenced by <c>Z</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflateInit(Z) -> ok</name>
+ <fsummary>Initialize a session for compression</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>Same as <c>zlib:deflateInit(Z, default)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflateInit(Z, Level) -> ok</name>
+ <fsummary>Initialize a session for compression</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Level = none | default | best_speed | best_compression | 0..9</v>
+ </type>
+ <desc>
+ <p>Initialize a zlib stream for compression.</p>
+ <p><c>Level</c> decides the compression level to be used, 0
+ (<c>none</c>), gives no compression at all, 1
+ (<c>best_speed</c>) gives best speed and 9
+ (<c>best_compression</c>) gives best compression.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) -> ok</name>
+ <fsummary>Initialize a session for compression</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Level = none | default | best_speed | best_compression | 0..9</v>
+ <v>Method = deflated</v>
+ <v>WindowBits = 9..15|-9..-15</v>
+ <v>MemLevel = 1..9</v>
+ <v>Strategy = default|filtered|huffman_only</v>
+ </type>
+ <desc>
+ <p>Initiates a zlib stream for compression.</p>
+ <p>The <c>Level</c> parameter decides the compression level to be
+ used, 0 (<c>none</c>), gives no compression at all, 1
+ (<c>best_speed</c>) gives best speed and 9
+ (<c>best_compression</c>) gives best compression.</p>
+ <p>The <c>Method</c> parameter decides which compression method to use,
+ currently the only supported method is <c>deflated</c>.</p>
+ <p>The <c>WindowBits</c> parameter is the base two logarithm
+ of the window size (the size of the history buffer). It
+ should be in the range 9 through 15. Larger values
+ of this parameter result in better compression at the
+ expense of memory usage. The default value is 15 if
+ <c>deflateInit/2</c>. A negative <c>WindowBits</c>
+ value suppresses the zlib header (and checksum) from the
+ stream. Note that the zlib source mentions this only as a
+ undocumented feature.</p>
+ <p>The <c>MemLevel</c> parameter specifies how much memory
+ should be allocated for the internal compression
+ state. <c>MemLevel</c>=1 uses minimum memory but is slow and
+ reduces compression ratio; <c>MemLevel</c>=9 uses maximum
+ memory for optimal speed. The default value is 8.</p>
+ <p>The <c>Strategy</c> parameter is used to tune the
+ compression algorithm. Use the value <c>default</c> for
+ normal data, <c>filtered</c> for data produced by a filter
+ (or predictor), or <c>huffman_only</c> to force Huffman
+ encoding only (no string match). Filtered data consists
+ mostly of small values with a somewhat random
+ distribution. In this case, the compression algorithm is
+ tuned to compress them better. The effect of
+ <c>filtered</c>is to force more Huffman coding and less
+ string matching; it is somewhat intermediate between
+ <c>default</c> and <c>huffman_only</c>. The <c>Strategy</c>
+ parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set
+ appropriately.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflate(Z, Data) -> Compressed</name>
+ <fsummary>Compress data</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Data = iodata()</v>
+ <v>Compressed = iolist()</v>
+ </type>
+ <desc>
+ <p>Same as <c>deflate(Z, Data, none)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflate(Z, Data, Flush) -> </name>
+ <fsummary>Compress data</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Data = iodata()</v>
+ <v>Flush = none | sync | full | finish</v>
+ <v>Compressed = iolist()</v>
+ </type>
+ <desc>
+ <p><c>deflate/3</c> compresses as much data as possible, and
+ stops when the input buffer becomes empty. It may introduce
+ some output latency (reading input without producing any
+ output) except when forced to flush.</p>
+ <p>If the parameter <c>Flush</c> is set to <c>sync</c>, all
+ pending output is flushed to the output buffer and the
+ output is aligned on a byte boundary, so that the
+ decompressor can get all input data available so far.
+ Flushing may degrade compression for some compression algorithms and so
+ it should be used only when necessary.</p>
+ <p>If <c>Flush</c> is set to <c>full</c>, all output is flushed as with
+ <c>sync</c>, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using <c>full</c> too often can seriously degrade
+ the compression.</p>
+ <p>If the parameter <c>Flush</c> is set to <c>finish</c>,
+ pending input is processed, pending output is flushed and
+ <c>deflate/3</c> returns. Afterwards the only possible
+ operations on the stream are <c>deflateReset/1</c> or <c>deflateEnd/1</c>.</p>
+ <p><c>Flush</c> can be set to <c>finish</c> immediately after
+ <c>deflateInit</c> if all compression is to be done in one step.</p>
+ <pre>
+
+zlib:deflateInit(Z),
+B1 = zlib:deflate(Z,Data),
+B2 = zlib:deflate(Z,&lt;&lt; &gt;&gt;,finish),
+zlib:deflateEnd(Z),
+list_to_binary([B1,B2])</pre>
+ </desc>
+ </func>
+ <func>
+ <name>deflateSetDictionary(Z, Dictionary) -> Adler32</name>
+ <fsummary>Initialize the compression dictionary</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Dictionary = binary()</v>
+ <v>Adler32 = integer()</v>
+ </type>
+ <desc>
+ <p>Initializes the compression dictionary from the given byte
+ sequence without producing any compressed output. This
+ function must be called immediately after
+ <c>deflateInit/[1|2|6]</c> or <c>deflateReset/1</c>, before
+ any call of <c>deflate/3</c>. The compressor and
+ decompressor must use exactly the same dictionary (see
+ <c>inflateSetDictionary/2</c>). The adler checksum of the
+ dictionary is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflateReset(Z) -> ok</name>
+ <fsummary>Reset the deflate session</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>This function is equivalent to <c>deflateEnd/1</c>
+ followed by <c>deflateInit/[1|2|6]</c>, but does not free
+ and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other
+ attributes.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflateParams(Z, Level, Strategy) -> ok </name>
+ <fsummary>Dynamicly update deflate parameters</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Level = none | default | best_speed | best_compression | 0..9</v>
+ <v>Strategy = default|filtered|huffman_only</v>
+ </type>
+ <desc>
+ <p>Dynamically update the compression level and compression
+ strategy. The interpretation of <c>Level</c> and
+ <c>Strategy</c> is as in <c>deflateInit/6</c>. This can be
+ used to switch between compression and straight copy of the
+ input data, or to switch to a different kind of input data
+ requiring a different strategy. If the compression level is
+ changed, the input available so far is compressed with the
+ old level (and may be flushed); the new level will take
+ effect only at the next call of <c>deflate/3</c>.</p>
+ <p>Before the call of deflateParams, the stream state must be set as for
+ a call of <c>deflate/3</c>, since the currently available input may have to
+ be compressed and flushed.</p>
+ </desc>
+ </func>
+ <func>
+ <name>deflateEnd(Z) -> ok</name>
+ <fsummary>End deflate session</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>End the deflate session and cleans all data used.
+ Note that this function will throw an <c>data_error</c>
+ exception if the last call to
+ <c>deflate/3</c> was not called with <c>Flush</c> set to
+ <c>finish</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>inflateInit(Z) -> ok </name>
+ <fsummary>Initialize a session for decompression</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>Initialize a zlib stream for decompression.</p>
+ </desc>
+ </func>
+ <func>
+ <name>inflateInit(Z, WindowBits) -> ok </name>
+ <fsummary>Initialize a session for decompression</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>WindowBits = 9..15|-9..-15</v>
+ </type>
+ <desc>
+ <p>Initialize decompression session on zlib stream.</p>
+ <p>The <c>WindowBits</c> parameter is the base two logarithm
+ of the maximum window size (the size of the history buffer).
+ It should be in the range 9 through 15.
+ The default value is 15 if <c>inflateInit/1</c> is used.
+ If a compressed stream with a larger window size is
+ given as input, inflate() will throw the <c>data_error</c>
+ exception. A negative <c>WindowBits</c> value makes zlib ignore the
+ zlib header (and checksum) from the stream. Note that the zlib
+ source mentions this only as a undocumented feature.</p>
+ </desc>
+ </func>
+ <func>
+ <name>inflate(Z, Data) -> DeCompressed </name>
+ <fsummary>Decompress data</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Data = iodata()</v>
+ <v>DeCompressed = iolist()</v>
+ </type>
+ <desc>
+ <p><c>inflate/2</c> decompresses as much data as possible.
+ It may some introduce some output latency (reading
+ input without producing any output).</p>
+ <p>If a preset dictionary is needed at this point (see
+ <c>inflateSetDictionary</c> below), <c>inflate/2</c> throws a
+ <c>{need_dictionary,Adler}</c> exception where <c>Adler</c> is
+ the adler32 checksum of the dictionary chosen by the
+ compressor.</p>
+ </desc>
+ </func>
+ <func>
+ <name>inflateSetDictionary(Z, Dictionary) -> ok</name>
+ <fsummary>Initialize the decompression dictionary</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Dictionary = binary()</v>
+ </type>
+ <desc>
+ <p>Initializes the decompression dictionary from the given
+ uncompressed byte sequence. This function must be called
+ immediately after a call of <c>inflate/2</c> if this call
+ threw a <c>{need_dictionary,Adler}</c> exception.
+ The dictionary chosen by the
+ compressor can be determined from the Adler value thrown
+ by the call to <c>inflate/2</c>. The compressor and decompressor
+ must use exactly the same dictionary (see <c>deflateSetDictionary/2</c>).</p>
+ <p>Example:</p>
+ <pre>
+unpack(Z, Compressed, Dict) ->
+ case catch zlib:inflate(Z, Compressed) of
+\011 {'EXIT',{{need_dictionary,DictID},_}} ->
+ \011 zlib:inflateSetDictionary(Z, Dict),
+\011 Uncompressed = zlib:inflate(Z, []);
+\011 Uncompressed ->
+\011 Uncompressed
+ end.</pre>
+ </desc>
+ </func>
+ <func>
+ <name>inflateReset(Z) -> ok</name>
+ <fsummary>>Reset the inflate session</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>This function is equivalent to <c>inflateEnd/1</c> followed
+ by <c>inflateInit/1</c>, but does not free and reallocate all
+ the internal decompression state. The stream will keep
+ attributes that may have been set by <c>inflateInit/[1|2]</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>inflateEnd(Z) -> ok</name>
+ <fsummary>End inflate session</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ </type>
+ <desc>
+ <p>End the inflate session and cleans all data used. Note
+ that this function will throw a <c>data_error</c> exception
+ if no end of stream was found (meaning that not all data
+ has been uncompressed).</p>
+ </desc>
+ </func>
+ <func>
+ <name>setBufSize(Z, Size) -> ok</name>
+ <fsummary>Set buffer size</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Size = integer()</v>
+ </type>
+ <desc>
+ <p>Sets the intermediate buffer size.</p>
+ </desc>
+ </func>
+ <func>
+ <name>getBufSize(Z) -> Size</name>
+ <fsummary>Get buffer size</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Size = integer()</v>
+ </type>
+ <desc>
+ <p>Get the size of intermediate buffer.</p>
+ </desc>
+ </func>
+ <func>
+ <name>crc32(Z) -> CRC</name>
+ <fsummary>Get current CRC</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>CRC = integer()</v>
+ </type>
+ <desc>
+ <p>Get the current calculated CRC checksum.</p>
+ </desc>
+ </func>
+ <func>
+ <name>crc32(Z, Binary) -> CRC</name>
+ <fsummary>Calculate CRC</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Binary = binary()</v>
+ <v>CRC = integer()</v>
+ </type>
+ <desc>
+ <p>Calculate the CRC checksum for <c>Binary</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>crc32(Z, PrevCRC, Binary) -> CRC </name>
+ <fsummary>Calculate CRC</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>PrevCRC = integer()</v>
+ <v>Binary = binary()</v>
+ <v>CRC = integer()</v>
+ </type>
+ <desc>
+ <p>Update a running CRC checksum for <c>Binary</c>.
+ If <c>Binary</c> is the empty binary, this function returns
+ the required initial value for the crc.</p>
+ <pre>
+Crc = lists:foldl(fun(Bin,Crc0) ->
+\011 zlib:crc32(Z, Crc0, Bin),
+\011 end, zlib:crc32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
+ </desc>
+ </func>
+ <func>
+ <name>crc32_combine(Z, CRC1, CRC2, Size2) -> CRC </name>
+ <fsummary>Combine two CRC's</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>CRC = integer()</v>
+ <v>CRC1 = integer()</v>
+ <v>CRC2 = integer()</v>
+ <v>Size2 = integer()</v>
+ </type>
+ <desc>
+ <p>Combine two CRC checksums into one. For two binaries,
+ <c>Bin1</c> and <c>Bin2</c> with sizes of <c>Size1</c> and
+ <c>Size2</c>, with CRC checksums <c>CRC1</c> and
+ <c>CRC2</c>. <c>crc32_combine/4</c> returns the <c>CRC</c>
+ checksum of <c>&lt;&lt;Bin1/binary,Bin2/binary&gt;&gt;</c>, requiring
+ only <c>CRC1</c>, <c>CRC2</c>, and <c>Size2</c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>adler32(Z, Binary) -> Checksum</name>
+ <fsummary>Calculate the adler checksum</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Binary = binary()</v>
+ <v>Checksum = integer()</v>
+ </type>
+ <desc>
+ <p>Calculate the Adler-32 checksum for <c>Binary</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>adler32(Z, PrevAdler, Binary) -> Checksum</name>
+ <fsummary>Calculate the adler checksum</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>PrevAdler = integer()</v>
+ <v>Binary = binary()</v>
+ <v>Checksum = integer()</v>
+ </type>
+ <desc>
+ <p>Update a running Adler-32 checksum for <c>Binary</c>.
+ If <c>Binary</c> is the empty binary, this function returns
+ the required initial value for the checksum.</p>
+ <pre>
+Crc = lists:foldl(fun(Bin,Crc0) ->
+\011 zlib:adler32(Z, Crc0, Bin),
+\011 end, zlib:adler32(Z,&lt;&lt; &gt;&gt;), Bins)</pre>
+ </desc>
+ </func>
+ <func>
+ <name>adler32_combine(Z, Adler1, Adler2, Size2) -> Adler </name>
+ <fsummary>Combine two Adler-32 checksums</fsummary>
+ <type>
+ <v>Z = zstream()</v>
+ <v>Adler = integer()</v>
+ <v>Adler1 = integer()</v>
+ <v>Adler2 = integer()</v>
+ <v>Size2 = integer()</v>
+ </type>
+ <desc>
+ <p>Combine two Adler-32 checksums into one. For two binaries,
+ <c>Bin1</c> and <c>Bin2</c> with sizes of <c>Size1</c> and
+ <c>Size2</c>, with Adler-32 checksums <c>Adler1</c> and
+ <c>Adler2</c>. <c>adler32_combine/4</c> returns the <c>Adler</c>
+ checksum of <c>&lt;&lt;Bin1/binary,Bin2/binary&gt;&gt;</c>, requiring
+ only <c>Adler1</c>, <c>Adler2</c>, and <c>Size2</c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>compress(Binary) -> Compressed </name>
+ <fsummary>Compress a binary with standard zlib functionality</fsummary>
+ <type>
+ <v>Binary = Compressed = binary()</v>
+ </type>
+ <desc>
+ <p>Compress a binary (with zlib headers and checksum).</p>
+ </desc>
+ </func>
+ <func>
+ <name>uncompress(Binary) -> Decompressed</name>
+ <fsummary>Uncompress a binary with standard zlib functionality</fsummary>
+ <type>
+ <v>Binary = Decompressed = binary()</v>
+ </type>
+ <desc>
+ <p>Uncompress a binary (with zlib headers and checksum).</p>
+ </desc>
+ </func>
+ <func>
+ <name>zip(Binary) -> Compressed</name>
+ <fsummary>Compress a binary without the zlib headers</fsummary>
+ <type>
+ <v>Binary = Compressed = binary()</v>
+ </type>
+ <desc>
+ <p>Compress a binary (without zlib headers and checksum).</p>
+ </desc>
+ </func>
+ <func>
+ <name>unzip(Binary) -> Decompressed</name>
+ <fsummary>Uncompress a binary without the zlib headers</fsummary>
+ <type>
+ <v>Binary = Decompressed = binary()</v>
+ </type>
+ <desc>
+ <p>Uncompress a binary (without zlib headers and checksum).</p>
+ </desc>
+ </func>
+ <func>
+ <name>gzip(Data) -> Compressed</name>
+ <fsummary>Compress a binary with gz header</fsummary>
+ <type>
+ <v>Binary = Compressed = binary()</v>
+ </type>
+ <desc>
+ <p>Compress a binary (with gz headers and checksum).</p>
+ </desc>
+ </func>
+ <func>
+ <name>gunzip(Bin) -> Decompressed</name>
+ <fsummary>Uncompress a binary with gz header</fsummary>
+ <type>
+ <v>Binary = Decompressed = binary()</v>
+ </type>
+ <desc>
+ <p>Uncompress a binary (with gz headers and checksum).</p>
+ </desc>
+ </func>
+ </funcs>
+</erlref>
+