1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2002-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(cprof).
21
22%% Call count profiling tool.
23
24-export ([start/0, start/1, start/2, start/3,
25	  stop/0, stop/1, stop/2, stop/3,
26	  restart/0, restart/1, restart/2, restart/3,
27	  pause/0, pause/1, pause/2, pause/3,
28	  analyse/0, analyse/1, analyse/2,
29	  analyze/0, analyze/1, analyze/2]).
30
31
32
33start() ->
34    tr({'_','_','_'}, true) + tr(on_load, true).
35
36start({_,_,_} = MFA) ->
37    tr(MFA, true);
38start({FuncSpec}) ->
39    tr(FuncSpec, true);
40start(M) ->
41    tr({M,'_','_'}, true).
42
43start(M,F) ->
44    tr({M,F,'_'}, true).
45
46start(M,F,A) ->
47    tr({M,F,A}, true).
48
49
50
51stop() ->
52    tr({'_','_','_'}, false) + tr(on_load, false).
53
54stop({_,_,_} = MFA) ->
55    tr(MFA, false);
56stop({FuncSpec}) ->
57    tr(FuncSpec, false);
58stop(M) ->
59    tr({M,'_','_'}, false).
60
61stop(M,F) ->
62    tr({M,F,'_'}, false).
63
64stop(M,F,A) ->
65    tr({M,F,A}, false).
66
67
68
69restart() ->
70    tr({'_','_','_'}, restart).
71
72restart({_,_,_} = MFA) ->
73    tr(MFA, restart);
74restart({FuncSpec}) ->
75    tr(FuncSpec, restart);
76restart(M) ->
77    tr({M,'_','_'}, restart).
78
79restart(M,F) ->
80    tr({M,F,'_'}, restart).
81
82restart(M,F,A) ->
83    tr({M,F,A}, restart).
84
85
86
87pause() ->
88    tr({'_','_','_'}, pause) + tr(on_load, false).
89
90pause({_,_,_} = MFA) ->
91    tr(MFA, pause);
92pause({FuncSpec}) ->
93    tr(FuncSpec, pause);
94pause(M) ->
95    tr({M,'_','_'}, pause).
96
97pause(M,F) ->
98    tr({M,F,'_'}, pause).
99
100pause(M,F,A) ->
101    tr({M,F,A}, pause).
102
103
104
105analyse() ->
106    analyse(1).
107
108analyse(Limit) when is_integer(Limit) ->
109    L0 = [analyse(element(1, Mod), Limit) || Mod <- code:all_loaded()],
110    L1 = [{C,M,Lm} || {M,C,Lm} <- L0, C > 0, M =/= ?MODULE],
111    N = lists:foldl(fun ({C,_,_}, Q) -> Q+C end, 0, L1),
112    L = [{M,C,Lm} || {C,M,Lm} <- lists:reverse(lists:sort(L1))],
113    {N,L};
114analyse(M) when is_atom(M) ->
115    analyse(M, 1).
116
117-dialyzer({no_improper_lists, analyse/2}).
118analyse(M, Limit) when is_atom(M), is_integer(Limit) ->
119    L0 = [begin
120	      MFA = {M,F,A},
121	      {_,C} = erlang:trace_info(MFA, call_count),
122	      [C|MFA]
123	  end || {F,A} <- M:module_info(functions)],
124    L1 = [X || [C|_]=X <- L0, is_integer(C)],
125    N = lists:foldl(fun ([C|_], Q) -> Q+C end, 0, L1),
126    L2 = [X || [C|_]=X <- L1, C >= Limit],
127    L = [{MFA,C} || [C|MFA] <- lists:reverse(lists:sort(L2))],
128    {M,N,L}.
129
130
131
132analyze() ->
133    analyse().
134
135analyze(X) ->
136    analyse(X).
137
138analyze(X, Y) ->
139    analyse(X, Y).
140
141
142
143tr(FuncSpec, State) ->
144    erlang:trace_pattern(FuncSpec, State, [call_count]).
145