diff options
Diffstat (limited to 'erts/doc/src')
-rw-r--r-- | erts/doc/src/Makefile | 38 | ||||
-rw-r--r-- | erts/doc/src/absform.xml | 5 | ||||
-rw-r--r-- | erts/doc/src/alt_dist.xml | 4 | ||||
-rw-r--r-- | erts/doc/src/driver.xml | 10 | ||||
-rw-r--r-- | erts/doc/src/driver_entry.xml | 48 | ||||
-rw-r--r-- | erts/doc/src/epmd.xml | 4 | ||||
-rw-r--r-- | erts/doc/src/erl.xml | 166 | ||||
-rw-r--r-- | erts/doc/src/erl_driver.xml | 326 | ||||
-rw-r--r--[-rwxr-xr-x] | erts/doc/src/erl_ext_fig.gif | bin | 3834 -> 3834 bytes | |||
-rw-r--r-- | erts/doc/src/erl_nif.xml | 52 | ||||
-rw-r--r-- | erts/doc/src/erl_prim_loader.xml | 88 | ||||
-rw-r--r-- | erts/doc/src/erlang.xml | 1081 | ||||
-rw-r--r-- | erts/doc/src/erlsrv.xml | 19 | ||||
-rw-r--r-- | erts/doc/src/erts_alloc.xml | 80 | ||||
-rw-r--r-- | erts/doc/src/init.xml | 67 | ||||
-rw-r--r-- | erts/doc/src/make.dep | 32 | ||||
-rw-r--r-- | erts/doc/src/match_spec.xml | 8 | ||||
-rw-r--r-- | erts/doc/src/notes.xml | 1042 | ||||
-rw-r--r-- | erts/doc/src/specs.xml | 7 | ||||
-rw-r--r-- | erts/doc/src/start_erl.xml | 31 | ||||
-rw-r--r-- | erts/doc/src/zlib.xml | 363 |
21 files changed, 2357 insertions, 1114 deletions
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index 6578923fe1..cfa5527474 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2010. All Rights Reserved. +# Copyright Ericsson AB 1997-2011. 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 @@ -16,6 +16,9 @@ # # %CopyrightEnd% # + +SPECS_ESRC = ../../preloaded/src/ + include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk @@ -43,6 +46,12 @@ XML_REF1_FILES = epmd.xml \ run_erl.xml \ start.xml +XML_REF3_EFILES = \ + erl_prim_loader.xml \ + erlang.xml \ + init.xml \ + zlib.xml + XML_REF3_FILES = \ driver_entry.xml \ erl_nif.xml \ @@ -98,18 +107,26 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf +SPECS_FILES = $(XML_REF3_EFILES:%.xml=$(SPECDIR)/specs_%.xml) + +TOP_SPECS_FILE = specs.xml + # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- XML_FLAGS += +KERNEL_SRC=$(ERL_TOP)/lib/kernel/src +KERNEL_INCLUDE=$(ERL_TOP)/lib/kernel/include +SPECS_FLAGS = -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE) + # ---------------------------------------------------- # Targets # ---------------------------------------------------- $(HTMLDIR)/%.gif: %.gif $(INSTALL_DATA) $< $@ -docs: pdf html man $(INFO_FILE) +docs: man pdf html $(INFO_FILE) $(TOP_PDF_FILE): $(XML_FILES) @@ -132,8 +149,25 @@ clean: rm -f $(MAN1DIR)/* rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) + rm -f $(SPECDIR)/* rm -f errs core *~ +$(SPECDIR)/specs_driver_entry.xml: + escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + -o$(dir $@) -module driver_entry +$(SPECDIR)/specs_erl_nif.xml: + escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + -o$(dir $@) -module erl_nif +$(SPECDIR)/specs_erl_set_memory_block.xml: + escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + -o$(dir $@) -module erl_set_memory_block +$(SPECDIR)/specs_erl_driver.xml: + escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + -o$(dir $@) -module erl_driver +$(SPECDIR)/specs_erts_alloc.xml: + escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ + -o$(dir $@) -module erts_alloc + # ---------------------------------------------------- # Release Target # ---------------------------------------------------- diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml index 4c84412dd6..4455d0ac92 100644 --- a/erts/doc/src/absform.xml +++ b/erts/doc/src/absform.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2001</year><year>2009</year> + <year>2001</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -285,7 +285,8 @@ <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> + Rep(E) = <c><![CDATA[{'fun',LINE,{function,Rep(Module),Rep(Name),Rep(Arity)}}]]></c>. + (Before the R15 release: 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> diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml index 36d83a685b..038950b54d 100644 --- a/erts/doc/src/alt_dist.xml +++ b/erts/doc/src/alt_dist.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2010</year> + <year>2000</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -377,7 +377,7 @@ ( 1) typedef enum { ( 2) portTypeUnknown, /* An uninitialized port */ ( 3) portTypeListener, /* A listening port/socket */ -( 4) portTypeAcceptor, /* An intermidiate stage when accepting +( 4) portTypeAcceptor, /* An intermediate stage when accepting ( 5) on a listen port */ ( 6) portTypeConnector, /* An intermediate stage when connecting */ ( 7) portTypeCommand, /* A connected open port in command mode */ diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml index 9f246c4a6c..52283879c7 100644 --- a/erts/doc/src/driver.xml +++ b/erts/doc/src/driver.xml @@ -30,11 +30,11 @@ </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. + interesting since it explains important concepts, but it was + written for an older driver interface so the examples do not + work anymore. The reader is encouraged to read + <seealso marker="erl_driver">erl_driver</seealso> and the + <seealso marker="driver_entry">driver_entry</seealso> documentation. </p></note> <section> diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml index 8bdd154cb9..a2efdf3ebc 100644 --- a/erts/doc/src/driver_entry.xml +++ b/erts/doc/src/driver_entry.xml @@ -34,18 +34,22 @@ <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 introduces - <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> + <p> + As of erts version 5.9 (OTP release R15B) the driver interface + has been changed with larger types for the callbacks + <seealso marker="#output">output</seealso>, + <seealso marker="#control">control</seealso> and + <seealso marker="#call">call</seealso>. + See driver <seealso marker="erl_driver#version_management"> + version management</seealso> in + <seealso marker="erl_driver">erl_driver</seealso>. + </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 do not have to use the extended interface).</p> + earlier erts version than 5.9) have to be updated and have + to use the extended interface (with + <seealso marker="erl_driver#version_management">version management + </seealso>).</p> </note> <p>The <c>driver_entry</c> structure is a C struct that all erlang drivers define. It contains entry points for the erlang driver @@ -53,7 +57,7 @@ the driver.</p> <p> <marker id="emulator"></marker> - The <seealso marker="driver_entry">erl_driver</seealso> driver + The <seealso marker="erl_driver">erl_driver</seealso> driver API functions need 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 @@ -84,7 +88,7 @@ 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 + <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 @@ -116,7 +120,7 @@ typedef struct erl_drv_entry { 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); + void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT len); /* called when we have output from erlang to the port */ void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event); @@ -130,8 +134,9 @@ typedef struct erl_drv_entry { 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); + ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen); /* "ioctl" for drivers - invoked by port_control/3 */ void (*timeout)(ErlDrvData drv_data); /* Handling of timeout in driver */ @@ -144,8 +149,9 @@ typedef struct erl_drv_entry { 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); + ErlDrvSSizeT (*call)(ErlDrvData drv_data, unsigned int command, + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen, unsigned int *flags); /* Works mostly like 'control', a synchronous call into the driver. */ void (*event)(ErlDrvData drv_data, ErlDrvEvent event, @@ -192,7 +198,7 @@ typedef struct erl_drv_entry { <c>start</c>, then <c>stop</c> is the place to deallocate that memory.</p> </item> - <tag><marker id="output"/>void (*output)(ErlDrvData drv_data, char *buf, int len)</tag> + <tag><marker id="output"/>void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT 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 @@ -243,7 +249,7 @@ typedef struct erl_drv_entry { 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> + <tag><marker id="control"></marker>ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT 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 @@ -316,7 +322,7 @@ typedef struct erl_drv_entry { 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> + <tag><marker id="call"/>ErlDrvSSizeT (*call)(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT 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 @@ -452,7 +458,7 @@ typedef struct erl_drv_entry { <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>, + <seealso marker="erlang">erlang(3)</seealso>, kernel(3)</p> </section> </cref> diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml index 411e627c85..3e7005410f 100644 --- a/erts/doc/src/epmd.xml +++ b/erts/doc/src/epmd.xml @@ -120,7 +120,7 @@ <item> <p>Let this instance of <c>epmd</c> listen only on the comma-separated list of IP addresses and on the loopback address - (which is implicitely added to the list if it has not been + (which is implicitly added to the list if it has not been specified). This can also be set using the <c><![CDATA[ERL_EPMD_ADDRESS]]></c> environment variable, see the section <seealso marker="#environment_variables">Environment @@ -243,7 +243,7 @@ <p>This environment variable may be set to a comma-separated list of IP addresses, in which case the <c>epmd</c> daemon will listen only on the specified address(es) and on the - loopback address (which is implicitely added to the list if it + loopback address (which is implicitly added to the list if it has not been specified). The default behaviour is to listen on all available IP addresses.</p> </item> diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 33a6339b04..f23e8bd9b8 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -41,25 +41,11 @@ 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> - <note><p>As of ERTS version 5.8 (OTP-R14A) the runtime system will by - default bind schedulers to logical processors using the - <c>default_bind</c> bind type if the amount of schedulers are - at least equal to the amount of logical processors configured, - binding of schedulers is supported, and a CPU topology is - available at startup. - </p><p> - If the Erlang runtime system is the only operating system - process that binds threads to logical processors, this - improves the performance of the runtime system. However, - if other operating system processes (as for example - another Erlang runtime system) also bind threads to - logical processors, there might be a performance penalty - instead. If this is the case you, are are advised to - unbind the schedulers using the - <seealso marker="#+sbt">+sbtu</seealso> command line argument, - or by invoking - <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, - unbound)</seealso>.</p> + <note><p>As of ERTS version 5.9 (OTP-R15B) the runtime system will by + default <em>not</em> bind schedulers to logical processors. + For more information see documentation of the + <seealso marker="#+sbt">+sbt</seealso> system flag. + </p> </note> </description> <funcs> @@ -587,6 +573,13 @@ <p>Enables auto load tracing, displaying info while loading code.</p> </item> + <tag><c><![CDATA[+L]]></c></tag> + <item> + <p>Don't load information about source filenames and line numbers. + This will save some memory, but exceptions will not contain + information about the filenames and line numbers. + </p> + </item> <tag><marker id="erts_alloc"><c><![CDATA[+MFlag Value]]></c></marker></tag> <item> <p>Memory allocator specific flags, see @@ -672,41 +665,66 @@ </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> + <item> + <p><c>unbound</c> - 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>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> + <item> + <p><c>no_spread</c> - Schedulers with close scheduler + identifiers will be bound as close as possible in hardware.</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> + <item> + <p><c>thread_spread</c> - Thread refers to hardware threads + (e.g. Intel's 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>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> + <item> + <p><c>processor_spread</c> - Schedulers will be spread like + <c>thread_spread</c>, but also over physical processor chips.</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> + <item> + <p><c>spread</c> - Schedulers will be spread as much as + possible.</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> + <item> + <p><c>no_node_thread_spread</c> - 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>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> + <item> + <p><c>no_node_processor_spread</c> - 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>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> + <item> + <p><c>thread_no_node_processor_spread</c> - 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>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> + <item> + <p><c>default_bind</c> - 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>Binding of schedulers is currently only supported on newer Linux, Solaris, FreeBSD, and Windows systems.</p> @@ -718,24 +736,34 @@ 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>The runtime system will by default bind schedulers to logical - processors using the <c>default_bind</c> bind type if the amount - of schedulers are at least equal to the amount of logical - processors configured, binding of schedulers is supported, - and a CPU topology is available at startup. + <p>The runtime system will by default <em>not</em> bind schedulers + to logical processors. </p> - <p><em>NOTE:</em> If the Erlang runtime system is the only operating - system process that binds threads to logical processors, this - improves the performance of the runtime system. However, if other - operating system processes (as for example another Erlang runtime - system) also bind threads to logical processors, there might be a - performance penalty instead. If this is the case you, are advised - to unbind the schedulers using the <c>+sbtu</c> command line - argument, or by invoking - <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, - unbound)</seealso>.</p> - <p>For more information, see - <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, SchedulerBindType)</seealso>. + <p><em>NOTE:</em> If the Erlang runtime system is the only operating system + process that binds threads to logical processors, this + improves the performance of the runtime system. However, + if other operating system processes (as for example + another Erlang runtime system) also bind threads to + logical processors, there might be a performance penalty + instead. In some cases this performance penalty might be + severe. If this is the case, you are advised to not + bind the schedulers.</p> + <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> + <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="erlang#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>. </p> </item> <tag><marker id="+scl"><c>+scl true|false</c></marker></tag> @@ -766,6 +794,12 @@ <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>Set a user defined CPU topology. The user defined + CPU topology will override any automatically detected + CPU topology. The CPU topology is used when + <seealso marker="#+sbt">binding schedulers to logical + processors</seealso>. + </p> <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 @@ -865,7 +899,7 @@ 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> + <seealso marker="erlang#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>.</p> </item> <tag><marker id="+sws"><c>+sws default|legacy|proposal</c></marker></tag> <item> @@ -1011,7 +1045,7 @@ 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> + <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> @@ -1034,7 +1068,7 @@ list of IP addresses, in which case the <seealso marker="epmd">epmd</seealso> daemon will listen only on the specified address(es) and on the - loopback address (which is implicitely added to the list if it + loopback address (which is implicitly added to the list if it has not been specified).</p> </item> <tag><c><![CDATA[ERL_EPMD_PORT]]></c></tag> diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index 2fb03954b6..4fd74b783e 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -37,15 +37,18 @@ <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>, + <seealso marker="#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> + <p>As of erts version 5.9 old drivers have to be recompiled + and have to use the extended interface. They also have to be + adjusted to the + <seealso marker="#rewrites_for_64_bits">64-bit capable driver interface. + </seealso> + </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 @@ -242,9 +245,9 @@ </p> </item> <tag>Adding / removing drivers</tag> - <item>A driver can add and later remove drivers.</item> + <item><p>A driver can add and later remove drivers.</p></item> <tag>Monitoring processes</tag> - <item>A driver can monitor a process that does not own a port.</item> + <item><p>A driver can monitor a process that does not own a port.</p></item> <tag><marker id="version_management">Version management</marker></tag> <item> <p>Version management is enabled for drivers that have set the @@ -268,15 +271,203 @@ 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 uses 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>The emulator will refuse to load a driver that does not use + the extended driver interface since, + to allow for 64-bit capable drivers, + incompatible type changes for the callbacks + <seealso marker="driver_entry#output">output</seealso>, + <seealso marker="driver_entry#control">control</seealso> and + <seealso marker="driver_entry#call">call</seealso> + were introduced in release R15B. A driver written + with the old types would compile with warnings and when + called return garbage sizes to the emulator causing it + to read random memory and create huge incorrect result blobs.</p> + <p>Therefore it is not enough to just recompile drivers written with + version management for pre-R15B types; the types have to be changed + in the driver suggesting other rewrites especially regarding + size variables. Investigate all warnings when recompiling!</p> + <p>Also, the API driver functions <c>driver_output*</c>, + <c>driver_vec_to_buf</c>, <c>driver_alloc/realloc*</c> + and the <c>driver_*</c> queue functions were changed to have + larger length arguments and return values. This is a + lesser problem since code that passes smaller types + will get them auto converted in the calls and as long as + the driver does not handle sizes that overflow an <c>int</c> + all will work as before.</p> + </item> + </taglist> + </section> + + <section> + <marker id="rewrites_for_64_bits"/> + <title> + REWRITES FOR 64-BIT DRIVER INTERFACE + </title> + <p> + For erts-5.9 two new integer types + <seealso marker="#ErlDrvSizeT">ErlDrvSizeT</seealso> and + <seealso marker="#ErlDrvSSizeT">ErlDrvSSizeT</seealso> + were introduced that can hold 64-bit sizes if necessary. + </p> + <p> + To not update a driver and just recompile it probably works + when building for a 32-bit machine creating a false sense of security. + Hopefully that will generate many important warnings. + But when recompiling the same driver later on for a 64-bit machine + there <em>will</em> be warnings and almost certainly crashes. + So it is a BAD idea to postpone updating the driver and + not fixing the warnings! + </p> + <p> + When recompiling with <c>gcc</c> use the <c>-Wstrict-prototypes</c> + flag to get better warnings. Try to find a similar flag if you + are using some other compiler. + </p> + <p> + Here follows a checklist for rewriting a pre erts-5.9 driver, + most important first. + </p> + <taglist> + <tag>Return types for driver callbacks</tag> + <item> + <p> + Rewrite driver callback + <c><seealso marker="driver_entry#control">control</seealso></c> + to use return type <c>ErlDrvSSizeT</c> instead of <c>int</c>. + </p> + <p> + Rewrite driver callback + <c><seealso marker="driver_entry#call">call</seealso></c> + to use return type <c>ErlDrvSSizeT</c> instead of <c>int</c>. + </p> + <note> + <p> + These changes are essential to not crash the emulator + or worse cause malfunction. + Without them a driver may return garbage in the high 32 bits + to the emulator causing it to build a huge result from random + bytes either crashing on memory allocation or succeeding with + a random result from the driver call. + </p> + </note> + </item> + <tag>Arguments to driver callbacks</tag> + <item> + <p> + Driver callback + <c><seealso marker="driver_entry#output">output</seealso></c> + now gets <c>ErlDrvSizeT</c> as 3rd argument instead + of previously <c>int</c>. + </p> + <p> + Driver callback + <c><seealso marker="driver_entry#control">control</seealso></c> + now gets <c>ErlDrvSizeT</c> as 4th and 6th arguments instead + of previously <c>int</c>. + </p> + <p> + Driver callback + <c><seealso marker="driver_entry#call">call</seealso></c> + now gets <c>ErlDrvSizeT</c> as 4th and 6th arguments instead + of previously <c>int</c>. + </p> + <p> + Sane compiler's calling conventions probably make these changes + necessary only for a driver to handle data chunks that require + 64-bit size fields (mostly larger than 2 GB since that is what + an <c>int</c> of 32 bits can hold). But it is possible to think + of non-sane calling conventions that would make the driver + callbacks mix up the arguments causing malfunction. + </p> + <note> + <p> + The argument type change is from signed to unsigned which + may cause problems for e.g. loop termination conditions or + error conditions if you just change the types all over the place. + </p> + </note> + </item> + <tag>Larger <c>size</c> field in <c>ErlIOVec</c></tag> + <item> + <p> + The <c>size</c> field in + <seealso marker="#ErlIOVec"><c>ErlIOVec</c></seealso> + has been changed to <c>ErlDrvSizeT</c> from <c>int</c>. + Check all code that use that field. + </p> + <p> + Automatic type casting probably makes these changes necessary only + for a driver that encounters sizes larger than 32 bits. + </p> + <note> + <p> + The <c>size</c> field changed from signed to unsigned which + may cause problems for e.g. loop termination conditions or + error conditions if you just change the types all over the place. + </p> + </note> + </item> + <tag>Arguments and return values in the driver API</tag> + <item> + <p> + Many driver API functions have changed argument type + and/or return value to <c>ErlDrvSizeT</c> from mostly <c>int</c>. + Automatic type casting probably makes these changes necessary only + for a driver that encounters sizes larger than 32 bits. + </p> + <taglist> + <tag><seealso marker="#driver_output">driver_output</seealso></tag> + <item>3rd argument</item> + <tag><seealso marker="#driver_output2">driver_output2</seealso></tag> + <item>3rd and 5th arguments</item> + <tag> + <seealso marker="#driver_output_binary">driver_output_binary</seealso> + </tag> + <item>3rd 5th and 6th arguments</item> + <tag><seealso marker="#driver_outputv">driver_outputv</seealso></tag> + <item>3rd and 5th arguments</item> + <tag> + <seealso marker="#driver_vec_to_buf">driver_vec_to_buf</seealso> + </tag> + <item>3rd argument and return value</item> + <tag><seealso marker="#driver_alloc">driver_alloc</seealso></tag> + <item>1st argument</item> + <tag><seealso marker="#driver_realloc">driver_realloc</seealso></tag> + <item>2nd argument</item> + <tag> + <seealso marker="#driver_alloc_binary">driver_alloc_binary</seealso> + </tag> + <item>1st argument</item> + <tag> + <seealso marker="#driver_realloc_binary">driver_realloc_binary</seealso> + </tag> + <item>2nd argument</item> + <tag><seealso marker="#driver_enq">driver_enq</seealso></tag> + <item>3rd argument</item> + <tag><seealso marker="#driver_pushq">driver_pushq</seealso></tag> + <item>3rd argument</item> + <tag><seealso marker="#driver_deq">driver_deq</seealso></tag> + <item>2nd argument and return value</item> + <tag><seealso marker="#driver_sizeq">driver_sizeq</seealso></tag> + <item>return value</item> + <tag><seealso marker="#driver_enq_bin">driver_enq_bin</seealso></tag> + <item>3rd and 4th argument</item> + <tag><seealso marker="#driver_pushq_bin">driver_pushq_bin</seealso></tag> + <item>3rd and 4th argument</item> + <tag><seealso marker="#driver_enqv">driver_enqv</seealso></tag> + <item>3rd argument</item> + <tag><seealso marker="#driver_pushqv">driver_pushqv</seealso></tag> + <item>3rd argument</item> + <tag><seealso marker="#driver_peekqv">driver_peekqv</seealso></tag> + <item>return value</item> + </taglist> + <note> + <p> + This is a change from signed to unsigned which + may cause problems for e.g. loop termination conditions and + error conditions if you just change the types all over the place. + </p> + </note> </item> </taglist> </section> @@ -285,7 +476,11 @@ <title>DATA TYPES</title> <taglist> - <tag><marker id="ErlDrvSysInfo"/>ErlDrvSysInfo</tag> + <tag><marker id="ErlDrvSizeT"/>ErlDrvSizeT</tag> + <item><p>An unsigned integer type to be used as <c>size_t</c></p></item> + <tag><marker id="ErlDrvSSizeT"/>ErlDrvSSizeT</tag> + <item><p>A signed integer type the size of <c>ErlDrvSizeT</c></p></item> + <tag><marker id="ErlDrvSysInfo"/>ErlDrvSysInfo</tag> <item> <p/> <code type="none"> @@ -332,12 +527,12 @@ typedef struct ErlDrvSysInfo { <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>). + <seealso marker="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>). + <seealso marker="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; @@ -351,12 +546,12 @@ typedef struct ErlDrvSysInfo { <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>). + <seealso marker="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>). + <seealso marker="erlang#system_info_schedulers">erlang:system_info(schedulers)</seealso>). </item> <tag><c>nif_major_version</c></tag> <item>The value of <c>ERL_NIF_MAJOR_VERSION</c> when the runtime system was compiled. @@ -371,7 +566,7 @@ typedef struct ErlDrvSysInfo { <p/> <code type="none"> typedef struct ErlDrvBinary { - int orig_size; + ErlDrvSint orig_size; char orig_bytes[]; } ErlDrvBinary; </code> @@ -423,7 +618,7 @@ typedef struct ErlDrvBinary { <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> + most often type casted to a specific pointer in the driver.</p> </item> <tag>SysIOVec</tag> <item> @@ -437,7 +632,7 @@ typedef struct ErlDrvBinary { <code type="none"> typedef struct ErlIOVec { int vsize; - int size; + ErlDrvSizeT size; SysIOVec* iov; ErlDrvBinary** binv; } ErlIOVec; @@ -630,7 +825,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_output(ErlDrvPort port, char *buf, int len)</nametext></name> + <name><ret>int</ret><nametext>driver_output(ErlDrvPort port, char *buf, ErlDrvSizeT len)</nametext></name> <fsummary>Send data from driver to port owner</fsummary> <desc> <marker id="driver_output"></marker> @@ -650,7 +845,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_output2(ErlDrvPort port, char *hbuf, int hlen, char *buf, int len)</nametext></name> + <name><ret>int</ret><nametext>driver_output2(ErlDrvPort port, char *hbuf, ErlDrvSizeT hlen, char *buf, ErlDrvSizeT len)</nametext></name> <fsummary>Send data and binary data to port owner</fsummary> <desc> <marker id="driver_output2"></marker> @@ -665,7 +860,7 @@ typedef struct ErlIOVec { </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> + <name><ret>int</ret><nametext>driver_output_binary(ErlDrvPort port, char *hbuf, ErlDrvSizeT hlen, ErlDrvBinary* bin, ErlDrvSizeT offset, ErlDrvSizeT len)</nametext></name> <fsummary>Send data from a driver binary to port owner</fsummary> <desc> <marker id="driver_output_binary"></marker> @@ -688,7 +883,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_outputv(ErlDrvPort port, char* hbuf, int hlen, ErlIOVec *ev, int skip)</nametext></name> + <name><ret>int</ret><nametext>driver_outputv(ErlDrvPort port, char* hbuf, ErlDrvSizeT hlen, ErlIOVec *ev, ErlDrvSizeT skip)</nametext></name> <fsummary>Send vectorized data to port owner</fsummary> <desc> <marker id="driver_outputv"></marker> @@ -711,7 +906,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_vec_to_buf(ErlIOVec *ev, char *buf, int len)</nametext></name> + <name><ret>ErlDrvSizeT</ret><nametext>driver_vec_to_buf(ErlIOVec *ev, char *buf, ErlDrvSizeT len)</nametext></name> <fsummary>Collect data segments into a buffer</fsummary> <desc> <marker id="driver_vec_to_buf"></marker> @@ -738,7 +933,7 @@ typedef struct ErlIOVec { <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> + function <seealso marker="driver_entry#timeout">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 is 0 (-1 only when the <c>timeout</c> driver @@ -832,7 +1027,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>void *</ret><nametext>driver_alloc(size_t size)</nametext></name> + <name><ret>void *</ret><nametext>driver_alloc(ErlDrvSizeT size)</nametext></name> <fsummary>Allocate memory</fsummary> <desc> <marker id="driver_alloc"></marker> @@ -846,7 +1041,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>void *</ret><nametext>driver_realloc(void *ptr, size_t size)</nametext></name> + <name><ret>void *</ret><nametext>driver_realloc(void *ptr, ErlDrvSizeT size)</nametext></name> <fsummary>Resize an allocated memory block</fsummary> <desc> <marker id="driver_realloc"></marker> @@ -872,7 +1067,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>ErlDrvBinary*</ret><nametext>driver_alloc_binary(int size)</nametext></name> + <name><ret>ErlDrvBinary*</ret><nametext>driver_alloc_binary(ErlDrvSizeT size)</nametext></name> <fsummary>Allocate a driver binary</fsummary> <desc> <marker id="driver_alloc_binary"></marker> @@ -892,7 +1087,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>ErlDrvBinary*</ret><nametext>driver_realloc_binary(ErlDrvBinary *bin, int size)</nametext></name> + <name><ret>ErlDrvBinary*</ret><nametext>driver_realloc_binary(ErlDrvBinary *bin, ErlDrvSizeT size)</nametext></name> <fsummary>Resize a driver binary</fsummary> <desc> <marker id="driver_realloc_binary"></marker> @@ -958,7 +1153,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_enq(ErlDrvPort port, char* buf, int len)</nametext></name> + <name><ret>int</ret><nametext>driver_enq(ErlDrvPort port, char* buf, ErlDrvSizeT len)</nametext></name> <fsummary>Enqueue data in the driver queue</fsummary> <desc> <marker id="driver_enq"></marker> @@ -982,7 +1177,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_pushq(ErlDrvPort port, char* buf, int len)</nametext></name> + <name><ret>int</ret><nametext>driver_pushq(ErlDrvPort port, char* buf, ErlDrvSizeT len)</nametext></name> <fsummary>Push data at the head of the driver queue</fsummary> <desc> <marker id="driver_pushq"></marker> @@ -997,7 +1192,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_deq(ErlDrvPort port, int size)</nametext></name> + <name><ret>ErlDrvSizeT</ret><nametext>driver_deq(ErlDrvPort port, ErlDrvSizeT size)</nametext></name> <fsummary>Dequeue data from the head of the driver queue</fsummary> <desc> <marker id="driver_deq"></marker> @@ -1013,7 +1208,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_sizeq(ErlDrvPort port)</nametext></name> + <name><ret>ErlDrvSizeT</ret><nametext>driver_sizeq(ErlDrvPort port)</nametext></name> <fsummary>Return the size of the driver queue</fsummary> <desc> <marker id="driver_sizeq"></marker> @@ -1026,7 +1221,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_enq_bin(ErlDrvPort port, ErlDrvBinary *bin, int offset, int len)</nametext></name> + <name><ret>int</ret><nametext>driver_enq_bin(ErlDrvPort port, ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len)</nametext></name> <fsummary>Enqueue binary in the driver queue</fsummary> <desc> <marker id="driver_enq_bin"></marker> @@ -1043,7 +1238,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_pushq_bin(ErlDrvPort port, ErlDrvBinary *bin, int offset, int len)</nametext></name> + <name><ret>int</ret><nametext>driver_pushq_bin(ErlDrvPort port, ErlDrvBinary *bin, ErlDrvSizeT offset, ErlDrvSizeT len)</nametext></name> <fsummary>Push binary at the head of the driver queue</fsummary> <desc> <marker id="driver_pushq_bin"></marker> @@ -1060,13 +1255,35 @@ typedef struct ErlIOVec { </desc> </func> <func> + <name><ret>ErlDrvSizeT</ret><nametext>driver_peekqv(ErlDrvPort port, ErlIOVec *ev)</nametext></name> + <fsummary>Get the driver queue as an IO vector</fsummary> + <desc> + <marker id="driver_peekqv"></marker> + <p> + This function retrieves the driver queue into a supplied + <c>ErlIOVec</c> <c>ev</c>. It also returns the queue size. + This is one of two ways to get data out of the queue. + </p> + <p> + If <c>ev</c> is <c>NULL</c> all ones i.e. <c>-1</c> type cast to + <c>ErlDrvSizeT</c> is returned. + </p> + <p>Nothing is removed from the queue by this function, that must be done + with <c>driver_deq</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>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 + elements in <c>vlen</c>. This is one of two ways to get data out of the queue.</p> <p>Nothing is removed from the queue by this function, that must be done with <c>driver_deq</c>.</p> @@ -1079,7 +1296,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_enqv(ErlDrvPort port, ErlIOVec *ev, int skip)</nametext></name> + <name><ret>int</ret><nametext>driver_enqv(ErlDrvPort port, ErlIOVec *ev, ErlDrvSizeT skip)</nametext></name> <fsummary>Enqueue vector in the driver queue</fsummary> <desc> <marker id="driver_enqv"></marker> @@ -1095,7 +1312,7 @@ typedef struct ErlIOVec { </desc> </func> <func> - <name><ret>int</ret><nametext>driver_pushqv(ErlDrvPort port, ErlIOVec *ev, int skip)</nametext></name> + <name><ret>int</ret><nametext>driver_pushqv(ErlDrvPort port, ErlIOVec *ev, ErlDrvSizeT skip)</nametext></name> <fsummary>Push vector at the head of the driver queue</fsummary> <desc> <marker id="driver_pushqv"></marker> @@ -1494,7 +1711,7 @@ ERL_DRV_EXT2TERM char *buf, ErlDrvUInt len 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="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 @@ -1638,12 +1855,19 @@ ERL_DRV_EXT2TERM char *buf, ErlDrvUInt len <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> + <p>This function used to cancel a scheduled asynchronous operation, + if it was still in the queue. It returned 1 if it succeeded, and + 0 if it failed.</p> + <p>Since it could not guarantee success, it was more or less useless. + The user had to implement synchronization of cancellation anyway. + It also unnecessarily complicated the implementation. Therefore, + as of OTP-R15B <c>driver_async_cancel()</c> is deprecated, and + scheduled for removal in OTP-R16. It will currently always fail, + and return 0.</p> + <warning><p><c>driver_async_cancel()</c> is deferred and will + be removed in the OTP-R16 release.</p> + </warning> + </desc> </func> <func> @@ -1687,7 +1911,7 @@ ERL_DRV_EXT2TERM char *buf, ErlDrvUInt len 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> + <seealso marker="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> @@ -2455,7 +2679,7 @@ ERL_DRV_EXT2TERM char *buf, ErlDrvUInt len <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> + <seealso marker="erlang">erlang(3)</seealso></p> <p>An Alternative Distribution Driver (ERTS User's Guide Ch. 3)</p> </section> diff --git a/erts/doc/src/erl_ext_fig.gif b/erts/doc/src/erl_ext_fig.gif Binary files differindex 14d6bbc871..14d6bbc871 100755..100644 --- a/erts/doc/src/erl_ext_fig.gif +++ b/erts/doc/src/erl_ext_fig.gif diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index cdce4ec0b8..5fc6508aad 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -136,9 +136,7 @@ ok then retrieved by calling <seealso marker="#enif_priv_data">enif_priv_data</seealso>.</p> <p>There is 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 also be unloaded if it is replaced - by another version of the library by a second call to - <c>erlang:load_nif/2</c> from the same module code.</p> + by the code server.</p> </description> <section> <title>FUNCTIONALITY</title> @@ -216,14 +214,14 @@ ok <p/> <code type="none"> ERL_NIF_TERM term; - MyStruct* ptr = enif_alloc_resource(my_resource_type, sizeof(MyStruct)); + MyStruct* obj = enif_alloc_resource(my_resource_type, sizeof(MyStruct)); /* initialize struct ... */ - term = enif_make_resource(env, ptr); + term = enif_make_resource(env, obj); if (keep_a_reference_of_our_own) { - /* store 'ptr' in static variable, private data or other resource object */ + /* store 'obj' in static variable, private data or other resource object */ } else { enif_release_resource(obj); @@ -308,21 +306,9 @@ ok 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> + and 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 @@ -339,6 +325,23 @@ ok called for a replaced library as a consequence of <c>reload</c>.</p> </item> + <tag><marker id="reload"/>int (*reload)(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)</tag> + <note><p>The reload mechanism is <em>deprecated</em>. It was only intended + as a development feature. Do not use it as an upgrade method for + live production systems. It might be removed in future releases. Be sure + to pass <c>reload</c> as <c>NULL</c> to <seealso marker="#ERL_NIF_INIT">ERL_NIF_INIT</seealso> + to disable it when not used.</p> + </note> + <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> + </taglist> </section> @@ -692,6 +695,10 @@ typedef enum { <fsummary>Determine if a term is an exception</fsummary> <desc><p>Return true if <c>term</c> is an exception.</p></desc> </func> + <func><name><ret>int</ret><nametext>enif_is_number(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name> + <fsummary>Determine if a term is a number (integer or float)</fsummary> + <desc><p>Return true if <c>term</c> is a number.</p></desc> + </func> <func><name><ret>int</ret><nametext>enif_is_fun(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name> <fsummary>Determine if a term is a fun</fsummary> <desc><p>Return true if <c>term</c> is a fun.</p></desc> @@ -822,6 +829,13 @@ typedef enum { <desc><p>Create an ordinary list containing the elements of array <c>arr</c> of length <c>cnt</c>. An empty list is returned if <c>cnt</c> is 0.</p></desc> </func> + <func><name><ret>int</ret><nametext>enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list)</nametext></name> + <fsummary>Create the reverse list of the list <c>term</c>.</fsummary> + <desc><p>Set <c>*list</c> to the reverse list of the list <c>term</c> and return true, + or return false if <c>term</c> is not a list. This function should only be used on + short lists as a copy will be created of the list which will not be released until after the + nif returns.</p></desc> + </func> <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_long(ErlNifEnv* env, long int i)</nametext></name> <fsummary>Create an integer term from a long int</fsummary> <desc><p>Create an integer term from a <c>long int</c>.</p></desc> diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml index ccaa9b725f..9f5b3f385b 100644 --- a/erts/doc/src/erl_prim_loader.xml +++ b/erts/doc/src/erl_prim_loader.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -55,33 +55,31 @@ <c>-loader_debug</c> are also experimental</p></warning> </description> + <datatypes> + <datatype> + <name name="host"/> + </datatype> + </datatypes> + <funcs> <func> - <name>start(Id, Loader, Hosts) -> {ok, Pid} | {error, What}</name> + <name name="start" arity="3"/> <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 + process reads the command line flags <c>-id <anno>Id</anno></c>, + <c>-loader <anno>Loader</anno></c>, and <c>-hosts <anno>Hosts</anno></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 + <p>If <c>-loader</c> is <c>inet</c>, the <c>-id <anno>Id</anno></c>, + <c>-hosts <anno>Hosts</anno></c>, and <c>-setcookie Cookie</c> flags must + also be supplied. <c><anno>Hosts</anno></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 + started on each of hosts given in <c><anno>Hosts</anno></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 @@ -90,35 +88,26 @@ </desc> </func> <func> - <name>get_file(Filename) -> {ok, Bin, FullName} | error</name> + <name name="get_file" arity="1"/> <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 + <c><anno>Filename</anno></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> + <c><anno>FullName</anno></c> is the complete name of the fetched file. + <c><anno>Bin</anno></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> + <p>The <c><anno>Filename</anno></c> can also be a file in an archive. For example + <c>$OTPROOT/lib/</c><c>mnesia-4.4.7.ez/mnesia-4.4.7/ebin/</c><c>mnesia.beam</c>. See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p> </desc> </func> <func> - <name>get_path() -> {ok, Path}</name> + <name name="get_path" arity="0"/> <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 @@ -126,35 +115,26 @@ </desc> </func> <func> - <name>list_dir(Dir) -> {ok, Filenames} | error</name> + <name name="list_dir" arity="1"/> <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 + <c>{ok, <anno>Filenames</anno>}</c> if successful. Otherwise, it returns + <c>error</c>. <c><anno>Filenames</anno></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> + <p>The <c><anno>Dir</anno></c> can also be a directory in an archive. For example + <c>$OTPROOT/lib/</c><c>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> + <name name="read_file_info" arity="1"/> <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>{ok, <anno>FileInfo</anno>}</c> if successful, otherwise + <c>error</c>. <c><anno>FileInfo</anno></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> @@ -162,18 +142,14 @@ -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> + <p>The <c><anno>Filename</anno></c> can also be a file in an archive. For example + <c>$OTPROOT/lib/</c><c>mnesia-4.4.7.ez/mnesia-4.4.7/ebin/</c><c>mnesia</c>. See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p> </desc> </func> <func> - <name>set_path(Path) -> ok</name> + <name name="set_path" arity="1"/> <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> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index f98e15cb52..0963904b83 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2011</year> + <year>1996</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -48,22 +48,24 @@ "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() + <datatypes> + <datatype> + <name><marker id="type-ext_binary">ext_binary()</marker></name> + <desc> + <p>A binary data object, structured according to + the Erlang external term format.</p> + </desc> + </datatype> + <datatype> + <name name="timestamp"></name> + <desc><p>See <seealso marker="#now/0">now/0</seealso>.</p> + </desc> + </datatype> + </datatypes> -iolist() = [char() | binary() | iolist()] - a binary is allowed as the tail of the list</code> - </section> <funcs> <func> - <name>abs(Number) -> int() | float()</name> + <name>abs(Number) -> integer() | float()</name> <fsummary>Arithmetical absolute value</fsummary> <type> <v>Number = number()</v> @@ -80,7 +82,7 @@ iolist() = [char() | binary() | iolist()] </desc> </func> <func> - <name>erlang:adler32(Data) -> int()</name> + <name>erlang:adler32(Data) -> integer()</name> <fsummary>Compute adler32 checksum</fsummary> <type> <v>Data = iodata()</v> @@ -90,10 +92,10 @@ iolist() = [char() | binary() | iolist()] </desc> </func> <func> - <name>erlang:adler32(OldAdler, Data) -> int()</name> + <name>erlang:adler32(OldAdler, Data) -> integer()</name> <fsummary>Compute adler32 checksum</fsummary> <type> - <v>OldAdler = int()</v> + <v>OldAdler = integer()</v> <v>Data = iodata()</v> </type> <desc> @@ -112,11 +114,11 @@ iolist() = [char() | binary() | iolist()] </desc> </func> <func> - <name>erlang:adler32_combine(FirstAdler, SecondAdler, SecondSize) -> int()</name> + <name>erlang:adler32_combine(FirstAdler, SecondAdler, SecondSize) -> integer()</name> <fsummary>Combine two adler32 checksums</fsummary> <type> - <v>FirstAdler = SecondAdler = int()</v> - <v>SecondSize = int()</v> + <v>FirstAdler = SecondAdler = integer()</v> + <v>SecondSize = integer()</v> </type> <desc> <p>Combines two previously computed adler32 checksums. @@ -155,20 +157,16 @@ iolist() = [char() | binary() | iolist()] </desc> </func> <func> - <name>apply(Fun, Args) -> term() | empty()</name> + <name name="apply" arity="2"/> <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 + <p>Call a fun, passing the elements in <c><anno>Args</anno></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> + <c><anno>Fun</anno>(Arg1, Arg2, ... ArgN)</c>.</p> <warning> - <p>Earlier, <c>Fun</c> could also be given as + <p>Earlier, <c><anno>Fun</anno></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 @@ -177,15 +175,11 @@ iolist() = [char() | binary() | iolist()] </desc> </func> <func> - <name>apply(Module, Function, Args) -> term() | empty()</name> + <name name="apply" arity="3"/> <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 + <c><anno>Module</anno></c> to <c><anno>Args</anno></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> @@ -198,7 +192,7 @@ iolist() = [char() | binary() | iolist()] "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> + <c><anno>Module</anno>:<anno>Function</anno>(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 @@ -221,9 +215,9 @@ iolist() = [char() | binary() | iolist()] 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 + <c>unicode</c>, the characters will be encoded using UTF-8 (meaning that characters from 16#80 up to 0xFF will be - encode in two bytes).</p> + encoded 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 @@ -258,8 +252,8 @@ iolist() = [char() | binary() | iolist()] <type> <v>Subject = binary()</v> <v>PosLen = {Start,Length}</v> - <v>Start = int()</v> - <v>Length = int()</v> + <v>Start = integer() >= 0</v> + <v>Length = integer() >= 0</v> </type> <desc> <p>Extracts the part of the binary described by <c>PosLen</c>.</p> @@ -274,7 +268,7 @@ iolist() = [char() | binary() | iolist()] <p>If <c>PosLen</c> in any way references outside the binary, a <c>badarg</c> exception is raised.</p> - <p><c>Start</c> is zero-based, i.e:</p> + <p><c>Start</c> is zero-based, i.e.:</p> <code> 1> Bin = <<1,2,3>> 2> binary_part(Bin,{0,2}). @@ -291,8 +285,8 @@ iolist() = [char() | binary() | iolist()] <fsummary>Extracts a part of a binary</fsummary> <type> <v>Subject = binary()</v> - <v>Start = int()</v> - <v>Length = int()</v> + <v>Start = integer() >= 0</v> + <v>Length = integer() >= 0</v> </type> <desc> <p>The same as <c>binary_part(Subject, {Pos, Len})</c>.</p> @@ -390,7 +384,7 @@ iolist() = [char() | binary() | iolist()] <name>binary_to_term(Binary) -> term()</name> <fsummary>Decode an Erlang external term format binary</fsummary> <type> - <v>Binary = ext_binary()</v> + <v>Binary = <seealso marker="#type-ext_binary">ext_binary()</seealso></v> </type> <desc> <p>Returns an Erlang term which is the result of decoding @@ -411,7 +405,7 @@ iolist() = [char() | binary() | iolist()] <fsummary>Decode an Erlang external term format binary</fsummary> <type> <v>Opts = [safe]</v> - <v>Binary = ext_binary()</v> + <v>Binary = <seealso marker="#type-ext_binary">ext_binary()</seealso></v> </type> <desc> <p>As <c>binary_to_term/1</c>, but takes options that affect decoding @@ -442,7 +436,7 @@ iolist() = [char() | binary() | iolist()] </desc> </func> <func> - <name>bit_size(Bitstring) -> int()</name> + <name>bit_size(Bitstring) -> integer() >= 0</name> <fsummary>Return the size of a bitstring</fsummary> <type> <v>Bitstring = bitstring()</v> @@ -461,7 +455,7 @@ iolist() = [char() | binary() | iolist()] <name>erlang:bump_reductions(Reductions) -> void()</name> <fsummary>Increment the reduction counter</fsummary> <type> - <v>Reductions = int()</v> + <v>Reductions = integer() >= 0</v> </type> <desc> <p>This implementation-dependent function increments @@ -478,7 +472,7 @@ iolist() = [char() | binary() | iolist()] </desc> </func> <func> - <name>byte_size(Bitstring) -> int()</name> + <name>byte_size(Bitstring) -> integer() >= 0</name> <fsummary>Return the size of a bitstring (or binary)</fsummary> <type> <v>Bitstring = bitstring()</v> @@ -500,7 +494,7 @@ iolist() = [char() | binary() | iolist()] <fsummary>Cancel a timer</fsummary> <type> <v>TimerRef = reference()</v> - <v>Time = int()</v> + <v>Time = integer() >= 0</v> </type> <desc> <p>Cancels a timer, where <c>TimerRef</c> was returned by @@ -524,7 +518,19 @@ iolist() = [char() | binary() | iolist()] </func> <func> - <name>check_process_code(Pid, Module) -> bool()</name> + <name>check_old_code(Module) -> boolean()</name> + <fsummary>Check if a module has old code</fsummary> + <type> + <v>Module = atom()</v> + </type> + <desc> + <p>Returns <c>true</c> if the <c>Module</c> has old code, + and <c>false</c> otherwise.</p> + <p>See also <seealso marker="kernel:code">code(3)</seealso>.</p> + </desc> + </func> + <func> + <name>check_process_code(Pid, Module) -> boolean()</name> <fsummary>Check if a process is executing old code for a module</fsummary> <type> <v>Pid = pid()</v> @@ -544,16 +550,7 @@ false</pre> </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>erlang:crc32(Data) -> int()</name> + <name>erlang:crc32(Data) -> integer() >= 0</name> <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary> <type> <v>Data = iodata()</v> @@ -563,10 +560,10 @@ false</pre> </desc> </func> <func> - <name>erlang:crc32(OldCrc, Data) -> int()</name> + <name>erlang:crc32(OldCrc, Data) -> integer() >= 0</name> <fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary> <type> - <v>OldCrc = int()</v> + <v>OldCrc = integer() >= 0</v> <v>Data = iodata()</v> </type> <desc> @@ -585,11 +582,11 @@ false</pre> </desc> </func> <func> - <name>erlang:crc32_combine(FirstCrc, SecondCrc, SecondSize) -> int()</name> + <name>erlang:crc32_combine(FirstCrc, SecondCrc, SecondSize) -> integer() >= 0</name> <fsummary>Combine two crc32 (IEEE 802.3) checksums</fsummary> <type> - <v>FirstCrc = SecondCrc = int()</v> - <v>SecondSize = int()</v> + <v>FirstCrc = SecondCrc = integer() >= 0</v> + <v>SecondSize = integer() >= 0</v> </type> <desc> <p>Combines two previously computed crc32 checksums. @@ -609,10 +606,10 @@ false</pre> </desc> </func> <func> - <name>date() -> {Year, Month, Day}</name> + <name>date() -> Date</name> <fsummary>Current date</fsummary> <type> - <v>Year = Month = Day = int()</v> + <v>Date = <seealso marker="calendar#type-date">calendar:date()</seealso></v> </type> <desc> <p>Returns the current date as <c>{Year, Month, Day}</c>.</p> @@ -631,20 +628,20 @@ false</pre> <v>Options = [Opt]</v> <v>Packet = binary() | HttpPacket</v> <v>Rest = binary()</v> - <v>Length = int() | undefined</v> + <v>Length = integer() > 0 | undefined</v> <v>Reason = term()</v> <v> 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>HttpHeader = {http_header, integer(), 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} | + <v>HttpUri = '*' | {absoluteURI, http|https, Host=HttpString, Port=integer()|undefined, Path=HttpString} | {scheme, Scheme=HttpString, HttpString} | {abs_path, HttpString} | HttpString</v> - <v>HttpVersion = {Major=int(), Minor=int()}</v> + <v>HttpVersion = {Major=integer(), Minor=integer()}</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> @@ -719,17 +716,20 @@ false</pre> </taglist> <p>The following options are available:</p> <taglist> - <tag><c>{packet_size, int()}</c></tag> + <tag><c>{packet_size, integer()}</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> + <tag><c>{line_length, integer()}</c></tag> + <item><p>For packet type <c>line</c>, truncate lines longer + than the indicated length.</p> + <p>Option <c>line_length</c> also applies to <c>http*</c> + packet types as an alias for option <c>packet_size</c> in the + case when <c>packet_size</c> itself is not set. This usage is + only intended for backward compatibility.</p> </item> </taglist> <pre> @@ -773,9 +773,9 @@ false</pre> turned off, nothing happens.</p> <p>Once <c>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 + due to the monitor will be placed in the caller's message queue in the future. A <c>{'DOWN', MonitorRef, _, _, _}</c> message - might have been placed in the callers message queue prior to + might have been placed in the caller's 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. @@ -800,13 +800,12 @@ false</pre> </desc> </func> <func> - <name>demonitor(MonitorRef, OptionList) -> true|false</name> + <name>demonitor(MonitorRef, OptionList) -> boolean()</name> <fsummary>Stop monitoring</fsummary> <type> <v>MonitorRef = reference()</v> <v>OptionList = [Option]</v> - <v>Option = flush</v> - <v>Option = info</v> + <v> Option = flush | info</v> </type> <desc> <p>The returned value is <c>true</c> unless <c>info</c> is part @@ -819,7 +818,7 @@ false</pre> <tag><c>flush</c></tag> <item> <p>Remove (one) <c>{_, MonitorRef, _, _, _}</c> message, - if there is one, from the callers message queue after + if there is one, from the caller's message queue after monitoring has been stopped.</p> <p>Calling <c>demonitor(MonitorRef, [flush])</c> is equivalent to the following, but more efficient:</p> @@ -848,7 +847,7 @@ false</pre> <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. + in the caller's message queue. </p> </item> </taglist> @@ -867,14 +866,11 @@ false</pre> </desc> </func> <func> - <name>disconnect_node(Node) -> bool() | ignored</name> + <name name="disconnect_node" arity="1"/> <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 + the node <c><anno>Node</anno></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, @@ -1032,6 +1028,56 @@ b</pre> </desc> </func> <func> + <name>erlang:external_size(Term) -> integer() >= 0</name> + <fsummary>Calculate the maximum size for a term encoded in the Erlang + external term format</fsummary> + <type> + <v>Term = term()</v> + </type> + <desc> + <p>Calculates, without doing the encoding, the maximum byte size for + a term encoded in the Erlang external term format. The following + condition applies always:</p> + <p> + <pre> +> <input>Size1 = byte_size(term_to_binary(Term)),</input> +> <input>Size2 = erlang:external_size(Term),</input> +> <input>true = Size1 =< Size2.</input> +true + </pre> + </p> + <p>This is equivalent to a call to: <code>erlang:external_size(Term, []) + </code></p> + </desc> + </func> + <func> + <name>erlang:external_size(Term, [Option]) -> integer() >= 0</name> + <fsummary>Calculate the maximum size for a term encoded in the Erlang + external term format</fsummary> + <type> + <v>Term = term()</v> + <v>Option = {minor_version, Version}</v> + </type> + <desc> + <p>Calculates, without doing the encoding, the maximum byte size for + a term encoded in the Erlang external term format. The following + condition applies always:</p> + <p> + <pre> +> <input>Size1 = byte_size(term_to_binary(Term, Options)),</input> +> <input>Size2 = erlang:external_size(Term, Options),</input> +> <input>true = Size1 =< Size2.</input> +true + </pre> + </p> + <p>The option <c>{minor_version, Version}</c> specifies how floats + are encoded. See + <seealso marker="#term_to_binary/2">term_to_binary/2</seealso> for + a more detailed description. + </p> + </desc> + </func> + <func> <name>float(Number) -> float()</name> <fsummary>Convert a number to a float</fsummary> <type> @@ -1069,15 +1115,11 @@ b</pre> </desc> </func> <func> - <name>erlang:fun_info(Fun) -> [{Item, Info}]</name> + <name name="fun_info" arity="1"/> <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 + <c><anno>Fun</anno></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> @@ -1156,11 +1198,16 @@ b</pre> </item> <tag><c>{new_uniq, Uniq}</c></tag> <item> - <p><c>Uniq</c> (a binary) is a unique value for this fun.</p> + <p><c>Uniq</c> (a binary) is a unique value for this fun. + It is calculated from the compiled code for the entire module.</p> </item> <tag><c>{uniq, Uniq}</c></tag> <item> - <p><c>Uniq</c> (an integer) is a unique value for this fun.</p> + <p><c>Uniq</c> (an integer) is a unique value for this fun. + Starting in the R15 release, this integer is calculated from + the compiled code for the entire module. Before R15, this + integer was based on only the body of the fun. + </p> </item> </taglist> </desc> @@ -1176,7 +1223,7 @@ b</pre> <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> + <c>module</c>, <c>name</c>, <c>arity</c>, <c>env</c>, or <c>type</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 @@ -1197,11 +1244,11 @@ b</pre> </desc> </func> <func> - <name>erlang:function_exported(Module, Function, Arity) -> bool()</name> + <name>erlang:function_exported(Module, Function, Arity) -> boolean()</name> <fsummary>Check if a function is exported and loaded</fsummary> <type> <v>Module = Function = atom()</v> - <v>Arity = int()</v> + <v>Arity = arity()</v> </type> <desc> <p>Returns <c>true</c> if the module <c>Module</c> is loaded @@ -1229,7 +1276,7 @@ b</pre> </desc> </func> <func> - <name>garbage_collect(Pid) -> bool()</name> + <name>garbage_collect(Pid) -> boolean()</name> <fsummary>Force an immediate garbage collection of a process</fsummary> <type> <v>Pid = pid()</v> @@ -1276,11 +1323,8 @@ b</pre> </desc> </func> <func> - <name>erlang:get_cookie() -> Cookie | nocookie</name> + <name name="get_cookie" arity="0"/> <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> @@ -1307,17 +1351,18 @@ b</pre> </desc> </func> <func> - <name>erlang:get_stacktrace() -> [{Module, Function, Arity | Args}]</name> + <name>erlang:get_stacktrace() -> [{Module, Function, Arity | Args, Location}]</name> <fsummary>Get the call stack back-trace of the last exception</fsummary> <type> <v>Module = Function = atom()</v> - <v>Arity = int()</v> + <v>Arity = arity()</v> <v>Args = [term()]</v> + <v>Location = [{atom(),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. + <c>{Module,Function,Arity,Location}</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> @@ -1327,6 +1372,25 @@ b</pre> <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><c>Location</c> is a (possibly empty) list of two-tuples that + may indicate the location in the source code of the function. + The first element is an atom that describes the type of + information in the second element. Currently the following + items may occur:</p> + <taglist> + <tag><c>file</c></tag> + <item> + <p>The second element of the tuple is a string (list of + characters) representing the filename of the source file + of the function.</p> + </item> + <tag><c>line</c></tag> + <item> + <p>The second element of the tuple is the line number + (an integer greater than zero) in the source file + where the exception occurred or the function was called.</p> + </item> + </taglist> <p>See also <seealso marker="#error/1">erlang:error/1</seealso> and <seealso marker="#error/2">erlang:error/2</seealso>.</p> @@ -1368,29 +1432,69 @@ b</pre> <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> + <p>The same as + <seealso marker="#halt/2"><c>halt(0, [])</c></seealso>.</p> <pre> > <input>halt().</input> -os_prompt%</pre> +os_prompt% </pre> </desc> </func> <func> <name>halt(Status)</name> <fsummary>Halt the Erlang runtime system</fsummary> <type> - <v>Status = int()>=0 | string()</v> + <v>Status = integer() >= 0 | string() | abort</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> + <p>The same as + <seealso marker="#halt/2"><c>halt(Status, [])</c></seealso>.</p> + <pre> +> <input>halt(17).</input> +os_prompt% <input>echo $?</input> +17 +os_prompt% </pre> + </desc> + </func> + <func> + <name>halt(Status, Options)</name> + <fsummary>Halt the Erlang runtime system</fsummary> + <type> + <v>Status = integer() >= 0 | string() | abort</v> + <v>Options = [Option]</v> + <v>Option = {flush,boolean()} | term()</v> + </type> + <desc> + <p><c>Status</c> must be a non-negative integer, a string, + or the atom <c>abort</c>. + Halts the Erlang runtime system. Has no return value. + Depending on <c>Status</c>: + </p> + <taglist> + <tag>integer()</tag> + <item>The runtime system exits with the integer value <c>Status</c> + as status code to the calling environment (operating system). + </item> + <tag>string()</tag> + <item>An erlang crash dump is produced with <c>Status</c> as slogan, + and then the runtime system exits with status code <c>1</c>. + </item> + <tag><c>abort</c></tag> + <item> + The runtime system aborts producing a core dump, if that is + enabled in the operating system. + </item> + </taglist> + <p>Note that on many platforms, only the status codes 0-255 are + supported by the operating system. + </p> + <p>For integer <c>Status</c> the Erlang runtime system closes all ports + and allows async threads to finish their operations before exiting. + To exit without such flushing use + <c>Option</c> as <c>{flush,false}</c>. + </p> + <p>For statuses <c>string()</c> and <c>abort</c> the <c>flush</c> + option is ignored and flushing is <em>not</em> done. + </p> </desc> </func> <func> @@ -1472,7 +1576,7 @@ os_prompt%</pre> <name>integer_to_list(Integer) -> string()</name> <fsummary>Text representation of an integer</fsummary> <type> - <v>Integer = int()</v> + <v>Integer = integer()</v> </type> <desc> <p>Returns a string which corresponds to the text @@ -1483,15 +1587,11 @@ os_prompt%</pre> </desc> </func> <func> - <name>integer_to_list(Integer, Base) -> string()</name> + <name name="integer_to_list" arity="2"/> <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> + representation of <c><anno>Integer</anno></c> in base <c><anno>Base</anno></c>.</p> <pre> > <input>integer_to_list(1023, 16).</input> "3FF"</pre> @@ -1518,7 +1618,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>iolist_size(Item) -> int()</name> + <name>iolist_size(Item) -> integer() >= 0</name> <fsummary>Size of an iolist</fsummary> <type> <v>Item = iolist() | binary()</v> @@ -1533,7 +1633,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_alive() -> bool()</name> + <name>is_alive() -> boolean()</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 @@ -1542,7 +1642,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_atom(Term) -> bool()</name> + <name>is_atom(Term) -> boolean()</name> <fsummary>Check whether a term is an atom</fsummary> <type> <v>Term = term()</v> @@ -1554,7 +1654,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_binary(Term) -> bool()</name> + <name>is_binary(Term) -> boolean()</name> <fsummary>Check whether a term is a binary</fsummary> <type> <v>Term = term()</v> @@ -1569,7 +1669,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_bitstring(Term) -> bool()</name> + <name>is_bitstring(Term) -> boolean()</name> <fsummary>Check whether a term is a bitstring</fsummary> <type> <v>Term = term()</v> @@ -1582,7 +1682,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_boolean(Term) -> bool()</name> + <name>is_boolean(Term) -> boolean()</name> <fsummary>Check whether a term is a boolean</fsummary> <type> <v>Term = term()</v> @@ -1595,11 +1695,11 @@ os_prompt%</pre> </desc> </func> <func> - <name>erlang:is_builtin(Module, Function, Arity) -> bool()</name> + <name>erlang:is_builtin(Module, Function, Arity) -> boolean()</name> <fsummary>Check if a function is a BIF implemented in C</fsummary> <type> <v>Module = Function = atom()</v> - <v>Arity = int()</v> + <v>Arity = arity()</v> </type> <desc> <p>Returns <c>true</c> if <c>Module:Function/Arity</c> is @@ -1608,7 +1708,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_float(Term) -> bool()</name> + <name>is_float(Term) -> boolean()</name> <fsummary>Check whether a term is a float</fsummary> <type> <v>Term = term()</v> @@ -1620,7 +1720,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_function(Term) -> bool()</name> + <name>is_function(Term) -> boolean()</name> <fsummary>Check whether a term is a fun</fsummary> <type> <v>Term = term()</v> @@ -1632,11 +1732,11 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_function(Term, Arity) -> bool()</name> + <name>is_function(Term, Arity) -> boolean()</name> <fsummary>Check whether a term is a fun with a given arity</fsummary> <type> <v>Term = term()</v> - <v>Arity = int()</v> + <v>Arity = arity()</v> </type> <desc> <p>Returns <c>true</c> if <c>Term</c> is a fun that can be @@ -1653,7 +1753,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_integer(Term) -> bool()</name> + <name>is_integer(Term) -> boolean()</name> <fsummary>Check whether a term is an integer</fsummary> <type> <v>Term = term()</v> @@ -1665,7 +1765,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_list(Term) -> bool()</name> + <name>is_list(Term) -> boolean()</name> <fsummary>Check whether a term is a list</fsummary> <type> <v>Term = term()</v> @@ -1677,7 +1777,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_number(Term) -> bool()</name> + <name>is_number(Term) -> boolean()</name> <fsummary>Check whether a term is a number</fsummary> <type> <v>Term = term()</v> @@ -1689,7 +1789,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_pid(Term) -> bool()</name> + <name>is_pid(Term) -> boolean()</name> <fsummary>Check whether a term is a pid</fsummary> <type> <v>Term = term()</v> @@ -1701,7 +1801,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_port(Term) -> bool()</name> + <name>is_port(Term) -> boolean()</name> <fsummary>Check whether a term is a port</fsummary> <type> <v>Term = term()</v> @@ -1713,7 +1813,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_process_alive(Pid) -> bool()</name> + <name>is_process_alive(Pid) -> boolean()</name> <fsummary>Check whether a process is alive</fsummary> <type> <v>Pid = pid()</v> @@ -1728,7 +1828,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_record(Term, RecordTag) -> bool()</name> + <name>is_record(Term, RecordTag) -> boolean()</name> <fsummary>Check whether a term appears to be a record</fsummary> <type> <v>Term = term()</v> @@ -1751,12 +1851,12 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_record(Term, RecordTag, Size) -> bool()</name> + <name>is_record(Term, RecordTag, Size) -> boolean()</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> + <v>Size = integer()</v> </type> <desc> <p><c>RecordTag</c> must be an atom. Returns <c>true</c> if @@ -1771,7 +1871,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_reference(Term) -> bool()</name> + <name>is_reference(Term) -> boolean()</name> <fsummary>Check whether a term is a reference</fsummary> <type> <v>Term = term()</v> @@ -1783,7 +1883,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>is_tuple(Term) -> bool()</name> + <name>is_tuple(Term) -> boolean()</name> <fsummary>Check whether a term is a tuple</fsummary> <type> <v>Term = term()</v> @@ -1795,7 +1895,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>length(List) -> int()</name> + <name>length(List) -> integer() >= 0</name> <fsummary>Length of a list</fsummary> <type> <v>List = [term()]</v> @@ -1916,7 +2016,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>list_to_integer(String) -> int()</name> + <name>list_to_integer(String) -> integer()</name> <fsummary>Convert from text representation to an integer</fsummary> <type> <v>String = string()</v> @@ -1932,19 +2032,15 @@ os_prompt%</pre> </desc> </func> <func> - <name>list_to_integer(String, Base) -> int()</name> + <name name="list_to_integer" arity="2"/> <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> + <c><anno>Base</anno></c> is <c><anno>String</anno></c>.</p> <pre> > <input>list_to_integer("3FF", 16).</input> 1023</pre> - <p>Failure: <c>badarg</c> if <c>String</c> contains a bad + <p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad representation of an integer.</p> </desc> </func> @@ -2095,12 +2191,10 @@ os_prompt%</pre> </desc> </func> <func> - <name>erlang:localtime() -> {Date, Time}</name> + <name>erlang:localtime() -> DateTime</name> <fsummary>Current local date and time</fsummary> <type> - <v>Date = {Year, Month, Day}</v> - <v>Time = {Hour, Minute, Second}</v> - <v> Year = Month = Day = Hour = Minute = Second = int()</v> + <v>DateTime = <seealso marker="calendar#type-datetime">calendar:datetime()</seealso></v> </type> <desc> <p>Returns the current local date and time @@ -2113,17 +2207,12 @@ os_prompt%</pre> </desc> </func> <func> - <name>erlang:localtime_to_universaltime({Date1, Time1}) -> {Date2, Time2}</name> + <name name="localtime_to_universaltime" arity="1"/> <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> 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> + no conversion is done and <c>{<anno>Date1</anno>, <anno>Time1</anno>}</c> is returned.</p> <pre> > <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).</input> {{1996,11,6},{13,45,17}}</pre> @@ -2135,9 +2224,8 @@ os_prompt%</pre> <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> Year = Month = Day = Hour = Minute = Second = int()</v> + <v>Date1 = Date2 = <seealso marker="calendar#type-date">calendar:date()</seealso></v> + <v>Time1 = Time2 = <seealso marker="calendar#type-time">calendar:time()</seealso></v> <v>IsDst = true | false | undefined</v> </type> <desc> @@ -2177,7 +2265,7 @@ os_prompt%</pre> <name>erlang:make_tuple(Arity, InitialValue) -> tuple()</name> <fsummary>Create a new tuple of a given arity</fsummary> <type> - <v>Arity = int()</v> + <v>Arity = arity()</v> <v>InitialValue = term()</v> </type> <desc> @@ -2192,7 +2280,7 @@ os_prompt%</pre> <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>Arity = arity()</v> <v>Default = term()</v> <v>InitList = [{Position,term()}]</v> <v>Position = integer()</v> @@ -2211,14 +2299,11 @@ os_prompt%</pre> </desc> </func> <func> - <name>max(Term1, Term2) -> Maximum</name> + <name name="max" arity="2"/> <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> + <p>Return the largest of <c><anno>Term1</anno></c> and <c><anno>Term2</anno></c>; + if the terms compare equal, <c><anno>Term1</anno></c> will be returned.</p> </desc> </func> <func> @@ -2468,18 +2553,15 @@ os_prompt%</pre> </desc> </func> <func> - <name>min(Term1, Term2) -> Minimum</name> + <name name="min" arity="2"/> <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> + <p>Return the smallest of <c><anno>Term1</anno></c> and <c><anno>Term2</anno></c>; + if the terms compare equal, <c><anno>Term1</anno></c> will be returned.</p> </desc> </func> <func> - <name>module_loaded(Module) -> bool()</name> + <name>module_loaded(Module) -> boolean()</name> <fsummary>Check if a module is loaded</fsummary> <type> <v>Module = atom()</v> @@ -2602,7 +2684,7 @@ os_prompt%</pre> <fsummary>Monitor the status of a node</fsummary> <type> <v>Node = node()</v> - <v>Flag = bool()</v> + <v>Flag = boolean()</v> </type> <desc> <p>Monitors the status of the node <c>Node</c>. If <c>Flag</c> @@ -2628,7 +2710,7 @@ os_prompt%</pre> <fsummary>Monitor the status of a node</fsummary> <type> <v>Node = node()</v> - <v>Flag = bool()</v> + <v>Flag = boolean()</v> <v>Options = [Option]</v> <v>Option = allow_passive_connect</v> </type> @@ -2711,11 +2793,8 @@ os_prompt%</pre> </desc> </func> <func> - <name>nodes() -> Nodes</name> + <name name="nodes" arity="0"/> <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> @@ -2765,11 +2844,12 @@ os_prompt%</pre> </desc> </func> <func> - <name>now() -> {MegaSecs, Secs, MicroSecs}</name> - <fsummary>Elapsed time since 00:00 GMT</fsummary> + <name>now() -> timestamp()</name> <type> - <v>MegaSecs = Secs = MicroSecs = int()</v> + <v>timestamp() = {MegaSecs, Secs, MicroSecs}</v> + <v>MegaSecs = Secs = MicroSecs = integer() >= 0</v> </type> + <fsummary>Elapsed time since 00:00 GMT</fsummary> <desc> <p>Returns the tuple <c>{MegaSecs, Secs, MicroSecs}</c> which is the elapsed time since 00:00 GMT, January 1, 1970 (zero hour) @@ -2792,12 +2872,12 @@ os_prompt%</pre> <v>PortName = {spawn, Command} | {spawn_driver, Command} | {spawn_executable, FileName} | {fd, In, Out}</v> <v> Command = string()</v> <v> FileName = [ FileNameChar ] | binary()</v> - <v> FileNameChar = int() (1..255 or any Unicode codepoint, see description)</v> - <v> In = Out = int()</v> + <v> FileNameChar = integer() (1..255 or any Unicode codepoint, see description)</v> + <v> In = Out = integer()</v> <v>PortSettings = [Opt]</v> <v> Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ ArgString ]} | {arg0, ArgString} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof</v> <v> N = 1 | 2 | 4</v> - <v> L = int()</v> + <v> L = integer()</v> <v> Dir = string()</v> <v> ArgString = [ FileNameChar ] | binary()</v> <v> Env = [{Name, Val}]</v> @@ -2829,7 +2909,7 @@ os_prompt%</pre> <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 + the shell on 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 @@ -2876,11 +2956,11 @@ os_prompt%</pre> <seealso marker="stdlib:unicode_usage">stdlib users guide </seealso> for details.</p> - <note>The characters in the name (if given as a list) + <note><p>The characters in the name (if given as a list) can only be > 255 if the Erlang VM is started in Unicode file name translation mode, otherwise the name of the executable is limited to the ISO-latin-1 - character set.</note> + character set.</p></note> <p>If the <c>Command</c> cannot be run, an error exception, with the posix error code as the reason, is @@ -2993,11 +3073,11 @@ os_prompt%</pre> Unicode translation of arguments, they can be supplied as binaries in whatever encoding is deemed appropriate.</p> - <note>The characters in the arguments (if given as a + <note><p>The characters in the arguments (if given as a list of characters) can only be > 255 if the Erlang VM is started in Unicode file name mode, otherwise the arguments are limited to the - ISO-latin-1 character set.</note> + ISO-latin-1 character set.</p></note> <p>If one, for any reason, wants to explicitly set the program name in the argument vector, the <c>arg0</c> @@ -3283,7 +3363,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>port_command(Port, Data, OptionList) -> true|false</name> + <name>port_command(Port, Data, OptionList) -> boolean()</name> <fsummary>Send data to a port</fsummary> <type> <v>Port = port() | atom()</v> @@ -3399,7 +3479,7 @@ os_prompt%</pre> <fsummary>Perform a synchronous control operation on a port</fsummary> <type> <v>Port = port() | atom()</v> - <v>Operation = int()</v> + <v>Operation = integer()</v> <v>Data = Res = iodata()</v> </type> <desc> @@ -3423,7 +3503,7 @@ os_prompt%</pre> <fsummary>Synchronous call to a port with term data</fsummary> <type> <v>Port = port() | atom()</v> - <v>Operation = int()</v> + <v>Operation = integer()</v> <v>Data = term()</v> </type> <desc> @@ -3682,12 +3762,6 @@ os_prompt%</pre> <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> > 0, call saving is made active for the process, which means that information about the <c>N</c> @@ -3858,11 +3932,26 @@ os_prompt%</pre> 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> + <tag><c>{current_function, {Module, Function, Arity}}</c></tag> <item> - <p><c>Module</c>, <c>Function</c>, <c>Args</c> is + <p><c>Module</c>, <c>Function</c>, <c>Arity</c> is the current function call of the process.</p> </item> + <tag><c>{current_location, {Module, Function, Arity, Location}}</c></tag> + <item> + <p><c>Module</c>, <c>Function</c>, <c>Arity</c> is + the current function call of the process. + <c>Location</c> is a list of two-tuples that describes the + location in the source code. + </p> + </item> + <tag><c>{current_stacktrace, Stack}</c></tag> + <item> + <p>Return the current call stack back-trace (<em>stacktrace</em>) + of the process. The stack has the same format as returned by + <seealso marker="#get_stacktrace/0">erlang:get_stacktrace/0</seealso>. + </p> + </item> <tag><c>{dictionary, Dictionary}</c></tag> <item> <p><c>Dictionary</c> is the dictionary of the process.</p> @@ -4109,7 +4198,7 @@ os_prompt%</pre> <v>Reason = term()</v> <v>Stacktrace = [{Module, Function, Arity | Args} | {Fun, Args}]</v> <v> Module = Function = atom()</v> - <v> Arity = int()</v> + <v> Arity = arity()</v> <v> Args = [term()]</v> <v> Fun = [fun()]</v> </type> @@ -4129,11 +4218,14 @@ os_prompt%</pre> 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 + 4-tuples <c>{Module, Function, Arity | Args, + Location}</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, Location}</c> tuples where <c>Fun</c> is a local fun and <c>Args</c> is an argument list.</p> + <p>The <c>Location</c> element at the end is optional. + Omitting it is equivalent to specifying an empty 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> @@ -4146,7 +4238,7 @@ os_prompt%</pre> </desc> </func> <func> - <name>erlang:read_timer(TimerRef) -> int() | false</name> + <name>erlang:read_timer(TimerRef) -> integer() >= 0 | false</name> <fsummary>Number of milliseconds remaining for a timer</fsummary> <type> <v>TimerRef = reference()</v> @@ -4262,7 +4354,7 @@ true</pre> </desc> </func> <func> - <name>round(Number) -> int()</name> + <name>round(Number) -> integer()</name> <fsummary>Return an integer by rounding a number</fsummary> <type> <v>Number = number()</v> @@ -4346,7 +4438,7 @@ true</pre> <name>erlang:send_after(Time, Dest, Msg) -> TimerRef</name> <fsummary>Start a timer</fsummary> <type> - <v>Time = int()</v> + <v>Time = integer() >= 0</v> <v> 0 <= Time <= 4294967295</v> <v>Dest = pid() | RegName </v> <v> LocalPid = pid() (of a process, alive or dead, on the local node)</v> @@ -4375,17 +4467,12 @@ true</pre> </desc> </func> <func> - <name>erlang:send_nosuspend(Dest, Msg) -> bool()</name> + <name name="send_nosuspend" arity="2"/> <fsummary>Try to send a message without ever blocking</fsummary> - <type> - <v>Dest = pid() | port() | RegName | {RegName, Node}</v> - <v> RegName = atom()</v> - <v> Node = node()</v> - <v>Msg = term()</v> - </type> + <type name="dst"/> <desc> <p>The same as - <seealso marker="#send/3">erlang:send(Dest, Msg, [nosuspend])</seealso>, but returns <c>true</c> if + <seealso marker="#send/3">erlang:send(<anno>Dest</anno>, <anno>Msg</anno>, [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 @@ -4393,7 +4480,7 @@ true</pre> (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 + <p>The same happens, if <c><anno>Dest</anno></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> @@ -4426,18 +4513,12 @@ true</pre> </desc> </func> <func> - <name>erlang:send_nosuspend(Dest, Msg, Options) -> bool()</name> + <name name="send_nosuspend" arity="3"/> <fsummary>Try to send a message without ever blocking</fsummary> - <type> - <v>Dest = pid() | port() | RegName | {RegName, Node}</v> - <v> RegName = atom()</v> - <v> Node = node()</v> - <v>Msg = term()</v> - <v>Option = noconnect</v> - </type> + <type name="dst"/> <desc> <p>The same as - <seealso marker="#send/3">erlang:send(Dest, Msg, [nosuspend | Options])</seealso>, + <seealso marker="#send/3">erlang:send(<anno>Dest</anno>, <anno>Msg</anno>, [nosuspend | <anno>Options</anno>])</seealso>, but with boolean return value.</p> <p>This function behaves like <seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2)</seealso>, @@ -4462,17 +4543,13 @@ true</pre> </desc> </func> <func> - <name>erlang:set_cookie(Node, Cookie) -> true</name> + <name name="set_cookie" arity="2"/> <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 + <p>Sets the magic cookie of <c><anno>Node</anno></c> to the atom + <c><anno>Cookie</anno></c>. If <c><anno>Node</anno></c> is the local node, the function also sets the cookie of all other unknown nodes to - <c>Cookie</c> (see + <c><anno>Cookie</anno></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> @@ -4497,7 +4574,7 @@ true</pre> </desc> </func> <func> - <name>size(Item) -> int()</name> + <name>size(Item) -> integer() >= 0</name> <fsummary>Size of a tuple or binary</fsummary> <type> <v>Item = tuple() | binary()</v> @@ -4512,28 +4589,21 @@ true</pre> </desc> </func> <func> - <name>spawn(Fun) -> pid()</name> + <name name="spawn" arity="1"/> <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 + of <c><anno>Fun</anno></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> + <name name="spawn" arity="2"/> <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. + of <c><anno>Fun</anno></c> to the empty list <c>[]</c> on <c><anno>Node</anno></c>. If + <c><anno>Node</anno></c> does not exist, a useless pid is returned. Otherwise works like <seealso marker="#spawn/3">spawn/3</seealso>.</p> </desc> @@ -4564,47 +4634,35 @@ true</pre> </desc> </func> <func> - <name>spawn(Node, Module, Function, Args) -> pid()</name> + <name name="spawn" arity="4"/> <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. + of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. If + <c><anno>Node</anno></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> + <name name="spawn_link" arity="1"/> <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 + of <c><anno>Fun</anno></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) -> pid()</name> + <name name="spawn_link" arity="2"/> <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 + of <c><anno>Fun</anno></c> to the empty list [] on <c><anno>Node</anno></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 + atomically. If <c><anno>Node</anno></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> @@ -4626,47 +4684,35 @@ true</pre> </desc> </func> <func> - <name>spawn_link(Node, Module, Function, Args) -> pid()</name> + <name name="spawn_link" arity="4"/> <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 + of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></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 + process, atomically. If <c><anno>Node</anno></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> + <name name="spawn_monitor" arity="1"/> <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 + of <c><anno>Fun</anno></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> + <name name="spawn_monitor" arity="3"/> <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 + of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c>, and the process is monitored at the same time. Returns the pid and a reference for the monitor. Otherwise works like @@ -4674,19 +4720,11 @@ true</pre> </desc> </func> <func> - <name>spawn_opt(Fun, [Option]) -> pid() | {pid(),reference()}</name> + <name name="spawn_opt" arity="2"/> <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} | {min_bin_vheap_size, VSize}</v> - <v> Level = low | normal | high</v> - <v> Number = int()</v> - <v> Size = int()</v> - <v> VSize = 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 + of <c><anno>Fun</anno></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 @@ -4695,37 +4733,19 @@ true</pre> </desc> </func> <func> - <name>spawn_opt(Node, Fun, [Option]) -> pid()</name> + <name name="spawn_opt" arity="3"/> <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} | {min_bin_vheap_size, VSize}</v> - <v> Level = low | normal | high</v> - <v> Number = int()</v> - <v> Size = int()</v> - <v> VSize = 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. + of <c><anno>Fun</anno></c> to the empty list <c>[]</c> on <c><anno>Node</anno></c>. If + <c><anno>Node</anno></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> + <name name="spawn_opt" arity="4"/> <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} | {min_bin_vheap_size, VSize}</v> - <v> Level = low | normal | high</v> - <v> Number = int()</v> - <v> Size = int()</v> - <v> VSize = int()</v> - </type> <desc> <p>Works exactly like <seealso marker="#spawn/3">spawn/3</seealso>, except that an @@ -4744,17 +4764,17 @@ true</pre> <p>Monitor the new process (just like <seealso marker="#monitor/2">monitor/2</seealso> does).</p> </item> - <tag><c>{priority, Level}</c></tag> + <tag><c>{priority, <anno>Level</anno>}</c></tag> <item> <p>Sets the priority of the new process. Equivalent to executing - <seealso marker="#process_flag_priority">process_flag(priority, Level)</seealso> in the start function of the new process, + <seealso marker="#process_flag_priority">process_flag(priority, <anno>Level</anno>)</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> + <tag><c>{fullsweep_after, <anno>Number</anno>}</c></tag> <item> <p>This option is only useful for performance tuning. In general, you should not use this option unless you @@ -4776,18 +4796,18 @@ true</pre> <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 + (Set <c><anno>Number</anno></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. + <c><anno>Number</anno></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 + by setting <c><anno>Number</anno></c> to zero. (The value may be set globally, see <seealso marker="#system_flag/2">erlang:system_flag/2</seealso>.)</p> </item> - <tag><c>{min_heap_size, Size}</c></tag> + <tag><c>{min_heap_size, <anno>Size</anno>}</c></tag> <item> <p>This option is only useful for performance tuning. In general, you should not use this option unless you @@ -4802,9 +4822,9 @@ true</pre> 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> + time with various <c><anno>Size</anno></c> values.</p> </item> - <tag><c>{min_bin_vheap_size, VSize}</c></tag> + <tag><c>{min_bin_vheap_size, <anno>VSize</anno>}</c></tag> <item> <p>This option is only useful for performance tuning. In general, you should not use this option unless you @@ -4818,29 +4838,19 @@ true</pre> Setting too high value, however, might waste memory. Therefore, it is recommended to use this option only for fine-tuning an application and to measure the execution - time with various <c>VSize</c> values.</p> + time with various <c><anno>VSize</anno></c> values.</p> </item> </taglist> </desc> </func> <func> - <name>spawn_opt(Node, Module, Function, Args, [Option]) -> pid()</name> + <name name="spawn_opt" arity="5"/> <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} | {min_bin_vheap_size, VSize}</v> - <v> Level = low | normal | high</v> - <v> Number = int()</v> - <v> Size = int()</v> - <v> VSize = 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. + of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. If + <c><anno>Node</anno></c> does not exist, a useless pid is returned. Otherwise works like <seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p> </desc> @@ -4874,7 +4884,7 @@ true</pre> <name>erlang:start_timer(Time, Dest, Msg) -> TimerRef</name> <fsummary>Start a timer</fsummary> <type> - <v>Time = int()</v> + <v>Time = integer() >= 0</v> <v> 0 <= Time <= 4294967295</v> <v>Dest = LocalPid | RegName </v> <v> LocalPid = pid() (of a process, alive or dead, on the local node)</v> @@ -4911,6 +4921,7 @@ true</pre> <v>Type, Res -- see below</v> </type> <desc> + <p>All times are in milliseconds unless otherwise specified.</p> <p>Returns information about the system as specified by <c>Type</c>:</p> <taglist> @@ -4924,15 +4935,20 @@ true</pre> <item> <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> + <note><p><c>statistics(exact_reductions)</c> is + a more expensive operation than + <seealso marker="#statistics_reductions">statistics(reductions)</seealso> + especially on an Erlang machine with SMP support.</p> + </note> </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> + <pre> +> <input>statistics(garbage_collection).</input> +{85,23961,0} +</pre> </item> <tag><c>io</c></tag> <item> @@ -4944,12 +4960,18 @@ true</pre> <tag><marker id="statistics_reductions"><c>reductions</c></marker></tag> <item> <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> + <c>{Total_Reductions, Reductions_Since_Last_Call}</c>.</p> + <note> + <p>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> + </note> + <pre> +> <input>statistics(reductions).</input> +{2046,11} +</pre> </item> <tag><c>run_queue</c></tag> <item> @@ -4962,7 +4984,74 @@ true</pre> 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> + <pre> +> <input>statistics(runtime).</input> +{1690,1620} +</pre> + </item> + <tag><marker id="statistics_scheduler_wall_time"><c>scheduler_wall_time</c></marker></tag> + <item> + <p>Returns a list of tuples with + <c>{SchedulerId, ActiveTime, TotalTime}</c>, where <c>SchedulerId</c> is an integer id of the scheduler, <c>ActiveTime</c> is + the duration the scheduler has been busy, <c>TotalTime</c> is the total time duration since + <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso> + activation. The time unit is not defined and may be subject to change + between releases, operating systems and system restarts. + <c>scheduler_wall_time</c> should only be used to calculate relative + values for scheduler-utilization. <c>ActiveTime</c> can never exceed <c>TotalTime</c>. + </p> + + <p>The definition of a busy scheduler is when it is not idle or not + scheduling (selecting) a process or port, meaning; executing process + code, executing linked-in-driver or NIF code, executing + built-in-functions or any other runtime handling, garbage collecting + or handling any other memory management. Note, a scheduler may also be + busy even if the operating system has scheduled out the scheduler + thread. + </p> + + <p> + Returns <c>undefined</c> if the system flag <seealso marker="#system_flag_scheduler_wall_time"> + scheduler_wall_time</seealso> is turned off. + </p> + + <p>The list of scheduler information is unsorted and may appear in different order + between calls. + </p> + <p>Using <c>scheduler_wall_time</c> to calculate scheduler utilization.</p> +<pre> +> <input>erlang:system_flag(scheduler_wall_time, true).</input> +false +> <input>Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input> +ok +</pre> + <p>Some time later we will take another snapshot and calculate scheduler-utilization per scheduler.</p> +<pre> +> <input>Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input> +ok +> <input>lists:map(fun({{I, A0, T0}, {I, A1, T1}}) -> + {I, (A1 - A0)/(T1 - T0)} end, lists:zip(Ts0,Ts1)).</input> +[{1,0.9743474730177548}, + {2,0.9744843782751444}, + {3,0.9995902361669045}, + {4,0.9738012596572161}, + {5,0.9717956667018103}, + {6,0.9739235846420741}, + {7,0.973237033077876}, + {8,0.9741297293248656}] +</pre> + <p>Using the same snapshots to calculate a total scheduler-utilization.</p> +<pre> +> <input>{A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) -> + {Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)), A/T.</input> +0.9769136803764825 +</pre> + + <note> + <p><c>scheduler_wall_time</c> is by default disabled. Use <c>erlang:system_flag(scheduler_wall_time, true)</c> to enable it. </p> + </note> </item> + <tag><c>wall_clock</c></tag> <item> <p>Returns @@ -4972,18 +5061,10 @@ true</pre> 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> + <name>erlang:suspend_process(Suspendee, OptList) -> boolean()</name> <fsummary>Suspend a process</fsummary> <type> <v>Suspendee = pid()</v> @@ -5083,15 +5164,12 @@ true</pre> </desc> </func> <func> - <name>erlang:suspend_process(Suspendee) -> true</name> + <name name="suspend_process" arity="1"/> <fsummary>Suspend a process</fsummary> - <type> - <v>Suspendee = pid()</v> - </type> <desc> - <p>Suspends the process identified by <c>Suspendee</c>. The + <p>Suspends the process identified by <c><anno>Suspendee</anno></c>. The same as calling - <seealso marker="#suspend_process/2">erlang:suspend_process(Suspendee, [])</seealso>. For more information see the documentation of <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>. + <seealso marker="#suspend_process/2">erlang:suspend_process(<anno>Suspendee</anno>, [])</seealso>. For more information see the documentation of <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>. </p> <warning> <p>This BIF is intended for debugging only.</p> @@ -5105,6 +5183,14 @@ true</pre> <v>Flag, Value, OldValue -- see below</v> </type> <desc> + <warning> + <p>The + <seealso marker="#system_flag_cpu_topology">cpu_topology</seealso>, + and + <seealso marker="#system_flag_scheduler_bind_type">scheduler_bind_type</seealso> + <c>Flag</c>s are <em>deprecated</em> and have been scheduled for + removal in erts-5.10/OTP-R16.</p> + </warning> <p>Sets various system properties of the Erlang node. Returns the old value of the flag.</p> <taglist> @@ -5115,6 +5201,12 @@ true</pre> </item> <tag><marker id="system_flag_cpu_topology"><c>erlang:system_flag(cpu_topology, CpuTopology)</c></marker></tag> <item> + <p><em>NOTE:</em> This argument is <em>deprecated</em> and + scheduled for removal in erts-5.10/OTP-R16. Instead of using + this argument you are advised to use the <c>erl</c> command + line argument <seealso marker="erts:erl#+sct">+sct</seealso>. + When this argument has been removed a final CPU topology to use + will be determined at emulator boot time.</p> <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> @@ -5129,15 +5221,15 @@ true</pre> 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 + the <seealso marker="erts: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>. + and the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso> + and <seealso marker="erts:erl#+sbt">+sbt</seealso> + command line flags. </p> </item> <tag><c>erlang:system_flag(fullsweep_after, Number)</c></tag> @@ -5213,6 +5305,12 @@ true</pre> </item> <tag><marker id="system_flag_scheduler_bind_type"><c>erlang:system_flag(scheduler_bind_type, How)</c></marker></tag> <item> + <p><em>NOTE:</em> This argument is <em>deprecated</em> and + scheduled for removal in erts-5.10/OTP-R16. Instead of using + this argument you are advised to use the <c>erl</c> command + line argument <seealso marker="erts:erl#+sbt">+sbt</seealso>. + When this argument has been removed a final scheduler bind type + to use will be determined at emulator boot time.</p> <p>Controls if and how schedulers are bound to logical processors.</p> <p>When <c>erlang:system_flag(scheduler_bind_type, How)</c> is @@ -5234,93 +5332,61 @@ true</pre> 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>. + the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso> command + line flag. </p> - <p>The runtime system will by default bind schedulers to logical - processors using the <c>default_bind</c> bind type if the amount - of schedulers are at least equal to the amount of logical - processors configured, binding of schedulers is supported, - and a CPU topology is available at startup. + <p>The runtime system will by default <em>not</em> bind schedulers + to logical processors. </p> <p><em>NOTE:</em> If the Erlang runtime system is the only operating system process that binds threads to logical processors, this improves the performance of the runtime system. However, if other operating system processes (as for example another Erlang runtime system) also bind threads to logical processors, there - might be a performance penalty instead. If this is the case you, - are are advised to unbind the schedulers using the - <seealso marker="erl#+sbt">+sbtu</seealso> command line argument, - or <c>erlang:system_flag(scheduler_bind_type, unbound)</c>.</p> + might be a performance penalty instead. In some cases this + performance penalty might be severe. If this is the case, you + are advised to not bind the schedulers.</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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt u</seealso>. + </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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt ns</seealso>. + </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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt ts</seealso>. + </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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt ps</seealso>. + </p></item> <tag><c>spread</c></tag> - <item> - <p>Schedulers will be spread as much as possible.</p> - </item> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt s</seealso>. + </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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt nnts</seealso>. + </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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt nnps</seealso>. + </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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt tnnps</seealso>. + </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> + <item><p>Same as the <c>erl</c> command line argument + <seealso marker="erts:erl#+sbt">+sbt db</seealso>. + </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> @@ -5339,17 +5405,25 @@ true</pre> </item> </taglist> <p>The scheduler bind type can also be set by passing - the <seealso marker="erl#+sbt">+sbt</seealso> command + the <seealso marker="erts: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>. + the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso> + and <seealso marker="erts:erl#+sct">+sct</seealso> command line + flags. </p> </item> + <tag><marker id="system_flag_scheduler_wall_time"><c>erlang:system_flag(scheduler_wall_time, Boolean)</c></marker></tag> + <item> + <p>Turns on/off scheduler wall time measurements. </p> + <p>For more information see, + <seealso marker="#statistics_scheduler_wall_time">erlang:statistics(scheduler_wall_time)</seealso>. + </p> + </item> + <tag><marker id="system_flag_schedulers_online"><c>erlang:system_flag(schedulers_online, SchedulersOnline)</c></marker></tag> <item> <p>Sets the amount of schedulers online. Valid range is @@ -5361,6 +5435,7 @@ true</pre> <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 @@ -5416,7 +5491,7 @@ true</pre> <p>Types:</p> <list type="bulleted"> <item><c>Allocator = undefined | glibc</c></item> - <item><c>Version = [int()]</c></item> + <item><c>Version = [integer()]</c></item> <item><c>Features = [atom()]</c></item> <item><c>Settings = [{Subsystem, [{Parameter, Value}]}]</c></item> <item><c>Subsystem = atom()</c></item> @@ -5548,10 +5623,12 @@ true</pre> <item> <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> + to logical processors. The CPU topology used is the + <seealso marker="erlang#system_info_cpu_topology_defined">user + defined CPU topology</seealso> if such exists; otherwise, the + <seealso marker="erlang#system_info_cpu_topology_detected">automatically + detected CPU topology</seealso> if such exists. If no CPU topology + exists, <c>undefined</c> is returned.</p> <p>Types:</p> <list type="bulleted"> <item><c>CpuTopology = LevelEntryList | undefined</c></item> @@ -5598,8 +5675,8 @@ true</pre> <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 + the <c>erl</c> <seealso marker="erts:erl#+sct">+sct</seealso> command + line flag, and the documentation of the <seealso marker="#system_info_cpu_topology">cpu_topology</seealso> argument. </p> @@ -5667,6 +5744,29 @@ true</pre> used by the runtime system. It will be on the form <seealso marker="erts:erl_driver#version_management">"<major ver>.<minor ver>"</seealso>.</p> </item> + <tag><c>dynamic_trace</c></tag> + <item> + <p>Returns an atom describing the dynamic trace framework + compiled into the virtual machine. It can currently be either + <c>dtrace</c>, <c>systemtap</c> or <c>none</c>. For a + commercial or standard build, this is always <c>none</c>, + the other return values indicate a custom configuration + (e.g. <c>./configure --with-dynamic-trace=dtrace</c>). See + the <seealso marker="runtime_tools:dyntrace">dyntrace + </seealso> manual page and the + <c>README.dtrace</c>/<c>README.systemtap</c> files in the + Erlang source code top directory for more information + about dynamic tracing.</p> + </item> + <tag><c>dynamic_trace_probes</c></tag> + <item> + <p>Returns a <c>boolean()</c> indicating if dynamic trace probes + (either dtrace or systemtap) are built into the + emulator. This can only be <c>true</c> if the virtual + machine was built for dynamic tracing + (i.e. <c>system_info(dynamic_trace)</c> returns + <c>dtrace</c> or <c>systemtap</c>).</p> + </item> <tag><c>elib_malloc</c></tag> <item> <p>This option will be removed in a future release. @@ -5677,12 +5777,12 @@ true</pre> <item> <p>Returns the value of the distribution buffer busy limit in bytes. This limit can be set on startup by passing the - <seealso marker="erl#+zdbbl">+zdbbl</seealso> command line + <seealso marker="erts:erl#+zdbbl">+zdbbl</seealso> command line flag to <c>erl</c>.</p> </item> <tag><c>fullsweep_after</c></tag> <item> - <p>Returns <c>{fullsweep_after, int()}</c> which is the + <p>Returns <c>{fullsweep_after, integer()}</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> @@ -5879,14 +5979,13 @@ true</pre> <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 + schedulers to be bound, 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 + the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso> + command line argument, and <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>. </p> </item> @@ -5909,7 +6008,8 @@ true</pre> <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>, + the <c>erl</c> <seealso marker="erts:erl#+sbt">+sbt</seealso> + command line argument, <seealso marker="#system_info_schedulers_online">erlang:system_info(schedulers_online)</seealso>. </p> </item> @@ -6013,7 +6113,7 @@ true</pre> </item> <tag><c>wordsize</c></tag> <item> - <p>Same as <c>{wordsize, internal}</c></p> + <p>Same as <c>{wordsize, internal}.</c></p> </item> <tag><c>{wordsize, internal}</c></tag> <item> @@ -6022,7 +6122,7 @@ true</pre> and on a pure 64-bit architecture 8 is returned. On a halfword 64-bit emulator, 4 is returned, as the Erlang terms are stored using a virtual wordsize of half the - systems wordsize.</p> + system's wordsize.</p> </item> <tag><c>{wordsize, external}</c></tag> <item> @@ -6050,7 +6150,7 @@ true</pre> <v> MonitorPid = pid()</v> <v> Options = [Option]</v> <v> Option = {long_gc, Time} | {large_heap, Size} | busy_port | busy_dist_port</v> - <v> Time = Size = int()</v> + <v> Time = Size = integer()</v> </type> <desc> <p>Returns the current system monitoring settings set by @@ -6084,7 +6184,7 @@ true</pre> <type> <v>MonitorPid = pid()</v> <v>Option = {long_gc, Time} | {large_heap, Size} | busy_port | busy_dist_port</v> - <v> Time = Size = int()</v> + <v> Time = Size = integer()</v> <v>MonSettings = {OldMonitorPid, [Option]}</v> <v> OldMonitorPid = pid()</v> </type> @@ -6314,7 +6414,7 @@ true</pre> <name>time() -> {Hour, Minute, Second}</name> <fsummary>Current time</fsummary> <type> - <v>Hour = Minute = Second = int()</v> + <v>Hour = Minute = Second = integer() >= 0</v> </type> <desc> <p>Returns the current time as <c>{Hour, Minute, Second}</c>.</p> @@ -6342,11 +6442,11 @@ true</pre> </desc> </func> <func> - <name>erlang:trace(PidSpec, How, FlagList) -> int()</name> + <name>erlang:trace(PidSpec, How, FlagList) -> integer() >= 0</name> <fsummary>Set trace flags for a process or processes</fsummary> <type> <v>PidSpec = pid() | existing | new | all</v> - <v>How = bool()</v> + <v>How = boolean()</v> <v>FlagList = [Flag]</v> <v> Flag -- see below</v> </type> @@ -6747,7 +6847,7 @@ true</pre> <type> <v>PidOrFunc = pid() | new | {Module, Function, Arity} | on_load</v> <v> Module = Function = atom()</v> - <v> Arity = int()</v> + <v> Arity = arity()</v> <v>Item, Res -- see below</v> </type> <desc> @@ -6850,7 +6950,7 @@ true</pre> </desc> </func> <func> - <name>erlang:trace_pattern(MFA, MatchSpec) -> int()</name> + <name>erlang:trace_pattern(MFA, MatchSpec) -> integer() >= 0</name> <fsummary>Set trace patterns for global call tracing</fsummary> <desc> <p>The same as @@ -6859,7 +6959,7 @@ true</pre> </desc> </func> <func> - <name>erlang:trace_pattern(MFA, MatchSpec, FlagList) -> int()</name> + <name>erlang:trace_pattern(MFA, MatchSpec, FlagList) -> integer() >= 0</name> <fsummary>Set trace patterns for tracing of function calls</fsummary> <type> <v>MFA, MatchSpec, FlagList -- see below</v> @@ -7039,7 +7139,7 @@ true</pre> </desc> </func> <func> - <name>trunc(Number) -> int()</name> + <name>trunc(Number) -> integer()</name> <fsummary>Return an integer by the truncating a number</fsummary> <type> <v>Number = number()</v> @@ -7053,7 +7153,7 @@ true</pre> </desc> </func> <func> - <name>tuple_size(Tuple) -> int()</name> + <name>tuple_size(Tuple) -> integer() >= 0</name> <fsummary>Return the size of a tuple</fsummary> <type> <v>Tuple = tuple()</v> @@ -7081,12 +7181,10 @@ true</pre> </desc> </func> <func> - <name>erlang:universaltime() -> {Date, Time}</name> + <name>erlang:universaltime() -> DateTime</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> Year = Month = Day = Hour = Minute = Second = int()</v> + <v>DateTime = <seealso marker="calendar#type-datetime">calendar:datetime()</seealso></v> </type> <desc> <p>Returns the current date and time according to Universal @@ -7104,9 +7202,8 @@ true</pre> <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> Year = Month = Day = Hour = Minute = Second = int()</v> + <v>Date1 = Date2 = <seealso marker="calendar#type-date">calendar:date()</seealso></v> + <v>Time1 = Time2 = <seealso marker="calendar#type-time">calendar:time()</seealso></v> </type> <desc> <p>Converts Universal Time Coordinated (UTC) date and time to @@ -7136,7 +7233,7 @@ true</pre> <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, + been placed in the caller's 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 @@ -7193,7 +7290,7 @@ true</pre> </desc> </func> <func> - <name>erlang:yield() -> true</name> + <name name="yield" arity="0"/> <fsummary>Let other processes get a chance to execute</fsummary> <desc> <p>Voluntarily let other processes (if any) get a chance to diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml index 0dfad2a112..c1ecbc7b77 100644 --- a/erts/doc/src/erlsrv.xml +++ b/erts/doc/src/erlsrv.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1998</year><year>2010</year> + <year>1998</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -273,7 +273,7 @@ </desc> </func> <func> - <name>erlsrv {start | stop | disable | enable} <service-name></name> + <name>erlsrv {start | start_disabled | stop | disable | enable} <service-name></name> <fsummary>Manipulate the current service status.</fsummary> <desc> <p>These commands are only added for convenience, the normal @@ -287,6 +287,21 @@ 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> + + <p>The <c>start_disabled</c> command operates on a service + regardless of if it's enabled/disabled or started/stopped. It + does this by first enabling it (regardless of if it's enabled + or not), then starting it (if it's not already started) and + then disabling it. The result will be a disabled but started + service, regardless of its earlier state. This is useful for + starting services temporarily during a release upgrade. The + difference between using <c>start_disabled</c> and the + sequence <c>enable</c>, <c>start</c> and <c>disable</c> is + that all other <c>erlsrv</c> commands are locked out during + the sequence of operations in <c>start_disable</c>, making the + operation atomic from an <c>erlsrv</c> user's point of + view.</p> + </desc> </func> <func> diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml index 452e5d990e..ec5e7d9b74 100644 --- a/erts/doc/src/erts_alloc.xml +++ b/erts/doc/src/erts_alloc.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2002</year><year>2010</year> + <year>2002</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -58,11 +58,8 @@ <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> + <item>A fast allocator used for some frequently used + fixed size data types.</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> @@ -83,7 +80,7 @@ where only small blocks are placed. Currently this allocator is disabled by default.</item> </taglist> - <p><c>sys_alloc</c> and <c>fix_alloc</c> are always enabled and + <p><c>sys_alloc</c> is 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>. @@ -104,7 +101,7 @@ <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 + implementing allocators. <c>sys_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 @@ -126,9 +123,8 @@ 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 + <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>), @@ -157,9 +153,8 @@ <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 + <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> @@ -180,6 +175,14 @@ used. The time complexity is proportional to log N, where N is the number of free blocks.</p> </item> + <tag>Address order first fit</tag> + <item> + <p>Strategy: Find the block with the lowest address 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 free blocks.</p> + </item> <tag>Good fit</tag> <item> <p>Strategy: Try to find the best fit, but settle for the best fit @@ -206,6 +209,14 @@ This since it will only cause problems for other allocators.</p> </item> </taglist> + <p>Apart from the ordinary allocators described above a number of + pre-allocators are used for some specific data types. These + pre-allocators pre-allocate a fixed amount of memory for certain data + types when the run-time system starts. As long as pre-allocated memory + is available, it will be used. When no pre-allocated memory is + available, memory will be allocated in ordinary allocators. These + pre-allocators are typically much faster than the ordinary allocators, + but can only satisfy a limited amount of requests.</p> </section> <note><p> @@ -266,18 +277,6 @@ 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><marker id="MMcci"><c><![CDATA[+MMcci <time>]]></c></marker></tag> - <item> - 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><marker id="MFe"><c>+MFe true</c></marker></tag> - <item> - 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> @@ -316,15 +315,15 @@ 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 + <c>F</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><marker id="M_as"><c><![CDATA[+M<S>as bf|aobf|gf|af]]></c></marker></tag> + <tag><marker id="M_as"><c><![CDATA[+M<S>as bf|aobf|aoff|gf|af]]></c></marker></tag> <item> 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 + <c>aobf</c> (address order best fit), <c>aoff</c> (address order first 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><marker id="M_asbcst"><c><![CDATA[+M<S>asbcst <size>]]></c></marker></tag> <item> @@ -435,26 +434,23 @@ 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><marker id="M_t"><c><![CDATA[+M<S>t true|false|<amount>]]></c></marker></tag> + <tag><marker id="M_t"><c><![CDATA[+M<S>t true|false]]></c></marker></tag> <item> - Multiple, thread specific instances of the allocator. + <p>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): + SMP support:</p> <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> + <item><c>NoSchedulers+1</c> instances. Each scheduler will use + a lock-free instance of its own and other threads will use + a common instance.</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>. + <p>It was previously (before ERTS version 5.9) possible to configure + a smaller amount of thread specific instances than schedulers. + This is, however, not possible any more.</p> </item> </taglist> <p>Currently the following flags are available for configuration of diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml index b0d0cda4fa..d5c43f6e57 100644 --- a/erts/doc/src/init.xml +++ b/erts/doc/src/init.xml @@ -47,15 +47,12 @@ </description> <funcs> <func> - <name>boot(BootArgs) -> void()</name> + <name name="boot" arity="1"/> <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 + <p><c><anno>BootArgs</anno></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 @@ -67,17 +64,12 @@ </desc> </func> <func> - <name>get_argument(Flag) -> {ok, Arg} | error</name> + <name name="get_argument" arity="1"/> <fsummary>Get the values associated with a command line user flag</fsummary> - <type> - <v>Flag = atom()</v> - <v>Arg = [Values]</v> - <v> 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> + <c><anno>Flag</anno></c>. If <c><anno>Flag</anno></c> is provided several times, each + <c><anno>Values</anno></c> is returned in preserved order.</p> <pre> % <input>erl -a b c -a d</input> ... @@ -113,48 +105,37 @@ </desc> </func> <func> - <name>get_arguments() -> Flags</name> + <name name="get_arguments" arity="0"/> <fsummary>Get all command line user flags</fsummary> - <type> - <v>Flags = [{Flag, Values}]</v> - <v> Flag = atom()</v> - <v> 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> + <name name="get_plain_arguments" arity="0"/> <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> + <name name="get_status" arity="0"/> <fsummary>Get system status information</fsummary> - <type> - <v>InternalStatus = starting | started | stopping</v> - <v>ProvidedStatus = term()</v> - </type> + <type name="internal_status"/> <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 + <c><anno>InternalStatus</anno></c> is <c>starting</c>, and + <c><anno>ProvidedStatus</anno></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> + interpreted in the boot script affects <c><anno>ProvidedStatus</anno></c>, + that is, <c><anno>ProvidedStatus</anno></c> gets the value of <c>Info</c>.</p> </desc> </func> <func> - <name>reboot() -> void()</name> + <name name="reboot" arity="0"/> <fsummary>Take down and restart an Erlang node smoothly</fsummary> <desc> <p>All applications are taken down smoothly, all code is @@ -168,7 +149,7 @@ </desc> </func> <func> - <name>restart() -> void()</name> + <name name="restart" arity="0"/> <fsummary>Restart the running Erlang node</fsummary> <desc> <p>The system is restarted <em>inside</em> the running Erlang @@ -183,20 +164,17 @@ </desc> </func> <func> - <name>script_id() -> Id</name> + <name name="script_id" arity="0"/> <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><anno>Id</anno></c> can be any Erlang term. In the delivered boot + scripts, <c><anno>Id</anno></c> is <c>{Name, Vsn}</c>. <c>Name</c> and <c>Vsn</c> are strings.</p> </desc> </func> <func> - <name>stop() -> void()</name> + <name name="stop" arity="0"/> <fsummary>Take down an Erlang node smoothly</fsummary> <desc> <p>All applications are taken down smoothly, all code is @@ -210,15 +188,12 @@ </desc> </func> <func> - <name>stop(Status) -> void()</name> + <name name="stop" arity="1"/> <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 + terminates by calling <c>halt(<anno>Status</anno>)</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 diff --git a/erts/doc/src/make.dep b/erts/doc/src/make.dep deleted file mode 100644 index 98bac78235..0000000000 --- a/erts/doc/src/make.dep +++ /dev/null @@ -1,32 +0,0 @@ -# ---------------------------------------------------- -# >>>> 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 index f0390c9db8..bdcf9c3816 100644 --- a/erts/doc/src/match_spec.xml +++ b/erts/doc/src/match_spec.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1999</year><year>2010</year> + <year>1999</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -75,7 +75,7 @@ <item>MatchCondition ::= { GuardFunction } | { GuardFunction, ConditionExpression, ... } </item> - <item>BoolFunction ::= <c><![CDATA[is_atom]]></c> | <c><![CDATA[is_constant]]></c> | + <item>BoolFunction ::= <c><![CDATA[is_atom]]></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> | @@ -133,7 +133,7 @@ <item>MatchCondition ::= { GuardFunction } | { GuardFunction, ConditionExpression, ... } </item> - <item>BoolFunction ::= <c><![CDATA[is_atom]]></c> | <c><![CDATA[is_constant]]></c> | + <item>BoolFunction ::= <c><![CDATA[is_atom]]></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> | @@ -172,7 +172,7 @@ <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 + <p><em>is_atom, 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 diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 2e6aca2951..028a2bbf3d 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -30,29 +30,985 @@ </header> <p>This document describes the changes made to the ERTS application.</p> -<section><title>Erts 5.8.4.1</title> +<section><title>Erts 5.9.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> + <p><c>erlang:system_profile</c> errorneous profiled the + profiler process when observing runnable processes. This + has been corrected. </p> <p> - Fix bug in tracing with matchspec body containing - <c>enable_trace</c> or <c>disable_trace</c>. Could cause - emulator crash if trace was altered with - erlang:trace_pattern by racing process during ongoing - tracing.</p> + Own Id: OTP-9849</p> + </item> + <item> + <p>Calling trace_info/2 asking for information about a + function that had native could could crash the run-time + system.</p> + <p> + Own Id: OTP-9886</p> + </item> + <item> + <p> + reduce smp locking time range in erts_garbage_collect + (thanks to Jovi Zhang)</p> + <p> + Own Id: OTP-9912</p> + </item> + <item> + <p> + Fix typo in supervisor behaviour doc (Thanks to Ricardo + Catalinas Jim�nez)</p> + <p> + Own Id: OTP-9924</p> + </item> + <item> + <p> + Correct spelling of registered (Thanks to Richard + Carlsson)</p> + <p> + Own Id: OTP-9925</p> + </item> + <item> + <p> + erts: Remove unused variable (Thanks to Jovi Zhang)</p> + <p> + Own Id: OTP-9926</p> + </item> + <item> + <p> + Fix bug in ETS with <c>compressed</c> option and + insertion of term containing large integers (>2G) on + 64-bit machines. Seen to cause emulator crash. (Thanks to + Diego Llarrull for excellent bug report)</p> + <p> + Own Id: OTP-9932</p> + </item> + <item> + <p> + Handle Linux OS where /sys/devices/system/node is only + readable by root. Fallback to /sys/devices/system/cpu for + topology info.</p> + <p> + Own Id: OTP-9978</p> + </item> + <item> + <p> When an escript ends now all printout to standard + output and standard error gets out on the terminal. This + bug has been corrected by changing the behaviour of + erlang:halt/0,1, which should fix the same problem for + other escript-like applications, i.e that data stored in + the output port driver buffers got lost when printing on + a TTY and exiting through erlang:halt/0,1. </p> + <p> The BIF:s erlang:halt/0,1 has gotten improved + semantics and there is a new BIF erlang:halt/2 to + accomplish something like the old semantics. See the + documentation. </p> + <p> Now erlang:halt/0 and erlang:halt/1 with an integer + argument will close all ports and allow all pending async + threads operations to finish before exiting the emulator. + Previously erlang:halt/0 and erlang:halt(0) would just + wait for pending async threads operations but not close + ports. And erlang:halt/1 with a non-zero integer argument + would not even wait for pending async threads operations. + </p> + <p> To roughly the old behaviour, to not wait for ports + and async threads operations when you exit the emulator, + you use erlang:halt/2 with an integer first argument and + an option list containing {flush,false} as the second + argument. Note that now is flushing not dependant of the + exit code, and you can not only flush async threads + operations which we deemed as a strange behaviour anyway. + </p> + <p>Also, erlang:halt/1,2 has gotten a new feature: If the + first argument is the atom 'abort' the emulator is + aborted producing a core dump, if the operating system so + allows. </p> + <p> + Own Id: OTP-9985</p> + </item> + <item> + <p> + Added check to inet driver to avoid building on operating + systems that do not yet have IPv6 compatible socket API. + (Thanks to Peer Stritzinger)</p> + <p> + Own Id: OTP-9996</p> + </item> + <item> + <p> + Fix bug when the number of CPUs actually found is lower + than the configured value. (Thanks to Benjamin + Herrenschmidt)</p> + <p> + Own Id: OTP-10004</p> + </item> + <item> + <p> + The runtime system without SMP support and without thread + support erroneously busy waited when no work was present. + This bug first appeared in <c>erts-5.9</c>.</p> + <p> + Own Id: OTP-10019</p> + </item> + <item> + <p> + Various typographical errors corrected in documentation + for common_test, driver, erl_driver and windows + installation instructions. (Thanks to Tuncer Ayaz)</p> + <p> + Own Id: OTP-10037</p> + </item> + <item> + <p> + Fix memory leak caused by race on exiting process</p> + <p> + Own Id: OTP-10041</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Add <c>erlang:statistics(scheduler_wall_time)</c> to + ensure correct determination of scheduler utilization. + Measuring scheduler utilization is strongly preferred + over CPU utilization, since CPU utilization gives very + poor indications of actual scheduler/vm usage.</p> + <p> + Own Id: OTP-9858</p> + </item> + <item> + <p> + ERTS internal API improvements. In some cases the amount + of atomic read operations needed have been reduced due to + this.</p> + <p> + Own Id: OTP-9922</p> + </item> + <item> + <p> + The DTrace source patch from Scott Lystig Fritchie is + integrated in the source tree. Using an emulator with + dtrace probe is still not supported for production use, + but may be a valuable debugging tool. Configure with + --with-dynamic-trace=dtrace (or + --with-dynamic-trace=systemtap) to create a build with + dtrace probes enabled. See runtime_tools for + documentation and examples.</p> + <p> + Own Id: OTP-10017</p> + </item> + </list> + </section> + + + <section><title>Known Bugs and Problems</title> + <list> + <item> + <p> + enif_make_copy may invalidate enif_inspect_binary.</p> + <p> + Own Id: OTP-9828</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 5.9.0.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A feature test for the <c>lwsync</c> instruction + performed on PowerPC hardware at runtime system startup + got into an eternal loop if the instruction was not + supported. This bug was introduced in erts-5.9/OTP-R15B.</p> + <p> + Own Id: OTP-9843</p> + </item> + <item> + <p> + I/O events could potentially be delayed for ever when + enabling kernel-poll on a non-SMP runtime system + executing on Solaris. When also combined with + async-threads the runtime system hung before completing + the boot phase. This bug was introduced in + erts-5.9/OTP-R15B.</p> + <p> + Own Id: OTP-9844</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 5.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Honor option <c>packet_size</c> for http packet parsing + by both TCP socket and <c>erlang:decode_packet</c>. This + gives the ability to accept HTTP headers larger than the + default setting, but also avoid DoS attacks by accepting + lines only up to whatever length you wish to allow. For + consistency, packet type <c>line</c> also honor option + <c>packet_size</c>. (Thanks to Steve Vinoski)</p> + <p> + Own Id: OTP-9389</p> + </item> + <item> + <p> A few contracts in the <c>lists</c> module have been + corrected. </p> + <p> + Own Id: OTP-9616</p> + </item> + <item> + <p> + The Unicode noncharacter code points 16#FFFE and 16#FFFE + were not allowed to be encoded or decoded using the + <c>unicode</c> module or bit syntax. That was + inconsistent with the other noncharacters 16#FDD0 to + 16#FDEF that could be encoded/decoded. To resolve the + inconsistency, 16#FFFE and 16#FFFE can now be encoded and + decoded. (Thanks to Alisdair Sullivan.)</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9624</p> + </item> + <item> + <p> + Make epp search directory of current file first when + including another file This completes a partial fix in + R11 that only worked for include_lib(). (Thanks to + Richard Carlsson)</p> + <p> + Own Id: OTP-9645</p> + </item> + <item> + <p> + Fixed memory leak in + <c>enif_inspect_io_list_as_binary</c> when applied on a + process independent environment.</p> + <p> + Own Id: OTP-9668</p> + </item> + <item> + <p>The number of beam catches allowed in code are no + longer statically defined and will grow according to its + need.</p> + <p> + Own Id: OTP-9692</p> + </item> + <item> + <p> + Add missing parenthesis in heart doc.</p> + <p> + Add missing spaces in the Reference Manual distributed + section.</p> + <p> + In the HTML version of the doc those spaces are necessary + to separate those words.</p> + <p> + Own Id: OTP-9693</p> + </item> + <item> + <p> + Fixes module erlang doc style: option description (Thanks + to Ricardo Catalinas Jim�nez)</p> + <p> + Own Id: OTP-9697</p> + </item> + <item> + <p> + Specifying a scope to binary:match/3 when using multiple + searchstrings resulted in faulty return values. This is + now corrected.</p> + <p> + Own Id: OTP-9701</p> + </item> + <item> + <p> + The runtime system crashed if more than one thread tried + to exit the runtime system at the same time.</p> + <p> + Own Id: OTP-9705</p> + </item> + <item> + <p> + Fix documentation for erlang:process_flag/2</p> + <p> + For the subsection about process_flag(save_calls, N) + there's an unrelated paragraph about process priorities + which was copied from the preceeding subsection regarding + process_flag(priority, Level). (Thanks to Filipe David + Manana)</p> + <p> + Own Id: OTP-9714</p> + </item> + <item> + <p> + Calls to <c>erlang:system_flag(schedulers_online, N)</c> + and/or <c>erlang:system_flag(multi_scheduling, + block|unblock)</c> could cause internal data used by this + functionality to get into an inconsistent state. When + this happened various problems occurred. This bug was + quite hard to trigger, so hopefully no-one has been + effected by it.</p> + <p> + A spinlock used by the run-queue management sometimes got + heavily contended. This code has now been rewritten, and + the spinlock has been removed.</p> + <p> + Own Id: OTP-9727</p> + </item> + <item> + <p> + Use libdlpi to get physical address (Thanks to Trond + Norbye)</p> + <p> + Own Id: OTP-9818</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> An option list argument can now be passed to + <c>file:read_file_info/2, file:read_link_info/2</c> and + <c>file:write_file_info/3</c> and set time type + information in the call. Valid options are <c>{time, + local}, {time, universal}</c> and <c>{time, posix}</c>. + In the case of <c>posix</c> time no conversions are made + which makes the operation a bit faster. </p> + <p> + Own Id: OTP-7687</p> + </item> + <item> + <p>A number of memory allocation optimizations have been + implemented. Most optimizations reduce contention caused + by synchronization between threads during allocation and + deallocation of memory. Most notably:</p> <list> <item> + Synchronization of memory management in scheduler + specific allocator instances has been rewritten to use + lock-free synchronization. </item> <item> Synchronization + of memory management in scheduler specific pre-allocators + has been rewritten to use lock-free synchronization. + </item> <item> The 'mseg_alloc' memory segment allocator + now use scheduler specific instances instead of one + instance. Apart from reducing contention this also + ensures that memory allocators always create memory + segments on the local NUMA node on a NUMA system. </item> + </list> + <p> + Own Id: OTP-7775</p> + </item> + <item> + <p> + The ethread atomic memory operations API used by the + runtime system has been extended and improved.</p> + <p> + The ethread library now also performs runtime tests for + presence of hardware features, such as for example SSE2 + instructions, instead of requiring this to be determined + at compile time.</p> + <p> + All uses of the old deprecated atomic API in the runtime + system have been replaced with the use of the new atomic + API. In a lot of places this change imply a relaxation of + memory barriers used.</p> + <p> + Own Id: OTP-9014</p> + </item> + <item> + <p>gen_sctp:open/0-2 may now return + {error,eprotonosupport} if SCTP is not supported</p> + <p>gen_sctp:peeloff/1 has been implemented and creates a + one-to-one socket which also are supported now</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9239</p> + </item> + <item> + <p> + Sendfile has been added to the file module's API. + sendfile/2 is used to read data from a file and send it + to a tcp socket using a zero copying mechanism if + available on that OS.</p> + <p> + Thanks to Tuncer Ayaz and Steve Vinovski for original + implementation</p> + <p> + Own Id: OTP-9240</p> + </item> + <item> + <p> + enif_get_reverse_list function added to nif API. This + function should be used to reverse small lists which are + deep within other structures making it impractical to do + the reverse in Erlang.</p> + <p> + Own Id: OTP-9392</p> + </item> + <item> + <p> + The deprecated concat_binary/1 BIF has been removed. Use + <c>list_to_binary</c> or <c>iolist_to_binary/1</c> + instead.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9421</p> + </item> + <item> + <p>Erlang/OTP can now be built using parallel make if you + limit the number of jobs, for instance using '<c>make + -j6</c>' or '<c>make -j10</c>'. '<c>make -j</c>' does not + work at the moment because of some missing + dependencies.</p> + <p> + Own Id: OTP-9451</p> + </item> + <item> + <p>Line number and filename information are now included + in exception backtraces as a fourth element in the MFA + tuple. The information will be pretty-printed by the + shell and used by <c>common_test</c> to provide better + indication of where a test case.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9468</p> + </item> + <item> + <p>All binary constants used to be handled as heap + binaries (i.e. the entire binary would be copied when + sent to another process). Binary constants larger than 64 + bytes are now refc binaries (i.e. the actual data in the + binary will not be copied when sent to another + process).</p> + <p> + Own Id: OTP-9486</p> + </item> + <item> + <p> + If a float and an integer is compared, the integer is + only converted to a float if the float datatype can + contain it. Otherwise the float is converted to an + integer.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9497</p> + </item> + <item> + <p> + Add NIF function enif_is_number</p> + <p> + This function allows for easily determining if a term + represents or not a number (integer, float, small or + big).(Thanks to Filipe David Manana)</p> + <p> + Own Id: OTP-9629</p> + </item> + <item> + <p> + The ERTS internal system block functionality has been + replaced by new functionality for blocking the system. + The old system block functionality had contention issues + and complexity issues. The new functionality piggy-backs + on thread progress tracking functionality needed by newly + introduced lock-free synchronization in the runtime + system. When the functionality for blocking the system + isn't used, there is more or less no overhead at all. + This since the functionality for tracking thread progress + is there and needed anyway.</p> + <p> + Own Id: OTP-9631</p> + </item> + <item> + <p> + An ERTS internal, generic, many to one, lock-free queue + for communication between threads has been introduced. + The many to one scenario is very common in ERTS, so it + can be used in a lot of places in the future. Currently + it is used by scheduling of certain jobs, and the async + thread pool, but more uses are planned for the future.</p> + <p> + Drivers using the driver_async functionality are not + automatically locked to the system anymore, and can be + unloaded as any dynamically linked in driver.</p> + <p> + Scheduling of ready async jobs is now also interleaved in + between other jobs. Previously all ready async jobs were + performed at once.</p> + <p> + Own Id: OTP-9632</p> + </item> + <item> <p> - Own Id: OTP-9422 Aux Id: seq11868 </p> + Tuple funs (a two-element tuple with a module name and a + function) are now officially deprecated and will be + removed in R16. Use '<c>fun M:F/A</c>' instead. To make + you aware that your system uses tuple funs, the very + first time a tuple fun is applied, a warning will be sent + to the error logger.</p> + <p> + Own Id: OTP-9649</p> + </item> + <item> + <p> + Changed the internal BIF calling convention. Will make + simpler faster code and allow BIFs with an arbitrary + arity.</p> + <p> + Own Id: OTP-9662</p> + </item> + <item> + <p> + Windows native critical sections are now used internally + in the runtime system on Windows as mutex implementation. + This since they perform better under extreme contention + than our own implementation.</p> + <p> + Own Id: OTP-9671</p> + </item> + <item> + <p> + Convert some erl_nif macros into inline functions. Allow + for better compile time type checking. (Thanks to Tuncer + Ayaz)</p> + <p> + Own Id: OTP-9675</p> + </item> + <item> + <p> + The <c>+scl</c> command line flag has been added. It can + be used for disabling compaction of scheduler load. For + more information see the <c>erl(1)</c> documentation.</p> + <p> + Own Id: OTP-9695</p> + </item> + <item> + <p>The build system has been updated so that Erlang/OTP + can be built on Mac OS X Lion systems without a GCC + compiler. The INSTALL guide has been updated with + instructions on how to install a GCC compiler and build + Erlang/OTP with it, in order to get a run-time system + with better performance.</p> + <p> + Own Id: OTP-9712</p> + </item> + <item> + <p> + When loading a module, the system use to run on a single + scheduler during the entire loading process. This has + been changed to only take down the system just before + inserting the loaded code into the system tables, + resulting in a much shorter disruption if a module is + loaded in a busy system. (Suggested by Bob Ippolito.)</p> + <p> + Own Id: OTP-9720</p> + </item> + <item> + <p> + Possible to run HiPE without floating point exceptions + (FPE). Useful on platforms that lack reliable FPE. Slower + float operations compared to HiPE with FPE.</p> + <p> + Own Id: OTP-9724</p> + </item> + <item> + <p> + As of ERTS version 5.9 (OTP-R15B) the runtime system will + by default <em>not</em> bind schedulers to logical + processors.</p> + <p> + If the Erlang runtime system is the only operating system + process that binds threads to logical processors, this + improves the performance of the runtime system. However, + if other operating system processes (as for example + another Erlang runtime system) also bind threads to + logical processors, there might be a performance penalty + instead. In some cases this performance penalty might be + severe. Due to this, we change the default so that the + user must make an active decision in order to bind + schedulers.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9726</p> + </item> + <item> + <p> + The use of <c>erlang:system_flag(scheduler_bind_type, + _)</c> and <c>erlang:system_flag(cpu_topology, _)</c> + have been deprecated and scheduled for removal in + erts-5.10/OTP-R16. For more information see the + documentation of <c>erlang:system_flag/2</c>.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9749</p> + </item> + <item> + <p> + An ancient workaround for a Windows bug was removed from + the open_port code, open_port({spawn,...}...) is now + faster. Thanks to Daniel Goertzen.</p> + <p> + Own Id: OTP-9766</p> + </item> + <item> + <p> + The use of deprecated 32bit time_t on 32bit Windows is + removed.</p> + <p> + Own Id: OTP-9767</p> + </item> + <item> + <p> + The NIF <c>reload</c> mechanism is deprecated. Do not use + it as an upgrade method for live production systems. It + might be removed in future releases. It can still serve + as a development feature but a warning message will be + logged each time it is used.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9771</p> + </item> + <item> + <p>The driver interface has been changed to enable 64-bit + aware drivers. Most importantly the return types for + ErlDrvEntry callbacks 'call' and 'control' has ben + enlarged which require drivers to be changed or they will + cause emulator crashes. See <seealso + marker="erl_driver#rewrites_for_64_bits"> Rewrites for + 64-bit driver interface </seealso> in the driver manual. + </p> + <p>Due to this driver <seealso + marker="erl_driver#version_management">version + management</seealso> is now mandatory. A driver that is + not written with version management or a driver that was + compiled with the wrong major version will be not be + loaded by the emulator.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9795</p> + </item> + <item> + <p> + Eliminate use of deprecated regexp module</p> + <p> + Own Id: OTP-9810</p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 5.8.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Several bugs concerning constant binary constructions + such as <<0:4294967295>> have been corrected. + Depending on the actual size of the binary and the type + of run-time system (32-bit, halfword, 64-bit), such + expression could either crash the run-time system or make + the loader refuse loading of the module.</p> + <p> + Own Id: OTP-9284</p> + </item> + <item> + <p> + The Erlsrv utility failed to stop the erlang machine if + no StopAction was defined when the service was stopped. + This is now corrected.</p> + <p> + Own Id: OTP-9344</p> + </item> + <item> + <p> + Due to a bug in glibc the runtime system could abort + while trying to destroy a mutex. A fix for this was + introduced in R14B02. This fix did, however, not solve + the problem. The runtime system will now issue a warning + instead of aborting.</p> + <p> + Own Id: OTP-9373 Aux Id: OTP-9009 </p> + </item> + <item> + <p> + Replace atom in DRV macro in prim_file with string</p> + <p> + An experimental version of Dialyzer discovered that the + atom that replaced the DRV macro in prim_file ends up in + calls to erlang:open_port({spawn, Driver}, Portopts) as + the Driver argument. The documentation states that this + call requires a string there.</p> + <p> + This change is also consistent with the one introduced in + commit 0f03b1e9d2bef3bc830c31a369261af4c5234727 by Kostis + Sagonas.</p> + <p> + Own Id: OTP-9377</p> + </item> + <item> + <p> + Fix typos in the epmd documentation (Thanks to Holger + Wei� )</p> + <p> + Own Id: OTP-9387</p> + </item> + <item> + <p> + Fix faulty integer terms created by NIF API from 64-bit + integers on halfword emulator. (Thanks to Paolo Negri and + Paul Davis)</p> + <p> + Own Id: OTP-9394</p> + </item> + <item> + <p> + Fix <c>epmd</c> crash on vxworks caused by faulty + argument to select() system call.</p> + <p> + Own Id: OTP-9427 Aux Id: seq11855 </p> + </item> + <item> + <p> + The ets:test_ms function could in rare cases truncate the + error messages. This is now corrected.</p> + <p> + Own Id: OTP-9435</p> + </item> + <item> + <p> + Fix bug related to hibernate and HiPE (clear + F_HIBERNATE_SCHED flag)</p> + <p> + F_HIBERNATE_SCHED flag that was introduced in + b7ecdcd1ae9e11b8f75e must be cleared in hipe_mode_switch + as well. Otherwise, processes running HiPE code that + hibernate, wake up and then trap into a BIF will not be + rescheduled.(Thanks to Paul Guyot)</p> + <p> + Own Id: OTP-9452</p> + </item> + <item> + <p> + Fix bug in FreeBSD topology detection code (Thanks to + Paul Guyot)</p> + <p> + Own Id: OTP-9453</p> + </item> + <item> + <p> + Fix use of logical operator && with constant + operand instead of bitwise & (Thanks to Cristian + Greco)</p> + <p> + Own Id: OTP-9454</p> + </item> + <item> + <p> + inet: error if fd does not match socket domain</p> + <p> + If an IPv4 fd is opened as an IPv6 socket, unexpected + behaviour can occur. For example, if an IPv4 UDP socket + is opened and passed into Erlang as an IPv6 socket, the + first 3 bytes (corresponding to 1 byte representing the + protocol family, 2 bytes set to the port) are stripped + from the payload. The cause of the UDP payload truncation + happens in inet_drv.c:packet_inet_input when a call to + inet_get_address fails silently because the family is set + to PF_INET6 but the buffer len is the size of an IPv4 + struct sockaddr_in.</p> + <p> + (Thanks to Andrew Tunnell-Jones for finding the bug and + the test case!)</p> + <p> + Own Id: OTP-9455</p> + </item> + <item> + <p> + erts: use a union to avoid strict aliasing issues</p> + <p> + Use a union for pointer type conversion to avoid compiler + warnings about strict-aliasing violations with gcc-4.1. + gcc >= 4.2 does not emit the warning. erts: adapt + matrix_nif to R14 erl_nif API changes (Thanks To Tuncer + Ayaz)</p> + <p> + Own Id: OTP-9487</p> + </item> + <item> + <p> + fix 64-bit issues in the garbage collection (Thanks to + Richard Carlsson)</p> + <p> + Own Id: OTP-9488</p> + </item> + <item> + <p> + epmd: fix compiler warnings</p> + <p> + Suppress compiler warnings about ignored return values. + (Thanks to Michael Santos )</p> + <p> + Own Id: OTP-9500</p> </item> <item> <p> - Fix emulator deadlock in <c>ets:delete</c> on tables with - <c>write_concurrency</c> caused by race with concurrent - process that tries to do other operation on the same - table. Does not apply to <c>ordered_set</c>. Bug exist - since R14B.</p> + Fix non-existing function (erlang:disconnect/1) in + distributed reference manual (Thanks to Fabian Kr�l)</p> <p> - Own Id: OTP-9423 Aux Id: seq11872 </p> + Own Id: OTP-9504</p> + </item> + <item> + <p> + Document fdatasync -lrt requirement (SunOS <= 5.10) + (Thanks to Tuncer Ayaz)</p> + <p> + Own Id: OTP-9512</p> + </item> + <item> + <p> + Let epmd ignore empty ERL_EPMD_ADDRESS</p> + <p> + If the environment variable ERL_EPMD_ADDRESS is set to + the empty string, empd now behaves like it does by + default when ERL_EPMD_ADDRESS is unset. That is, in this + case, epmd now listens on all available interfaces + instead of using only the loopback interface, which + happened because epmd added the loopback address to the + (in this case empty) list of addresses specified via + ERL_EPMD_ADDRESS.</p> + <p> + Also, epmd now ignores ERL_EPMD_ADDRESS if it contains + only separator characters (comma and space).</p> + <p> + The same applies to epmd's -address option.(Thanks to + Holger Wei�)</p> + <p> + Own Id: OTP-9525</p> + </item> + <item> + <p> + Remove dead code in erl_compile (Thanks to Tuncer Ayaz)</p> + <p> + Own Id: OTP-9527</p> + </item> + <item> + <p> + Add erlang:external_size/2 BIF</p> + <p> + This BIF's second parameter is a list of options. + Currently the only allowed option is {minor_version, + Version} where version is either 0 (default) or 1. + (Thanks to Filipe David Manana )</p> + <p> + Own Id: OTP-9528</p> + </item> + <item> + <p> + Fix enif_compare on 64bits machines</p> + <p> + In 64bits machines the Sint type has a size of 8 bytes, + while on 32bits machines it has a 4 bytes size. + enif_compare was ignoring this and therefore returning + incorrect values when the result of the CMP function + (which returns a Sint value) doesn't fit in 4 bytes. + (Thanks to Filipe David Manana)</p> + <p> + Own Id: OTP-9533</p> + </item> + <item> + <p> + Implement or fix -Werror option</p> + <p> + If -Werror is enabled and there are warnings no output + file is written. Also make sure that error/warning + reporting is consistent. (Thanks to Tuncer Ayaz)</p> + <p> + Own Id: OTP-9536</p> + </item> + <item> + <p>In some rare cases we did not have a run queue when + scheduling misc ops. This is now fixed.</p> + <p> + Own Id: OTP-9537</p> + </item> + <item> + <p>Remove misc. compiler warnings</p> + <p> + Own Id: OTP-9542</p> + </item> + <item> + <p> + Two bugs in gen_sctp has been corrected: getopts/setopts + hence also send could only be called from socket owner, + and options 'linger', 'rcvbuf' and 'sndbuf' was read from + wrong protocol layer hence read wrong values by getopts.</p> + <p> + Own Id: OTP-9544</p> + </item> + <item> + <p> + Erlang/OTP can now be built on MacOS X Lion.</p> + <p> + Own Id: OTP-9547</p> + </item> + <item> + <p> XML files have been corrected. </p> + <p> + Own Id: OTP-9550 Aux Id: OTP-9541 </p> + </item> + <item> + <p> + Fix potential errors inspired by running cppcheck(1) + (Thanks to Christian von Roques)</p> + <p> + Own Id: OTP-9557</p> + </item> + <item> + <p>When auxiliary work was enqueued on a scheduler, the + wakeup of the scheduler in order to handle this work + could be lost. Wakeups in order to handle ordinary work + were not effected by this bug. The bug only effected + runtime systems with SMP support as follows:</p> <list> + <item>Deallocation of some ETS data structures could be + delayed.</item> <item>On Linux systems not using the NPTL + thread library (typically ancient systems with kernel + versions prior to 2.6) and Windows systems, the <c>{Port, + {exit_status, Status}}</c> message from a terminating + port program could be delayed. That is, it only effected + port programs which had been started by passing + <c>exit_status</c> as an option to + <c>open_port/2</c>.</item> </list> + <p> + Own Id: OTP-9567</p> + </item> + <item> + <p> + Handle rare race in the crypto key server functionality</p> + <p> + Own Id: OTP-9586</p> </item> </list> </section> @@ -61,16 +1017,40 @@ <section><title>Improvements and New Features</title> <list> <item> + <p> Types and specifications have been added. </p> + <p> + Own Id: OTP-9356</p> + </item> + <item> + <p> + New allocator strategy "address order first fit". May + ease the emptying of memory carriers and thereby real + release of memory back to the OS.</p> + <p> + Own Id: OTP-9424</p> + </item> + <item> + <p> + The new <c>erlang:check_old_code/1</c> BIF checks whether + a module has old code.</p> + <p> + Own Id: OTP-9495</p> + </item> + <item> + <p> Update documentation and specifications of some of + the zlib functions. </p> + <p> + Own Id: OTP-9506</p> + </item> + <item> + <p> + Detect the available CPUs on IRIX</p> <p> - The <c>erts_alloc_util</c> framework has been extended - with functionality for separation of small blocks from - other blocks in separate carriers. This functionality is - currently disabled by default, but can be enabled in - order to finetune memory management. For more information - see <seealso - marker="erts:erts_alloc">erts_alloc(3)</seealso>.</p> + Add support for querying the number of configured and + online processors on SGI systems running IRIX.(Thanks to + Holger Wei�)</p> <p> - Own Id: OTP-9339 Aux Id: Seq11780 </p> + Own Id: OTP-9531</p> </item> </list> </section> @@ -1996,6 +2976,24 @@ </section> +<section><title>Erts 5.7.5.2</title> + + <section><title>Known Bugs and Problems</title> + <list> + <item> + <p> + Two bugs in gen_sctp has been corrected: getopts/setopts + hence also send could only be called from socket owner, + and options 'linger', 'rcvbuf' and 'sndbuf' was read from + wrong protocol layer hence read wrong values by getopts.</p> + <p> + Own Id: OTP-9544</p> + </item> + </list> + </section> + +</section> + <section><title>Erts 5.7.5.1</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -4581,7 +5579,7 @@ 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 + created a table that accidentally got the same internal table index as the table being removed.</p> <p> Own Id: OTP-7349</p> diff --git a/erts/doc/src/specs.xml b/erts/doc/src/specs.xml new file mode 100644 index 0000000000..e5c2f4783f --- /dev/null +++ b/erts/doc/src/specs.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="latin1" ?> +<specs xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="../specs/specs_erl_prim_loader.xml"/> + <xi:include href="../specs/specs_erlang.xml"/> + <xi:include href="../specs/specs_init.xml"/> + <xi:include href="../specs/specs_zlib.xml"/> +</specs> diff --git a/erts/doc/src/start_erl.xml b/erts/doc/src/start_erl.xml index 21cc901f52..92d87b095a 100644 --- a/erts/doc/src/start_erl.xml +++ b/erts/doc/src/start_erl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1998</year><year>2009</year> + <year>1998</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -69,12 +69,29 @@ <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 <release root></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 <Erlang root>\\releases). The - <c><![CDATA[start_erl.data]]></c> file is expected to be placed in - this directory (if not otherwise specified).</item> + + <item>Mandatory if the environment variable + <c><![CDATA[RELDIR]]></c> is not specified and no + <c>-rootdir</c> option is given. Tells start_erl where the + root of the release tree is placed in the file-system (typically + <Erlang root>\\releases). The + <c><![CDATA[start_erl.data]]></c> file is expected to be + placed in this directory (if not otherwise specified). If + only the <c>-rootdir</c> option is given, the directory is + assumed to be <Erlang root>\\releases.</item> + + <tag>-rootdir <Erlang root directory></tag> + + <item>Mandatory if <c>-reldir</c> is not given and there is + no <c><![CDATA[RELDIR]]></c> in the environment. This + specifies the Erlang installation root directory (under + which the <c>lib</c>, <c>releases</c> and + <c>erts-<Version></c> directories are placed). If only + <c>-reldir</c> (or the environment variable + <c><![CDATA[RELDIR]]></c>) is given, the Erlang root is assumed to + be the directory exactly one level above the release + directory.</item> + <tag>-data <data file name></tag> <item>Optional, specifies another data file than start_erl.data in the <release root>. It is specified relative to the diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml index b1e768bce9..8917ab5c3a 100644 --- a/erts/doc/src/zlib.xml +++ b/erts/doc/src/zlib.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2005</year><year>2010</year> + <year>2005</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -76,96 +76,92 @@ list_to_binary([Compressed|Last])</pre> </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> + <datatypes> + <datatype> + <name name="zstream"/> + <desc> + <p>A zlib stream, see <seealso marker="#open/0">open/0</seealso>. + </p> + </desc> + </datatype> + <datatype> + <name name="zlevel"/> + </datatype> + <datatype> + <name name="zmemlevel"/> + </datatype> + <datatype> + <name name="zmethod"/> + </datatype> + <datatype> + <name name="zstrategy"/> + </datatype> + <datatype> + <name name="zwindowbits"/> + <desc> + <p>Normally in the range <c>-15..-9 | 9..15</c>.</p> + </desc> + </datatype> + </datatypes> <funcs> <func> - <name>open() -> Z </name> + <name name="open" arity="0"/> <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> + <name name="close" arity="1"/> <fsummary>Close a stream</fsummary> - <type> - <v>Z = zstream()</v> - </type> <desc> - <p>Closes the stream referenced by <c>Z</c>.</p> + <p>Closes the stream referenced by <c><anno>Z</anno></c>.</p> </desc> </func> <func> - <name>deflateInit(Z) -> ok</name> + <name name="deflateInit" arity="1"/> <fsummary>Initialize a session for compression</fsummary> - <type> - <v>Z = zstream()</v> - </type> <desc> - <p>Same as <c>zlib:deflateInit(Z, default)</c>.</p> + <p>Same as <c>zlib:deflateInit(<anno>Z</anno>, default)</c>.</p> </desc> </func> <func> - <name>deflateInit(Z, Level) -> ok</name> + <name name="deflateInit" arity="2"/> <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 + <p><c><anno>Level</anno></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> + <name name="deflateInit" arity="6"/> <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 + <p>The <c><anno>Level</anno></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, + <p>The <c><anno>Method</anno></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 + <p>The <c><anno>WindowBits</anno></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> + <c>deflateInit/2</c>. A negative <c><anno>WindowBits</anno></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 + <p>The <c><anno>MemLevel</anno></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 + state. <c><anno>MemLevel</anno></c>=1 uses minimum memory but is slow and + reduces compression ratio; <c><anno>MemLevel</anno></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 + <p>The <c><anno>Strategy</anno></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 @@ -175,54 +171,43 @@ zstream = a zlib stream, see open/0</code> 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> + <c>default</c> and <c>huffman_only</c>. The <c><anno>Strategy</anno></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> + <name name="deflate" arity="2"/> <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> + <p>Same as <c>deflate(<anno>Z</anno>, <anno>Data</anno>, none)</c>.</p> </desc> </func> <func> - <name>deflate(Z, Data, Flush) -> </name> + <name name="deflate" arity="3"/> <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 + <p>If the parameter <c><anno>Flush</anno></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 + <p>If <c><anno>Flush</anno></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>, + <p>If the parameter <c><anno>Flush</anno></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 + <p><c><anno>Flush</anno></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> @@ -234,13 +219,8 @@ list_to_binary([B1,B2])</pre> </desc> </func> <func> - <name>deflateSetDictionary(Z, Dictionary) -> Adler32</name> + <name name="deflateSetDictionary" arity="2"/> <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 @@ -253,11 +233,8 @@ list_to_binary([B1,B2])</pre> </desc> </func> <func> - <name>deflateReset(Z) -> ok</name> + <name name="deflateReset" arity="1"/> <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 @@ -267,34 +244,26 @@ list_to_binary([B1,B2])</pre> </desc> </func> <func> - <name>deflateParams(Z, Level, Strategy) -> ok </name> + <name name="deflateParams" arity="3"/> <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 + strategy. The interpretation of <c><anno>Level</anno></c> and + <c><anno>Strategy</anno></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 + <p>Before the call of <c>deflateParams</c>, 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> + <name name="deflateEnd" arity="1"/> <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> @@ -304,43 +273,31 @@ list_to_binary([B1,B2])</pre> </desc> </func> <func> - <name>inflateInit(Z) -> ok </name> + <name name="inflateInit" arity="1"/> <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> + <name name="inflateInit" arity="2"/> <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 + <p>The <c><anno>WindowBits</anno></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 + exception. A negative <c><anno>WindowBits</anno></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> + <name name="inflate" arity="2"/> <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 @@ -353,12 +310,8 @@ list_to_binary([B1,B2])</pre> </desc> </func> <func> - <name>inflateSetDictionary(Z, Dictionary) -> ok</name> + <name name="inflateSetDictionary" arity="2"/> <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 @@ -381,11 +334,8 @@ unpack(Z, Compressed, Dict) -> </desc> </func> <func> - <name>inflateReset(Z) -> ok</name> + <name name="inflateReset" arity="1"/> <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 @@ -394,11 +344,8 @@ unpack(Z, Compressed, Dict) -> </desc> </func> <func> - <name>inflateEnd(Z) -> ok</name> + <name name="inflateEnd" arity="1"/> <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 @@ -407,198 +354,132 @@ unpack(Z, Compressed, Dict) -> </desc> </func> <func> - <name>setBufSize(Z, Size) -> ok</name> + <name name="setBufSize" arity="2"/> <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> + <name name="getBufSize" arity="1"/> <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> + <name name="crc32" arity="1"/> <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> + <name name="crc32" arity="2"/> <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> + <p>Calculate the CRC checksum for <c><anno>Data</anno></c>.</p> </desc> </func> <func> - <name>crc32(Z, PrevCRC, Binary) -> CRC </name> + <name name="crc32" arity="3"/> <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 + <desc> + <p>Update a running CRC checksum for <c><anno>Data</anno></c>. + If <c><anno>Data</anno></c> is the empty binary or the empty iolist, this function returns the required initial value for the crc.</p> <pre> -Crc = lists:foldl(fun(Bin,Crc0) -> - zlib:crc32(Z, Crc0, Bin), - end, zlib:crc32(Z,<< >>), Bins)</pre> +Crc = lists:foldl(fun(Data,Crc0) -> + zlib:crc32(Z, Crc0, Data), + end, zlib:crc32(Z,<< >>), Datas)</pre> </desc> </func> <func> - <name>crc32_combine(Z, CRC1, CRC2, Size2) -> CRC </name> + <name name="crc32_combine" arity="4"/> <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><<Bin1/binary,Bin2/binary>></c>, requiring - only <c>CRC1</c>, <c>CRC2</c>, and <c>Size2</c>. + <desc> + <p>Combine two CRC checksums into one. For two binaries or iolists, + <c>Data1</c> and <c>Data2</c> with sizes of <c>Size1</c> and + <c><anno>Size2</anno></c>, with CRC checksums <c><anno>CRC1</anno></c> and + <c><anno>CRC2</anno></c>. <c>crc32_combine/4</c> returns the <c><anno>CRC</anno></c> + checksum of <c>[Data1,Data2]</c>, requiring + only <c><anno>CRC1</anno></c>, <c><anno>CRC2</anno></c>, and <c><anno>Size2</anno></c>. </p> </desc> </func> <func> - <name>adler32(Z, Binary) -> Checksum</name> + <name name="adler32" arity="2"/> <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> + <p>Calculate the Adler-32 checksum for <c><anno>Data</anno></c>.</p> </desc> </func> <func> - <name>adler32(Z, PrevAdler, Binary) -> Checksum</name> + <name name="adler32" arity="3"/> <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 + <desc> + <p>Update a running Adler-32 checksum for <c><anno>Data</anno></c>. + If <c><anno>Data</anno></c> is the empty binary or the empty iolist, this function returns the required initial value for the checksum.</p> <pre> -Crc = lists:foldl(fun(Bin,Crc0) -> - zlib:adler32(Z, Crc0, Bin), - end, zlib:adler32(Z,<< >>), Bins)</pre> +Crc = lists:foldl(fun(Data,Crc0) -> + zlib:adler32(Z, Crc0, Data), + end, zlib:adler32(Z,<< >>), Datas)</pre> </desc> </func> <func> - <name>adler32_combine(Z, Adler1, Adler2, Size2) -> Adler </name> + <name name="adler32_combine" arity="4"/> <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><<Bin1/binary,Bin2/binary>></c>, requiring - only <c>Adler1</c>, <c>Adler2</c>, and <c>Size2</c>. + <desc> + <p>Combine two Adler-32 checksums into one. For two binaries or iolists, + <c>Data1</c> and <c>Data2</c> with sizes of <c>Size1</c> and + <c><anno>Size2</anno></c>, with Adler-32 checksums <c><anno>Adler1</anno></c> and + <c><anno>Adler2</anno></c>. <c>adler32_combine/4</c> returns the <c><anno>Adler</anno></c> + checksum of <c>[Data1,Data2]</c>, requiring + only <c><anno>Adler1</anno></c>, <c><anno>Adler2</anno></c>, and <c><anno>Size2</anno></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> + <name name="compress" arity="1"/> + <fsummary>Compress data with standard zlib functionality</fsummary> <desc> - <p>Compress a binary (with zlib headers and checksum).</p> + <p>Compress data (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> + <name name="uncompress" arity="1"/> + <fsummary>Uncompress data with standard zlib functionality</fsummary> <desc> - <p>Uncompress a binary (with zlib headers and checksum).</p> + <p>Uncompress data (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> + <name name="zip" arity="1"/> + <fsummary>Compress data without the zlib headers</fsummary> <desc> - <p>Compress a binary (without zlib headers and checksum).</p> + <p>Compress data (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> + <name name="unzip" arity="1"/> + <fsummary>Uncompress data without the zlib headers</fsummary> <desc> - <p>Uncompress a binary (without zlib headers and checksum).</p> + <p>Uncompress data (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> + <name name="gzip" arity="1"/> + <fsummary>Compress data with gz header</fsummary> <desc> - <p>Compress a binary (with gz headers and checksum).</p> + <p>Compress data (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> + <name name="gunzip" arity="1"/> + <fsummary>Uncompress data with gz header</fsummary> <desc> - <p>Uncompress a binary (with gz headers and checksum).</p> + <p>Uncompress data (with gz headers and checksum).</p> </desc> </func> </funcs> |