aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded/src/erts_internal.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/preloaded/src/erts_internal.erl')
-rw-r--r--erts/preloaded/src/erts_internal.erl338
1 files changed, 306 insertions, 32 deletions
diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl
index 6aae5ba38c..8f29a569f2 100644
--- a/erts/preloaded/src/erts_internal.erl
+++ b/erts/preloaded/src/erts_internal.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2012-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,7 +31,8 @@
-export([await_port_send_result/3]).
-export([cmp_term/2]).
--export([map_to_tuple_keys/1, term_type/1, map_hashmap_children/1]).
+-export([map_to_tuple_keys/1, term_type/1, map_hashmap_children/1,
+ map_next/3]).
-export([open_port/2, port_command/3, port_connect/2, port_close/1,
port_control/3, port_call/3, port_info/1, port_info/2]).
@@ -39,10 +40,13 @@
gather_system_check_result/1]).
-export([request_system_task/3, request_system_task/4]).
+-export([garbage_collect/1]).
-export([check_process_code/3]).
-export([check_dirty_process_code/2]).
-export([is_process_executing_dirty/1]).
+-export([dirty_process_handle_signals/1]).
+
-export([release_literal_area_switch/0]).
-export([purge_module/2]).
@@ -59,8 +63,39 @@
-export([trace/3, trace_pattern/3]).
+-export([dist_ctrl_put_data/2]).
+
+-export([get_dflags/0]).
+-export([new_connection/1]).
+-export([abort_connection/2]).
+
+-export([scheduler_wall_time/1, system_flag_scheduler_wall_time/1,
+ gather_sched_wall_time_result/1,
+ await_sched_wall_time_modifications/2]).
+
+-export([group_leader/2, group_leader/3]).
+
%% Auto import name clash
--export([check_process_code/2]).
+-export([check_process_code/1]).
+
+-export([is_process_alive/1, is_process_alive/2]).
+
+-export([gather_alloc_histograms/1, gather_carrier_info/1]).
+
+-export([suspend_process/2]).
+
+-export([process_display/2]).
+
+-export([process_flag/3]).
+
+-export([create_dist_channel/4]).
+
+-export([erase_persistent_terms/0]).
+
+-export([atomics_new/2]).
+
+-export([counters_new/1, counters_get/2, counters_add/3,
+ counters_put/3, counters_info/1]).
%%
%% Await result of send to port
@@ -205,8 +240,9 @@ port_info(_Result, _Item) ->
-spec request_system_task(Pid, Prio, Request) -> 'ok' when
Prio :: 'max' | 'high' | 'normal' | 'low',
- Request :: {'garbage_collect', term()}
- | {'check_process_code', term(), module(), non_neg_integer()}
+ Type :: 'major' | 'minor',
+ Request :: {'garbage_collect', term(), Type}
+ | {'check_process_code', term(), module()}
| {'copy_literals', term(), boolean()},
Pid :: pid().
@@ -216,7 +252,7 @@ request_system_task(_Pid, _Prio, _Request) ->
-spec request_system_task(RequesterPid, TargetPid, Prio, Request) -> 'ok' | 'dirty_execution' when
Prio :: 'max' | 'high' | 'normal' | 'low',
Request :: {'garbage_collect', term()}
- | {'check_process_code', term(), module(), non_neg_integer()}
+ | {'check_process_code', term(), module()}
| {'copy_literals', term(), boolean()},
RequesterPid :: pid(),
TargetPid :: pid().
@@ -224,12 +260,14 @@ request_system_task(_Pid, _Prio, _Request) ->
request_system_task(_RequesterPid, _TargetPid, _Prio, _Request) ->
erlang:nif_error(undefined).
--define(ERTS_CPC_ALLOW_GC, (1 bsl 0)).
+-spec garbage_collect(Mode) -> 'true' when Mode :: 'major' | 'minor'.
--spec check_process_code(Module, Flags) -> boolean() when
- Module :: module(),
- Flags :: non_neg_integer().
-check_process_code(_Module, _Flags) ->
+garbage_collect(_Mode) ->
+ erlang:nif_error(undefined).
+
+-spec check_process_code(Module) -> boolean() when
+ Module :: module().
+check_process_code(_Module) ->
erlang:nif_error(undefined).
-spec check_process_code(Pid, Module, OptionList) -> CheckResult | async when
@@ -240,7 +278,7 @@ check_process_code(_Module, _Flags) ->
OptionList :: [Option],
CheckResult :: boolean() | aborted.
check_process_code(Pid, Module, OptionList) ->
- {Async, Flags} = get_cpc_opts(OptionList, sync, ?ERTS_CPC_ALLOW_GC),
+ Async = get_cpc_opts(OptionList, sync),
case Async of
{async, ReqId} ->
{priority, Prio} = erlang:process_info(erlang:self(),
@@ -249,13 +287,12 @@ check_process_code(Pid, Module, OptionList) ->
Prio,
{check_process_code,
ReqId,
- Module,
- Flags}),
+ Module}),
async;
sync ->
case Pid == erlang:self() of
true ->
- erts_internal:check_process_code(Module, Flags);
+ erts_internal:check_process_code(Module);
false ->
{priority, Prio} = erlang:process_info(erlang:self(),
priority),
@@ -264,8 +301,7 @@ check_process_code(Pid, Module, OptionList) ->
Prio,
{check_process_code,
ReqId,
- Module,
- Flags}),
+ Module}),
receive
{check_process_code, ReqId, CheckResult} ->
CheckResult
@@ -273,20 +309,17 @@ check_process_code(Pid, Module, OptionList) ->
end
end.
-% gets async and flag opts and verify valid option list
-get_cpc_opts([{async, _ReqId} = AsyncTuple | Options], _OldAsync, Flags) ->
- get_cpc_opts(Options, AsyncTuple, Flags);
-get_cpc_opts([{allow_gc, AllowGC} | Options], Async, Flags) ->
- get_cpc_opts(Options, Async, cpc_flags(Flags, ?ERTS_CPC_ALLOW_GC, AllowGC));
-get_cpc_opts([], Async, Flags) ->
- {Async, Flags}.
-
-cpc_flags(OldFlags, Bit, true) ->
- OldFlags bor Bit;
-cpc_flags(OldFlags, Bit, false) ->
- OldFlags band (bnot Bit).
-
--spec check_dirty_process_code(Pid,Module) -> 'true' | 'false' when
+% gets async opt and verify valid option list
+get_cpc_opts([{async, _ReqId} = AsyncTuple | Options], _OldAsync) ->
+ get_cpc_opts(Options, AsyncTuple);
+get_cpc_opts([{allow_gc, AllowGC} | Options], Async) when AllowGC == true;
+ AllowGC == false ->
+ get_cpc_opts(Options, Async);
+get_cpc_opts([], Async) ->
+ Async.
+
+-spec check_dirty_process_code(Pid, Module) -> Result when
+ Result :: boolean() | 'normal' | 'busy',
Pid :: pid(),
Module :: module().
check_dirty_process_code(_Pid,_Module) ->
@@ -297,6 +330,13 @@ check_dirty_process_code(_Pid,_Module) ->
is_process_executing_dirty(_Pid) ->
erlang:nif_error(undefined).
+-spec dirty_process_handle_signals(Pid) -> Res when
+ Pid :: pid(),
+ Res :: 'false' | 'true' | 'noproc' | 'normal' | 'more' | 'ok'.
+
+dirty_process_handle_signals(_Pid) ->
+ erlang:nif_error(undefined).
+
-spec release_literal_area_switch() -> 'true' | 'false'.
release_literal_area_switch() ->
@@ -366,6 +406,18 @@ term_type(_T) ->
map_hashmap_children(_M) ->
erlang:nif_error(undefined).
+%% return the next assoc in the iterator and a new iterator
+-spec map_next(I, M, A) -> {K,V,NI} | list() when
+ I :: non_neg_integer(),
+ M :: map(),
+ K :: term(),
+ V :: term(),
+ A :: iterator | list(),
+ NI :: maps:iterator().
+
+map_next(_I, _M, _A) ->
+ erlang:nif_error(undefined).
+
-spec erts_internal:flush_monitor_messages(Ref, Multi, Res) -> term() when
Ref :: reference(),
Multi :: boolean(),
@@ -438,10 +490,11 @@ microstate_accounting(Ref, Threads) ->
trace(_PidSpec, _How, _FlagList) ->
erlang:nif_error(undefined).
+-type match_variable() :: atom(). % Approximation of '$1' | '$2' | ...
-type trace_pattern_mfa() ::
{atom(),atom(),arity() | '_'} | on_load.
-type trace_match_spec() ::
- [{[term()] | '_' ,[term()],[term()]}].
+ [{[term()] | '_' | match_variable() ,[term()],[term()]}].
-spec trace_pattern(MFA, MatchSpec, FlagList) -> non_neg_integer() when
MFA :: trace_pattern_mfa(),
@@ -452,3 +505,224 @@ trace(_PidSpec, _How, _FlagList) ->
FlagList :: [ ].
trace_pattern(_MFA, _MatchSpec, _FlagList) ->
erlang:nif_error(undefined).
+
+-spec dist_ctrl_put_data(DHandle, Data) -> 'ok' when
+ DHandle :: erlang:dist_handle(),
+ Data :: iolist().
+
+dist_ctrl_put_data(DHandle, IoList) ->
+ %%
+ %% Helper for erlang:dist_ctrl_put_data/2
+ %%
+ %% erlang:dist_ctrl_put_data/2 traps to
+ %% this function if second argument is
+ %% a list...
+ %%
+ try
+ Binary = erlang:iolist_to_binary(IoList),
+ %% Restart erlang:dist_ctrl_put_data/2
+ %% with the iolist converted to a binary...
+ erlang:dist_ctrl_put_data(DHandle, Binary)
+ catch
+ Class : Reason ->
+ %% Throw exception as if thrown from
+ %% erlang:dist_ctrl_put_data/2 ...
+ RootST = try erlang:error(Reason)
+ catch
+ error:Reason:ST ->
+ case ST of
+ [] -> [];
+ [_|T] -> T
+ end
+ end,
+ StackTrace = [{erlang, dist_ctrl_put_data,
+ [DHandle, IoList], []}
+ | RootST],
+ erlang:raise(Class, Reason, StackTrace)
+ end.
+
+
+-spec erts_internal:get_dflags() -> {erts_dflags, integer(), integer(),
+ integer(), integer(), integer()}.
+get_dflags() ->
+ erlang:nif_error(undefined).
+
+-spec erts_internal:new_connection(Node) -> ConnId when
+ Node :: atom(),
+ ConnId :: {integer(), erlang:dist_handle()}.
+new_connection(_Node) ->
+ erlang:nif_error(undefined).
+
+-spec erts_internal:abort_connection(Node, ConnId) -> boolean() when
+ Node :: atom(),
+ ConnId :: {integer(), erlang:dist_handle()}.
+abort_connection(_Node, _ConnId) ->
+ erlang:nif_error(undefined).
+
+%% Scheduler wall time
+
+-spec erts_internal:system_flag_scheduler_wall_time(Enable) -> boolean() when
+ Enable :: boolean().
+
+system_flag_scheduler_wall_time(Bool) ->
+ kernel_refc:scheduler_wall_time(Bool).
+
+
+-spec erts_internal:await_sched_wall_time_modifications(Ref, Result) -> boolean() when
+ Ref :: reference(),
+ Result :: boolean().
+
+-spec erts_internal:scheduler_wall_time(Enable) -> boolean() when
+ Enable :: boolean().
+
+scheduler_wall_time(_Enable) ->
+ erlang:nif_error(undefined).
+
+await_sched_wall_time_modifications(Ref, Result) ->
+ sched_wall_time(Ref, erlang:system_info(schedulers)),
+ Result.
+
+-spec erts_internal: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 erts_internal:group_leader(GL, Pid) -> true | false | badarg when
+ GL :: pid(),
+ Pid :: pid().
+
+group_leader(_GL, _Pid) ->
+ erlang:nif_error(undefined).
+
+-spec erts_internal:group_leader(GL, Pid, Ref) -> ok when
+ GL :: pid(),
+ Pid :: pid(),
+ Ref :: reference().
+
+group_leader(_GL, _Pid, _Ref) ->
+ erlang:nif_error(undefined).
+
+-spec erts_internal:is_process_alive(Pid, Ref) -> 'ok' when
+ Pid :: pid(),
+ Ref :: reference().
+
+is_process_alive(_Pid, _Ref) ->
+ erlang:nif_error(undefined).
+
+-spec erts_internal:is_process_alive(Pid) -> boolean() when
+ Pid :: pid().
+
+is_process_alive(Pid) ->
+ Ref = make_ref(),
+ erts_internal:is_process_alive(Pid, Ref),
+ receive
+ {Ref, Res} ->
+ Res
+ end.
+
+-spec gather_alloc_histograms({Type, SchedId, HistWidth, HistStart, Ref}) -> MsgCount when
+ Type :: atom(),
+ SchedId :: non_neg_integer(),
+ HistWidth :: non_neg_integer(),
+ HistStart :: non_neg_integer(),
+ Ref :: reference(),
+ MsgCount :: non_neg_integer().
+
+gather_alloc_histograms(_) ->
+ erlang:nif_error(undef).
+
+-spec gather_carrier_info({Type, SchedId, HistWidth, HistStart, Ref}) -> MsgCount when
+ Type :: atom(),
+ SchedId :: non_neg_integer(),
+ HistWidth :: non_neg_integer(),
+ HistStart :: non_neg_integer(),
+ Ref :: reference(),
+ MsgCount :: non_neg_integer().
+
+gather_carrier_info(_) ->
+ erlang:nif_error(undef).
+
+-spec suspend_process(Suspendee, OptList) -> Result when
+ Result :: boolean() | 'badarg' | reference(),
+ Suspendee :: pid(),
+ OptList :: [Opt],
+ Opt :: unless_suspending | asynchronous | {asynchronous, term()}.
+
+suspend_process(_Suspendee, _OptList) ->
+ erlang:nif_error(undefined).
+
+%% process_display/2
+-spec process_display(Pid, Type) -> 'true' | 'badarg' | reference() when
+ Pid :: pid(),
+ Type :: backtrace.
+process_display(_Pid, _Type) ->
+ erlang:nif_error(undefined).
+
+%% process_flag/3
+-spec process_flag(Pid, Flag, Value) -> OldValue | 'badarg' | reference() when
+ Pid :: pid(),
+ Flag :: save_calls,
+ Value :: non_neg_integer(),
+ OldValue :: non_neg_integer().
+process_flag(_Pid, _Flag, _Value) ->
+ erlang:nif_error(undefined).
+
+-spec create_dist_channel(Node, DistCtrlr, Flags, Ver) -> Result when
+ Node :: atom(),
+ DistCtrlr :: port() | pid(),
+ Flags :: integer(),
+ Ver :: integer(),
+ Result :: {'ok', erlang:dist_handle()}
+ | {'message', reference()}
+ | 'badarg'
+ | 'system_limit'.
+
+create_dist_channel(_Node, _DistCtrlr, _Flags, _Ver) ->
+ erlang:nif_error(undefined).
+
+-spec erase_persistent_terms() -> 'ok'.
+erase_persistent_terms() ->
+ erlang:nif_error(undefined).
+
+-spec atomics_new(pos_integer(), pos_integer()) -> reference().
+atomics_new(_Arity, _EncOpts) ->
+ erlang:nif_error(undef).
+
+-spec counters_new(pos_integer()) -> reference().
+counters_new(_Size) ->
+ erlang:nif_error(undef).
+
+-spec counters_get(reference(), pos_integer()) -> integer().
+counters_get(_Ref, _Ix) ->
+ erlang:nif_error(undef).
+
+-spec counters_add(reference(), pos_integer(), integer()) -> ok.
+counters_add(_Ref, _Ix, _Incr) ->
+ erlang:nif_error(undef).
+
+-spec counters_put(reference(), pos_integer(), integer()) -> ok.
+counters_put(_Ref, _Ix, _Value) ->
+ erlang:nif_error(undef).
+
+-spec counters_info(reference()) -> #{}.
+counters_info(_Ref) ->
+ erlang:nif_error(undef).