aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded/src/erlang.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/preloaded/src/erlang.erl')
-rw-r--r--erts/preloaded/src/erlang.erl334
1 files changed, 107 insertions, 227 deletions
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index f6410d9050..53e90a4f2d 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -31,8 +31,7 @@
-export([localtime_to_universaltime/1]).
-export([suspend_process/1]).
-export([min/2, max/2]).
--export([dlink/1, dunlink/1, dsend/2, dsend/3, dgroup_leader/2,
- dexit/2, dmonitor_node/3, dmonitor_p/2]).
+-export([dmonitor_node/3]).
-export([delay_trap/2]).
-export([set_cookie/2, get_cookie/0]).
-export([nodes/0]).
@@ -40,15 +39,18 @@
-export([integer_to_list/2]).
-export([integer_to_binary/2]).
-export([set_cpu_topology/1, format_cpu_topology/1]).
--export([await_proc_exit/3]).
-export([memory/0, memory/1]).
-export([alloc_info/1, alloc_sizes/1]).
--export([gather_sched_wall_time_result/1,
- await_sched_wall_time_modifications/2,
- gather_gc_info_result/1]).
+-export([gather_gc_info_result/1]).
--deprecated([now/0]).
+-export([dist_ctrl_input_handler/2,
+ dist_ctrl_put_data/2,
+ dist_ctrl_get_data/1,
+ dist_ctrl_get_data_notification/1,
+ dist_get_stat/1]).
+
+-deprecated([get_stacktrace/0,now/0]).
%% Get rid of autoimports of spawn to avoid clashes with ourselves.
-compile({no_auto_import,[spawn_link/1]}).
@@ -87,6 +89,10 @@
-export_type([prepared_code/0]).
+-opaque dist_handle() :: atom().
+
+-export_type([dist_handle/0]).
+
-type iovec() :: [binary()].
-export_type([iovec/0]).
@@ -114,8 +120,8 @@
-export([crc32/2, crc32_combine/3, date/0, decode_packet/3]).
-export([delete_element/2]).
-export([delete_module/1, demonitor/1, demonitor/2, display/1]).
--export([display_nl/0, display_string/1, dist_exit/3, erase/0, erase/1]).
--export([error/1, error/2, exit/1, exit/2, external_size/1]).
+-export([display_nl/0, display_string/1, erase/0, erase/1]).
+-export([error/1, error/2, exit/1, exit/2, exit_signal/2, external_size/1]).
-export([external_size/2, finish_after_on_load/2, finish_loading/1, float/1]).
-export([float_to_binary/1, float_to_binary/2,
float_to_list/1, float_to_list/2, floor/1]).
@@ -135,7 +141,7 @@
-export([list_to_integer/1, list_to_integer/2]).
-export([list_to_pid/1, list_to_port/1, list_to_ref/1, list_to_tuple/1, loaded/0]).
-export([localtime/0, make_ref/0]).
--export([map_size/1, match_spec_test/3, md5/1, md5_final/1]).
+-export([map_size/1, map_get/2, match_spec_test/3, md5/1, md5_final/1]).
-export([md5_init/0, md5_update/2, module_loaded/1, monitor/2]).
-export([monitor_node/2, monitor_node/3, nif_error/1, nif_error/2]).
-export([node/0, node/1, now/0, phash/2, phash2/1, phash2/2]).
@@ -417,9 +423,11 @@ binary_to_term(_Binary) ->
erlang:nif_error(undefined).
%% binary_to_term/2
--spec binary_to_term(Binary, Opts) -> term() when
+-spec binary_to_term(Binary, Opts) -> term() | {term(), Used} when
Binary :: ext_binary(),
- Opts :: [safe].
+ Opt :: safe | used,
+ Opts :: [Opt],
+ Used :: pos_integer().
binary_to_term(_Binary, _Opts) ->
erlang:nif_error(undefined).
@@ -692,14 +700,6 @@ display_nl() ->
display_string(_P1) ->
erlang:nif_error(undefined).
-%% dist_exit/3
--spec erlang:dist_exit(P1, P2, P3) -> true when
- P1 :: pid(),
- P2 :: kill | noconnection | normal,
- P3 :: pid() | port().
-dist_exit(_P1, _P2, _P3) ->
- erlang:nif_error(undefined).
-
%% dt_append_vm_tag_data/1
-spec erlang:dt_append_vm_tag_data(IoData) -> IoDataRet when
IoData :: iodata(),
@@ -785,6 +785,13 @@ exit(_Reason) ->
exit(_Pid, _Reason) ->
erlang:nif_error(undefined).
+%% exit_signal/2
+-spec erlang:exit_signal(Pid, Reason) -> true when
+ Pid :: pid() | port(),
+ Reason :: term().
+exit_signal(_Pid, _Reason) ->
+ erlang:nif_error(undefined).
+
%% external_size/1
-spec erlang:external_size(Term) -> non_neg_integer() when
Term :: term().
@@ -1011,8 +1018,20 @@ group_leader() ->
-spec group_leader(GroupLeader, Pid) -> true when
GroupLeader :: pid(),
Pid :: pid().
-group_leader(_GroupLeader, _Pid) ->
- erlang:nif_error(undefined).
+group_leader(GroupLeader, Pid) ->
+ case case erts_internal:group_leader(GroupLeader, Pid) of
+ false ->
+ Ref = erlang:make_ref(),
+ erts_internal:group_leader(GroupLeader,
+ Pid,
+ Ref),
+ receive {Ref, MsgRes} -> MsgRes end;
+ Res ->
+ Res
+ end of
+ true -> true;
+ Error -> erlang:error(Error, [GroupLeader, Pid])
+ end.
%% halt/0
%% Shadowed by erl_bif_types: erlang:halt/0
@@ -1211,6 +1230,14 @@ make_ref() ->
map_size(_Map) ->
erlang:nif_error(undefined).
+%% Shadowed by erl_bif_types: erlang:map_get/2
+-spec map_get(Key, Map) -> Value when
+ Map :: map(),
+ Key :: any(),
+ Value :: any().
+map_get(_Key, _Map) ->
+ erlang:nif_error(undefined).
+
%% match_spec_test/3
-spec erlang:match_spec_test(MatchAgainst, MatchSpec, Type) -> TestResult when
MatchAgainst :: [term()] | tuple(),
@@ -1651,7 +1678,7 @@ setnode(_P1, _P2) ->
erlang:nif_error(undefined).
%% setnode/3
--spec erlang:setnode(P1, P2, P3) -> true when
+-spec erlang:setnode(P1, P2, P3) -> dist_handle() when
P1 :: atom(),
P2 :: port(),
P3 :: {term(), term(), term(), term()}.
@@ -1903,7 +1930,7 @@ element(_N, _Tuple) ->
%% Not documented
-type module_info_key() :: attributes | compile | exports | functions | md5
- | module | native | native_addresses.
+ | module | native | native_addresses | nifs.
-spec erlang:get_module_info(Module, Item) -> ModuleInfo when
Module :: atom(),
Item :: module_info_key(),
@@ -2100,7 +2127,7 @@ nodes(_Arg) ->
| stream
| {line, L :: non_neg_integer()}
| {cd, Dir :: string() | binary()}
- | {env, Env :: [{Name :: string(), Val :: string() | false}]}
+ | {env, Env :: [{Name :: os:env_var_name(), Val :: os:env_var_value() | false}]}
| {args, [string() | binary()]}
| {arg0, string() | binary()}
| exit_status
@@ -2334,7 +2361,8 @@ spawn_opt(_Tuple) ->
MSAcc_Thread :: #{ type := MSAcc_Thread_Type,
id := MSAcc_Thread_Id,
counters := MSAcc_Counters},
- MSAcc_Thread_Type :: scheduler | async | aux,
+ MSAcc_Thread_Type :: async | aux | dirty_io_scheduler
+ | dirty_cpu_scheduler | poll | scheduler,
MSAcc_Thread_Id :: non_neg_integer(),
MSAcc_Counters :: #{ MSAcc_Thread_State => non_neg_integer() },
MSAcc_Thread_State :: alloc | aux | bif | busy_wait | check_io |
@@ -2561,10 +2589,10 @@ tuple_to_list(_Tuple) ->
Settings :: [{Subsystem :: atom(),
[{Parameter :: atom(),
Value :: term()}]}];
- (alloc_util_allocators) -> [Alloc] when
- Alloc :: atom();
({allocator, Alloc}) -> [_] when %% More or less anything
Alloc :: atom();
+ (alloc_util_allocators) -> [Alloc] when
+ Alloc :: atom();
({allocator_sizes, Alloc}) -> [_] when %% More or less anything
Alloc :: atom();
(atom_count) -> pos_integer();
@@ -2591,6 +2619,7 @@ tuple_to_list(_Tuple) ->
(driver_version) -> string();
(dynamic_trace) -> none | dtrace | systemtap;
(dynamic_trace_probes) -> boolean();
+ (end_time) -> non_neg_integer();
(elib_malloc) -> false;
(eager_check_io) -> boolean();
(ets_limit) -> pos_integer();
@@ -2618,6 +2647,7 @@ tuple_to_list(_Tuple) ->
(otp_release) -> string();
(os_monotonic_time_source) -> [{atom(),term()}];
(os_system_time_source) -> [{atom(),term()}];
+ (port_parallelism) -> boolean();
(port_count) -> non_neg_integer();
(port_limit) -> pos_integer();
(process_count) -> pos_integer();
@@ -2647,7 +2677,8 @@ tuple_to_list(_Tuple) ->
(trace_control_word) -> non_neg_integer();
(update_cpu_info) -> changed | unchanged;
(version) -> string();
- (wordsize | {wordsize, internal} | {wordsize, external}) -> 4 | 8.
+ (wordsize | {wordsize, internal} | {wordsize, external}) -> 4 | 8;
+ (overview) -> boolean().
system_info(_Item) ->
erlang:nif_error(undefined).
@@ -3218,33 +3249,51 @@ port_get_data(_Port) ->
erlang:nif_error(undefined).
%%
-%% If the emulator wants to perform a distributed command and
-%% a connection is not established to the actual node the following
-%% functions are called in order to set up the connection and then
-%% reactivate the command.
+%% Distribution channel management
%%
--spec erlang:dlink(pid() | port()) -> 'true'.
-dlink(Pid) ->
- case net_kernel:connect(erlang:node(Pid)) of
- true -> erlang:link(Pid);
- false -> erlang:dist_exit(erlang:self(), noconnection, Pid), true
- end.
+-spec erlang:dist_ctrl_input_handler(DHandle, InputHandler) -> 'ok' when
+ DHandle :: dist_handle(),
+ InputHandler :: pid().
-%% Can this ever happen?
--spec erlang:dunlink(identifier()) -> 'true'.
-dunlink(Pid) ->
- case net_kernel:connect(erlang:node(Pid)) of
- true -> erlang:unlink(Pid);
- false -> true
- end.
+dist_ctrl_input_handler(_DHandle, _InputHandler) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:dist_ctrl_put_data(DHandle, Data) -> 'ok' when
+ DHandle :: dist_handle(),
+ Data :: iodata().
+
+dist_ctrl_put_data(_DHandle, _Data) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:dist_ctrl_get_data(DHandle) -> Data | 'none' when
+ DHandle :: dist_handle(),
+ Data :: iodata().
+
+dist_ctrl_get_data(_DHandle) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:dist_ctrl_get_data_notification(DHandle) -> 'ok' when
+ DHandle :: dist_handle().
+
+dist_ctrl_get_data_notification(_DHandle) ->
+ erlang:nif_error(undefined).
+
+-spec erlang:dist_get_stat(DHandle) -> Res when
+ DHandle :: dist_handle(),
+ InputPackets :: non_neg_integer(),
+ OutputPackets :: non_neg_integer(),
+ PendingOutputPackets :: boolean(),
+ Res :: {'ok', InputPackets, OutputPackets, PendingOutputPackets}.
+
+dist_get_stat(_DHandle) ->
+ erlang:nif_error(undefined).
-dmonitor_node(Node, Flag, []) ->
- case net_kernel:connect(Node) of
- true -> erlang:monitor_node(Node, Flag, []);
- false -> erlang:self() ! {nodedown, Node}, true
- end;
+dmonitor_node(Node, _Flag, []) ->
+ %% Only called when auto-connect attempt failed early in VM
+ erlang:self() ! {nodedown, Node},
+ true;
dmonitor_node(Node, Flag, Opts) ->
case lists:member(allow_passive_connect, Opts) of
true ->
@@ -3256,72 +3305,6 @@ dmonitor_node(Node, Flag, Opts) ->
dmonitor_node(Node,Flag,[])
end.
-dgroup_leader(Leader, Pid) ->
- case net_kernel:connect(erlang:node(Pid)) of
- true -> erlang:group_leader(Leader, Pid);
- false -> true %% bad arg ?
- end.
-
-dexit(Pid, Reason) ->
- case net_kernel:connect(erlang:node(Pid)) of
- true -> erlang:exit(Pid, Reason);
- false -> true
- end.
-
-dsend(Pid, Msg) when erlang:is_pid(Pid) ->
- case net_kernel:connect(erlang:node(Pid)) of
- true -> erlang:send(Pid, Msg);
- false -> Msg
- end;
-dsend(Port, Msg) when erlang:is_port(Port) ->
- case net_kernel:connect(erlang:node(Port)) of
- true -> erlang:send(Port, Msg);
- false -> Msg
- end;
-dsend({Name, Node}, Msg) ->
- case net_kernel:connect(Node) of
- true -> erlang:send({Name,Node}, Msg);
- false -> Msg;
- ignored -> Msg % Not distributed.
- end.
-
-dsend(Pid, Msg, Opts) when erlang:is_pid(Pid) ->
- case net_kernel:connect(erlang:node(Pid)) of
- true -> erlang:send(Pid, Msg, Opts);
- false -> ok
- end;
-dsend(Port, Msg, Opts) when erlang:is_port(Port) ->
- case net_kernel:connect(erlang:node(Port)) of
- true -> erlang:send(Port, Msg, Opts);
- false -> ok
- end;
-dsend({Name, Node}, Msg, Opts) ->
- case net_kernel:connect(Node) of
- true -> erlang:send({Name,Node}, Msg, Opts);
- false -> ok;
- ignored -> ok % Not distributed.
- end.
-
--spec erlang:dmonitor_p('process', pid() | {atom(),atom()}) -> reference().
-dmonitor_p(process, ProcSpec) ->
- %% ProcSpec = pid() | {atom(),atom()}
- %% ProcSpec CANNOT be an atom because a locally registered process
- %% is never handled here.
- Node = case ProcSpec of
- {S,N} when erlang:is_atom(S),
- erlang:is_atom(N),
- N =/= erlang:node() -> N;
- _ when erlang:is_pid(ProcSpec) -> erlang:node(ProcSpec)
- end,
- case net_kernel:connect(Node) of
- true ->
- erlang:monitor(process, ProcSpec);
- false ->
- Ref = erlang:make_ref(),
- erlang:self() ! {'DOWN', Ref, process, ProcSpec, noconnection},
- Ref
- end.
-
%%
%% Trap function used when modified timing has been enabled.
%%
@@ -3554,33 +3537,6 @@ rvrs(Xs) -> rvrs(Xs, []).
rvrs([],Ys) -> Ys;
rvrs([X|Xs],Ys) -> rvrs(Xs, [X|Ys]).
-%% erlang:await_proc_exit/3 is for internal use only!
-%%
-%% BIFs that need to await a specific process exit before
-%% returning traps to erlang:await_proc_exit/3.
-%%
-%% NOTE: This function is tightly coupled to
-%% the implementation of the
-%% erts_bif_prep_await_proc_exit_*()
-%% functions in bif.c. Do not make
-%% any changes to it without reading
-%% the comment about them in bif.c!
--spec erlang:await_proc_exit(dst(), 'apply' | 'data' | 'reason', term()) -> term().
-await_proc_exit(Proc, Op, Data) ->
- Mon = erlang:monitor(process, Proc),
- receive
- {'DOWN', Mon, process, _Proc, Reason} ->
- case Op of
- apply ->
- {M, F, A} = Data,
- erlang:apply(M, F, A);
- data ->
- Data;
- reason ->
- Reason
- end
- end.
-
-spec min(Term1, Term2) -> Minimum when
Term1 :: term(),
Term2 :: term(),
@@ -3604,11 +3560,9 @@ max(A, _) -> A.
%%
-type memory_type() :: 'total' | 'processes' | 'processes_used' | 'system'
- | 'atom' | 'atom_used' | 'binary' | 'code' | 'ets'
- | 'low' | 'maximum'.
+ | 'atom' | 'atom_used' | 'binary' | 'code' | 'ets'.
-define(CARRIER_ALLOCS, [mseg_alloc]).
--define(LOW_ALLOCS, [ll_low_alloc, std_low_alloc]).
-define(ALL_NEEDED_ALLOCS, (erlang:system_info(alloc_util_allocators)
-- ?CARRIER_ALLOCS)).
@@ -3620,9 +3574,7 @@ max(A, _) -> A.
atom_used = 0,
binary = 0,
code = 0,
- ets = 0,
- low = 0,
- maximum = 0}).
+ ets = 0}).
-spec erlang:memory() -> [{Type, Size}] when
Type :: memory_type(),
@@ -3632,14 +3584,6 @@ memory() ->
notsup ->
erlang:error(notsup);
Mem ->
- InstrTail = case Mem#memory.maximum of
- 0 -> [];
- _ -> [{maximum, Mem#memory.maximum}]
- end,
- Tail = case Mem#memory.low of
- 0 -> InstrTail;
- _ -> [{low, Mem#memory.low} | InstrTail]
- end,
[{total, Mem#memory.total},
{processes, Mem#memory.processes},
{processes_used, Mem#memory.processes_used},
@@ -3648,7 +3592,7 @@ memory() ->
{atom_used, Mem#memory.atom_used},
{binary, Mem#memory.binary},
{code, Mem#memory.code},
- {ets, Mem#memory.ets} | Tail]
+ {ets, Mem#memory.ets}]
end.
-spec erlang:memory(Type :: memory_type()) -> non_neg_integer();
@@ -3736,16 +3680,6 @@ need_mem_info(binary) ->
{false, [binary_alloc], true, false};
need_mem_info(ets) ->
{true, [ets_alloc], true, false};
-need_mem_info(low) ->
- LowAllocs = ?LOW_ALLOCS -- ?CARRIER_ALLOCS,
- {_, _, FeatureList, _} = erlang:system_info(allocator),
- AlcUAllocs = case LowAllocs -- FeatureList of
- [] -> LowAllocs;
- _ -> []
- end,
- {false, AlcUAllocs, true, true};
-need_mem_info(maximum) ->
- {true, [], true, true};
need_mem_info(_) ->
{false, [], false, true}.
@@ -3758,8 +3692,6 @@ get_memval(atom_used, #memory{atom_used = V}) -> V;
get_memval(binary, #memory{binary = V}) -> V;
get_memval(code, #memory{code = V}) -> V;
get_memval(ets, #memory{ets = V}) -> V;
-get_memval(low, #memory{low = V}) -> V;
-get_memval(maximum, #memory{maximum = V}) -> V;
get_memval(_, #memory{}) -> 0.
memory_is_supported() ->
@@ -3814,16 +3746,6 @@ fix_proc([_ | Rest], Acc) ->
fix_proc([], Acc) ->
Acc.
-is_low_alloc(_A, []) ->
- false;
-is_low_alloc(A, [A|_As]) ->
- true;
-is_low_alloc(A, [_A|As]) ->
- is_low_alloc(A, As).
-
-is_low_alloc(A) ->
- is_low_alloc(A, ?LOW_ALLOCS).
-
au_mem_data(notsup, _) ->
notsup;
au_mem_data(_, [{_, false} | _]) ->
@@ -3876,16 +3798,11 @@ au_mem_data(#memory{total = Tot,
Rest)
end;
au_mem_data(#memory{total = Tot,
- system = Sys,
- low = Low} = Mem,
- [{A, _, Data} | Rest]) ->
+ system = Sys} = Mem,
+ [{_, _, Data} | Rest]) ->
Sz = blocks_size(Data, 0),
au_mem_data(Mem#memory{total = Tot+Sz,
- system = Sys+Sz,
- low = case is_low_alloc(A) of
- true -> Low+Sz;
- false -> Low
- end},
+ system = Sys+Sz},
Rest);
au_mem_data(EMD, []) ->
EMD.
@@ -3907,10 +3824,6 @@ receive_emd(Ref) ->
receive_emd(Ref, #memory{}, erlang:system_info(schedulers)).
aa_mem_data(#memory{} = Mem,
- [{maximum, Max} | Rest]) ->
- aa_mem_data(Mem#memory{maximum = Max},
- Rest);
-aa_mem_data(#memory{} = Mem,
[{total, Tot} | Rest]) ->
aa_mem_data(Mem#memory{total = Tot,
system = 0}, % system will be adjusted later
@@ -4020,38 +3933,6 @@ receive_allocator(Ref, N, Acc) ->
receive_allocator(Ref, N-1, insert_info(InfoList, Acc))
end.
--spec erlang:await_sched_wall_time_modifications(Ref, Result) -> boolean() when
- Ref :: reference(),
- Result :: boolean().
-
-await_sched_wall_time_modifications(Ref, Result) ->
- sched_wall_time(Ref, erlang:system_info(schedulers)),
- Result.
-
--spec erlang:gather_sched_wall_time_result(Ref) -> [{pos_integer(),
- non_neg_integer(),
- non_neg_integer()}] when
- Ref :: reference().
-
-gather_sched_wall_time_result(Ref) when erlang:is_reference(Ref) ->
- sched_wall_time(Ref, erlang:system_info(schedulers), []).
-
-sched_wall_time(_Ref, 0) ->
- ok;
-sched_wall_time(Ref, N) ->
- receive Ref -> sched_wall_time(Ref, N-1) end.
-
-sched_wall_time(_Ref, 0, Acc) ->
- Acc;
-sched_wall_time(Ref, N, undefined) ->
- receive {Ref, _} -> sched_wall_time(Ref, N-1, undefined) end;
-sched_wall_time(Ref, N, Acc) ->
- receive
- {Ref, undefined} -> sched_wall_time(Ref, N-1, undefined);
- {Ref, SWTL} when erlang:is_list(SWTL) -> sched_wall_time(Ref, N-1, Acc ++ SWTL);
- {Ref, SWT} -> sched_wall_time(Ref, N-1, [SWT|Acc])
- end.
-
-spec erlang:gather_gc_info_result(Ref) ->
{number(),number(),0} when Ref :: reference().
@@ -4065,4 +3946,3 @@ gc_info(Ref, N, {OrigColls,OrigRecl}) ->
{Ref, {_,Colls, Recl}} ->
gc_info(Ref, N-1, {Colls+OrigColls,Recl+OrigRecl})
end.
-