Age | Commit message (Collapse) | Author |
|
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.
|
|
* bjorn/misc-beam-fixes:
Correctly handle get_map_elements with a literal map
core_parse: Fix handling of negative sizes in binaries
|
|
* sverker/inline-sys_memcpy:
erts: Optimize macro DMC_PUSH
erts: Make sys_memcpy and friends inline functions
|
|
to call a common static function dmc_stack_grow()
and reduce the code bloat.
and did a combined DMC_PUSH2
|
|
to avoid argument-evaluated-twice bugs
like in macro DMC_PUSH.
Had to shuffle around some #include and #define
to make erl_child_setup build debug target.
|
|
A get_map_elements instruction that has a literal map operand
would never be translated to a i_get_map_element instruction.
That would be a problem for the following instruction:
get_map_elements Fail #{} {x,0}, {x,1}
Since the key is not a literal, get_map_element must be used,
since get_map_elements requires that a hash value can be
calculated for each element.
When the instruction is translated to i_get_map_element, the
hash value will be set to 0 and an assertion will trigger in
the debug build.
|
|
make erlang:process_info/1 not retrieve messages
|
|
|
|
Remove low memory need for HiPE on x86_64
|
|
* rickard/dirty-work-gone/OTP-14978:
Reschedule on ordinary scheduler if dirty work is gone
|
|
|
|
* rickard/pre-alloc-alignment/OTP-14977:
Force 64-bit alignment for pre-allocators unless x86
|
|
|
|
* rickard/remove-approx-started/OTP-14975:
Remove process start time for crash dumps
|
|
* sverker/dict-put-immed-opt:
erts: Optimize erlang:put/2 for hash collision lists
erts: Optimize erlang:put/2 for immed values
erts: Refactor erlang:put/2
|
|
|
|
|
|
|
|
* john/erts/tuple-arityval-fixes/OTP-14963/ERL-577:
Make doc entry for maximum tuple size reflect reality
Assert that sz <= MAX_ARITYVAL in make_arityval(sz)
|
|
* john/erts/assert-on-memcpy-memset-etc:
Always use sys_memcpy/cmp/etc instead of plain memcpy/cmp/etc
Check the arguments to sys_memcpy and friends
|
|
process_info/1 retrieves a number of properties related to a process,
including the list of messages in its mailbox. This is potentially
unsafe if the target process has a large number of queued messages:
- there is no a priori upper bound on the amount of memory being
allocated to hold that list, and
- the loop to retrieve the messages is uninterruptible, so the
Erlang scheduler where this executes blocks for the duration
We've seen process_info/1 bring down heavily loaded nodes on more
than one occasion. At least once it appeared to have blocked the
Erlang heart process from executing, causing the external heart to
kill the VM.
Consequently this removes 'messages' from the list of process_info
tags to retrieve for process_info/1. Note that process_info/1 still
retrieves 'message_queue_len', and process_info/2 can still retrieve
'messages' when asked to.
A few places in the OTP libraries need minor adjustments, since they
want 'message_queue_len' but compute it from the length of the list
of messages.
|
|
|
|
Passing NULL is undefined behavior and unconditionally executing these
may result in the compiler optimizing away a later NULL check. It can
often work since the pointer isn't touched when the length is 0, but
it's a major footgun. See ERL-573.
|
|
Bug introduced in commit fbb10ebc4a37555c7ea7f99e14286d862993976a
|
|
Instead of rebuilding all cons cells before key,
just unlink key cell from list with a destructive heap write op.
This is safe as these lists never leak out and any new-to-old-heap-refs
are preserved.
|
|
|
|
|
|
|
|
|
|
|
|
Just to simplify and get 4 distinctive states
IDLE, PENDING, CONNECTED and EXITING.
The old possible flag combos were:
0
PENDING
CONNECTED
CONNECTED|EXITING
EXITING
The two EXITING states did not serve any purpose
other then as a slight optimization in monitor_node(_,false,_)
to shortcut EXITING when there can be no monitors.
|
|
to only transcode if output buffer actually contains
unsupported BIT_BINARY_EXT or EXPORT_EXT.
|
|
to replace DFLAGS_STRICT_ORDER_DELIVERY
and remove that compile time dependency.
|
|
for kernel to ask erts about distribution flags
and keep this info in one place.
|
|
This is a fix for a bug introduced in 22cde2bda
|
|
* john/erts/binary-bin_to_list-performance-fix/OTP-14741:
Replace binary:bin_to_list CIF implementation with binary_to_list
|
|
|
|
* sverker/erts/more-crash-dump-info/OTP-14820:
erts,observer: Add port-suspended pids to crash dump
erts,observer: Add port states and flags to crash dump
erts,observer: Add dirty schedulers to crash dump
observer: Refactor get_schedulerinfo1
erts,observer: Add more port info to crash dump
erts: Cleanup dump_process_info()
erts: Include failing garbing process in crash dump
erts: Remove unused args to collect_live_heap_frags
erts: Add binary vheap sizes to crash dump
|
|
Conflicts:
erts/emulator/beam/erl_trace.c
|
|
* lukas/erts/dirty_trace_clean_fix/OTP-14938:
erts: Delay cleanup of removed tracer on dirty scheds
|
|
binary:bin_to_list had a poor implementation that resulted in
excessive garbage collection. binary_to_list is almost identical and
has a generally better implementation, so I've replaced
binary:bin_to_list's CIF with a thin wrapper around binary_to_list.
Granted, binary_to_list has a deprecated indexing scheme, but we're
unlikely to ever remote it entirely and it's somewhat easy to move
it to the 'binary' module later on.
|
|
It is not simple to do the correct de-allocation on
a dirty schedulers, so we just delay it until this
process runs on a normal scheduler.
|
|
* john/erts/nif-binary-iovec-fixes/OTP-14845/OTP-14931/OTP-14932:
Suggest using enif_make_new_binary when possible
Make enif_make_binary return heap binaries if possible
Expand ErlNifBinary by another word for future additions
Unconditionally transfer ownership to the created term
Tweak asserts and explain why the copy buf doesn't use the tmp obj list
Free temporary iovecs through the tmp object list
Add a helper function for attaching tmp objects to NIF environments
|
|
This does not avoid allocating a ProcBin since we still need to
release the binary somehow (and using the tmp obj list is slightly
slower since it's an unavoidable off-heap allocation), but it does give
us a hard limit on how long said ProcBin will live, which is a lot
better than before.
OTP-14845
|
|
When fixing OTP-14931/14932 we had to settle for a solution that
decreased performance in a few corner cases like multiple calls to
enif_make_binary, as the other options on the table required extra
fields which would have broken ABI compatibility.
This is ABI-compatible since the fields are unused and at the end.
|
|
This fixes two corner-cases:
1) We will no longer return an invalid term when a binary inspected
on environment A is used in enif_make_binary on environment B
2) A double-free in this sequence of events:
* enif_alloc_binary(size, &bin);
* enif_ioq_enq_binary(ioq, &bin, skip);
* enif_make_binary(env, &bin);
* enif_make_binary(env, &bin);
OTP-14931
OTP-14932
|
|
|
|
Attaching to a ProcBin is the fastest way to delay the release of an
already allocated Binary, but alloc_tmp_obj is a lot faster when
starting from scratch since it usually uses temp_alloc.
|
|
|