aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erl_tracer.xml13
-rw-r--r--erts/doc/src/notes.xml555
-rw-r--r--erts/emulator/Makefile.in4
-rw-r--r--erts/emulator/beam/bif.c6
-rw-r--r--erts/emulator/beam/erl_alloc_util.c12
-rw-r--r--erts/emulator/beam/erl_alloc_util.h7
-rw-r--r--erts/emulator/beam/erl_bits.c2
-rw-r--r--erts/emulator/beam/erl_bits.h1
-rw-r--r--erts/emulator/beam/erl_cpu_topology.c57
-rw-r--r--erts/emulator/beam/erl_db_hash.c2
-rw-r--r--erts/emulator/beam/erl_process.c6
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c16
-rw-r--r--erts/emulator/test/Makefile1
-rw-r--r--erts/emulator/test/binary_SUITE.erl14
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl2
-rw-r--r--erts/emulator/test/call_trace_SUITE.erl2
-rw-r--r--erts/emulator/test/ddll_SUITE.erl2
-rw-r--r--erts/emulator/test/distribution_SUITE.erl132
-rw-r--r--erts/emulator/test/evil_SUITE.erl2
-rw-r--r--erts/emulator/test/exception_SUITE.erl2
-rw-r--r--erts/emulator/test/gc_SUITE.erl151
-rw-r--r--erts/emulator/test/lttng_SUITE.erl2
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl2
-rw-r--r--erts/emulator/test/nested_SUITE.erl2
-rw-r--r--erts/emulator/test/old_scheduler_SUITE.erl384
-rw-r--r--erts/emulator/test/port_SUITE.erl2
-rw-r--r--erts/emulator/test/port_trace_SUITE.erl2
-rw-r--r--erts/emulator/test/process_SUITE.erl83
-rw-r--r--erts/emulator/test/receive_SUITE.erl55
-rw-r--r--erts/emulator/test/timer_bif_SUITE.erl24
-rw-r--r--erts/emulator/test/trace_SUITE.erl10
-rw-r--r--erts/emulator/test/trace_port_SUITE.erl2
32 files changed, 315 insertions, 1242 deletions
diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml
index 63feebb0b5..fd3c17f337 100644
--- a/erts/doc/src/erl_tracer.xml
+++ b/erts/doc/src/erl_tracer.xml
@@ -653,7 +653,7 @@ ok
<0.37.0>
3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]).
0
-{<0.39.0>,<0.27.0>}
+{trace,<0.39.0>,<0.27.0>}
4> {ok, D} = file:open("/tmp/tmp.data",[write]).
{trace,#Port<0.486>,<0.40.0>}
{trace,<0.40.0>,<0.21.0>}
@@ -758,18 +758,21 @@ static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/*
* argv[0]: TraceTag, should only be 'send'
- * argv[1]: TracerState, process to send {argv[2], argv[4]} to
+ * argv[1]: TracerState, process to send {Tracee, Recipient} to
* argv[2]: Tracee
- * argv[3]: Recipient
- * argv[4]: Options, ignored
+ * argv[3]: Message
+ * argv[4]: Options, map containing Recipient
*/
static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifPid to_pid;
+ ERL_NIF_TERM recipient, msg;
if (enif_get_local_pid(env, argv[1], &to_pid)) {
- ERL_NIF_TERM msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], argv[4]);
+ if (enif_get_map_value(env, argv[4], enif_make_atom(env, "extra"), &recipient)) {
+ msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], recipient);
enif_send(env, &to_pid, NULL, msg);
+ }
}
return enif_make_atom(env, "ok");
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index d0fa170e66..8ae87ac280 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -32,559 +32,20 @@
<p>This document describes the changes made to the ERTS application.</p>
-<section><title>Erts 9.0</title>
+<section><title>Erts 8.3.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
<item>
- <p>Fix various bugs regarding loading, upgrade and purge
- of HiPE compiled code:</p> <list> <item>The native code
- memory for a purged module was never deallocated.</item>
- <item>Wrong functions could in some cases be called after
- a module upgrade.</item>
- <item><c>erlang:check_process_code</c> did not check for
- recursive calls made from native code.</item> </list>
<p>
- Own Id: OTP-13968</p>
- </item>
- <item>
- <p>
- Hipe optional LLVM backend does require LLVM version 3.9
- or later as older versions forced strong dependencies on
- erts internals structures.</p>
- <p>
- Own Id: OTP-14238</p>
- </item>
- <item>
- <p>When an exception such as '<c>throw(HugeTerm)</c>' was
- caught, <c>HugeTerm</c> term would be kept in the process
- until the next exception occurred, potentially increasing
- the heap size for the process. That has been
- corrected.</p>
- <p>
- Own Id: OTP-14255 Aux Id: OTP-14400, OTP-14401 </p>
- </item>
- <item>
- <p>
- Slogans in crash dumps have been extended to print more
- complex terms.</p>
- <p>
- Own Id: OTP-14303</p>
- </item>
- <item>
- <p>
- Fixed bug when using <c>enif_inspect_binary</c> in
- combination with <c>enif_copy</c>. In some circumstances
- the inspected binary could be realloced by the
- <c>enif_copy</c> call when it shouldn't have been.</p>
- <p>
- Own Id: OTP-14304</p>
- </item>
- <item>
- <p>
- The address family <c>local</c> (AF_UNIX / AF_LOCAL) now
- does not ensure zero termination of Linux Abstract
- Addresses so they can use all bytes.</p>
- <p>
- Own Id: OTP-14305</p>
- </item>
- <item>
- <p>
- Use <c>-fno-PIE</c> for Gentoo Hardened and others that
- don't accept linker flag <c>-no-pie</c>.</p>
- <p>
- Own Id: OTP-14307 Aux Id: PR-1379 </p>
- </item>
- <item>
- <p>
- Disable hipe for <c>ppc64le</c> architecture (little
- endian) as it is not, and has never been, supported. It
- was earlier equated with <c>ppc64</c> (big endian) which
- lead to broken build without <c>--disable-hipe</c>.</p>
- <p>
- Own Id: OTP-14314 Aux Id: ERL-369, PR-1394 </p>
- </item>
- <item>
- <p>
- Fix 'epmd -kill' to return a failure exit status code if
- epmd was not killed because of some error.</p>
- <p>
- Own Id: OTP-14324</p>
- </item>
- <item>
- <p>Fixed the following dirty scheduler related bugs:</p>
- <list> <item><p>the <c>+SDPcpu</c> command line argument
- could cause the amount of dirty CPU schedulers to be set
- to zero</p></item>
- <item><p><c>erlang:system_flag(multi_scheduling, _)</c>
- failed when only one normal scheduler was used together
- with dirty scheduler support</p></item> </list>
- <p>
- Own Id: OTP-14335</p>
- </item>
- <item>
- <p>
- Fix erlexec to handle mismatch in sysconf and proc fs
- when figuring out the cpu topology. This behaviour has
- been seen when using docker together with
- <c>--cpuset-cpus</c>.</p>
- <p>
- Own Id: OTP-14352</p>
- </item>
- <item>
- <p>
- Fixed memory segment cache used for multiblock carriers.
- Huge (> 2GB) memory segments could cause a VM crash.
- Creation of such huge memory segments used for multiblock
- carriers is however very uncommon.</p>
- <p>
- Own Id: OTP-14360 Aux Id: ERL-401, PR-1417 </p>
- </item>
- <item>
- <p>
- Fix bug causing <c>code:is_module_native</c> to falsely
- return true when <c>local</c> call trace is enabled for
- the module.</p>
- <p>
- Own Id: OTP-14390</p>
- </item>
- <item>
- <p>
- Fix emulator crash when receive tracing on a
- <c>trace_delivered</c> message.</p>
- <p>
- Own Id: OTP-14411</p>
- </item>
- <item>
- <p>
- <c>escript</c> did not handle paths with spaces correct.</p>
- <p>
- Own Id: OTP-14433</p>
- </item>
- <item>
- <p>
- Fix erroneous lock check assertion when <c>wx</c> is run
- on MacOS X.</p>
- <p>
- Own Id: OTP-14437 Aux Id: ERL-360 </p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Added <c>erlang:garbage_collect/2</c> that takes an
- option list as the last argument that can be used to
- control whether a minor or a major garbage collection is
- to be done. Doing a minor collection only collects terms
- that have recently died, but is cheaper than a mjor
- collection.</p>
- <p>
- Own Id: OTP-11695</p>
- </item>
- <item>
- <p>
- Optimized test for tuples with an atom as first element.</p>
- <p>
- Own Id: OTP-12148</p>
- </item>
- <item>
- <p>
- Erlang literals are no longer copied during process to
- process messaging.</p>
- <p>
- Own Id: OTP-13529</p>
- </item>
- <item>
- <p>Add support in the <c>erl_nif</c> API for asynchronous
- message notifications when sockets or other file
- descriptors are ready to accept read or write operations.
- The following functions have been added:</p> <list>
- <item><p>enif_select</p></item>
- <item><p>enif_monitor_process</p></item>
- <item><p>enif_demonitor_process</p></item>
- <item><p>enif_compare_monitors</p></item>
- <item><p>enif_open_resource_type_x</p></item> </list>
- <p>
- Own Id: OTP-13684</p>
- </item>
- <item>
- <p>There are two new guard BIFs '<c>floor/1</c>' and
- '<c>ceil/1</c>'. They both return integers. In the
- '<c>math</c>' module, there are two new BIFs with the
- same names that return floating point values.</p>
- <p>
- Own Id: OTP-13692</p>
- </item>
- <item>
- <p>
- Remove deprecated <c>erlang:hash/2</c>.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13827</p>
- </item>
- <item>
- <p>Replaced usage of deprecated symbolic <seealso
- marker="erts:erlang#type-time_unit"><c>time
- unit</c></seealso> representations.</p>
- <p>
- Own Id: OTP-13831 Aux Id: OTP-13735 </p>
- </item>
- <item>
- <p>
- Added support in zlib for extraction of the inflation
- dictionary.</p>
- <p>
- Own Id: OTP-13842</p>
- </item>
- <item>
- <p>
- The previously used purge strategy has been removed. The
- optional purge strategy introduced in ERTS version 8.1 is
- now the only strategy available.</p>
- <p>
- The new purge strategy is slightly incompatible with the
- old strategy. Previously processes holding <c>fun</c>s
- that referred to the module being purged either failed a
- soft purge, or was killed during a hard purge. The new
- strategy completely ignores <c>fun</c>s. If <c>fun</c>s
- referring to the code being purged exist, and are used
- after a purge, an exception will be raised upon usage.
- That is, the behavior will be exactly the same as the
- case when a <c>fun</c> is received by a process after the
- purge.</p>
- <p>
- For more information see the documentation of <seealso
- marker="erts:erlang#check_process_code/3"><c>erlang:check_process_code/3</c></seealso>.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13844 Aux Id: OTP-13833 </p>
- </item>
- <item>
- <p>
- Dirty schedulers are now enabled by default when the
- runtime system is built with SMP support.</p>
- <p>
- Own Id: OTP-13860</p>
- </item>
- <item>
- <p>
- Improved ETS lookup/insert/delete speed for large
- <c>set</c>, <c>bag</c> and <c>duplicate_bag</c> by a
- significant reduction of the hash load factor. This speed
- improvement comes at the expense of less than one word
- per table entry. Tables with less than 256 entries are
- not affected at all.</p>
- <p>
- Own Id: OTP-13903</p>
- </item>
- <item>
- <p>
- The NIF library <c>reload</c> feature is not supported
- anymore. It has been marked as deprecated since OTP R15B.
- This means that you are only allowed to do one successful
- call to <c>erlang:load_nif/2</c> for each module
- instance. A second call to <c>erlang:load_nif/2</c> will
- return <c>{error, {reload, _}}</c> even if the NIF
- library imlements the <c>reload</c> callback.</p>
- <p>
- Runtime upgrade of a NIF library is still supported by
- using the Erlang module upgrade mechanics with a current
- and an old module instance existing at the same time with
- their corresponding NIF libraries.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-13908</p>
- </item>
- <item>
- <p>
- Add <c>erlang:system_info(atom_count)</c> and
- <c>erlang:system_info(atom_limit)</c> to provide a way to
- retrieve the current and maximum number of atoms.</p>
- <p>
- Own Id: OTP-13976</p>
- </item>
- <item>
- <p>The function <c>fmod/2</c> has been added to the
- <c>math</c> module.</p>
- <p>
- Own Id: OTP-14000</p>
- </item>
- <item>
- <p>
- <c>erlang:load_nif/2</c> returns new error type
- <c>notsup</c> when called for a HiPE compiled module,
- which is not supported.</p>
- <p>
- Own Id: OTP-14002</p>
- </item>
- <item>
- <p>
- Add driver and nif lock instrumentation to lcnt</p>
- <p>
- Own Id: OTP-14069</p>
- </item>
- <item>
- <p>
- Reduce memory pressure by converting sub-binaries to
- heap-binaries when possible. This is done during garbage
- collection.</p>
- <p>
- Own Id: OTP-14149</p>
- </item>
- <item>
- <p>
- Dirty schedulers are now enabled and supported on Erlang
- runtime systems with SMP support.</p>
- <p>
- Besides support for dirty NIFs also support for dirty
- BIFs and dirty garbage collection have been introduced.
- All garbage collections that potentially will take a long
- time to complete are now performed on dirty schedulers if
- enabled.</p>
- <p>
- <seealso
- marker="erts:erlang#statistics/1"><c>erlang:statistics/1</c></seealso>
- with arguments inspecting scheduler and run queue states
- have been changed due to the dirty scheduler support.
- Code using this functionality may have to be rewritten
- taking these incompatibilities into consideration.
- Examples of such uses are calls to <seealso
- marker="erts:erlang#statistics_scheduler_wall_time"><c>erlang:statistics(scheduler_wall_time)</c></seealso>,
- <seealso
- marker="erts:erlang#statistics_total_run_queue_lengths"><c>statistics(total_run_queue_lengths)</c></seealso>,
- <seealso
- marker="erts:erlang#statistics_total_active_tasks"><c>statistics(total_active_tasks)</c></seealso>,
- etc.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14152</p>
- </item>
- <item>
- <p>Atoms may now contain arbitrary Unicode
- characters.</p>
- <p>
- Own Id: OTP-14178</p>
- </item>
- <item>
- <p>
- Introduce an event manager in Erlang to handle OS
- signals. A subset of OS signals may be subscribed to and
- those are described in the Kernel application.</p>
- <p>
- Own Id: OTP-14186</p>
- </item>
- <item>
- <p>
- The <c>escript</c> program now handles symbolic links to
- escripts.</p>
- <p>
- This is useful for standalone systems with
- <c>escript</c>s residing on a bin directory not included
- in the execution path (as it may cause their <c>erl</c>
- program(s) to override the desired one). Instead the
- <c>escript</c>s can be referred to via symbolic links
- from a bin directory in the path.</p>
- <p>
- Own Id: OTP-14201 Aux Id: PR-1293 </p>
- </item>
- <item>
- <p>
- All uses of the magic binary kludge has been replaced by
- uses of erlang references.</p>
- <p>
- A magic binary was presented as an empty binary, but
- actually referred other data internally in the Erlang VM.
- Since they were presented as empty binaries, different
- magic binaries compared as equal, and also lost their
- internal data when passed out of an erlang node.</p>
- <p>
- The new usage of references has not got any of these
- strange semantic issues, and the usage of these
- references has been optimized to give the same
- performance benefits as well as memory usage benefits as
- magic binaries had.</p>
- <p>
- A couple of examples of previous uses of magic binaries
- are match specifications and NIF resources.</p>
- <p>
- Own Id: OTP-14205</p>
- </item>
- <item>
- <p>
- The non-smp emulators have been deprecated and are
- scheduled for removal in OTP-21.</p>
- <p>
- In preperations for this, the threaded non-smp emulator
- is no longer built by default and has to be enabled using
- the --enable-plain-emulator to configure.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14272</p>
- </item>
- <item>
- <p>
- Allow HiPE to run on VM built with
- <c>--enable-m32-build</c>.</p>
- <p>
- Own Id: OTP-14330 Aux Id: PR-1397 </p>
- </item>
- <item>
- <p>
- Upgraded the OTP internal PCRE library from version 8.33
- to version 8.40. This library is used for implementation
- of the <seealso marker="stdlib:re"><c>re</c></seealso>
- regular expressions module.</p>
- <p>
- Besides various bug fixes, the new version allows for
- better stack protection. In order to utilize this
- feature, the stack size of normal scheduler threads is
- now by default set to 128 kilo words on all platforms.
- The stack size of normal scheduler threads can be set
- upon system start by passing the <seealso
- marker="erts:erl#sched_thread_stack_size"><c>+sss</c></seealso>
- command line argument to the <seealso
- marker="erts:erl"><c>erl</c></seealso> command.</p>
- <p>
- See <url
- href="http://pcre.org/original/changelog.txt"><c>http://pcre.org/original/changelog.txt</c></url>
- for information about changes made to PCRE between the
- versions 8.33 and 8.40.</p>
- <p>
- *** POTENTIAL INCOMPATIBILITY ***</p>
- <p>
- Own Id: OTP-14331 Aux Id: ERL-208 </p>
- </item>
- <item>
- <p>
- Remove generation of atoms in old latin1 external format.
- The old latin1 format can still be decoded but is never
- generated by <c>term_to_binary</c> or sent on a
- distribution channel. The new utf8 format for atoms was
- introduced in OTP R16. An OTP 20 node can therefore not
- connect to nodes older than R16.</p>
- <p>
- Own Id: OTP-14337</p>
- </item>
- <item>
- <p>
- Added function <c>re:version/0</c> which returns
- information about the OTP internal PCRE version used for
- implementation of the <c>re</c> module.</p>
- <p>
- Own Id: OTP-14347 Aux Id: PR-1412 </p>
- </item>
- <item>
- <p>
- Added new debug bif <c>erlang:list_to_port/1</c>.</p>
- <p>
- Own Id: OTP-14348</p>
- </item>
- <item>
- <p>
- Various improvements of timer management internally in
- the VM. These improvements both reduced memory
- consumption of timer wheels as well as reduce the amount
- of work that has to be performed in order to handle
- timers.</p>
- <p>
- Own Id: OTP-14356</p>
- </item>
- <item>
- <p> Sockets can now be bound to device (SO_BINDTODEVICE)
- on platforms where it is supported. </p> <p> This has
- been implemented e.g to support VRF-Lite under Linux; see
- <url
- href="https://www.kernel.org/doc/Documentation/networking/vrf.txt">
- VRF </url>, and GitHub pull request <url
- href="https://github.com/erlang/otp/pull/1326">#1326</url>.
- </p>
- <p>
- Own Id: OTP-14357 Aux Id: PR-1326 </p>
- </item>
- <item>
- <p>Added the following <seealso
- marker="erl"><c>erl</c></seealso> command line arguments
- with which you can set suggested stack for dirty
- schedulers:</p> <taglist> <tag><seealso
- marker="erl#dcpu_sched_thread_stack_size"><c>+sssdcpu</c></seealso></tag>
- <item><p>for dirty CPU schedulers</p></item>
- <tag><seealso
- marker="erl#dio_sched_thread_stack_size"><c>+sssdio</c></seealso></tag>
- <item><p>for dirty IO schedulers</p></item> </taglist>
- <p>The default suggested stack size for dirty schedulers
- is 40 kilo words.</p>
- <p>
- Own Id: OTP-14380</p>
- </item>
- <item>
- <p>
- Changed erts startup program name, argv 0, to use the
- environment variable <c>ESCRIPT_NAME</c> so that
- <c>erlc</c>, <c>dialyzer</c>, <c>typer</c>,
- <c>ct_run</c>, or the escript name can be seen with
- external programs, such as ps and htop (depending on
- options), on unix.</p>
- <p>
- Own Id: OTP-14381</p>
- </item>
- <item>
- <p>
- Improvements of <c>escript</c> documentation.</p>
- <p>
- Own Id: OTP-14384 Aux Id: OTP-14201 </p>
- </item>
- <item>
- <p>
- Add function <c>enif_hash</c> for NIFs to calculate hash
- values of arbitrary terms.</p>
- <p>
- Own Id: OTP-14385 Aux Id: PR-1413 </p>
- </item>
- <item>
- <p>'<c>./configure --enable-lock-counter</c>' will
- enabling building of an additional emulator that has
- support for lock counting. (The option previously
- existed, but would turn on lock counting in the default
- emulator being built.) To start the lock-counting
- emulator, use '<c>erl -emu_type lcnt</c>'.</p>
- <p>On Windows, <c>erl</c> recognized the undocumented
- option <c>-debug</c> for starting a debug-compiled
- emulator. That option has been removed. Use '<c>erl
- -emu_type debug</c>' instead.</p>
- <p>
- Own Id: OTP-14407</p>
- </item>
- <item>
- <p>
- Warnings have been added to the relevant documentation
- about not using un-secure distributed nodes in exposed
- environments.</p>
- <p>
- Own Id: OTP-14425</p>
- </item>
- <item>
- <p>
- Improvement of the documentation of the environment
- variable <c>ERL_CRASH_DUMP_SECONDS</c> as well as the
- default behavior when it is not set.</p>
- <p>
- Own Id: OTP-14434</p>
- </item>
- <item>
- <p>
- Enabled off-heap message queue for some system processes
- that might receive large amounts of messages.</p>
+ Add option to make SIGTERM trigger the OS default
+ behaviour instead of doing a gracefull shutdown. To
+ activate this bahviour the environment variable
+ ERL_ZZ_SIGTERM_KILL should be set to "true". This option
+ only works in OTP 19 as OTP 20 will have a different way
+ to deal with SIGTERM.</p>
<p>
- Own Id: OTP-14438</p>
+ Own Id: OTP-14418 Aux Id: ERIERL-15 </p>
</item>
</list>
</section>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 254e59f2c7..61c1e14741 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -149,6 +149,8 @@ endif
LIBS += $(TYPE_LIBS)
+ORIG_LIBS:= $(LIBS)
+
comma:=,
space:=
space+=
@@ -965,7 +967,7 @@ $(OBJDIR)/%.o: hipe/%.c
$(V_CC) $(subst O2,O3, $(CFLAGS)) $(INCLUDES) -c $< -o $@
$(BINDIR)/hipe_mkliterals$(TF_MARKER): $(OBJDIR)/hipe_mkliterals.o
- $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(TYPE_LIBS)
+ $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(ORIG_LIBS)
$(OBJDIR)/hipe_mkliterals.o: $(HIPE_ASM) $(TTF_DIR)/erl_alloc_types.h $(DTRACE_HEADERS) \
$(TTF_DIR)/OPCODES-GENERATED $(TTF_DIR)/TABLES-GENERATED
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 7134d2da56..40dd4129d2 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -2047,8 +2047,6 @@ ebif_bang_2(BIF_ALIST_2)
#define SEND_YIELD_CONTINUE (-8)
-Sint do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext*);
-
static Sint remote_send(Process *p, DistEntry *dep,
Eterm to, Eterm full_to, Eterm msg,
ErtsSendContext* ctx)
@@ -2102,8 +2100,8 @@ static Sint remote_send(Process *p, DistEntry *dep,
return res;
}
-Sint
-do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext* ctx)
+static Sint
+do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx)
{
Eterm portid;
Port *pt;
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 4889fac923..6fddba4b34 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -821,7 +821,7 @@ static void clear_literal_range(void* start, Uint size)
#if HAVE_ERTS_MSEG
-void*
+static void*
erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags)
{
void *res;
@@ -832,7 +832,7 @@ erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags)
return res;
}
-void*
+static void*
erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg,
Uint old_size, Uint *new_size_p)
{
@@ -845,7 +845,7 @@ erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg,
return res;
}
-void
+static void
erts_alcu_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags)
{
erts_mseg_dealloc_opt(allctr->alloc_no, seg, (UWord) size, flags, &allctr->mseg_opt);
@@ -996,7 +996,7 @@ erts_alcu_exec_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags)
#endif /* HAVE_ERTS_MSEG */
-void*
+static void*
erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign)
{
void *res;
@@ -1013,7 +1013,7 @@ erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign)
return res;
}
-void*
+static void*
erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size, int superalign)
{
void *res;
@@ -1035,7 +1035,7 @@ erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size,
return res;
}
-void
+static void
erts_alcu_sys_dealloc(Allctr_t *allctr, void *ptr, Uint size, int superalign)
{
#if ERTS_SA_MB_CARRIERS && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index f570703f25..7a96bd0319 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -195,10 +195,6 @@ extern UWord erts_literal_vspace_map[];
# define ERTS_VSPACE_WORD_BITS (sizeof(UWord)*8)
#endif
-void* erts_alcu_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags);
-void* erts_alcu_mseg_realloc(Allctr_t*, void *seg, Uint old_size, Uint *new_size_p);
-void erts_alcu_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags);
-
#if HAVE_ERTS_MSEG
# if defined(ARCH_32)
void* erts_alcu_literal_32_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags);
@@ -218,9 +214,6 @@ void erts_alcu_exec_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags);
# endif
#endif /* HAVE_ERTS_MSEG */
-void* erts_alcu_sys_alloc(Allctr_t*, Uint *size_p, int superalign);
-void* erts_alcu_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign);
-void erts_alcu_sys_dealloc(Allctr_t*, void *ptr, Uint size, int superalign);
#ifdef ARCH_32
void* erts_alcu_literal_32_sys_alloc(Allctr_t*, Uint *size_p, int superalign);
void* erts_alcu_literal_32_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign);
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index eea55b3239..71c64997c1 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -1636,7 +1636,7 @@ erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb)
return LSB[0] | (LSB[1]<<8) | (LSB[2]<<16) | (LSB[3]<<24);
}
-void
+static void
erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf)
{
Uint bits = mb->size - mb->offset;
diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h
index 632855255e..5da2b28a89 100644
--- a/erts/emulator/beam/erl_bits.h
+++ b/erts/emulator/beam/erl_bits.h
@@ -202,7 +202,6 @@ void erts_new_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes));
Uint erts_bits_bufs_size(void);
Uint32 erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb);
-void erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf);
Eterm erts_bs_get_utf8(ErlBinMatchBuffer* mb);
Eterm erts_bs_get_utf16(ErlBinMatchBuffer* mb, Uint flags);
Eterm erts_bs_append(Process* p, Eterm* reg, Uint live, Eterm build_size_term,
diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c
index 4347f9f2b7..d0fd763798 100644
--- a/erts/emulator/beam/erl_cpu_topology.c
+++ b/erts/emulator/beam/erl_cpu_topology.c
@@ -2243,45 +2243,6 @@ add_cpu_groups(int groups,
return cgm;
}
-static void
-remove_cpu_groups(erts_cpu_groups_callback_t callback, void *arg)
-{
- erts_cpu_groups_map_t *prev_cgm, *cgm;
- erts_cpu_groups_callback_list_t *prev_cgcl, *cgcl;
-
- ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
-
- no_cpu_groups_callbacks--;
-
- prev_cgm = NULL;
- for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
- prev_cgcl = NULL;
- for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) {
- if (cgcl->callback == callback && cgcl->arg == arg) {
- if (prev_cgcl)
- prev_cgcl->next = cgcl->next;
- else
- cgm->callback_list = cgcl->next;
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgcl);
- if (!cgm->callback_list) {
- if (prev_cgm)
- prev_cgm->next = cgm->next;
- else
- cpu_groups_maps = cgm->next;
- if (cgm->array)
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm->array);
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm);
- }
- return;
- }
- prev_cgcl = cgcl;
- }
- prev_cgm = cgm;
- }
-
- erts_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n");
-}
-
static int
cpu_groups_lookup(erts_cpu_groups_map_t *map,
ErtsSchedulerData *esdp)
@@ -2321,21 +2282,3 @@ update_cpu_groups_maps(void)
for (cgm = cpu_groups_maps; cgm; cgm = cgm->next)
make_cpu_groups_map(cgm, 0);
}
-
-void
-erts_add_cpu_groups(int groups,
- erts_cpu_groups_callback_t callback,
- void *arg)
-{
- erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
- add_cpu_groups(groups, callback, arg);
- erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
-}
-
-void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback,
- void *arg)
-{
- erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
- remove_cpu_groups(callback, arg);
- erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
-}
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index 08a0f0e83b..0addfaa3c7 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -676,7 +676,7 @@ int db_create_hash(Process *p, DbTable *tbl)
sizeof(DbTableHashFineLocks));
for (i=0; i<DB_HASH_LOCK_CNT; ++i) {
erts_smp_rwmtx_init_opt_x(&tb->locks->lck_vec[i].lck, &rwmtx_opt,
- "db_hash_slot", make_small(i));
+ "db_hash_slot", tb->common.the_name);
}
/* This important property is needed to guarantee the two buckets
* involved in a grow/shrink operation it protected by the same lock:
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 00fc6116e5..fc2b34e70f 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -13933,7 +13933,11 @@ erts_continue_exit_process(Process *p)
erts_set_gc_state(p, 1);
state = erts_smp_atomic32_read_acqb(&p->state);
- if (state & ERTS_PSFLG_ACTIVE_SYS) {
+ if (state & ERTS_PSFLG_ACTIVE_SYS
+#ifdef ERTS_DIRTY_SCHEDULERS
+ || p->dirty_sys_tasks
+#endif
+ ) {
if (cleanup_sys_tasks(p, state, CONTEXT_REDS) >= CONTEXT_REDS/2)
goto yield;
}
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 0acc2432a7..f8341f788a 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -969,17 +969,21 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,
fdrec.sfv_len = SENDFILE_CHUNK_SIZE;
else
fdrec.sfv_len = *nbytes;
+
retval = sendfilev(out_fd, &fdrec, 1, &len);
- /* Sometimes sendfilev can return -1 and still send data.
- When that happens we just pretend that no error happend. */
- if (retval != -1 || errno == EAGAIN || errno == EINTR ||
- len != 0) {
+ if (retval == -1 && errno == EINVAL) {
+ /* On some solaris versions (I've seen it on SunOS 5.10),
+ using a sfv_len larger then a filesize will result in
+ a -1 && errno == EINVAL return. We translate this so
+ a successful send of the data.*/
+ retval = len;
+ }
+
+ if (retval != -1 || errno == EAGAIN || errno == EINTR) {
*offset += len;
*nbytes -= len;
written += len;
- if (errno != EAGAIN && errno != EINTR && len != 0)
- retval = len;
}
} while (len == SENDFILE_CHUNK_SIZE);
#elif defined(__DARWIN__)
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index 2479ccc01f..fcd7244ae9 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -117,7 +117,6 @@ MODULES= \
tracer_SUITE \
tracer_test \
scheduler_SUITE \
- old_scheduler_SUITE \
port_trace_SUITE \
unique_SUITE \
z_SUITE \
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 355be7a36d..4d17276e5c 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -1358,17 +1358,19 @@ do_trapping(N, Bif, ArgFun) ->
io:format("N=~p: Do ~p ~s gc.\n", [N, Bif, case N rem 2 of 0 -> "with"; 1 -> "without" end]),
Pid = spawn(?MODULE,trapping_loop,[Bif, ArgFun, 1000, self()]),
receive ok -> ok end,
- receive after 100 -> ok end,
Ref = make_ref(),
case N rem 2 of
- 0 -> erlang:garbage_collect(Pid, [{async,Ref}]),
- receive after 100 -> ok end;
+ 0 ->
+ erlang:garbage_collect(Pid, [{async,Ref}]),
+ receive after 1 -> ok end;
1 -> void
end,
- exit(Pid,kill),
+ exit(Pid, kill),
case N rem 2 of
- 0 -> receive {garbage_collect, Ref, _} -> ok end;
- 1 -> void
+ 0 ->
+ receive {garbage_collect, Ref, _} -> ok end;
+ 1 ->
+ void
end,
receive after 1 -> ok end,
do_trapping(N-1, Bif, ArgFun).
diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl
index ed03284a5b..779d81daa5 100644
--- a/erts/emulator/test/bs_construct_SUITE.erl
+++ b/erts/emulator/test/bs_construct_SUITE.erl
@@ -35,7 +35,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[test1, test2, test3, test4, test5, testf, not_used,
diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl
index 95171d04ce..1251d644ae 100644
--- a/erts/emulator/test/call_trace_SUITE.erl
+++ b/erts/emulator/test/call_trace_SUITE.erl
@@ -43,7 +43,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 2}}].
all() ->
Common = [errors, on_load],
diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl
index 0b9f76a892..031b05790d 100644
--- a/erts/emulator/test/ddll_SUITE.erl
+++ b/erts/emulator/test/ddll_SUITE.erl
@@ -55,7 +55,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[ddll_test, errors, reference_count, kill_port,
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index 434e729310..dc7afa381b 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -62,8 +62,7 @@
-export([sender/3, receiver2/2, dummy_waiter/0, dead_process/0,
roundtrip/1, bounce/1, do_dist_auto_connect/1, inet_rpc_server/1,
dist_parallel_sender/3, dist_parallel_receiver/0,
- dist_evil_parallel_receiver/0,
- sendersender/4, sendersender2/4]).
+ dist_evil_parallel_receiver/0]).
%% epmd_module exports
-export([start_link/0, register_node/2, register_node/3, port_please/2]).
@@ -129,52 +128,53 @@ bulk_send_small(Config) when is_list(Config) ->
bulk_send_big(Config) when is_list(Config) ->
bulk_send(32, 64).
-bulk_send_bigbig(Config) when is_list(Config) ->
- bulk_sendsend(32*5, 4).
-
bulk_send(Terms, BinSize) ->
ct:timetrap({seconds, 30}),
io:format("Sending ~w binaries, each of size ~w K", [Terms, BinSize]),
{ok, Node} = start_node(bulk_receiver),
Recv = spawn(Node, erlang, apply, [fun receiver/2, [0, 0]]),
- Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)),
+ Bin = binary:copy(<<253>>, BinSize*1024),
Size = Terms*size(Bin),
{Elapsed, {Terms, Size}} = test_server:timecall(?MODULE, sender,
[Recv, Bin, Terms]),
stop_node(Node),
- {comment, integer_to_list(trunc(Size/1024/max(1,Elapsed)+0.5)) ++ " K/s"}.
+ {comment, integer_to_list(round(Size/1024/max(1,Elapsed))) ++ " K/s"}.
-bulk_sendsend(Terms, BinSize) ->
+sender(To, _Bin, 0) ->
+ To ! {done, self()},
+ receive
+ Any ->
+ Any
+ end;
+sender(To, Bin, Left) ->
+ To ! {term, Bin},
+ sender(To, Bin, Left-1).
+
+bulk_send_bigbig(Config) when is_list(Config) ->
+ Terms = 32*5,
+ BinSize = 4,
{Rate1, MonitorCount1} = bulk_sendsend2(Terms, BinSize, 5),
{Rate2, MonitorCount2} = bulk_sendsend2(Terms, BinSize, 995),
Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0;
true -> MonitorCount1 / MonitorCount2
end,
- Comment = integer_to_list(Rate1) ++ " K/s, " ++
- integer_to_list(Rate2) ++ " K/s, " ++
- integer_to_list(MonitorCount1) ++ " monitor msgs, " ++
- integer_to_list(MonitorCount2) ++ " monitor msgs, " ++
- float_to_list(Ratio) ++ " monitor ratio",
- if
- %% A somewhat arbitrary ratio, but hopefully one that will
- %% accommodate a wide range of CPU speeds.
- Ratio > 8.0 ->
- {comment,Comment};
- true ->
- io:put_chars(Comment),
- ct:fail(ratio_too_low)
- end.
+ Comment0 = io_lib:format("~p K/s, ~p K/s, "
+ "~p monitor msgs, ~p monitor msgs, "
+ "~.1f monitor ratio",
+ [Rate1,Rate2,MonitorCount1,
+ MonitorCount2,Ratio]),
+ Comment = lists:flatten(Comment0),
+ {comment,Comment}.
bulk_sendsend2(Terms, BinSize, BusyBufSize) ->
ct:timetrap({seconds, 30}),
- io:format("Sending ~w binaries, each of size ~w K",
+ io:format("\nSending ~w binaries, each of size ~w K",
[Terms, BinSize]),
{ok, NodeRecv} = start_node(bulk_receiver),
Recv = spawn(NodeRecv, erlang, apply, [fun receiver/2, [0, 0]]),
- Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)),
- %%Size = Terms*size(Bin),
+ Bin = binary:copy(<<253>>, BinSize*1024),
%% SLF LEFT OFF HERE.
%% When the caller uses small hunks, like 4k via
@@ -185,74 +185,62 @@ bulk_sendsend2(Terms, BinSize, BusyBufSize) ->
%% default busy size and "+zdbbl 5", and if the 5 case gets
%% "many many more" monitor messages, then we know we're working.
- {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ integer_to_list(BusyBufSize)),
- _Send = spawn(NodeSend, erlang, apply, [fun sendersender/4, [self(), Recv, Bin, Terms]]),
+ {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++
+ integer_to_list(BusyBufSize)),
+ _Send = spawn(NodeSend, erlang, apply,
+ [fun sendersender/4, [self(), Recv, Bin, Terms]]),
{Elapsed, {_TermsN, SizeN}, MonitorCount} =
- receive
- %% On some platforms (windows), the time taken is 0 so we
- %% simulate that some little time has passed.
- {sendersender, {0.0,T,MC}} ->
- {0.0015, T, MC};
- {sendersender, BigRes} ->
- BigRes
- end,
+ receive
+ %% On some platforms (Windows), the time taken is 0 so we
+ %% simulate that some little time has passed.
+ {sendersender, {0.0,T,MC}} ->
+ {0.0015, T, MC};
+ {sendersender, BigRes} ->
+ BigRes
+ end,
stop_node(NodeRecv),
stop_node(NodeSend),
- {trunc(SizeN/1024/Elapsed+0.5), MonitorCount}.
-
-sender(To, _Bin, 0) ->
- To ! {done, self()},
- receive
- Any ->
- Any
- end;
-sender(To, Bin, Left) ->
- To ! {term, Bin},
- sender(To, Bin, Left-1).
+ {round(SizeN/1024/Elapsed), MonitorCount}.
%% Sender process to be run on a slave node
sendersender(Parent, To, Bin, Left) ->
erlang:system_monitor(self(), [busy_dist_port]),
- [spawn(fun() -> sendersender2(To, Bin, Left, false) end) ||
- _ <- lists:seq(1,1)],
+ _ = spawn(fun() ->
+ sendersender_send(To, Bin, Left),
+ exit(normal)
+ end),
{USec, {Res, MonitorCount}} =
- timer:tc(?MODULE, sendersender2, [To, Bin, Left, true]),
+ timer:tc(fun() ->
+ sendersender_send(To, Bin, Left),
+ To ! {done, self()},
+ count_monitors(0)
+ end),
Parent ! {sendersender, {USec/1000000, Res, MonitorCount}}.
-sendersender2(To, Bin, Left, SendDone) ->
- sendersender3(To, Bin, Left, SendDone, 0).
+sendersender_send(_To, _Bin, 0) ->
+ ok;
+sendersender_send(To, Bin, Left) ->
+ To ! {term, Bin},
+ sendersender_send(To, Bin, Left-1).
-sendersender3(To, _Bin, 0, SendDone, MonitorCount) ->
- if SendDone ->
- To ! {done, self()};
- true ->
- ok
- end,
+count_monitors(MonitorCount) ->
receive
{monitor, _Pid, _Type, _Info} ->
- sendersender3(To, _Bin, 0, SendDone, MonitorCount + 1)
+ count_monitors(MonitorCount + 1)
after 0 ->
- if SendDone ->
- receive
- Any when is_tuple(Any), size(Any) == 2 ->
- {Any, MonitorCount}
- end;
- true ->
- exit(normal)
- end
- end;
-sendersender3(To, Bin, Left, SendDone, MonitorCount) ->
- To ! {term, Bin},
- %%timer:sleep(50),
- sendersender3(To, Bin, Left-1, SendDone, MonitorCount).
+ receive
+ {_,_}=Any ->
+ {Any,MonitorCount}
+ end
+ end.
%% Receiver process to be run on a slave node.
receiver(Terms, Size) ->
receive
{term, Bin} ->
- receiver(Terms+1, Size+size(Bin));
+ receiver(Terms+1, Size+byte_size(Bin));
{done, ReplyTo} ->
ReplyTo ! {Terms, Size}
end.
diff --git a/erts/emulator/test/evil_SUITE.erl b/erts/emulator/test/evil_SUITE.erl
index 9416ac7a02..fb1954ce37 100644
--- a/erts/emulator/test/evil_SUITE.erl
+++ b/erts/emulator/test/evil_SUITE.erl
@@ -34,7 +34,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 1}}].
all() ->
[heap_frag, encode_decode_ext, decode_integer_ext,
diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl
index 76e3556bc4..ad6d8c890f 100644
--- a/erts/emulator/test/exception_SUITE.erl
+++ b/erts/emulator/test/exception_SUITE.erl
@@ -33,7 +33,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[badmatch, pending_errors, nil_arith, stacktrace,
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index 35dd147550..2c2cb9c32d 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -203,89 +203,90 @@ long_receive() ->
end.
minor_major_gc_option_self(_Config) ->
- Endless = fun Endless() ->
- receive
- {gc, Type} -> erlang:garbage_collect(self(), [{type, Type}])
- after 100 -> ok end,
- Endless()
- end,
-
- %% Try as major, a test process will self-trigger GC
- P1 = spawn(Endless),
- erlang:garbage_collect(P1, []),
- erlang:trace(P1, true, [garbage_collection]),
- P1 ! {gc, major},
- expect_trace_messages(P1, [gc_major_start, gc_major_end]),
- erlang:trace(P1, false, [garbage_collection]),
- erlang:exit(P1, kill),
-
- %% Try as minor, a test process will self-trigger GC
- P2 = spawn(Endless),
- erlang:garbage_collect(P2, []),
- erlang:trace(P2, true, [garbage_collection]),
- P2 ! {gc, minor},
- expect_trace_messages(P2, [gc_minor_start, gc_minor_end]),
- erlang:trace(P2, false, [garbage_collection]),
- erlang:exit(P2, kill).
+ %% Try as major, the test process will self-trigger GC
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ Pid ! {gc, Ref, major}
+ end, [gc_major_start, gc_major_end]),
+
+ %% Try as minor, the test process will self-trigger GC
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ Pid ! {gc, Ref, minor}
+ end, [gc_minor_start, gc_minor_end]).
minor_major_gc_option_async(_Config) ->
- Endless = fun Endless() ->
- receive after 100 -> ok end,
- Endless()
- end,
-
- %% Try with default option, must be major gc
- P1 = spawn(Endless),
- erlang:garbage_collect(P1, []),
- erlang:trace(P1, true, [garbage_collection]),
- erlang:garbage_collect(P1, []),
- expect_trace_messages(P1, [gc_major_start, gc_major_end]),
- erlang:trace(P1, false, [garbage_collection]),
- erlang:exit(P1, kill),
+ %% Try with default option, must be major GC
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [])
+ end, [gc_major_start, gc_major_end]),
%% Try with the 'major' type
- P2 = spawn(Endless),
- erlang:garbage_collect(P2, []),
- erlang:trace(P2, true, [garbage_collection]),
- erlang:garbage_collect(P2, [{type, major}]),
- expect_trace_messages(P2, [gc_major_start, gc_major_end]),
- erlang:trace(P2, false, [garbage_collection]),
- erlang:exit(P2, kill),
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [{type, major}])
+ end, [gc_major_start, gc_major_end]),
%% Try with 'minor' option, once
- P3 = spawn(Endless),
- erlang:garbage_collect(P3, []),
- erlang:trace(P3, true, [garbage_collection]),
- erlang:garbage_collect(P3, [{type, minor}]),
- expect_trace_messages(P3, [gc_minor_start, gc_minor_end]),
- erlang:trace(P3, false, [garbage_collection]),
- erlang:exit(P3, kill),
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [{type, minor}])
+ end, [gc_minor_start, gc_minor_end]),
%% Try with 'minor' option, once, async
- P4 = spawn(Endless),
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ ?assertEqual(async,
+ erlang:garbage_collect(Pid, [{type, minor}, {async, Ref}])),
+
+ receive
+ {garbage_collect, Ref, true} ->
+ ok
+ after 10000 ->
+ ct:fail("Did not receive a completion notification on async GC")
+ end
+ end, [gc_minor_start, gc_minor_end]).
+
+%% Traces garbage collection around the given operation, and fails the test if
+%% it results in any unexpected messages or if the expected trace tags are not
+%% received.
+check_gc_tracing_around(Fun, ExpectedTraceTags) ->
Ref = erlang:make_ref(),
- erlang:garbage_collect(P4, []),
- erlang:trace(P4, true, [garbage_collection]),
- ?assertEqual(async,
- erlang:garbage_collect(P4, [{type, minor}, {async, Ref}])),
- expect_trace_messages(P4, [gc_minor_start, gc_minor_end]),
- erlang:trace(P4, false, [garbage_collection]),
- receive {garbage_collect, Ref, true} -> ok;
- Other4 -> ct:pal("Unexpected message: ~p~n"
- ++ "while waiting for async gc result", [Other4])
- after 2000 -> ?assert(false)
- end,
- erlang:exit(P4, kill).
-
-%% Given a list of atoms, trace tags - receives messages and checks if they are
-%% trace events, and if the tag matches. Else will crash failing the test.
-expect_trace_messages(_Pid, []) -> ok;
+ Pid = spawn(
+ fun Endless() ->
+ receive
+ {gc, Ref, Type} ->
+ erlang:garbage_collect(self(), [{type, Type}])
+ after 100 ->
+ ok
+ end,
+ Endless()
+ end),
+ erlang:garbage_collect(Pid, []),
+ erlang:trace(Pid, true, [garbage_collection]),
+ Fun(Pid, Ref),
+ expect_trace_messages(Pid, ExpectedTraceTags),
+ erlang:trace(Pid, false, [garbage_collection]),
+ erlang:exit(Pid, kill),
+ check_no_unexpected_messages().
+
+%% Ensures that trace messages with the provided tags have all been received
+%% within a reasonable timeframe.
+expect_trace_messages(_Pid, []) ->
+ ok;
expect_trace_messages(Pid, [Tag | TraceTags]) ->
receive
- {trace, Pid, Tag, _Data} -> ok;
- AnythingElse ->
- ct:pal("Unexpected message: ~p~nWhile expected {trace, _, ~p, _}",
- [AnythingElse, Tag]),
- ?assert(false)
- end,
- expect_trace_messages(Pid, TraceTags).
+ {trace, Pid, Tag, _Data} ->
+ expect_trace_messages(Pid, TraceTags)
+ after 4000 ->
+ ct:fail("Didn't receive tag ~p within 4000ms", [Tag])
+ end.
+
+check_no_unexpected_messages() ->
+ receive
+ Anything ->
+ ct:fail("Unexpected message: ~p", [Anything])
+ after 0 ->
+ ok
+ end.
diff --git a/erts/emulator/test/lttng_SUITE.erl b/erts/emulator/test/lttng_SUITE.erl
index c12f63706a..1c1952f912 100644
--- a/erts/emulator/test/lttng_SUITE.erl
+++ b/erts/emulator/test/lttng_SUITE.erl
@@ -40,7 +40,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[t_lttng_list,
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index eb189c2c33..92ddc23592 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -42,7 +42,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 1}}].
all() ->
case test_server:is_native(match_spec_SUITE) of
diff --git a/erts/emulator/test/nested_SUITE.erl b/erts/emulator/test/nested_SUITE.erl
index 7af2873ce2..5059317172 100644
--- a/erts/emulator/test/nested_SUITE.erl
+++ b/erts/emulator/test/nested_SUITE.erl
@@ -27,7 +27,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[case_in_case, case_in_after, catch_in_catch,
diff --git a/erts/emulator/test/old_scheduler_SUITE.erl b/erts/emulator/test/old_scheduler_SUITE.erl
deleted file mode 100644
index 8515a87df8..0000000000
--- a/erts/emulator/test/old_scheduler_SUITE.erl
+++ /dev/null
@@ -1,384 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. 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.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
-
--module(old_scheduler_SUITE).
-
--include_lib("common_test/include/ct.hrl").
-
--export([all/0, suite/0,
- init_per_testcase/2, end_per_testcase/2]).
--export([equal/1, many_low/1, few_low/1, max/1, high/1]).
-
-suite() ->
- [{ct_hooks,[ts_install_cth]},
- {timetrap, {minutes, 11}}].
-
-all() ->
- case catch erlang:system_info(modified_timing_level) of
- Level when is_integer(Level) ->
- {skipped,
- "Modified timing (level " ++
- integer_to_list(Level) ++
- ") is enabled. Testcases gets messed "
- "up by modfied timing."};
- _ -> [equal, many_low, few_low, max, high]
- end.
-
-
-%%-----------------------------------------------------------------------------------
-%% TEST SUITE DESCRIPTION
-%%
-%% The test case function spawns two controlling processes: Starter and Receiver.
-%% Starter spawns a number of prio A and a number of prio B test processes. Each
-%% test process loops for a number of times, sends a report to the Receiver, then
-%% loops again. For each report, the Receiver increases a counter that corresponds
-%% to the priority of the sender. After a certain amount of time, the Receiver
-%% sends the collected data to the main test process and waits for the test case
-%% to terminate. From this data, it's possible to calculate the average run time
-%% relationship between the prio A and B test processes.
-%%
-%% Note that in order to be able to run tests with high or max prio test processes,
-%% the main test process and the Receiver needs to run at max prio, or they will
-%% be starved by the test processes. The controlling processes must not wait for
-%% messages from a normal (or low) prio process while max or high prio test processes
-%% are running (which happens e.g. if an io function is called).
-%%-----------------------------------------------------------------------------------
-
-init_per_testcase(_Case, Config) ->
- %% main test process needs max prio
- Prio = process_flag(priority, max),
- MS = erlang:system_flag(multi_scheduling, block_normal),
- [{prio,Prio},{multi_scheduling, MS}|Config].
-
-end_per_testcase(_Case, Config) ->
- erlang:system_flag(multi_scheduling, unblock_normal),
- Prio=proplists:get_value(prio, Config),
- process_flag(priority, Prio),
- ok.
-
-ok(Config) when is_list(Config) ->
- case proplists:get_value(multi_scheduling, Config) of
- blocked ->
- {comment,
- "Multi-scheduling blocked during test. This testcase was not "
- "written to work with multiple schedulers."};
- _ -> ok
- end.
-
-%% Run equal number of low and normal prio processes.
-
-equal(Config) when is_list(Config) ->
- Self = self(),
-
- %% specify number of test processes to run
- Normal = {normal,500},
- Low = {low,500},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- %% start controllers
- Receiver =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
- Starter =
- spawn(fun() -> starter(Normal, Low, Receiver) end),
-
- %% receive test data from Receiver
- {NRs,NAvg,LRs,LAvg,Ratio} =
- receive
- {Receiver,Res} -> Res
- end,
-
- %% stop controllers and test processes
- exit(Starter, kill),
- exit(Receiver, kill),
-
- io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [NRs,NAvg,LRs,LAvg,Ratio]),
-
- %% runtime ratio between normal and low should be ~8
- if Ratio < 7.5 ; Ratio > 8.5 ->
- ct:fail({bad_ratio,Ratio});
- true ->
- ok(Config)
- end.
-
-
-%% Run many low and few normal prio processes.
-
-many_low(Config) when is_list(Config) ->
- Self = self(),
- Normal = {normal,1},
- Low = {low,1000},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
- Starter =
- spawn(fun() -> starter(Normal, Low, Receiver) end),
- {NRs,NAvg,LRs,LAvg,Ratio} =
- receive
- {Receiver,Res} -> Res
- end,
- exit(Starter, kill),
- exit(Receiver, kill),
- io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [NRs,NAvg,LRs,LAvg,Ratio]),
- if Ratio < 7.5 ; Ratio > 8.5 ->
- ct:fail({bad_ratio,Ratio});
- true ->
- ok(Config)
- end.
-
-
-%% Run few low and many normal prio processes.
-
-few_low(Config) when is_list(Config) ->
- Self = self(),
- Normal = {normal,1000},
- Low = {low,1},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Normal, Low) end),
- Starter =
- spawn(fun() -> starter(Normal, Low, Receiver) end),
- {NRs,NAvg,LRs,LAvg,Ratio} =
- receive
- {Receiver,Res} -> Res
- end,
- exit(Starter, kill),
- exit(Receiver, kill),
- io:format("Reports: ~w normal (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [NRs,NAvg,LRs,LAvg,Ratio]),
- if Ratio < 7.0 ; Ratio > 8.5 ->
- ct:fail({bad_ratio,Ratio});
- true ->
- ok(Config)
- end.
-
-
-%% Run max prio processes and verify they get at least as much
-%% runtime as high, normal and low.
-
-max(Config) when is_list(Config) ->
- max = process_flag(priority, max), % should already be max (init_per_tc)
- Self = self(),
- Max = {max,2},
- High = {high,2},
- Normal = {normal,100},
- Low = {low,100},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver1 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, High) end),
- Starter1 =
- spawn(fun() -> starter(Max, High, Receiver1) end),
- {M1Rs,M1Avg,HRs,HAvg,Ratio1} =
- receive
- {Receiver1,Res1} -> Res1
- end,
- exit(Starter1, kill),
- exit(Receiver1, kill),
- io:format("Reports: ~w max (~w/proc), ~w high (~w/proc). Ratio: ~w~n",
- [M1Rs,M1Avg,HRs,HAvg,Ratio1]),
- if Ratio1 < 1.0 ->
- ct:fail({bad_ratio,Ratio1});
- true ->
- ok(Config)
- end,
-
- Receiver2 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Normal) end),
- Starter2 =
- spawn(fun() -> starter(Max, Normal, Receiver2) end),
- {M2Rs,M2Avg,NRs,NAvg,Ratio2} =
- receive
- {Receiver2,Res2} -> Res2
- end,
- exit(Starter2, kill),
- exit(Receiver2, kill),
- io:format("Reports: ~w max (~w/proc), ~w normal (~w/proc). Ratio: ~w~n",
- [M2Rs,M2Avg,NRs,NAvg,Ratio2]),
- if Ratio2 < 1.0 ->
- ct:fail({bad_ratio,Ratio2});
- true ->
- ok
- end,
-
- Receiver3 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, Max, Low) end),
- Starter3 =
- spawn(fun() -> starter(Max, Low, Receiver3) end),
- {M3Rs,M3Avg,LRs,LAvg,Ratio3} =
- receive
- {Receiver3,Res3} -> Res3
- end,
- exit(Starter3, kill),
- exit(Receiver3, kill),
- io:format("Reports: ~w max (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [M3Rs,M3Avg,LRs,LAvg,Ratio3]),
- if Ratio3 < 1.0 ->
- ct:fail({bad_ratio,Ratio3});
- true ->
- ok(Config)
- end.
-
-
-%% Run high prio processes and verify they get at least as much
-%% runtime as normal and low.
-
-high(Config) when is_list(Config) ->
- max = process_flag(priority, max), % should already be max (init_per_tc)
- Self = self(),
- High = {high,2},
- Normal = {normal,100},
- Low = {low,100},
-
- %% specify time of test (in seconds)
- Time = 30,
-
- Receiver1 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Normal) end),
- Starter1 =
- spawn(fun() -> starter(High, Normal, Receiver1) end),
- {H1Rs,H1Avg,NRs,NAvg,Ratio1} =
- receive
- {Receiver1,Res1} -> Res1
- end,
- exit(Starter1, kill),
- exit(Receiver1, kill),
- io:format("Reports: ~w high (~w/proc), ~w normal (~w/proc). Ratio: ~w~n",
- [H1Rs,H1Avg,NRs,NAvg,Ratio1]),
- if Ratio1 < 1.0 ->
- ct:fail({bad_ratio,Ratio1});
- true ->
- ok
- end,
-
- Receiver2 =
- spawn(fun() -> receiver(erlang:monotonic_time(), Time, Self, High, Low) end),
- Starter2 =
- spawn(fun() -> starter(High, Low, Receiver2) end),
- {H2Rs,H2Avg,LRs,LAvg,Ratio2} =
- receive
- {Receiver2,Res2} -> Res2
- end,
- exit(Starter2, kill),
- exit(Receiver2, kill),
- io:format("Reports: ~w high (~w/proc), ~w low (~w/proc). Ratio: ~w~n",
- [H2Rs,H2Avg,LRs,LAvg,Ratio2]),
- if Ratio2 < 1.0 ->
- ct:fail({bad_ratio,Ratio2});
- true ->
- ok(Config)
- end.
-
-
-%%-----------------------------------------------------------------------------------
-%% Controller processes and help functions
-%%-----------------------------------------------------------------------------------
-
-receiver(T0, TimeSec, Main, {P1,P1N}, {P2,P2N}) ->
- %% prio should be max so that mailbox doesn't overflow
- process_flag(priority, max),
- receiver(T0, TimeSec*1000, Main, P1,P1N,0, P2,P2N,0, 100000).
-
-%% uncomment lines below to get life sign (debug)
-receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 0) ->
- % T = erlang:convert_time_unit(erlang:monotonic_time() - T0, native, millisecond),
- % erlang:display({round(T/1000),P1Rs,P2Rs}),
- receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, 100000);
-
-receiver(T0, Time, Main, P1,P1N,P1Rs, P2,P2N,P2Rs, C) ->
- Remain = Time - erlang:convert_time_unit(erlang:monotonic_time() - T0,
- native, millisecond), % test time remaining
- Remain1 = if Remain < 0 ->
- 0;
- true ->
- Remain
- end,
- {P1Rs1,P2Rs1} =
- receive
- {_Pid,P1} -> % report from a P1 process
- {P1Rs+1,P2Rs};
- {_Pid,P2} -> % report from a P2 process
- {P1Rs,P2Rs+1}
- after Remain1 ->
- {P1Rs,P2Rs}
- end,
- if Remain > 0 -> % keep going
- receiver(T0, Time, Main, P1,P1N,P1Rs1, P2,P2N,P2Rs1, C-1);
- true -> % finish
- %% calculate results and send to main test process
- P1Avg = P1Rs1/P1N,
- P2Avg = P2Rs1/P2N,
- Ratio = if P2Avg < 1.0 -> P1Avg;
- true -> P1Avg/P2Avg
- end,
- Main ! {self(),{P1Rs1,round(P1Avg),P2Rs1,round(P2Avg),Ratio}},
- flush_loop()
- end.
-
-starter({P1,P1N}, {P2,P2N}, Receiver) ->
- %% start N1 processes with prio P1
- start_p(P1, P1N, Receiver),
- %% start N2 processes with prio P2
- start_p(P2, P2N, Receiver),
- erlang:display({started,P1N+P2N}),
- flush_loop().
-
-start_p(_, 0, _) ->
- ok;
-start_p(Prio, N, Receiver) ->
- spawn_link(fun() -> p(Prio, Receiver) end),
- start_p(Prio, N-1, Receiver).
-
-p(Prio, Receiver) ->
- %% set process priority
- process_flag(priority, Prio),
- p_loop(0, Prio, Receiver).
-
-p_loop(100, Prio, Receiver) ->
- receive after 0 -> ok end,
- %% if Receiver gone, we're done
- case is_process_alive(Receiver) of
- false -> exit(bye);
- true -> ok
- end,
- %% send report
- Receiver ! {self(),Prio},
- p_loop(0, Prio, Receiver);
-
-p_loop(N, Prio, Receiver) ->
- p_loop(N+1, Prio, Receiver).
-
-
-flush_loop() ->
- receive _ ->
- ok
- end,
- flush_loop().
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 94ee9851dd..fccbaf13ee 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -153,7 +153,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 10}}].
+ {timetrap, {minutes, 1}}].
all() ->
[otp_6224, {group, stream}, basic_ping, slow_writes,
diff --git a/erts/emulator/test/port_trace_SUITE.erl b/erts/emulator/test/port_trace_SUITE.erl
index 03efdc15db..bfc3c8cb51 100644
--- a/erts/emulator/test/port_trace_SUITE.erl
+++ b/erts/emulator/test/port_trace_SUITE.erl
@@ -52,7 +52,7 @@
-define(ECHO_DRV_REMOTE_SEND_TERM, 15).
suite() -> [{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 2}}].
all() ->
[port_specs, ports, open_close,
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index e14185e881..4204d12eb3 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -134,6 +134,11 @@ init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
[{testcase, Func}|Config].
end_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ %% Restore max_heap_size to default value.
+ erlang:system_flag(max_heap_size,
+ #{size => 0,
+ kill => true,
+ error_logger => true}),
ok.
fun_spawn(Fun) ->
@@ -1024,36 +1029,48 @@ bump_big(Prev, Limit) ->
%% Priority 'low' should be mixed with 'normal' using a factor of
%% about 8. (OTP-2644)
low_prio(Config) when is_list(Config) ->
- case erlang:system_info(schedulers_online) of
- 1 ->
- ok = low_prio_test(Config);
- _ ->
- erlang:system_flag(multi_scheduling, block_normal),
- ok = low_prio_test(Config),
- erlang:system_flag(multi_scheduling, unblock_normal),
- {comment,
- "Test not written for SMP runtime system. "
- "Multi scheduling blocked during test."}
- end.
+ erlang:system_flag(multi_scheduling, block_normal),
+ Prop = low_prio_test(Config),
+ erlang:system_flag(multi_scheduling, unblock_normal),
+ Str = lists:flatten(io_lib:format("Low/high proportion is ~.3f",
+ [Prop])),
+ {comment,Str}.
low_prio_test(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- S = spawn_link(?MODULE, prio_server, [0, 0]),
+
+ %% Spawn the server running with high priority. The server must
+ %% not run at normal priority as that would skew the results for
+ %% two reasons:
+ %%
+ %% 1. There would be one more normal-priority processes than
+ %% low-priority processes.
+ %%
+ %% 2. The receive queue would grow faster than the server process
+ %% could process it. That would in turn trigger the reduction
+ %% punishment for the clients.
+ S = spawn_opt(?MODULE, prio_server, [0, 0], [link,{priority,high}]),
+
+ %% Spawn the clients and let them run for a while.
PCs = spawn_prio_clients(S, erlang:system_info(schedulers_online)),
- ct:sleep({seconds,3}),
+ ct:sleep({seconds,2}),
lists:foreach(fun (P) -> exit(P, kill) end, PCs),
+
+ %% Stop the server and retrieve the result.
S ! exit,
- receive {'EXIT', S, {A, B}} -> check_prio(A, B) end,
- ok.
+ receive
+ {'EXIT', S, {A, B}} ->
+ check_prio(A, B)
+ end.
check_prio(A, B) ->
Prop = A/B,
ok = io:format("Low=~p, High=~p, Prop=~p\n", [A, B, Prop]),
- %% It isn't 1/8, it's more like 0.3, but let's check that
- %% the low-prio processes get some little chance to run at all.
- true = (Prop < 1.0),
- true = (Prop > 1/32).
+ %% Prop is expected to be appr. 1/8. Allow a reasonable margin.
+ true = Prop < 1/4,
+ true = Prop > 1/16,
+ Prop.
prio_server(A, B) ->
receive
@@ -2057,6 +2074,7 @@ max_heap_size_test(Option, Size, Kill, ErrorLogger) ->
end,
if ErrorLogger ->
receive
+ %% There must be at least one error message.
{error, _, {emulator, _, [Pid|_]}} ->
ok
end;
@@ -2069,22 +2087,33 @@ max_heap_size_test(Option, Size, Kill, ErrorLogger) ->
{'DOWN', Ref, process, Pid, die} ->
ok
end,
- flush();
+ %% If the process was not killed, the limit may have
+ %% been reached more than once and there may be
+ %% more {error, ...} messages left.
+ receive_error_messages(Pid);
true ->
ok
end,
+
+ %% Make sure that there are no unexpected messages.
+ receive_unexpected().
+
+receive_error_messages(Pid) ->
receive
- M ->
- ct:fail({unexpected_message, M})
- after 10 ->
+ {error, _, {emulator, _, [Pid|_]}} ->
+ receive_error_messages(Pid)
+ after 1000 ->
ok
end.
-flush() ->
+receive_unexpected() ->
receive
- _M ->
- flush()
- after 1000 ->
+ {info_report, _, _} ->
+ %% May be an alarm message from os_mon. Ignore.
+ receive_unexpected();
+ M ->
+ ct:fail({unexpected_message, M})
+ after 10 ->
ok
end.
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
index 83653a7a36..c7d5a3f5a0 100644
--- a/erts/emulator/test/receive_SUITE.erl
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -39,25 +39,43 @@ groups() ->
call_with_huge_message_queue(Config) when is_list(Config) ->
Pid = spawn_link(fun echo_loop/0),
-
- {Time,ok} = tc(fun() -> calls(10, Pid) end),
-
- [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ _WarmUpTime = time_calls(Pid),
+ Time = time_calls(Pid),
+ _ = [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ io:format("Time for empty message queue: ~p", [Time]),
erlang:garbage_collect(),
- {NewTime1,ok} = tc(fun() -> calls(10, Pid) end),
- {NewTime2,ok} = tc(fun() -> calls(10, Pid) end),
+ call_with_huge_message_queue_1(Pid, Time, 5).
+
+call_with_huge_message_queue_1(_Pid, _Time, 0) ->
+ ct:fail(bad_ratio);
+call_with_huge_message_queue_1(Pid, Time, NumTries) ->
+ HugeTime = time_calls(Pid),
+ io:format("Time for huge message queue: ~p", [HugeTime]),
+
+ case (HugeTime+1) / (Time+1) of
+ Q when Q < 10 ->
+ ok;
+ Q ->
+ io:format("Too high ratio: ~p\n", [Q]),
+ call_with_huge_message_queue_1(Pid, Time, NumTries-1)
+ end.
- io:format("Time for empty message queue: ~p", [Time]),
- io:format("Time1 for huge message queue: ~p", [NewTime1]),
- io:format("Time2 for huge message queue: ~p", [NewTime2]),
-
- case hd(lists:sort([(NewTime1+1) / (Time+1), (NewTime2+1) / (Time+1)])) of
- Q when Q < 10 ->
- ok;
- Q ->
- ct:fail("Best Q = ~p", [Q])
- end,
- ok.
+%% Time a number calls. Try to avoid returning a zero time.
+time_calls(Pid) ->
+ time_calls(Pid, 10).
+
+time_calls(_Pid, 0) ->
+ 0;
+time_calls(Pid, NumTries) ->
+ case timer:tc(fun() -> calls(Pid) end) of
+ {0,ok} ->
+ time_calls(Pid, NumTries-1);
+ {Time,ok} ->
+ Time
+ end.
+
+calls(Pid) ->
+ calls(100, Pid).
calls(0, _) -> ok;
calls(N, Pid) ->
@@ -108,6 +126,3 @@ echo_loop() ->
Pid ! {Ref,Msg},
echo_loop()
end.
-
-tc(Fun) ->
- timer:tc(erlang, apply, [Fun,[]]).
diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl
index 7cbd93a0f3..a977eb41c4 100644
--- a/erts/emulator/test/timer_bif_SUITE.erl
+++ b/erts/emulator/test/timer_bif_SUITE.erl
@@ -488,24 +488,40 @@ registered_process(Config) when is_list(Config) ->
same_time_yielding(Config) when is_list(Config) ->
Mem = mem(),
+ Ref = make_ref(),
SchdlrsOnln = erlang:system_info(schedulers_online),
Tmo = erlang:monotonic_time(millisecond) + 3000,
Tmrs = lists:map(fun (I) ->
process_flag(scheduler, (I rem SchdlrsOnln) + 1),
- erlang:start_timer(Tmo, self(), hej, [{abs, true}])
+ erlang:start_timer(Tmo, self(), Ref, [{abs, true}])
end,
lists:seq(1, (?TIMEOUT_YIELD_LIMIT*3+1)*SchdlrsOnln)),
true = mem_larger_than(Mem),
- lists:foreach(fun (Tmr) -> receive {timeout, Tmr, hej} -> ok end end, Tmrs),
+ receive_all_timeouts(length(Tmrs), Ref),
Done = erlang:monotonic_time(millisecond),
true = Done >= Tmo,
+ MsAfterTmo = Done - Tmo,
+ io:format("Done ~p ms after Tmo\n", [MsAfterTmo]),
case erlang:system_info(build_type) of
- opt -> true = Done < Tmo + 200;
- _ -> true = Done < Tmo + 1000
+ opt ->
+ true = MsAfterTmo < 200;
+ _ ->
+ true = MsAfterTmo < 1000
end,
Mem = mem(),
ok.
+%% Read out all timeouts in receive queue order. This is efficient
+%% even if there are very many messages.
+
+receive_all_timeouts(0, _Ref) ->
+ ok;
+receive_all_timeouts(N, Ref) ->
+ receive
+ {timeout, _Tmr, Ref} ->
+ receive_all_timeouts(N-1, Ref)
+ end.
+
same_time_yielding_with_cancel(Config) when is_list(Config) ->
same_time_yielding_with_cancel_test(false, false).
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index 643c2e0472..bd0ea22de9 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -46,7 +46,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 5}}].
+ {timetrap, {minutes, 1}}].
all() ->
[cpu_timestamp, receive_trace, link_receive_call_correlation,
@@ -184,10 +184,10 @@ receive_trace(Config) when is_list(Config) ->
{'EXIT', Intruder, {badarg, _}} = receive_first(),
%% Untrace the process; we should not receive anything.
- ?line 1 = erlang:trace(Receiver, false, ['receive']),
- ?line Receiver ! {hello, there},
- ?line Receiver ! any_garbage,
- ?line receive_nothing(),
+ 1 = erlang:trace(Receiver, false, ['receive']),
+ Receiver ! {hello, there},
+ Receiver ! any_garbage,
+ receive_nothing(),
%% Verify restrictions in matchspec for 'receive'
F3 = fun (Pat) -> {'EXIT', {badarg,_}} = (catch erlang:trace_pattern('receive', Pat, [])) end,
diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl
index e4db368ea1..5eb27a7b68 100644
--- a/erts/emulator/test/trace_port_SUITE.erl
+++ b/erts/emulator/test/trace_port_SUITE.erl
@@ -37,7 +37,7 @@
suite() ->
[{ct_hooks,[ts_install_cth]},
- {timetrap, {seconds, 30}}].
+ {timetrap, {minutes, 2}}].
all() ->
[call_trace, return_trace, send, receive_trace,