diff options
Diffstat (limited to 'erts')
29 files changed, 195 insertions, 1046 deletions
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 74654a295d..4cf0066999 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -631,14 +631,16 @@ of process heaps is destroyed by the crash dump generation.</p> <p>Option <c>+d</c> instructs the emulator to produce only a core dump and no crash dump if an internal error is detected.</p> - <p>Calling <seealso marker="erlang:halt/1"> + <p>Calling <seealso marker="erlang#halt/1"> <c>erlang:halt/1</c></seealso> with a string argument still produces a crash dump. On Unix systems, sending an emulator process a <c>SIGUSR1</c> signal also forces a crash dump.</p> </item> <tag><marker id="+e"/><c><![CDATA[+e Number]]></c></tag> <item> - <p>Sets the maximum number of ETS tables.</p> + <p>Sets the maximum number of ETS tables. This limit is + <seealso marker="stdlib:ets#max_ets_tables">partially obsolete</seealso>. + </p> </item> <tag><c><![CDATA[+ec]]></c></tag> <item> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index cff56b9cb8..1b973cd60e 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -36,8 +36,8 @@ in this module. Some of the BIFs are viewed more or less as part of the Erlang programming language and are <em>auto-imported</em>. Thus, it is not necessary to specify the - module name. For example, the calls <c>atom_to_list(Erlang)</c> - and <c>erlang:atom_to_list(Erlang)</c> are identical.</p> + module name. For example, the calls <c>atom_to_list(erlang)</c> + and <c>erlang:atom_to_list(erlang)</c> are identical.</p> <p>Auto-imported BIFs are listed without module prefix. BIFs listed with module prefix are not auto-imported.</p> @@ -4832,11 +4832,11 @@ RealSystem = system + MissedSystem</code> </item> <tag><c>error_logger</c></tag> <item> - <p>When set to <c>true</c>, the runtime system sends a - message to the current <seealso marker="kernel:error_logger"> - <c>error_logger</c></seealso> + <p>When set to <c>true</c>, the runtime system logs an + error event via <seealso marker="kernel:logger"> + <c>logger</c></seealso>, containing details about the process when the maximum - heap size is reached. One <c>error_logger</c> report is sent + heap size is reached. One log event is sent each time the limit is reached.</p> <p>If <c>error_logger</c> is not defined in the map, the system default is used. The default system default is <c>true</c>. @@ -4850,7 +4850,7 @@ RealSystem = system + MissedSystem</code> amount of memory that is used during the garbage collection. When contemplating using this option, it is recommended to first run it in production with <c>kill</c> set to <c>false</c> and inspect - the <c>error_logger</c> reports to see what the normal peak sizes + the log events to see what the normal peak sizes of the processes in the system is and then tune the value accordingly. </p> @@ -7382,7 +7382,7 @@ ok <note><p>If a scheduler fails to bind, this is often silently ignored, as it is not always possible to verify valid logical processor identifiers. If an error is reported, - it is reported to <c>error_logger</c>. To verify that the + an error event is logged. To verify that the schedulers have bound as requested, call <seealso marker="#system_info_scheduler_bindings"> <c>erlang:system_info(scheduler_bindings)</c></seealso>.</p> @@ -8166,16 +8166,18 @@ ok <c>erl(1)</c>. </p> </item> + <tag><marker id="system_info_ets_count"/> + <c>ets_count</c></tag> + <item> + <p>Returns the number of ETS tables currently existing at the + local node.</p> + </item> <tag><marker id="system_info_ets_limit"/> <c>ets_limit</c></tag> <item> - <p>Returns the maximum number of ETS tables allowed. This - limit can be increased at startup by passing - command-line flag - <seealso marker="erts:erl#+e"><c>+e</c></seealso> to - <c>erl(1)</c> or by setting environment variable - <c>ERL_MAX_ETS_TABLES</c> before starting the Erlang - runtime system.</p> + <p>Returns the limit for number of ETS tables. This limit is + <seealso marker="stdlib:ets#max_ets_tables">partially obsolete</seealso> + and number of tables are only limited by available memory.</p> </item> <tag><marker id="system_info_port_count"/><c>port_count</c></tag> <item> diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index d741e29958..f7f86084a9 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,220 +31,12 @@ </header> <p>This document describes the changes made to the ERTS application.</p> -<section><title>Erts 10.0</title> +<section><title>Erts 9.3.2</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> <p> - The type specifications for <c>file:posix/0</c> and - <c>inet:posix/0</c> have been updated according to which - errors file and socket operations should be able to - return.</p> - <p> - Own Id: OTP-14019 Aux Id: ERL-550 </p> - </item> - <item> - <p> - Fix error printout from run_erl and a bug that could - cause unintended fds to be leaked into the started - program.</p> - <p> - Own Id: OTP-14537 Aux Id: PR1529 </p> - </item> - <item> - <p> File operations used to accept <seealso - marker="kernel:file#type-name_all">filenames</seealso> - containing null characters (integer value zero). This - caused the name to be truncated and in some cases - arguments to primitive operations to be mixed up. - Filenames containing null characters inside the filename - are now <em>rejected</em> and will cause primitive file - operations to fail. </p> <p> Also environment variable - operations used to accept <seealso - marker="kernel:os#type-env_var_name">names</seealso> and - <seealso - marker="kernel:os#type-env_var_value">values</seealso> of - environment variables containing null characters (integer - value zero). This caused operations to silently produce - erroneous results. Environment variable names and values - containing null characters inside the name or value are - now <em>rejected</em> and will cause environment variable - operations to fail. </p> <p>Primitive environment - variable operations also used to accept the <c>$=</c> - character in environment variable names causing various - problems. <c>$=</c> characters in environment variable - names are now also <em>rejected</em>. </p> <p>Also - <seealso - marker="kernel:os#cmd/1"><c>os:cmd/1</c></seealso> now - reject null characters inside its <seealso - marker="kernel:os#type-os_command">command</seealso>. - </p> <p><seealso - marker="erts:erlang#open_port/2"><c>erlang:open_port/2</c></seealso> - will also reject null characters inside the port name - from now on.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14543 Aux Id: ERL-370 </p> - </item> - <item> - <p> - Fix bugs related to the bookkeeping of microstate - accounting states.</p> - <p> - Own Id: OTP-14652</p> - </item> - <item> - <p><c>os:putenv</c> and <c>os:getenv</c> no longer access - the process environment directly and instead work on a - thread-safe emulation. The only observable difference is - that it's <em>not</em> kept in sync with libc - <c>getenv(3)</c> / <c>putenv(3)</c>, so those who relied - on that behavior in drivers or NIFs will need to add - manual synchronization.</p> <p>On Windows this means that - you can no longer resolve DLL dependencies by modifying - the <c>PATH</c> just before loading the driver/NIF. To - make this less of a problem, the emulator now adds the - target DLL's folder to the DLL search path.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14666</p> - </item> - <item> - <p>Corrected <c>erlang:is_builtin(erlang, M, F)</c> to - return <c>true</c> for <c>apply/2</c> and - <c>yield/0</c>.</p> - <p> - Own Id: OTP-14713 Aux Id: ERL-500 </p> - </item> - <item> - <p>Fixed a bug where the PATH environment variable wasn't - updated correctly on a release downgrade, effectively - keeping the PATH of the new release.</p> - <p> - Own Id: OTP-14719</p> - </item> - <item> - <p>A receive optimization that avoids scanning the entire - message queue when receiving a message containing a - freshly created reference could in rare circumstances - (involving recursive calls to the functions that does the - receive) cause the receive to hang. This has been - corrected.</p> - <p> - Own Id: OTP-14782 Aux Id: ERL-511 </p> - </item> - <item> - <p> - Fix building of Erlang/OTP on platforms which have small - data area with short addressing. For example the - PowerPC/RTEMS platform.</p> - <p> - Own Id: OTP-14909 Aux Id: PR-1692 </p> - </item> - <item> - <p>Fixed a crash when <c>enif_make_binary</c> is called - with a binary produced by <c>enif_inspect_binary</c> in a - different environment.</p> - <p> - Own Id: OTP-14931</p> - </item> - <item> - <p>Fixed a crash when <c>enif_make_binary</c> is called - more than once with a binary that had previously been - added to an <c>enif_ioq</c>.</p> - <p> - Own Id: OTP-14932</p> - </item> - <item> - <p> - The erl_child_setup program now ignores SIGTERM signals.</p> - <p> - Own Id: OTP-14943 Aux Id: ERL-576 </p> - </item> - <item> - <p> - Force 64-bit alignment on pre-allocators on architectures - which needs it.</p> - <p> - Own Id: OTP-14977</p> - </item> - <item> - <p> - Fixed a bug where dirty scheduler picked up non-dirty - work.</p> - <p> - Own Id: OTP-14978</p> - </item> - <item> - <p> - Calls to <c>gen_tcp:send/2</c> on closed sockets now - returns <c>{error, closed}</c> instead of - <c>{error,enotconn}</c>.</p> - <p> - Own Id: OTP-15001</p> - </item> - <item> - <p> - <c>erlang:monotonic_time/1</c> failed with <c>badarg</c> - when passing the <c>perf_counter</c> time unit as - argument.</p> - <p> - Own Id: OTP-15008</p> - </item> - <item> - <p> - Fix bug where rapid <c>init:restart()</c> calls would - sometimes crash because a code load request leaked in - between the restarts.</p> - <p> - Own Id: OTP-15013</p> - </item> - <item> - <p> - Improve <c>float_to_list(F, [{decimals,D}])</c> to closer - conform with <c>io_lib:format("~.*f", [D,F])</c>.</p> - <p> - There are however, still cases when <c>float_to_list</c> - does not produce the exact same result as - <c>io_lib:format</c>, especially for large values - <c>F</c> and/or many decimals <c>D</c>.</p> - <p> - Own Id: OTP-15015 Aux Id: OTP-14890 </p> - </item> - <item> - <p>Fixed a deadlock that would occur on certain - allocators when a reallocation failed with <c>+ramv</c> - enabled.</p> - <p> - Own Id: OTP-15024</p> - </item> - <item> - <p> - Fix bug that made it impossible to use an erl_tracer as - the seq_trace trace receiver.</p> - <p> - Own Id: OTP-15029</p> - </item> - <item> - <p> - Fix bug where a large (> 1 GB) emulator generated error - logger message would cause the emulator to crash.</p> - <p> - Own Id: OTP-15032</p> - </item> - <item> - <p>The emulator will no longer crash when reading the - file information of an ordinary file that has an NTFS - reparse point, such as files stored in a OneDrive-mapped - folder.</p> - <p> - Own Id: OTP-15062 Aux Id: ERL-615 </p> - </item> - <item> - <p> Fixed bug in <c>enif_binary_to_term</c> which could cause memory corruption for immediate terms (atoms, small integers, pids, ports, empty lists).</p> @@ -259,650 +51,6 @@ <p> Own Id: OTP-15085</p> </item> - <item> - <p> - On OSs with per thread CPU time support, change - <c>cpu_timestamp</c> in <seealso - marker="erlang#trace/3">erlang:trace/3</seealso> to use - it instead of per process CPU time. This makes this - option useable on such OSs when running multiple - schedulers.</p> - <p> - Own Id: OTP-15090</p> - </item> - </list> - </section> - - - <section><title>Improvements and New Features</title> - <list> - <item> - <p>It is now possible to open device files and FIFOs with - <c>file:open/2</c>.</p> - <p> - Own Id: OTP-11462</p> - </item> - <item> - <p> - The <c>erlang:system_flag(scheduler_wall_time,Bool)</c> - call is now reference counted and will be turned off if - the (last) process that started the performance - statistics dies. Thus it is no longer possible to start - the statistics with <c>rpc:call(Node, erlang, - system_flag, [scheduler_wall_time, true])</c> since it - will be turned off directly afterwards when the rpc - process dies.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-11694</p> - </item> - <item> - <p>A new logging API is added to Erlang/OTP, see the - <seealso - marker="kernel:logger"><c>logger(3)</c></seealso> manual - page, and section <seealso - marker="kernel:logger_chapter">Logging</seealso> in the - Kernel User's Guide.</p> - <p>Calls to <c>error_logger</c> are automatically - redirected to the new API, and legacy error logger event - handlers can still be used. It is, however, recommended - to use the Logger API directly when writing new code.</p> - <p>Notice the following potential incompatibilities:</p> - <list> <item><p>Kernel configuration parameters - <c>error_logger</c> still works, but is overruled if the - default handler's output destination is configured with - Kernel configuration parameter <c>logger</c>.</p> <p>In - general, parameters for configuring error logger are - overwritten by new parameters for configuring - Logger.</p></item> <item><p>The concept of SASL error - logging is deprecated, meaning that by default the SASL - application does not affect which log events are - logged.</p> <p>By default, supervisor reports and crash - reports are logged by the default Logger handler started - by Kernel, and end up at the same destination (terminal - or file) as other standard log event from Erlang/OTP.</p> - <p>Progress reports are not logged by default, but can be - enabled with the Kernel configuration parameter - <c>logger_progress_reports</c>.</p> <p>To obtain - backwards compatibility with the SASL error logging - functionality from earlier releases, set Kernel - configuration parameter <c>logger_sasl_compatible</c> to - <c>true</c>. This prevents the default Logger handler - from logging any supervisor-, crash-, or progress - reports. Instead, SASL adds a separate Logger handler - during application start, which takes care of these log - events. The SASL configuration parameters - <c>sasl_error_logger</c> and <c>sasl_errlog_type</c> - specify the destination (terminal or file) and severity - level to log for these events.</p></item></list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-13295</p> - </item> - <item> - <p> - <c>gen_sctp:connect_init/4</c> or rather connect in - <c>inet_drv.c</c> for SCTP has been fixed to not check - the write file descriptor for writeability after a - connect, since for SCTP (SOCK_SEQPACKET) that property - does not seem to be any kind of indicator for when a - connect has finished. This fixes connects that the OS - returned as "in progress" that was misinterpreted by - <c>gen_sctp:connect_init</c> as failed.</p> - <p> - Own Id: OTP-13760 Aux Id: PR-1592 </p> - </item> - <item> - <p>The file driver has been rewritten as a NIF, - decreasing the latency of file operations. Two notable - incompatibilities are:</p> <list> <item><p>The - <c>use_threads</c> option for <c>file:sendfile/5</c> no - longer has any effect; we either use non-blocking - <c>sendfile(2)</c> or fall back to <c>file:read</c> + - <c>gen_tcp:send</c>. </p></item> <item><p>The - file-specific DTrace probes have been removed. The same - effect can be achieved with normal tracing together with - the <c>nif__entry</c>/<c>nif__return</c> probes to track - scheduling.</p></item> </list> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14256</p> - </item> - <item> - <p>The I/O polling functionality of erts has been - re-written to better make use of the OSs polling - mechanisms. This change means that erts will now always - prefer to use a kernel-polling mechanism if possible. - Also all of the I/O polling has been moved to dedicated - threads instead of being placed in the scheduler - loops.</p> <p>As a result of this, the <c>erl</c> options - <c>+K</c> and <c>+secio</c> have been removed. It is - still possible to disable kernel-poll, but it has to be - done at compile time through the configure option - <c>--disable-kernel-poll</c>.</p> <p>The new <c>erl</c> - options <seealso marker="erl#+IOt"><c>+IOt</c></seealso> - and <seealso marker="erl#+IOp"><c>+IOp</c></seealso> can - be used to change how many IO poll threads and poll sets - that erts should use. See their respective documentation - for more details.</p> - <p> - Own Id: OTP-14346</p> - </item> - <item> - <p>Truly asynchronous auto-connect. Earlier, when - <c>erlang:send</c> was done toward an unconnected node, - the function would not return until the connection setup - had completed (or failed). Now the function returns - directly after the signal has been enqueued and the - connection setup started.</p> - <p>The same applies to all distributed operations that - may trigger auto-connect, i.e. <c>'!'</c>, <c>send</c>, - <c>link</c>, <c>monitor</c>, <c>monitor_node</c>, - <c>exit/2</c> and <c>group_leader</c>.</p> - <p>The interface for all these functions are unchanged as - they do not return connection failures. The only - exception is <c>erlang:monitor</c> where a <em>possible - incompatibility</em> is introduced: An attempt to monitor - a process on a primitive node (such as erl_interface or - jinterface), where remote process monitoring is not - implemented, will no longer fail with <c>badarg</c> - exception. Instead a monitor will be created, but it will - only supervise the connection to the node.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14370</p> - </item> - <item> - <p>Changed the default behaviour of <c>.erlang</c> - loading: <c>.erlang</c> is no longer loaded from the - current directory. <c>c:erlangrc(PathList)</c> can be - used to search and load an <c>.erlang</c> file from user - specified directories.</p> <p><c>escript</c>, - <c>erlc</c>, <c>dialyzer</c> and <c>typer</c> no longer - load an <c>.erlang</c> at all.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14439</p> - </item> - <item> - <p> - New functionality for implementation of alternative - carriers for the Erlang distribution has been introduced. - This mainly consists of support for usage of distribution - controller processes (previously only ports could be used - as distribution controllers). For more information see - <seealso marker="erts:alt_dist#distribution_module">ERTS - User's Guide ➜ How to implement an Alternative Carrier - for the Erlang Distribution ➜ Distribution - Module</seealso>.</p> - <p> - Own Id: OTP-14459</p> - </item> - <item> - <p> - Add support for the lcc compiler and in extension the - Elbrus 2000 platform.</p> - <p> - Own Id: OTP-14492</p> - </item> - <item> - <p>Support for "tuple calls" have been removed from the - run-time system. Tuple calls was an undocumented and - unsupported feature which allowed the module argument for - an apply operation to be a tuple: <c>Var = dict:new(), - Var:size()</c>. This "feature" frequently caused - confusion, especially when such call failed. The - stacktrace would point out functions that don't exist in - the source code.</p> - <p>For legacy code that need to use parameterized modules - or tuple calls for some other reason, there is a new - compiler option called <c>tuple_calls</c>. When this - option is given, the compiler will generate extra code - that emulates the old behavior for calls where the module - is a variable.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14497</p> - </item> - <item> - <p>Creation of small maps with literal keys has been - optimized to be faster and potentially use less memory. - The keys are combined into a literal key tuple which is - put into the literal pool. The key tuple can be shared - between many instances of maps having the same keys.</p> - <p> - Own Id: OTP-14502</p> - </item> - <item> - <p> - When an exception is thrown, include the arguments of the - call in the stacktrace for BIFs <c>band</c>, <c>bor</c>, - <c>bsl</c>, <c>bsr</c>, <c>bxor</c>, <c>div</c>, - <c>rem</c> and the operators <c>+</c>, <c>-</c>, <c>*</c> - and <c>/</c>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14508</p> - </item> - <item> - <p> - The non-smp emulators have been removed. This means that - the configure options <c>--disable-threads</c> and - <c>--enable-plain-emulator</c> have been removed and - configure will now refuse to build Erlang/OTP on - platforms without thread support.</p> - <p> - In order to achieve a similar setup as the non-smp - emulator, it is possible to start Erlang/OTP with the - <c>+S 1</c> option.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14518</p> - </item> - <item> - <p>Modules that use floating point constants compiled - with R15 or earlier will need to be re-compiled before - they can be loaded.</p> - <p> - Own Id: OTP-14575</p> - </item> - <item> - <p> - Implementation of true asynchronous signaling between - processes in order to improve scalability. Signals - affected include exit, monitor, demonitor, monitor - triggered, link, unlink, and group leader.</p> - <p> - Own Id: OTP-14589</p> - </item> - <item> - <p> - Added a PGO (profile guided optimization) pass to the - build step of erts. This can be disabled by passing - --disable-pgo to configure.</p> - <p> - Own Id: OTP-14604</p> - </item> - <item> - <p> - Improved the performance of <c>binary:split</c> and - <c>binary:match</c>.</p> - <p> - Own Id: OTP-14610 Aux Id: PR-1480 </p> - </item> - <item> - <p> - It is not longer possible to disable dirty schedulers - when building erlang.</p> - <p> - Own Id: OTP-14613</p> - </item> - <item> - <p>Loaded BEAM code in a 64-bit system requires less - memory because of better packing of operands for - instructions.</p> - <p>These memory savings were achieved by major - improvements to the <c>beam_makeops</c> scripts used when - building the run time system and BEAM compiler. There is - also new for documentation for <c>beam_makeops</c> that - describes how new BEAM instructions and loader - transformations can be implemented. The documentation is - found in here in a source directory or git repository: - erts/emulator/internal_doc/beam_makeops.md. An online - version can be found here: - https://github.com/erlang/otp/blob/master/erts/emulator/internal_doc/beam_makeops.md</p> - <p> - Own Id: OTP-14626</p> - </item> - <item> - <p><c>file:read_file</c> has been changed to read the - content of files that report a size of 0 even when data - can be read from them. An example of such a file is - <c>/proc/cpuinfo</c> on Linux.</p> - <p> - Own Id: OTP-14637 Aux Id: ERL-327 PR-1524 </p> - </item> - <item> - <p> - It is no longer possible to disable the <c>temp_alloc</c> - allocator. Disabling it caused serious performance - degradations and was never what was wanted.</p> - <p> - Own Id: OTP-14651</p> - </item> - <item> - <p>The reduction cost of sending messages is now - constant. It will no longer scale according to the length - of the receiving process' message queue.</p> - <p> - Own Id: OTP-14667</p> - </item> - <item> - <p> - Improved loading of modules with <c>-on_load</c> - directive, to no longer block all schedulers when the - load operation is completed.</p> - <p> - Own Id: OTP-14680</p> - </item> - <item> - <p> - On platforms with real-time signals available, SIGRTMIN+1 - is now used as the internal scheduler suspend signal - instead of SIGUSR2.</p> - <p> - Own Id: OTP-14682</p> - </item> - <item> - <p>When the value returned from a '<c>catch</c>' - expression is ignored, no stacktrace will be built if an - exception is caught. That will save time and produce less - garbage. There are also some minor optimizations of - '<c>try</c>/<c>catch</c>' both in the compiler and - run-time system.</p> - <p> - Own Id: OTP-14683</p> - </item> - <item> - <p>The guarantees and non-guarantees of - <c>erlang:get_stacktrace/0</c> are now documented.</p> - <p> - Own Id: OTP-14687</p> - </item> - <item> - <p>There is a new syntax in '<c>try/catch</c>' for - retrieving the stacktrace without calling - '<c>erlang:get_stacktrace/0</c>'. See the reference - manual for a description of the new syntax. The - '<c>erlang:get_stacktrace/0</c>' BIF is now - deprecated.</p> - <p> - Own Id: OTP-14692</p> - </item> - <item> - <p> - New 'used' option for <c>binary_to_term/2</c> that will - also return number of bytes actually read from the - binary. This enables easy access to any extra data in the - binary located directly after the returned term.</p> - <p> - Own Id: OTP-14780</p> - </item> - <item> - <p> - Added more statistics for - <c>erlang:system_info({allocator,A})</c> in the - <c>mbcs_pool</c> section.</p> - <p> - Own Id: OTP-14795 Aux Id: ERL-88 </p> - </item> - <item> - <p>Added <c>enif_ioq_peek_head</c> to retrieve Erlang - terms from NIF IO queues without having to resort to - copying.</p> - <p> - Own Id: OTP-14797</p> - </item> - <item> - <p>There is a new option '<c>makedep_side_effect</c>' for - the compiler and <c>-MMD</c> for '<c>erlc</c>' that - generates dependencies and continues to compile as - normal.</p> - <p> - Own Id: OTP-14830</p> - </item> - <item> - <p>Added <c>ets:whereis/1</c> for retrieving the table - identifier of a named table.</p> - <p> - Own Id: OTP-14884</p> - </item> - <item> - <p><c>seq_trace</c> labels may now be any erlang - term.</p> - <p> - Own Id: OTP-14899</p> - </item> - <item> - <p> - Optimized the common case of <c>monitor</c> followed by - <c>send</c> to the same local process. The monitor signal - is now delayed in order to be piggybacked with the sent - message and thereby only get one lock operation on the - message queue of the receiver. A delayed monitor signal - is flushed if no <c>send</c> has been done at the latest - when the process is scheduled out.</p> - <p> - Own Id: OTP-14901</p> - </item> - <item> - <p> - Make hipe compiled code work on x86_64 (amd64) with OS - security feature PIE, where executable code can be loaded - into a random location. Old behavior, if hipe was - enabled, was to disable PIE build options for the VM.</p> - <p> - Own Id: OTP-14903</p> - </item> - <item> - <p>The number of driver async threads will now default to - 1 as the standard drivers do not use them anymore. Users - that changed this value to tweak the file driver should - replace <c>+A</c> with <c>+SDio</c> since it now uses - dirty IO schedulers instead of async threads.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14928</p> - </item> - <item> - <p> - Optimize <c>==</c> and <c>/=</c> for binaries with - different sizes to be constant in time instead of - proportional to the size of their common prefix.</p> - <p> - Own Id: OTP-14934 Aux Id: PR-1708 </p> - </item> - <item> - <p> - Refactorings making some internal process flags available - for other usage.</p> - <p> - Own Id: OTP-14948</p> - </item> - <item> - <p> - Removed need for HiPE to allocate native executable - memory in low 2GB address space on x86_64. Command line - option <c>+MXscs</c> is thereby obsolete and ignored.</p> - <p> - Own Id: OTP-14951</p> - </item> - <item> - <p>Added <c>enif_make_map_from_arrays</c> for creating a - populated map, analogous to - <c>enif_make_list_from_array</c>.</p> - <p> - Own Id: OTP-14954</p> - </item> - <item> - <p>Added configuration switches for busy-wait and wake up - thresholds for dirty schedulers, and changing these - settings for normal schedulers will no longer affect - dirty schedulers. </p> <p>Refer to the documentation for - details. The new switches are <seealso - marker="erl#+sbwtdcpu">+sbwtdcpu</seealso>, <seealso - marker="erl#+sbwtdio">+sbwtdio</seealso>, <seealso - marker="erl#+swtdcpu">+swtdcpu</seealso>, and <seealso - marker="erl#+swtdio">+swtdio</seealso>.</p> <p>The - default busy wait threshold for dirty scheduler threads - has also been lowered to <c>short</c>.</p> - <p> - Own Id: OTP-14959</p> - </item> - <item> - <p> - The list of "taints" now also includes dynamic loaded - drivers in addition to NIF libraries. Statically linked - drivers and NIF libraries that are part of erts are not - included. The "taints" are returned by - <c>system_info(taints)</c> and printed in the header of - <c>erl_crash.dump</c> files.</p> - <p> - Own Id: OTP-14960</p> - </item> - <item> - <p>Added <c>instrument:allocations</c> and - <c>instrument:carriers</c> for retrieving information - about memory utilization and fragmentation.</p> - <p>The old <c>instrument</c> interface has been removed, - as have the related options <c>+Mim</c> and - <c>+Mis</c>.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14961</p> - </item> - <item> - <p>The process suspend functionality used by the <seealso - marker="erlang:suspend_process/2">erlang:suspend_process/2</seealso> - BIF has been reimplemented using the newly introduced - true asynchronous signaling between processes. This - mainly to reduce memory usage in the process control - block of all processes, but also in order to simplify the - implementation.</p> <warning> <p>You can easily create - deadlocks if processes suspends each other (directly or - in circles). In ERTS versions prior to ERTS version 10.0, - the runtime system prevented such deadlocks, but this - prevention has now been removed due to performance - reasons.</p> </warning> <p>Other ERTS internal - functionality that used the previous process suspend - functionality have also been reimplemented to use - asynchronous signaling instead.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14964 Aux Id: OTP-14589 </p> - </item> - <item> - <p>Added the <c>nifs</c> option to - <c>?MODULE:module_info/1</c> for listing a module's - installed NIF functions.</p> - <p> - Own Id: OTP-14965</p> - </item> - <item> - <p> - New implementation of <c>erlang:process_info/[1,2]</c>.</p> - <p> - In the general case when inspecting another process, the - new implementation sends an asynchronous process-info - request signal to the other process and waits for the - result instead of locking the other process and reading - the result directly. In some special cases where no - conflicts occur, signal order wont be violated, and the - amount of data requested is guaranteed to be small, the - inspected process may be inspected directly.</p> - <p> - Appropriate amount of reductions are now also bumped when - inspecting a process.</p> - <p> - Own Id: OTP-14966</p> - </item> - <item> - <p> - Removed process start time from crash dump in order to - save memory in process control block.</p> - <p> - Own Id: OTP-14975 Aux Id: PR-1597 </p> - </item> - <item> - <p> - Optimize <c>erlang:put/2</c> when updating existing key - with a new immediate value (atom, small integer, pid, - port).</p> - <p> - Own Id: OTP-14976</p> - </item> - <item> - <p> - <c>erlang:process_info/1</c> has been changed to no - longer include <c>messages</c> by default. Instead - <c>erlang:process_info/2</c> should be used.</p> - <p> - *** POTENTIAL INCOMPATIBILITY ***</p> - <p> - Own Id: OTP-14986 Aux Id: PR-1745 </p> - </item> - <item> - <p> - New NIF functions: <c>enif_mutex_name</c>, - <c>enif_cond_name</c>, <c>enif_rwlock_name</c>, - <c>enif_thread_name</c>, <c>enif_vfprintf</c>, - <c>enif_vsnprintf</c>.</p> - <p> - Own Id: OTP-14994</p> - </item> - <item> - <p>When <c>erlang:system_flag(backtrace_depth, 0)</c> has - been called, all exceptions will now contain the entry - for <em>one</em> function (despite the zero). It used to - be that a hand-made stack backtrace passed to - <c>erlang:raise/3</c> would be be truncated to an empty - list.</p> - <p> - Own Id: OTP-15026</p> - </item> - <item> - <p> - Fixed bug for named <c>ets</c> tables which could cause - unexpected results from matchspec iteration functions - (<c>ets:select*</c> and <c>ets:match*</c>) if the table - was deleted and recreated with the same name during the - iteration. The iteration could incorrectly continue - through the recreated table. The expected correct - behavior is now for the iteration call to fail with a - <c>badarg</c> exception if the table is deleted before - the iteration has completed.</p> - <p> - Own Id: OTP-15031</p> - </item> - <item> - <p>Two new guards BIFs operating on maps have been added: - <c>map_get/2</c> and <c>is_map_key/2</c>. They do the - same as <c>maps:get/2</c> and <c>maps:is_key/2</c>, - respectively, except that they are allowed to be used in - guards.</p> - <p> - Own Id: OTP-15037 Aux Id: PR-1784, PR-1802 </p> - </item> - <item> - <p> - Release run-queue lock while cleaning up terminated dirty - process.</p> - <p> - Own Id: OTP-15081</p> - </item> - <item> - <p>The callback module passed as <c>-epmd_module</c> to - erl has been expanded to be able to do name and port - resolving.</p> <p>Documentation has also been added in - the <seealso - marker="kernel:erl_epmd"><c>erl_epmd</c></seealso> - reference manual and ERTS User's Guide <seealso - marker="erts:alt_disco">How to Implement an Alternative - Service Discovery for Erlang Distribution</seealso>.</p> - <p> - Own Id: OTP-15086 Aux Id: PR-1694 </p> - </item> </list> </section> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 221cf84622..054692819e 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -517,7 +517,9 @@ release_docs_spec: # Generated source code. Put in $(TARGET) directory # +ifneq ($(strip $(CREATE_DIRS)),) _create_dirs := $(shell mkdir -p $(CREATE_DIRS)) +endif # has to be run after _create_dirs diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index d99d2ea57b..575d6ca867 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -2821,20 +2821,20 @@ erts_allocator_options(void *proc) Eterm as[4]; Eterm ts[4]; - as[l] = am_atom_put("e", 1); + as[l] = ERTS_MAKE_AM("e"); ts[l++] = am_true; switch (a) { case ERTS_ALC_A_SYSTEM: - as[l] = am_atom_put("m", 1); - ts[l++] = am_atom_put("libc", 4); + as[l] = ERTS_MAKE_AM("m"); + ts[l++] = ERTS_MAKE_AM("libc"); if(sas.trim_threshold >= 0) { - as[l] = am_atom_put("tt", 2); + as[l] = ERTS_MAKE_AM("tt"); ts[l++] = erts_bld_uint(hpp, szp, (Uint) sas.trim_threshold); } if(sas.top_pad >= 0) { - as[l] = am_atom_put("tp", 2); + as[l] = ERTS_MAKE_AM("tp"); ts[l++] = erts_bld_uint(hpp, szp, (Uint) sas.top_pad); } break; @@ -2848,7 +2848,7 @@ erts_allocator_options(void *proc) } else { - Eterm atom = am_atom_put("e", 1); + Eterm atom = ERTS_MAKE_AM("e"); Eterm term = am_false; tmp = erts_bld_2tup_list(hpp, szp, 1, &atom, &term); } @@ -2859,12 +2859,12 @@ erts_allocator_options(void *proc) #if HAVE_ERTS_MSEG if (use_mseg) { - atoms[length] = am_atom_put("mseg_alloc", 10); + atoms[length] = ERTS_MAKE_AM("mseg_alloc"); terms[length++] = erts_mseg_info_options(0, NULL, NULL, hpp, szp); } #endif - atoms[length] = am_atom_put("alloc_util", 10); + atoms[length] = ERTS_MAKE_AM("alloc_util"); terms[length++] = erts_alcu_au_info_options(NULL, NULL, hpp, szp); #if HAVE_ERTS_MMAP @@ -2874,17 +2874,15 @@ erts_allocator_options(void *proc) #endif { Eterm o[1], v[1]; - o[0] = am_atom_put("t", 1); + o[0] = ERTS_MAKE_AM("t"); v[0] = erts_mtrace_enabled ? am_true : am_false; - atoms[length] = am_atom_put("instr", 5); + atoms[length] = ERTS_MAKE_AM("instr"); terms[length++] = erts_bld_2tup_list(hpp, szp, 1, o, v); } - atoms[length] = am_atom_put("lock_physical_memory", 20); - terms[length++] = (lock_all_physical_memory - ? am_atom_put("all", 3) - : am_atom_put("no", 2)); + atoms[length] = ERTS_MAKE_AM("lock_physical_memory"); + terms[length++] = (lock_all_physical_memory ? am_all : am_no); settings = erts_bld_2tup_list(hpp, szp, length, atoms, terms); @@ -2899,10 +2897,10 @@ erts_allocator_options(void *proc) #if HAVE_ERTS_MSEG if (use_mseg) - terms[length++] = am_atom_put("mseg_alloc", 10); + terms[length++] = ERTS_MAKE_AM("mseg_alloc"); #endif #if ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC - terms[length++] = am_atom_put("sys_aligned_alloc", 17); + terms[length++] = ERTS_MAKE_AM("sys_aligned_alloc"); #endif #if defined(ARCH_64) && defined(ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION) terms[length++] = ERTS_MAKE_AM("literal_mmap"); @@ -2911,7 +2909,7 @@ erts_allocator_options(void *proc) #if defined(__GLIBC__) { - Eterm AM_glibc = am_atom_put("glibc", 5); + Eterm AM_glibc = ERTS_MAKE_AM("glibc"); Eterm version; version = erts_bld_cons(hpp, diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index 9db600dce0..5409b89bab 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -118,9 +118,6 @@ type PORT DRIVER SYSTEM port type ATOM LONG_LIVED ATOM atom_entry type MODULE LONG_LIVED CODE module_entry type REG_PROC STANDARD PROCESSES reg_proc -type LINK_LH STANDARD PROCESSES link_lh -type SUSPEND_MON STANDARD PROCESSES suspend_monitor -type PEND_SUSPEND SHORT_LIVED PROCESSES pending_suspend type PROC_LIST SHORT_LIVED PROCESSES proc_list type SAVED_ESTACK SHORT_LIVED PROCESSES saved_estack type FUN_ENTRY LONG_LIVED CODE fun_entry @@ -133,7 +130,6 @@ type TMP_HEAP TEMPORARY PROCESSES tmp_heap type MSG_REF FIXED_SIZE PROCESSES msg_ref type MSG EHEAP PROCESSES message type MSGQ_CHNG SHORT_LIVED PROCESSES messages_queue_change -type MSG_ROOTS TEMPORARY PROCESSES msg_roots type ROOTSET TEMPORARY PROCESSES root_set type LOADER_TMP TEMPORARY CODE loader_tmp type PREPARED_CODE SHORT_LIVED CODE prepared_code @@ -178,7 +174,6 @@ type BPD STANDARD SYSTEM bpd type LINEBUF STANDARD SYSTEM line_buf type IOQ STANDARD SYSTEM io_queue type BITS_BUF STANDARD SYSTEM bits_buf -type TMP_DIST_BUF TEMPORARY SYSTEM tmp_dist_buf type ASYNC_DATA LONG_LIVED SYSTEM internal_async_data type ESTACK TEMPORARY SYSTEM estack type DB_TABLE ETS ETS db_tab @@ -191,7 +186,6 @@ type DB_MC_STK TEMPORARY ETS db_mc_stack type DB_MS_RUN_HEAP SHORT_LIVED ETS db_match_spec_run_heap type DB_MS_CMPL_HEAP TEMPORARY ETS db_match_spec_cmpl_heap type DB_SEG ETS ETS db_segment -type DB_SEG_TAB ETS ETS db_segment_tab type DB_STK ETS ETS db_stack type DB_TRANS_TAB ETS ETS db_trans_tab type DB_SEL_LIST ETS ETS db_select_list @@ -200,7 +194,6 @@ type DB_DMC_ERR_INFO ETS ETS db_dmc_error_info type DB_TERM ETS ETS db_term type DB_PROC_CLEANUP SHORT_LIVED ETS db_proc_cleanup_state type ETS_ALL_REQ SHORT_LIVED ETS ets_all_request -type INSTR_INFO LONG_LIVED SYSTEM instr_info type LOGGER_DSBUF TEMPORARY SYSTEM logger_dsbuf type TMP_DSBUF TEMPORARY SYSTEM tmp_dsbuf type INFO_DSBUF SYSTEM SYSTEM info_dsbuf @@ -215,7 +208,6 @@ type PT_HNDL_LIST SHORT_LIVED SYSTEM port_task_handle_list type MISC_OP_LIST SHORT_LIVED SYSTEM misc_op_list type PORT_NAMES SHORT_LIVED SYSTEM port_names type PORT_DATA_LOCK DRIVER SYSTEM port_data_lock -type NODES_MON STANDARD PROCESSES nodes_monitor type PTAB_LIST_DEL SHORT_LIVED PROCESSES ptab_list_deleted_el type PTAB_LIST_CNKI SHORT_LIVED PROCESSES ptab_list_chunk_info type PTAB_LIST_PIDS SHORT_LIVED PROCESSES ptab_list_pids @@ -238,10 +230,8 @@ type CPUDATA LONG_LIVED SYSTEM cpu_data type TMP_CPU_IDS SHORT_LIVED SYSTEM tmp_cpu_ids type EXT_TERM_DATA SHORT_LIVED PROCESSES external_term_data type CPU_GRPS_MAP LONG_LIVED SYSTEM cpu_groups_map -type AUX_WORK_TMO LONG_LIVED SYSTEM aux_work_timeouts type MISC_AUX_WORK_Q LONG_LIVED SYSTEM misc_aux_work_q type CODE_IX_LOCK_Q SHORT_LIVED SYSTEM code_ix_lock_q -type PROC_INTERVAL LONG_LIVED SYSTEM process_interval type BUSY_CALLER_TAB SHORT_LIVED SYSTEM busy_caller_table type BUSY_CALLER SHORT_LIVED SYSTEM busy_caller type PROC_SYS_TSK SHORT_LIVED PROCESSES proc_sys_task @@ -250,8 +240,6 @@ type NEW_TIME_OFFSET SHORT_LIVED SYSTEM new_time_offset type IOB_REQ SHORT_LIVED SYSTEM io_bytes_request type TRACER_NIF LONG_LIVED SYSTEM tracer_nif type TRACE_MSG_QUEUE SHORT_LIVED SYSTEM trace_message_queue -type SCHED_ASYNC_JOB SHORT_LIVED SYSTEM async_calls -type DIRTY_START STANDARD PROCESSES dirty_start type DIRTY_SL SHORT_LIVED SYSTEM dirty_short_lived type MREF_NSCHED_ENT FIXED_SIZE SYSTEM nsched_magic_ref_entry type MREF_ENT STANDARD SYSTEM magic_ref_entry @@ -259,7 +247,6 @@ type MREF_TAB_BKTS STANDARD SYSTEM magic_ref_table_buckets type MREF_TAB LONG_LIVED SYSTEM magic_ref_table type MINDIRECTION FIXED_SIZE SYSTEM magic_indirection type BINARY_FIND SHORT_LIVED PROCESSES binary_find -type OPEN_PORT_ENV TEMPORARY SYSTEM open_port_env type CRASH_DUMP STANDARD SYSTEM crash_dump type DIST_TRANSCODE SHORT_LIVED SYSTEM dist_transcode_context @@ -273,10 +260,8 @@ type THR_Q_LL LONG_LIVED SYSTEM long_lived_thr_queue type ASYNC SHORT_LIVED SYSTEM async type ZLIB STANDARD SYSTEM zlib -type PORT_LOCK STANDARD SYSTEM port_lock type DRIVER_LOCK STANDARD SYSTEM driver_lock type XPORTS_LIST SHORT_LIVED SYSTEM extra_port_list -type PROC_LCK_WTR LONG_LIVED SYSTEM proc_lock_waiter type RUNQ_BLNS LONG_LIVED SYSTEM run_queue_balancing type THR_PRGR_IDATA LONG_LIVED SYSTEM thr_prgr_internal_data type THR_PRGR_DATA LONG_LIVED SYSTEM thr_prgr_data @@ -317,12 +302,6 @@ type HIPE_EXEC EXEC CODE hipe_code +endif -+if heap_frag_elim_test - -type SSB SHORT_LIVED PROCESSES ssb - -+endif - +if lcnt type LCNT_CARRIER STANDARD SYSTEM lcnt_lock_info_carrier @@ -342,7 +321,6 @@ type PURGE_DATA SHORT_LIVED CODE purge_data type DB_HEIR_DATA STANDARD ETS db_heir_data type DB_MS_PSDO_PROC LONG_LIVED ETS db_match_pseudo_proc type SCHDLR_DATA LONG_LIVED SYSTEM scheduler_data -type LL_TEMP_TERM LONG_LIVED SYSTEM ll_temp_term type NIF_TRAP_EXPORT STANDARD PROCESSES nif_trap_export_entry type NIF_EXP_TRACE FIXED_SIZE PROCESSES nif_export_trace @@ -366,21 +344,17 @@ type DRV_TAB LONG_LIVED SYSTEM drv_tab type DRV_EV_STATE LONG_LIVED SYSTEM driver_event_state type DRV_SEL_D_STATE FIXED_SIZE SYSTEM driver_select_data_state type NIF_SEL_D_STATE FIXED_SIZE SYSTEM enif_select_data_state -type FD_LIST SHORT_LIVED SYSTEM fd_list type POLLSET LONG_LIVED SYSTEM pollset type POLLSET_UPDREQ SHORT_LIVED SYSTEM pollset_update_req type POLL_FDS LONG_LIVED SYSTEM poll_fds -type POLL_RES_EVS LONG_LIVED SYSTEM poll_result_events type FD_STATUS LONG_LIVED SYSTEM fd_status type SELECT_FDS LONG_LIVED SYSTEM select_fds +if unix type SYS_READ_BUF TEMPORARY SYSTEM sys_read_buf -type FD_TAB LONG_LIVED SYSTEM fd_tab type FD_ENTRY_BUF STANDARD SYSTEM fd_entry_buf type CS_PROG_PATH LONG_LIVED SYSTEM cs_prog_path -type PRT_REP_EXIT STANDARD SYSTEM port_report_exit type SYS_BLOCKING STANDARD SYSTEM sys_blocking type SYS_WRITE_BUF TEMPORARY SYSTEM sys_write_buf @@ -392,7 +366,6 @@ type SYS_WRITE_BUF TEMPORARY SYSTEM sys_write_buf type DRV_DATA_BUF SYSTEM SYSTEM drv_data_buf type PRELOADED LONG_LIVED SYSTEM preloaded type WAITER_OBJ LONG_LIVED SYSTEM waiter_object -type CON_VPRINTF_BUF TEMPORARY SYSTEM con_vprintf_buf +endif diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h index ff4d10b206..cbae8ce98a 100644 --- a/erts/emulator/beam/erl_alloc_util.h +++ b/erts/emulator/beam/erl_alloc_util.h @@ -414,6 +414,10 @@ struct AOFF_RBTree_t_ { AOFF_RBTree_t *right; Uint32 flags; Uint32 max_sz; /* of all blocks in this sub-tree */ + union { + AOFF_RBTree_t* next; /* for best fit */ + Sint64 birth_time; /* for age first fit */ + } u; }; void aoff_add_pooled_mbc(Allctr_t*, Carrier_t*); diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c index 0c5545401a..ebbe4af53d 100644 --- a/erts/emulator/beam/erl_ao_firstfit_alloc.c +++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c @@ -100,22 +100,14 @@ #define AOFF_BLK_SZ(B) MBC_FBLK_SZ(&(B)->hdr) -/* BF block nodes keeps list of all with equal size - */ -typedef struct { - AOFF_RBTree_t t; - AOFF_RBTree_t *next; -}AOFF_RBTreeList_t; - -#define LIST_NEXT(N) (((AOFF_RBTreeList_t*) (N))->next) -#define LIST_PREV(N) (((AOFF_RBTreeList_t*) (N))->t.parent) +#define LIST_NEXT(N) (((AOFF_RBTree_t*)(N))->u.next) +#define LIST_PREV(N) (((AOFF_RBTree_t*)(N))->parent) typedef struct AOFF_Carrier_t_ AOFF_Carrier_t; struct AOFF_Carrier_t_ { Carrier_t crr; AOFF_RBTree_t rbt_node; /* My node in the carrier tree */ - Sint64 birth_time; AOFF_RBTree_t* root; /* Root of my block tree */ }; #define RBT_NODE_TO_MBC(PTR) ErtsContainerStruct((PTR), AOFF_Carrier_t, rbt_node) @@ -199,9 +191,7 @@ static ERTS_INLINE SWord cmp_blocks(enum AOFFSortOrder order, { ASSERT(lhs != rhs); if (order == FF_AGEFF) { - AOFF_Carrier_t* lc = RBT_NODE_TO_MBC(lhs); - AOFF_Carrier_t* rc = RBT_NODE_TO_MBC(rhs); - Sint64 diff = lc->birth_time - rc->birth_time; + Sint64 diff = lhs->u.birth_time - rhs->u.birth_time; #ifdef ARCH_64 if (diff) return diff; @@ -296,8 +286,10 @@ erts_aoffalc_start(AOFFAllctr_t *alc, allctr->mbc_header_size = sizeof(AOFF_Carrier_t); allctr->min_mbc_size = MIN_MBC_SZ; allctr->min_mbc_first_free_size = MIN_MBC_FIRST_FREE_SZ; - allctr->min_block_size = (aoffinit->blk_order == FF_BF ? - sizeof(AOFF_RBTreeList_t):sizeof(AOFF_RBTree_t)); + allctr->min_block_size = (aoffinit->blk_order == FF_BF + ? (offsetof(AOFF_RBTree_t, u.next) + + ErtsSizeofMember(AOFF_RBTree_t, u.next)) + : offsetof(AOFF_RBTree_t, u)); allctr->vsn_str = ERTS_ALC_AOFF_ALLOC_VSN_STR; @@ -939,8 +931,11 @@ static void aoff_creating_mbc(Allctr_t *allctr, Carrier_t *carrier) HARD_CHECK_TREE(NULL, alc->crr_order, *root, 0); crr->rbt_node.hdr.bhdr = 0; - if (alc->crr_order == FF_AGEFF || IS_DEBUG) - crr->birth_time = get_birth_time(); + if (alc->crr_order == FF_AGEFF || IS_DEBUG) { + Sint64 bt = get_birth_time(); + crr->rbt_node.u.birth_time = bt; + crr->crr.cpool.pooled.u.birth_time = bt; + } rbt_insert(alc->crr_order, root, &crr->rbt_node); /* aoff_link_free_block will add free block later */ @@ -978,6 +973,7 @@ static void aoff_add_mbc(Allctr_t *allctr, Carrier_t *carrier) void aoff_add_pooled_mbc(Allctr_t *allctr, Carrier_t *crr) { + AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr; AOFF_RBTree_t **root = &allctr->cpool.pooled_tree; ASSERT(allctr == crr->cpool.orig_allctr); @@ -985,7 +981,7 @@ void aoff_add_pooled_mbc(Allctr_t *allctr, Carrier_t *crr) /* Link carrier in address order tree */ - rbt_insert(FF_AOFF, root, &crr->cpool.pooled); + rbt_insert(alc->crr_order, root, &crr->cpool.pooled); HARD_CHECK_TREE(NULL, 0, *root, 0); } diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.h b/erts/emulator/beam/erl_ao_firstfit_alloc.h index 9cf4fc81a8..dad864801f 100644 --- a/erts/emulator/beam/erl_ao_firstfit_alloc.h +++ b/erts/emulator/beam/erl_ao_firstfit_alloc.h @@ -29,10 +29,10 @@ typedef struct AOFFAllctr_t_ AOFFAllctr_t; enum AOFFSortOrder { - FF_AGEFF = 0, + FF_AGEFF = 0, /* carrier trees only */ FF_AOFF = 1, - FF_AOBF = 2, - FF_BF = 3 + FF_AOBF = 2, /* block trees only */ + FF_BF = 3 /* block trees only */ }; typedef struct { diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c index 9095bcd380..cf92687595 100644 --- a/erts/emulator/beam/erl_bif_chksum.c +++ b/erts/emulator/beam/erl_bif_chksum.c @@ -44,7 +44,7 @@ void erts_init_bif_chksum(void) { /* Non visual BIF to trap to. */ erts_init_trap_export(&chksum_md5_2_exp, - am_erlang, am_atom_put("md5_trap",8), 2, + am_erlang, ERTS_MAKE_AM("md5_trap"), 2, &md5_2); } diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 8b2b1a58c7..5789fa8e71 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -3129,6 +3129,9 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) else if (ERTS_IS_ATOM_STR("ets_limit",BIF_ARG_1)) { BIF_RET(make_small(erts_db_get_max_tabs())); } + else if (ERTS_IS_ATOM_STR("ets_count",BIF_ARG_1)) { + BIF_RET(make_small(erts_ets_table_count())); + } else if (ERTS_IS_ATOM_STR("atom_limit",BIF_ARG_1)) { BIF_RET(make_small(erts_get_atom_limit())); } diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 3a29f8cf56..82e31f4cab 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -322,10 +322,10 @@ erts_db_make_tid(Process *c_p, DbTableCommon *tb) /* ** The meta hash table of all NAMED ets tables */ -# define META_NAME_TAB_LOCK_CNT 16 +# define META_NAME_TAB_LOCK_CNT 256 union { erts_rwmtx_t lck; - byte _cache_line_alignment[64]; + byte align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(erts_rwmtx_t))]; }meta_name_tab_rwlocks[META_NAME_TAB_LOCK_CNT]; static struct meta_name_tab_entry { union { @@ -450,7 +450,7 @@ save_sched_table(Process *c_p, DbTable *tb) DbTable *first; ASSERT(esdp); - esdp->ets_tables.count++; + erts_atomic_inc_nob(&esdp->ets_tables.count); erts_refc_inc(&tb->common.refc, 1); first = esdp->ets_tables.clist; @@ -474,8 +474,8 @@ remove_sched_table(ErtsSchedulerData *esdp, DbTable *tb) ASSERT(erts_get_ref_numbers_thr_id(ERTS_MAGIC_BIN_REFN(tb->common.btid)) == (Uint32) esdp->no); - ASSERT(esdp->ets_tables.count > 0); - esdp->ets_tables.count--; + ASSERT(erts_atomic_read_nob(&esdp->ets_tables.count) > 0); + erts_atomic_dec_nob(&esdp->ets_tables.count); eaydp = ERTS_SCHED_AUX_YIELD_DATA(esdp, ets_all); if (eaydp->ongoing) { @@ -1776,9 +1776,11 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) ret = make_tid(BIF_P, tb); save_sched_table(BIF_P, tb); + save_owned_table(BIF_P, tb); if (is_named && !insert_named_tab(BIF_ARG_1, tb, 0)) { tid_clear(BIF_P, tb); + delete_owned_table(BIF_P, tb); db_lock(tb,LCK_WRITE); free_heir_data(tb); @@ -1789,7 +1791,6 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) } BIF_P->flags |= F_USING_DB; /* So we can remove tb if p dies */ - save_owned_table(BIF_P, tb); #ifdef HARDDEBUG erts_fprintf(stderr, @@ -1968,8 +1969,6 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) save_owned_table(BIF_P, tb); } - tid_clear(BIF_P, tb); - if (is_table_named(tb)) remove_named_tab(tb, 0); @@ -1978,6 +1977,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1) tb->common.heir = am_none; reds -= free_fixations_locked(BIF_P, tb); + tid_clear(BIF_P, tb); db_unlock(tb, LCK_WRITE); reds = free_table_continue(BIF_P, tb, reds); @@ -2445,7 +2445,7 @@ ets_all_reply(ErtsSchedulerData *esdp, ErtsEtsAllReq **reqpp, ASSERT(!*tablepp); /* Max heap size needed... */ - sz = esdp->ets_tables.count; + sz = erts_atomic_read_nob(&esdp->ets_tables.count); sz *= ERTS_MAGIC_REF_THING_SIZE + 2; sz += 3 + ERTS_REF_THING_SIZE; hfragp = new_message_buffer(sz); @@ -2529,7 +2529,8 @@ erts_handle_yielded_ets_all_request(ErtsSchedulerData *esdp, if (!eaydp->queue) return 0; /* All work completed! */ - if (yc < ERTS_ETS_ALL_TB_YCNT_START && yc > esdp->ets_tables.count) + if (yc < ERTS_ETS_ALL_TB_YCNT_START && + yc > erts_atomic_read_nob(&esdp->ets_tables.count)) return 1; /* Yield! */ eaydp->ongoing = ongoing = eaydp->queue; @@ -2608,7 +2609,6 @@ BIF_RETTYPE ets_internal_request_all_0(BIF_ALIST_0) BIF_RET(ref); } - /* ** db_slot(Db, Slot) -> [Items]. */ @@ -3490,7 +3490,11 @@ void init_db(ErtsDbSpinCount db_spin_count) db_max_tabs, ((Uint)1)<<SMALL_BITS); } - meta_name_tab_mask = (((Uint) 1)<<(bits-1)) - 1; /* At least half the size of main tab */ + /* + * We don't have ony hard limit for number of tables anymore, . + * but we use 'db_max_tabs' to determine size of name hash table. + */ + meta_name_tab_mask = (((Uint) 1)<<bits) - 1; size = sizeof(struct meta_name_tab_entry)*(meta_name_tab_mask+1); meta_name_tab = erts_db_alloc_nt(ERTS_ALC_T_DB_TABLES, size); ERTS_ETS_MISC_MEM_ADD(size); @@ -3505,27 +3509,27 @@ void init_db(ErtsDbSpinCount db_spin_count) /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_delete_continue_exp, - am_ets, am_atom_put("delete_trap",11), 1, + am_ets, ERTS_MAKE_AM("select_delete_trap"), 1, &ets_select_delete_trap_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_count_continue_exp, - am_ets, am_atom_put("count_trap",11), 1, + am_ets, ERTS_MAKE_AM("count_trap"), 1, &ets_select_count_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_replace_continue_exp, - am_ets, am_atom_put("replace_trap",11), 1, + am_ets, ERTS_MAKE_AM("replace_trap"), 1, &ets_select_replace_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_select_continue_exp, - am_ets, am_atom_put("select_trap",11), 1, + am_ets, ERTS_MAKE_AM("select_trap"), 1, &ets_select_trap_1); /* Non visual BIF to trap to. */ erts_init_trap_export(&ets_delete_continue_exp, - am_ets, am_atom_put("delete_trap",11), 1, + am_ets, ERTS_MAKE_AM("delete_trap"), 1, &ets_delete_trap); } @@ -3538,7 +3542,7 @@ erts_ets_sched_spec_data_init(ErtsSchedulerData *esdp) eaydp->tab = NULL; eaydp->queue = NULL; esdp->ets_tables.clist = NULL; - esdp->ets_tables.count = 0; + erts_atomic_init_nob(&esdp->ets_tables.count, 0); } @@ -3750,7 +3754,6 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks) && give_away_to_heir(c_p, tb)) { break; } - tid_clear(c_p, tb); /* Clear all access bits. */ tb->common.status &= ~(DB_PROTECTED | DB_PUBLIC | DB_PRIVATE); tb->common.status |= DB_DELETE; @@ -3760,6 +3763,7 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks) free_heir_data(tb); reds -= free_fixations_locked(c_p, tb); + tid_clear(c_p, tb); db_unlock(tb, LCK_WRITE); state->op = FREE_OWNED_TABLE; break; @@ -3907,7 +3911,7 @@ static void free_fixations_op(DbFixation* fix, void* vctx) struct free_fixations_ctx* ctx = (struct free_fixations_ctx*) vctx; erts_aint_t diff; - ASSERT(!btid2tab(fix->tabs.btid)); + ASSERT(btid2tab(fix->tabs.btid) == ctx->tb); ASSERT(fix->counter > 0); ASSERT(ctx->tb->common.status & DB_DELETE); @@ -4154,7 +4158,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) else if (What == am_data) { print_table(ERTS_PRINT_STDOUT, NULL, 1, tb); ret = am_true; - } else if (What == am_atom_put("fixed",5)) { + } else if (ERTS_IS_ATOM_STR("fixed",What)) { if (IS_FIXED(tb)) ret = am_true; else @@ -4206,7 +4210,7 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) ret = am_false; } erts_mtx_unlock(&tb->common.fixlock); - } else if (What == am_atom_put("stats",5)) { + } else if (ERTS_IS_ATOM_STR("stats",What)) { if (IS_HASH_TABLE(tb->common.status)) { FloatDef f; DbHashStats stats; @@ -4346,6 +4350,18 @@ erts_db_get_max_tabs() return db_max_tabs; } +Uint erts_ets_table_count(void) +{ + Uint tb_count = 0; + Uint six; + + for (six = 0; six < erts_no_schedulers; six++) { + ErtsSchedulerData *esdp = &erts_aligned_scheduler_data[six].esd; + tb_count += erts_atomic_read_nob(&esdp->ets_tables.count); + } + return tb_count; +} + /* * For testing of meta tables only. * diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h index db86c81914..db1dec015c 100644 --- a/erts/emulator/beam/erl_db.h +++ b/erts/emulator/beam/erl_db.h @@ -45,7 +45,7 @@ typedef struct { } ErtsEtsAllYieldData; typedef struct { - Uint count; + erts_atomic_t count; DbTable *clist; } ErtsEtsTables; @@ -69,6 +69,7 @@ typedef struct { /*TT*/ Uint erts_get_ets_misc_mem_size(void); +Uint erts_ets_table_count(void); typedef struct { DbTableCommon common; @@ -93,7 +94,7 @@ union db_table { /*TT*/ }; -#define DB_DEF_MAX_TABS 2053 /* Superseeded by environment variable +#define DB_DEF_MAX_TABS 8192 /* Superseeded by environment variable "ERL_MAX_ETS_TABLES" */ #define ERL_MAX_ETS_TABLES_ENV "ERL_MAX_ETS_TABLES" diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 37d261d0df..f1d47326b4 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -2770,9 +2770,7 @@ Eterm db_format_dmc_err_info(Process *p, DMCErrInfo *ei) sys_strcpy(buff,tmp->error_string); sl = sys_strlen(buff); shp = HAlloc(p, sl * 2 + 5); - sev = (tmp->severity == dmcWarning) ? - am_atom_put("warning",7) : - am_error; + sev = (tmp->severity == dmcWarning) ? am_warning : am_error; tlist = buf_to_intlist(&shp, buff, sl, NIL); tpl = TUPLE2(shp, sev, tlist); shp += 3; @@ -5180,7 +5178,7 @@ BIF_RETTYPE match_spec_test_3(BIF_ALIST_3) { Eterm res; #ifdef DMC_DEBUG - if (BIF_ARG_3 == am_atom_put("dis",3)) { + if (BIF_ARG_3 == ERTS_MAKE_AM("dis")) { test_disassemble_next = 1; BIF_RET(am_true); } else @@ -5291,7 +5289,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) erts_free(ERTS_ALC_T_DB_TMP, arr); } erts_bin_free(mps); - ret = TUPLE4(hp, am_atom_put("ok",2), res, flg, lint_res); + ret = TUPLE4(hp, am_ok, res, flg, lint_res); } return ret; } diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 4a3671df0c..3953a4c2e9 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -1567,8 +1567,9 @@ fail: erts_port_dec_refc(pp); if (ptp) { - abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT, - ptp->type, &ptp->u.alive.td, 0); + if (ptp->type == ERTS_PORT_TASK_PROC_SIG) + abort_signal_task(pp, ERTS_PROC2PORT_SIG_ABORT, + ptp->type, &ptp->u.alive.td, 0); port_task_free(ptp); } diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index e9b41ad298..d6d22677e7 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -423,13 +423,13 @@ sig_enqueue_trace(Process *c_p, ErtsMessage **sigp, int op, } static void -sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig, ErtsMessage *last) +sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig) { ErtsMessage *tmp; /* The usual case; no tracing signals... */ - if (sig == (ErtsSignal *) first && sig == (ErtsSignal *) last) { - sig->common.next = NULL; + if (sig == (ErtsSignal *) first) { + ASSERT(sig->common.next == NULL); return; } @@ -445,6 +445,8 @@ sig_enqueue_trace_cleanup(ErtsMessage *first, ErtsSignal *sig, ErtsMessage *last case ERTS_SIG_Q_OP_TRACE_CHANGE_STATE: destroy_trace_info((ErtsSigTraceInfo *) tmp_free); break; + case ERTS_SIG_Q_OP_MONITOR: + break; /* ignore flushed pending signal */ default: ERTS_INTERNAL_ERROR("Unexpected signal op"); break; @@ -667,7 +669,7 @@ proc_queue_signal(Process *c_p, Eterm pid, ErtsSignal *sig, int op) first_last_done: sig->common.specific.next = NULL; - /* may add signals before and/or after sig */ + /* may add signals before sig */ sig_enqueue_trace(c_p, sigp, op, rp, &last_next); last->next = NULL; @@ -688,22 +690,18 @@ first_last_done: erts_proc_unlock(rp, ERTS_PROC_LOCK_MSGQ); if (res == 0) { + sig_enqueue_trace_cleanup(first, sig); if (pend_sig) { + erts_proc_sig_send_monitor_down((ErtsMonitor*)pend_sig, am_noproc); if (sig == pend_sig) { /* We did a switch, callers signal is now pending (still ok) */ ASSERT(esdp->pending_signal.sig); res = 1; } - else { - ASSERT(first == (ErtsMessage*)pend_sig); - first = first->next; - } - erts_proc_sig_send_monitor_down((ErtsMonitor*)pend_sig, am_noproc); } - sig_enqueue_trace_cleanup(first, sig, last); } - - erts_proc_notify_new_sig(rp, state, 0); + else + erts_proc_notify_new_sig(rp, state, 0); if (!is_normal_sched) erts_proc_dec_refc(rp); @@ -2725,6 +2723,9 @@ handle_process_info(Process *c_p, ErtsSigRecvTracing *tracing, Uint reds = 0; Process *rp; + ASSERT(!!is_alive == !(erts_atomic32_read_nob(&c_p->state) + & ERTS_PSFLG_EXITING)); + if (pisig->msgq_len_offset != ERTS_PROC_SIG_PI_MSGQ_LEN_IGNORE) { /* * Request requires message queue data to be updated @@ -3009,10 +3010,8 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep, ERTS_HDBG_CHECK_SIGNAL_PRIV_QUEUE(c_p, 0); ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN == erts_proc_lc_my_proc_locks(c_p)); - if (local_only) - state = -1; /* can never be a valid state... */ - else { - state = erts_atomic32_read_nob(&c_p->state); + state = erts_atomic32_read_nob(&c_p->state); + if (!local_only) { if (ERTS_PSFLG_SIG_IN_Q & state) { erts_proc_lock(c_p, ERTS_PROC_LOCK_MSGQ); erts_proc_sig_fetch(c_p); @@ -3025,13 +3024,15 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep, yield = 0; if (!c_p->sig_qs.cont) { - if (state == -1) - *statep = erts_atomic32_read_nob(&c_p->state); - else - *statep = state; + *statep = state; return !0; } + if (state & ERTS_PSFLG_EXITING) { + *statep = state; + return 0; + } + next_nm_sig = &c_p->sig_qs.nmsigs.next; setup_tracing_state(c_p, &tracing); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 1478b71195..8253ec4f40 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -9186,6 +9186,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) internal_sched_out_proc: ERTS_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p); + ASSERT(p->scheduler_data || ERTS_SCHEDULER_IS_DIRTY(esdp)); ASSERT(actual_reds >= 0); if (reds < ERTS_PROC_MIN_CONTEXT_SWITCH_REDS_COST) @@ -9618,6 +9619,8 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) state = erts_atomic32_read_nob(&p->state); if (is_normal_sched) { + ASSERT(!p->scheduler_data); + p->scheduler_data = esdp; if ((!!(state & ERTS_PSFLGS_DIRTY_WORK)) & (!(state & ERTS_PSFLG_ACTIVE_SYS))) { /* Migrate to dirty scheduler... */ @@ -9625,8 +9628,6 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) erts_proc_unlock(p, ERTS_PROC_LOCK_STATUS); goto sched_out_proc; } - ASSERT(!p->scheduler_data); - p->scheduler_data = esdp; } else { if (!(state & ERTS_PSFLGS_DIRTY_WORK)) { diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c index 8673e029e6..d225916ac5 100644 --- a/erts/emulator/beam/erl_unicode.c +++ b/erts/emulator/beam/erl_unicode.c @@ -79,23 +79,23 @@ void erts_init_unicode(void) max_loop_limit = CONTEXT_REDS * LOOP_FACTOR; /* Non visual BIFs to trap to. */ erts_init_trap_export(&characters_to_utf8_trap_exp, - am_erlang, am_atom_put("characters_to_utf8_trap",23), 3, + am_erlang, ERTS_MAKE_AM("characters_to_utf8_trap"), 3, &characters_to_utf8_trap); erts_init_trap_export(&characters_to_list_trap_1_exp, - am_erlang, am_atom_put("characters_to_list_trap_1",25), 3, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_1"), 3, &characters_to_list_trap_1); erts_init_trap_export(&characters_to_list_trap_2_exp, - am_erlang, am_atom_put("characters_to_list_trap_2",25), 3, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_2"), 3, &characters_to_list_trap_2); erts_init_trap_export(&characters_to_list_trap_3_exp, - am_erlang, am_atom_put("characters_to_list_trap_3",25), 3, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_3"), 3, &characters_to_list_trap_3); erts_init_trap_export(&characters_to_list_trap_4_exp, - am_erlang, am_atom_put("characters_to_list_trap_4",25), 1, + am_erlang, ERTS_MAKE_AM("characters_to_list_trap_4"), 1, &characters_to_list_trap_4); c_to_b_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_binary_int,2); diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index d74052d8b2..78d9d5e613 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -1946,7 +1946,7 @@ do_allocate_logger_message(Eterm gleader, ErtsMonotonicTime *ts, Eterm *pid, else sz += MAP4_SZ /* metadata map w gl w pid*/; - *ts = ERTS_MONOTONIC_TO_USEC(erts_get_monotonic_time(NULL)) + ERTS_MONOTONIC_OFFSET_USEC; + *ts = ERTS_MONOTONIC_TO_USEC(erts_get_monotonic_time(NULL) + erts_get_time_offset()); erts_bld_sint64(NULL, &sz, *ts); *bp = new_message_buffer(sz); @@ -1972,8 +1972,7 @@ static void do_send_logger_message(Eterm gl, Eterm tag, Eterm format, Eterm args break; } - md = MAP2(hp, am_emulator, am_true, - am_atom_put("tag", 3), el_tag); + md = MAP2(hp, am_emulator, am_true, ERTS_MAKE_AM("tag"), el_tag); hp += MAP2_SZ; if (is_nil(gl) && is_non_value(pid)) { @@ -1994,14 +1993,14 @@ static void do_send_logger_message(Eterm gl, Eterm tag, Eterm format, Eterm args /* no gl */ md = MAP3(hp, am_error_logger, md, - am_atom_put("gl", 2), gl, + ERTS_MAKE_AM("gl"), gl, am_time, time); hp += MAP3_SZ; pid = NIL; } else { md = MAP4(hp, am_error_logger, md, - am_atom_put("gl", 2), gl, + ERTS_MAKE_AM("gl"), gl, am_pid, pid, am_time, time); hp += MAP4_SZ; diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c index 5dadd8a5a6..145503bea7 100644 --- a/erts/emulator/sys/common/erl_mmap.c +++ b/erts/emulator/sys/common/erl_mmap.c @@ -2514,8 +2514,8 @@ Eterm erts_mmap_debug_info(Process* p) sizeof(values)/sizeof(*values), tags, values); - sa_list = TUPLE2(hp, am_atom_put("sa_free_segs",12), sa_list); hp+=3; - sua_list = TUPLE2(hp, am_atom_put("sua_free_segs",13), sua_list); hp+=3; + sa_list = TUPLE2(hp, ERTS_MAKE_AM("sa_free_segs"), sa_list); hp+=3; + sua_list = TUPLE2(hp, ERTS_MAKE_AM("sua_free_segs"), sua_list); hp+=3; list = CONS(hp, sua_list, list); hp+=2; list = CONS(hp, sa_list, list); hp+=2; diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index fdf4aab24d..7309908337 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -37,6 +37,7 @@ -export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1, memory/1, ets_limit/1, atom_limit/1, + ets_count/1, atom_count/1]). suite() -> @@ -45,6 +46,7 @@ suite() -> all() -> [process_count, system_version, misc_smoke_tests, + ets_count, heap_size, wordsize, memory, ets_limit, atom_limit, atom_count]. %%% @@ -478,6 +480,21 @@ get_node_name(Config) -> ++ "-" ++ integer_to_list(erlang:unique_integer([positive]))). +ets_count(Config) when is_list(Config) -> + [ets_count_do([Type | Named]) + || Type <- [set, bag, duplicate_bag, ordered_set], + Named <- [[named_table], []] + ], + ok. + +ets_count_do(Opts) -> + Before = erlang:system_info(ets_count), + T = ets:new(?MODULE, Opts), + After = erlang:system_info(ets_count), + After = Before + 1, + ets:delete(T), + Before = erlang:system_info(ets_count). + %% Verify system_info(ets_limit) reflects max ETS table settings. ets_limit(Config0) when is_list(Config0) -> diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c index d739d21f12..c84e63ad7c 100644 --- a/erts/etc/common/escript.c +++ b/erts/etc/common/escript.c @@ -139,15 +139,6 @@ get_env(char *key) } static void -free_env_val(char *value) -{ -#ifdef __WIN32__ - if (value) - efree(value); -#endif -} - -static void set_env(char *key, char *value) { #ifdef __WIN32__ @@ -422,7 +413,6 @@ main(int argc, char** argv) int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; - char* env; char* basename; char* def_emu_lookup_path; char scriptname[PMAX]; @@ -504,7 +494,7 @@ main(int argc, char** argv) } /* Determine path to emulator */ - emulator = env = get_env("ESCRIPT_EMULATOR"); + emulator = get_env("ESCRIPT_EMULATOR"); if (emulator == NULL) { emulator = get_default_emulator(def_emu_lookup_path); @@ -518,7 +508,6 @@ main(int argc, char** argv) */ PUSH(emulator); - free_env_val(env); PUSH("+B"); PUSH2("-boot", "no_dot_erlang"); diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index 39e378193a..5b89621733 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -1346,7 +1346,6 @@ define etp-sigq-int else if $etp_sig_save_last && *$etp_sig_save_last == $etp_sig printf " %% <== SAVED_LAST" - else end end if $etp_sig_next diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in index 48660f7c71..dfaf664a18 100644 --- a/erts/lib_src/Makefile.in +++ b/erts/lib_src/Makefile.in @@ -334,7 +334,7 @@ ETHREAD_LIB= endif -ifneq ($(CREATE_DIRS),) +ifneq ($(strip $(CREATE_DIRS)),) _create_dirs := $(shell mkdir -p $(CREATE_DIRS)) endif diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex 52f4c686a9..99f11495a5 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 3a42e841e2..f4f31b1e4b 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -3778,8 +3778,8 @@ blocks_size([], Acc) -> Acc. get_fix_proc([{ProcType, A1, U1}| Rest], {A0, U0}) when ProcType == proc; - ProcType == monitor_sh; - ProcType == nlink_sh; + ProcType == monitor; + ProcType == link; ProcType == msg_ref; ProcType == ll_ptimer; ProcType == hl_ptimer; @@ -3903,7 +3903,6 @@ aa_mem_data(#memory{processes = Proc, processes_used = ProcU, system = Sys} = Mem, [{ProcData, Sz} | Rest]) when ProcData == bif_timer; - ProcData == link_lh; ProcData == process_table -> aa_mem_data(Mem#memory{processes = Proc+Sz, processes_used = ProcU+Sz, diff --git a/erts/preloaded/src/erts_code_purger.erl b/erts/preloaded/src/erts_code_purger.erl index fd214228c7..c41532ed87 100644 --- a/erts/preloaded/src/erts_code_purger.erl +++ b/erts/preloaded/src/erts_code_purger.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2016. All Rights Reserved. +%% Copyright Ericsson AB 2016-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ -export([start/0, purge/1, soft_purge/1, pending_purge_lambda/3, finish_after_on_load/2]). --spec start() -> term(). +-spec start() -> no_return(). start() -> register(erts_code_purger, self()), process_flag(trap_exit, true), diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl index a4ef42204d..6f53e67901 100644 --- a/erts/preloaded/src/zlib.erl +++ b/erts/preloaded/src/zlib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2017. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ %%------------------------------------------------------------------------ %% Public data types. --type zstream() :: term(). +-type zstream() :: reference(). -type zflush() :: 'none' | 'sync' | 'full' | 'finish'. -type zlevel() :: @@ -102,11 +102,11 @@ -type zmethod() :: 'deflated'. -record(zlib_opts, { - stream :: zstream(), - method :: term(), - input_chunk_size :: integer(), - output_chunk_size :: integer(), - flush :: integer() + stream :: zstream() | 'undefined', + method :: function(), + input_chunk_size :: pos_integer(), + output_chunk_size :: pos_integer(), + flush :: non_neg_integer() }). %%------------------------------------------------------------------------ @@ -168,7 +168,7 @@ deflateInit_nif(_Z, _Level, _Method, _WindowBits, _MemLevel, _Strategy) -> -spec deflateSetDictionary(Z, Dictionary) -> Adler32 when Z :: zstream(), Dictionary :: iodata(), - Adler32 :: integer(). + Adler32 :: non_neg_integer(). deflateSetDictionary(Z, Dictionary) -> deflateSetDictionary_nif(Z, Dictionary). deflateSetDictionary_nif(_Z, _Dictionary) -> @@ -295,7 +295,7 @@ inflate(Z, Data) -> Options :: list({exception_on_need_dict, boolean()}), Decompressed :: iolist() | {need_dictionary, - Adler32 :: integer(), + Adler32 :: non_neg_integer(), Output :: iolist()}. inflate(Z, Data, Options) -> enqueue_input(Z, Data), @@ -357,7 +357,7 @@ exception_on_need_dict(Z, Output) when is_list(Output); is_binary(Output) -> Result :: {continue, Output :: iolist()} | {finished, Output :: iolist()} | {need_dictionary, - Adler32 :: integer(), + Adler32 :: non_neg_integer(), Output :: iolist()}. safeInflate(Z, Data) -> enqueue_input(Z, Data), @@ -389,7 +389,7 @@ getBufSize_nif(_Z) -> -spec crc32(Z) -> CRC when Z :: zstream(), - CRC :: integer(). + CRC :: non_neg_integer(). crc32(Z) -> crc32_nif(Z). crc32_nif(_Z) -> @@ -398,7 +398,7 @@ crc32_nif(_Z) -> -spec crc32(Z, Data) -> CRC when Z :: zstream(), Data :: iodata(), - CRC :: integer(). + CRC :: non_neg_integer(). crc32(Z, Data) when is_reference(Z) -> erlang:crc32(Data); crc32(_Z, _Data) -> @@ -406,9 +406,9 @@ crc32(_Z, _Data) -> -spec crc32(Z, PrevCRC, Data) -> CRC when Z :: zstream(), - PrevCRC :: integer(), + PrevCRC :: non_neg_integer(), Data :: iodata(), - CRC :: integer(). + CRC :: non_neg_integer(). crc32(Z, CRC, Data) when is_reference(Z) -> erlang:crc32(CRC, Data); crc32(_Z, _CRC, _Data) -> @@ -416,10 +416,10 @@ crc32(_Z, _CRC, _Data) -> -spec crc32_combine(Z, CRC1, CRC2, Size2) -> CRC when Z :: zstream(), - CRC :: integer(), - CRC1 :: integer(), - CRC2 :: integer(), - Size2 :: integer(). + CRC :: non_neg_integer(), + CRC1 :: non_neg_integer(), + CRC2 :: non_neg_integer(), + Size2 :: non_neg_integer(). crc32_combine(Z, CRC1, CRC2, Size2) when is_reference(Z) -> erlang:crc32_combine(CRC1, CRC2, Size2); crc32_combine(_Z, _CRC1, _CRC2, _Size2) -> @@ -428,7 +428,7 @@ crc32_combine(_Z, _CRC1, _CRC2, _Size2) -> -spec adler32(Z, Data) -> CheckSum when Z :: zstream(), Data :: iodata(), - CheckSum :: integer(). + CheckSum :: non_neg_integer(). adler32(Z, Data) when is_reference(Z) -> erlang:adler32(Data); adler32(_Z, _Data) -> @@ -436,9 +436,9 @@ adler32(_Z, _Data) -> -spec adler32(Z, PrevAdler, Data) -> CheckSum when Z :: zstream(), - PrevAdler :: integer(), + PrevAdler :: non_neg_integer(), Data :: iodata(), - CheckSum :: integer(). + CheckSum :: non_neg_integer(). adler32(Z, Adler, Data) when is_reference(Z) -> erlang:adler32(Adler, Data); adler32(_Z, _Adler, _Data) -> @@ -446,10 +446,10 @@ adler32(_Z, _Adler, _Data) -> -spec adler32_combine(Z, Adler1, Adler2, Size2) -> Adler when Z :: zstream(), - Adler :: integer(), - Adler1 :: integer(), - Adler2 :: integer(), - Size2 :: integer(). + Adler :: non_neg_integer(), + Adler1 :: non_neg_integer(), + Adler2 :: non_neg_integer(), + Size2 :: non_neg_integer(). adler32_combine(Z, Adler1, Adler2, Size2) when is_reference(Z) -> erlang:adler32_combine(Adler1, Adler2, Size2); adler32_combine(_Z, _Adler1, _Adler2, _Size2) -> diff --git a/erts/vsn.mk b/erts/vsn.mk index 6a966f17b8..687c62343e 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 10.0 +VSN = 9.3.2 # Port number 4365 in 4.2 # Port number 4366 in 4.3 |
