aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src/seq_trace.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src/seq_trace.erl')
-rw-r--r--lib/kernel/src/seq_trace.erl126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/kernel/src/seq_trace.erl b/lib/kernel/src/seq_trace.erl
new file mode 100644
index 0000000000..78c3040f21
--- /dev/null
+++ b/lib/kernel/src/seq_trace.erl
@@ -0,0 +1,126 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(seq_trace).
+
+-define(SEQ_TRACE_SEND, 1). %(1 << 0)
+-define(SEQ_TRACE_RECEIVE, 2). %(1 << 1)
+-define(SEQ_TRACE_PRINT, 4). %(1 << 2)
+-define(SEQ_TRACE_TIMESTAMP, 8). %(1 << 3)
+
+-export([set_token/1,
+ set_token/2,
+ get_token/0,
+ get_token/1,
+ print/1,
+ print/2,
+ reset_trace/0,
+ set_system_tracer/1,
+ get_system_tracer/0]).
+
+%%---------------------------------------------------------------------------
+
+-type flag() :: 'send' | 'receive' | 'print' | 'timestamp'.
+-type component() :: 'label' | 'serial' | flag().
+-type value() :: non_neg_integer()
+ | {non_neg_integer(), non_neg_integer()}
+ | boolean().
+-type token_pair() :: {component(), value()}.
+
+%%---------------------------------------------------------------------------
+
+-type token() :: [] | {integer(), boolean(), _, _, _}.
+-spec set_token(token()) -> token() | 'ok'.
+
+set_token([]) ->
+ erlang:seq_trace(sequential_trace_token,[]);
+set_token({Flags,Label,Serial,_From,Lastcnt}) ->
+ F = decode_flags(Flags),
+ set_token2([{label,Label},{serial,{Lastcnt, Serial}} | F]).
+
+%% We limit the label type to always be a small integer because erl_interface
+%% expects that, the BIF can however "unofficially" handle atoms as well, and
+%% atoms can be used if only Erlang nodes are involved
+
+-spec set_token(component(), value()) -> token_pair().
+
+set_token(Type, Val) ->
+ erlang:seq_trace(Type, Val).
+
+-spec get_token() -> term().
+
+get_token() ->
+ element(2,process_info(self(),sequential_trace_token)).
+
+-spec get_token(component()) -> token_pair().
+
+get_token(Type) ->
+ erlang:seq_trace_info(Type).
+
+-spec print(term()) -> 'ok'.
+
+print(Term) ->
+ erlang:seq_trace_print(Term),
+ ok.
+
+-spec print(integer(), term()) -> 'ok'.
+
+print(Label, Term) when is_atom(Label) ->
+ erlang:error(badarg, [Label, Term]);
+print(Label, Term) ->
+ erlang:seq_trace_print(Label, Term),
+ ok.
+
+-spec reset_trace() -> 'true'.
+
+reset_trace() ->
+ erlang:system_flag(1, 0).
+
+%% reset_trace(Pid) -> % this might be a useful function too
+
+-type tracer() :: pid() | port() | 'false'.
+
+-spec set_system_tracer(tracer()) -> tracer().
+
+set_system_tracer(Pid) ->
+ erlang:system_flag(sequential_tracer, Pid).
+
+-spec get_system_tracer() -> tracer().
+
+get_system_tracer() ->
+ element(2, erlang:system_info(sequential_tracer)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% internal help functions
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+set_token2([{Type,Val}|T]) ->
+ erlang:seq_trace(Type, Val),
+ set_token2(T);
+set_token2([]) ->
+ ok.
+
+decode_flags(Flags) ->
+ Print = (Flags band ?SEQ_TRACE_PRINT) > 0,
+ Send = (Flags band ?SEQ_TRACE_SEND) > 0,
+ Rec = (Flags band ?SEQ_TRACE_RECEIVE) > 0,
+ Ts = (Flags band ?SEQ_TRACE_TIMESTAMP) > 0,
+ [{print,Print},{send,Send},{'receive',Rec},{timestamp,Ts}].