| Commit message (Collapse) | Author | Age | Files | Lines |
|\
| |
| | |
Add "since" versions to XML taglist
|
| | |
|
| | |
|
| | |
|
| |
| |
| |
| |
| | |
Usable to indicate OTP version when a particular option
was introduced.
|
|\ \
| | |
| | | |
Make maps_order optional in io_lib:format_spec()
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The 'maps_order' key has been added to the public type
io_lib:format_spec() in OTP26 RC1, as a required key.
Besides, the key presence is assumed in the implementation
of io_lib:unscan_format/1. This makes it a breaking change,
resulting in unexpected behavior for existing code calling
it on a map without the key (returns a list of maps).
- fix the typespec to make the key optional
- don't require the key in io_lib:unscan_format/1
- add a guard to detect we're not building a correct charlist
|
|\ \ \
| | | |
| | | | |
Improve `lists:nth/2` and `nthtail/2`
|
| |/ / |
|
|\ \ \
| | | |
| | | |
| | | |
| | | | |
Add `lists:enumerate/3`
OTP-18495
|
| |/ / |
|
|/ / |
|
|\ \
| | |
| | | |
Fixes bug in shell completion OTP-14835
|
| | |
| | |
| | |
| | |
| | | |
previously multi arity functions with a zero arity variant
omitted the zero arity function.
|
|\ \ \
| |_|/
|/| |
| | |
| | | |
ms_transform: allow caller_line and current_stacktrace action functions
OTP-18494
|
| |/
| |
| |
| |
| |
| | |
caller_line/0 was added in https://github.com/erlang/otp/pull/5305,
while current_stacktrace/0,/1 were added in
https://github.com/erlang/otp/pull/6628
|
|\ \
| |/
|/| |
Optimize the copy that occurs in ets:lookup_element
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Michal Muskala pointed to me that sometimes ets:lookup_element can be
slower than ets:lookup, even when the value is found. For example:
```
erlperf "ets:lookup(ac_tab, {env, kernel, logger})." "ets:lookup_element(ac_tab, {env, kernel, logger}, 2)."
Code || QPS Time Rel
ets:lookup(ac_tab, {env, kernel, logger}). 1 2859 Ki 349 ns 100%
ets:lookup_element(ac_tab, {env, kernel, logger}, 2). 1 2164 Ki 462 ns 75%
```
The reason for this is that lookup can find the size of the allocation
needed directly in the DbTerm, then copy the whole thing efficiently
with copy_shallow_x, whereas lookup_element must first walk all over
the value to be copied in size_object_x, and then walk it again in
copy_struct_x.
This patch fixes this in three steps:
- Make db_store_term (used by ets:insert among others) use a
specialized version of copy_struct that makes the fields be laid in
order (instead of being chaotically interspersed as usual)
- Finding the size of the needed allocation can now be done
efficiently (see db_field_size)
- And we can use copy_shallow_x for the copy like lookup (just with a
small change so that it does not assume that it is copying a tuple).
Result:
```
PATH=~/otp/bin:$PATH erlperf "ets:lookup(ac_tab, {env, kernel, logger})." "ets:lookup_element(ac_tab, {env, kernel, logger}, 2)."
Code || QPS Time Rel
ets:lookup_element(ac_tab, {env, kernel, logger}, 2). 1 2945 Ki 339 ns 100%
ets:lookup(ac_tab, {env, kernel, logger}). 1 2860 Ki 349 ns 97%
```
I've tried measuring the potential impact on ets:insert performance
by looking at the 2 throughput benchmarks in ets_SUITE.
More specifically, I looked at the 50% insert/50% delete mix
(since it maximizes the impact of insert) and at the 1 process case
(since my change should not affect concurrency in any way).
Here are the results for the long benchmark, with 3 runs in each
configuration, listing all three kinds of table tested:
[set, {write_concurrency, auto}, {read_concurrency, true}]:
Baseline: 3.55 / 3.31 / 2.85
This patch: 3.20 / 3.08 / 3.44
[set, {write_concurrency, true}, {read_concurrency, true}]:
Baseline: 3.31 / 3.11 / 2.78
This patch: 3.13 / 3.08 / 3.42
[ordered_set, {write_concurrency, true}, {read_concurrency, true}]:
Baseline: 1.51 / 1.56 / 1.17
This patch: 1.50 / 1.37 / 1.59
(all running on my M1 MBP)
There is no obvious performance regression, but the noise is
sufficiently high that I may have missed some.
Co-authored-by: Sverker Eriksson <sverker@erlang.org>
|
|\ \
| | |
| | | |
Improve the `lists:merge` family of functions
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The merge functions no longer accept non-list arguments for merging.
Before, non-list arguments were accepted and returned if they were
the first argument and the second (and third, where applicable,
ie in merge3/3 and umerge3/3) arguments were empty lists. For merge/1
and umerge/1, non-list arguments were accepted if they were the only
element in a list of otherwise empty lists.
The merge functions now also return the second (or third, where
applicable) list immediately and unchanged if the other lists
are empty.
Before, this was only done for the first argument, if the second
(and third, where applicable) list was empty. In all other cases,
the merging process would be performed, unnecessarily.
The same applies for the undocumented reverse-merge functions like
rmerge/2,3, rumerge/2,3 etc.
Co-authored-by: Jan Uhlig <juhlig@hnc-agency.org>
|
|\ \ \
| |/ /
|/| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
* raimo/gen-sync-start-fail/GH-6339:
Update documentation after review
Fix bug - start_link should not return an unwrapped error Reason
Change to a more coherent behaviour for init_fail and exit in init
Clarify documentation
Update doc with proc_lib:init_fail/2,3
Simplify error propagation
Implement synchronous init failure for gen processes
Test looping over gen_server init failure
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
See GitHub PR#6843.
When `init()` function exits, return `{error, EXIT_reason}`.
A link, of course, still may kill the caller.
Never leave an {`EXIT',_,_} message lingering after an error return.
|
| | | |
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | | |
After fixing how proc_lib:start_link/* handles exit(normal)
it is, from an init/1 function, equivalent to call exit(Reason)
instead of proc_lib:init_fail({error, Reason}, {exit, Reason}).
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
* Implement a function `proc_lib:init_fail/2,3` to call from
`proc_lib` started processes when they fail to initialize instead
of `proc_lib:init_ack/1,2`. The new function sends a `{nack,,}`
to the spawner that then uses a process monitor on the spawned
process to await the monitor `'DOWN'` message before returning
a failure to the spawner.
This avoids a race when using `proc_lib:init_ack/1,2` which
allows the spawner to get and return the failure return value,
and restart a new server instance while the old instance not
yet has been scheduled for exit and cleanup. The old server
instance may hold a VM resource such as a named ETS table
that the new server instance fails to create.
* Use the new init fail function in Kernel and Stdlib.
* Fix a bug when `proc_lib:start_link/*` is called from
a process that does _not_ trap exits and the `init/1` function
simply exits with reason normal without calling
`proc_lib:init_fail/2,3 or `proc_lib:init_ack/1,2`. Then
the caller would wait for the start `Timeout` which could
be `infinity`. This is solved by using a process monitor
also for `proc_lib:start_link/*`.
|
| | | |
|
|\ \ \
| | | |
| | | |
| | | |
| | | |
| | | | |
Fix a bug that `file:read(standard_io, ..)` unexpectedly returns `eof`
OTP-18486
PR-6881
|
| | | | |
|
|\ \ \ \
| | | | |
| | | | | |
stdlib: Hibernate static supervisors
|
| |/ / /
| | | |
| | | |
| | | |
| | | | |
Static supervisors are very idle processes after they have started
so they will now be hibernated after start to improve resource management.
|
|\ \ \ \
| |/ / /
|/| | |
| | | |
| | | |
| | | |
| | | | |
kikofernandez/kiko/dialyzer/unbound-single-type-variable/GH-6508/OTP-18389
dialyzer: fix singleton type var in union types
OTP-18389
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Dialyzer (erl_lint) was accepting code of the following form:
```erlang
-spec run_test(Opts) -> term()
when Opts :: {join_specs, Bool} | {test, Bool}.
run_test(Opts) -> {error, fail}.
```
But this cannot be ever checked by Dialyzer as the type variable `Bool`
is in an union, which means that `Bool` happened only once and thus, `Bool`
is an unbound type variable. Essentially, the example above should be
rejected by Dialyzer in the same manner as this other one below:
```erlang
-spec run_test_error(Opts) -> term()
when Opts :: {join_specs, Bool}.
run_test_error(Opts) ->
{error, fail}.
```
This commit fixes GH-6508 and adds a bunch of tests to `erl_lint.erl`
so that we can keep track of which singleton type variables should throw
an error and which ones are ok.
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The code for the `binary:encode_hex/1` and `binary:encode_hex/2`
functions has been simplified. The simplified implementation has a
more consistent runtime compared to the old implementation. To test
the performance, I made a new `hex_bench` benchmark based on the
`base64` benchmark:
https://gist.github.com/bjorng/522470f313ac01d16156a597657f97bb
For the old implementation, on my M1 Mac the results for the best case
and worst case are as follows:
Size: 1024*1024 (divisible by 8)
fun binary:encode_hex/1: 1000 iterations in 1899 ms: 526 it/sec
Size: 1024*1024 + 1 (not divisible by 2 through 7)
fun binary:encode_hex/1: 1000 iterations in 5984 ms: 167 it/sec
That is, the worst case is about three times slower than the best
case.
The simplifed encode function shows much less variation:
Size: 1024*1024 (divisible by 8)
fun binary:encode_hex/1: 1000 iterations in 1899 ms: 526 it/sec
Size: 1024*1024 + 1 (not divisible by 8)
fun binary:encode_hex/1: 1000 iterations in 2100 ms: 476 it/sec
For the old implementation of `decode_hex/1`, the benchmark results
are:
fun binary:decode_hex/1: 1000 iterations in 28823 ms: 34 it/sec
The results for the simplified implementation are:
Size: 1024*1024 (divisible by 8)
fun binary:decode_hex/1: 1000 iterations in 3041 ms: 328 it/sec
Size: 1024*1024+1 (not divisible by 8)
fun binary:decode_hex/1: 1000 iterations in 3144 ms: 318 it/sec
That is, the simplified implementation is almost 10 times faster.
All hex functions now raise exceptions with correct stack traces (with
the function being called at the top of the stack trace) and error
information.
|
| |
| |
| |
| | |
This reverts commit 587341d994f91af5b30483ee9434e932e3d7b802.
|
| | |
|
| | |
|
|\ \
| | |
| | |
| | |
| | | |
* rickard/60bit-pids/OTP-18435:
[erts] Fix test cases for new internal pids
|
| | | |
|
|\ \ \ |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Document the new valid return value for Module:init/1
for both gen_server and gen_statem.
OTP-18423
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Update the 'start' test case of the gen_server_SUITE
and gen_statem_SUITE.
OTP-18423
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Add a new "legal" return value for Module:init/1 (for both
gen_server and gen_statem); {error, Reason}
This should have same effect as ignore, except that the return value
should be '{error, Reason}' instead of 'ignore'.
OTP-18423
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Earlier during development of Erlang/OTP 26 we hard-coded the
`maybe_expr` feature to be always enable in the runtime system.
Remove that hack and no longer require any compile-time feature to be
enabled in the runtime system.
|
|\ \ \ \
| | | | |
| | | | | |
STDLIB tests: Fix falling map iterator tests in debug build
|
| | |/ /
| |/| |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The `>=/2` sort function is not appropriate for sorting maps with
mixed integer and float keys. It happens to work with small maps
because `maps:to_list/1` returns a list already correctly sorted. In a
debug build, the four-elements maps are large maps and the test case
fails.
While at it, also correct `ARevCmpFun` in `maps_SUITE`.
|
|/ / /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Dialyzer's warnings about unknown functions and types are enabled by
default.
Prior to this PR, Dialyzer used to have disabled (by default) warnings
about unknown types and functions.
This default value has been overwritten; Dialyzer now warns about
unknown types and functions (as requested by the community in GH-5695).
Thus, the following two examples are equivalent, i.e., passing the
`-Wunknown` function is enabled by default:
```bash
dialyzer moduler.erl -Wunknown -Wmissing_return
dialyzer moduler.erl -Wmissing_return
```
Dialyzer has a new flag, `-Wno_unknown`. Its purpose is to supress
warnings about unknown functions and types.
Users who wish to suppress these warnings can invoke Dialyzer using this
flag. Example:
```bash
dialyzer module.erl -Wno_unknown
```
|
|\ \ \ |
|
| |\ \ \
| | | | |
| | | | | |
OTP-18434
|