Age | Commit message (Collapse) | Author |
|
Introduce is_map_key/2 guard BIF
OTP-15037
|
|
This makes the nightly tests slightly more stable as they assert
that the server isn't alive when lcnt:start/0 is called, which it
could still be since the stop command was a plain gen_server call
that didn't wait until the termination was completed.
|
|
This reverts commit 202bb737e3deabfebee683266f4b7c42781eb521.
|
|
This reverts commit 345f7f527a4c26ef49cef0d81e2c8b71bf01ebc3.
|
|
|
|
|
|
This complements the `map_get/2` guard BIF introduced in #1784.
Rationale.
`map_get/2` allows accessing map fields in guards, but it might be
problematic in more complex guard expressions, for example:
foo(X) when map_get(a, X) =:= 1 or is_list(X) -> ...
The `is_list/1` part of the guard could never succeed since the
`map_get/2` guard would fail the whole guard expression. In this
situation, this could be solved by using `;` instead of `or` to separate
the guards, but it is not possible in every case.
To solve this situation, this PR proposes a `is_map_key/2` guard that
allows to check if a map has key inside a guard before trying to access
that key. When combined with `is_map/1` this allows to construct a
purely boolean guard expression testing a value of a key in a map.
Implementation.
Given the use case motivating the introduction of this function, the PR
contains compiler optimisations that produce optimial code for the
following guard expression:
foo(X) when is_map(X) and is_map_key(a, X) and map_get(a, X) =:= 1 -> ok;
foo(_) -> error.
Given all three tests share the failure label, the `is_map_key/2` and
`is_map/2` tests are optimised away.
As with `map_get/2` the `is_map_key/2` BIF is allowed in match specs.
|
|
* 'map-get-bif' of git://github.com/michalmuskala/otp:
Introduce map_get guard-safe function
OTP-15037
|
|
Rationale
Today all compound data types except for maps can be deconstructed in guards.
For tuples we have `element/2` and for lists `hd/1` and `tl/1`. Maps are
completely opaque to guards. This means matching on maps can't be
abstracted into macros, which is often done with repetitive guards. It
also means that maps have to be always selected whole from ETS tables,
even when only one field would be enough, which creates a potential
efficiency issue.
This PR introduces an `erlang:map_get/2` guard-safe function that allows
extracting a map field in guard. An alternative to this function would be
to introduce the syntax for extracting a value from a map that was planned
in the original EEP: `Map#{Key}`.
Even outside of guards, since this function is a guard-BIF it is more
efficient than using `maps:get/2` (since it does not need to set up the
stack), and more convenient from pattern matching on the map (compare:
`#{key := Value} = Map, Value` to `map_get(key, Map)`).
Performance considerations
A common concern against adding this function is the notion that "guards
have to be fast" and ideally execute in constant time. While there are
some counterexamples (`length/1`), what is more important is the fact
that adding those functions does not change in any way the time
complexity of pattern matching - it's already possible to match on map
fields today directly in patterns - adding this ability to guards will
niether slow down or speed up the execution, it will only make certain
programs more convenient to write.
This first version is very naive and does not perform any optimizations.
|
|
This commit replaces the old memory instrumentation with a new
implementation that scans carriers instead of wrapping
erts_alloc/erts_free. The old implementation could not extract
information without halting the emulator, had considerable runtime
overhead, and the memory maps it produced were noisy and lacked
critical information.
Since the new implementation walks through existing data structures
there's no longer a need to start the emulator with special flags to
get information about carrier utilization/fragmentation. Memory
fragmentation is also easier to diagnose as it's presented on a
per-carrier basis which eliminates the need to account for "holes"
between mmap segments.
To help track allocations, each allocation can now be tagged with
what it is and who allocated it at the cost of one extra word per
allocation. This is controlled on a per-allocator basis with the
+M<S>atags option, and is enabled by default for binary_alloc and
driver_alloc (which is also used by NIFs).
|
|
|
|
* rickard/signals/OTP-14589:
Fix VM probes compilation
Fix lock counting
Fix signal order for is_process_alive
Fix signal handling priority elevation
|
|
|
|
Implementation of true asynchronous signaling between processes
|
|
Communication between Erlang processes has conceptually always been
performed through asynchronous signaling. The runtime system
implementation has however previously preformed most operation
synchronously. In a system with only one true thread of execution, this
is not problematic (often the opposite). In a system with multiple threads
of execution (as current runtime system implementation with SMP support)
it becomes problematic. This since it often involves locking of structures
when updating them which in turn cause resource contention. Utilizing
true asynchronous communication often avoids these resource contention
issues.
The case that triggered this change was contention on the link lock due
to frequent updates of the monitor trees during communication with a
frequently used server. The signal order delivery guarantees of the
language makes it hard to change the implementation of only some signals
to use true asynchronous signaling. Therefore the implementations
of (almost) all signals have been changed.
Currently the following signals have been implemented as true
asynchronous signals:
- Message signals
- Exit signals
- Monitor signals
- Demonitor signals
- Monitor triggered signals (DOWN, CHANGE, etc)
- Link signals
- Unlink signals
- Group leader signals
All of the above already defined as asynchronous signals in the
language. The implementation of messages signals was quite
asynchronous to begin with, but had quite strict delivery constraints
due to the ordering guarantees of signals between a pair of processes.
The previously used message queue partitioned into two halves has been
replaced by a more general signal queue partitioned into three parts
that service all kinds of signals. More details regarding the signal
queue can be found in comments in the erl_proc_sig_queue.h file.
The monitor and link implementations have also been completely replaced
in order to fit the new asynchronous signaling implementation as good
as possible. More details regarding the new monitor and link
implementations can be found in the erl_monitor_link.h file.
|
|
Conflicts:
OTP_VERSION
|
|
|
|
|
|
* maint:
Add updated type-spec to Emacs skeletons of OTP behaviours
|
|
* pr/1620:
Add updated type-spec to Emacs skeletons of OTP behaviours
|
|
The changes are based on the latest versions of following modules
and are also similar to gen_statem Emacs skeleton. Note that the
gen_fsm is not updated because it is deprecated.
application:
* add/update type-spec for all callbacks
* add start_phase/3 callback
* add prep_stop/1 callback
* add config_change/3 callback
supervisor:
* add/update type-spec for all callbacks
supervisor_bridge:
* add/update type-spec for all callbacks
gen_server:
* add/update type-spec for all callbacks
* add format_status/2 callback
gen_event:
* add/update type-spec for all callbacks
* add format_status/2 callback
|
|
* maint:
Derive `erlang-shell-mode` properly from `comint-mode`
|
|
|
|
* maint:
emacs: delimiter first in icr works
emacs: Indent delimiter first in term elements correctly
emacs: Indent tuple (and maps) elements as list elements
Add emacs indention testcase
|
|
* dgud/tools/emacs/indent-tests:
emacs: delimiter first in icr works
emacs: Indent delimiter first in term elements correctly
emacs: Indent tuple (and maps) elements as list elements
Add emacs indention testcase
OTP-14944
|
|
|
|
|
|
Avoid
From:
{
^^element1,
^^element2
}
To:
{
^element1,
^element2
}
|
|
Split the manual testcase and run them in daily tests instead.
Easy to run directly as well:
(cd ../test; cerl -eval "emacs_SUITE:indent([])")
|
|
|
|
|
|
|
|
lcnt:collect is documented as implicitly starting the lcnt server
but didn't do so prior to this commit. I've decided to extend this
behavior to all operations as the overhead is negligible and it's
a bit more convenient to use.
|
|
|
|
|
|
* maint:
tools: Correct a counting bug in Cover
|
|
See also PR #1641, https://github.com/erlang/otp/pull/1641.
The bug was introduced in commit ab435488a (Erlang/OTP 18).
|
|
* dgud/kernel/refc_sched_wall_time/OTP-11694:
test: spawn scheduler_wall_time flag holder
Turn on scheduler_wall_time in an alive process
Redirect system_flag(scheduler_wall_time,_) to kernel_refc
kernel: add a resource reference counter
|
|
|
|
|
|
|
|
|
|
The tests assume that the most active process will be the current
one, which is no longer true since the delayed_write option now
uses a wrapper process for much of its work.
The timeout for this test has been increased to account for the
lack of delayed_write; 60s was enough for everything except the
debug build on some machines.
|
|
|
|
|
|
|
|
|
|
|
|
This commit also adds a check to see that all files that
are part of an xi:include also have part of XML_FILES
and vice versa. It also fixes any applications where this
was not true.
|
|
erlang:is_builtin(erlang, M, F) returns false for apply/2 and
yield/0. The documentation for erlang:is_builtin/3 says that it
returns true for BIFs that are implemented in C. apply/2 and
yield/0 are implemented in C (as BEAM instructions), and
therefore the correct return value is true.
Also see a similar argument that was made for apply/3 in the past:
http://erlang.org/pipermail/erlang-bugs/2015-October/005101.html
https://bugs.erlang.org/browse/ERL-500
|