Merge branch 'pu'
[jungerl.git] / lib / pan / src / panFool.erl
blob419e4d0175f0e6f44fa302f5013803d022f4b651
1 %%%-------------------------------------------------------------------
2 %%% File : panFool.erl
3 %%% Author : Mats Cronqvist <etxmacr@cbe2077>
4 %%% Description :
5 %%%
6 %%% Created : 14 Jan 2003 by Mats Cronqvist <etxmacr@cbe2077>
7 %%%-------------------------------------------------------------------
8 -module(panFool).
9 -export([go/0,go/1,go/2,go/3]).
11 -define(CALLBACK, cb_foolprof).
13 go() -> procs().
14 go(Proc) -> go(Proc, []).
15 go(Proc, Prefix) -> go(Proc, Prefix, -1).
16 go(Proc, Prefix, Count) ->
17 Pid = key(Proc),
18 Tot = ets_lup(?CALLBACK, {total, time}),
19 Ptot = ets_lup(?CALLBACK, {{pid, time}, Pid}),
20 stax(Count, 0, Tot, Pid, Prefix, ets:next(?CALLBACK, {{stack,time},Pid,0})).
22 stax(M, M, _, Pid, _, {_,Pid,_}) -> {did, M, stacks};
23 stax(M, N, Tot, Pid, Prefix, {_,Pid,_} = Key) ->
24 {_, Stak, Time} = ets_lup(?CALLBACK, Key),
25 case prefix(lists:reverse(Stak), Prefix) of
26 {yes, Tail} -> io:fwrite("~6w ~w~n", [N, Tail]);
27 no -> ok
28 end,
29 stax(M, N+1, Tot, Pid, Prefix, ets:next(?CALLBACK, Key));
30 stax(_, _, _, Pid, _, _) -> {Pid, exhausted}.
32 prefix(Rest, '') -> prefix(Rest, []);
33 prefix(Rest, []) -> {yes, Rest};
34 prefix([MFA|Rest], [MFA|Tail]) -> prefix(Rest, Tail);
35 prefix(_, _) -> no.
37 procs() ->
38 Tot = ets_lup(?CALLBACK, {total, time}),
39 TPs = ets:match(?CALLBACK, {{{pid,time},'$2'},'$1'}),
40 RTs = [{reg(P), T} || [T, P] <- TPs],
41 F = fun({R, T}, [{R, N, TT}|O]) ->
42 [{R, N+1, percent(T, Tot)+TT}|O];
43 ({R, T}, O) ->
44 [{R, 1, percent(T, Tot)}|O]
45 end,
46 RNTs = lists:foldl(F, [], lists:sort(RTs)),
47 [[length(TPs), Tot]|rsort(3, RNTs)].
49 reg(P) -> ets_lup(panScan, {P,registered_name}).
50 rsort(Pos, L) -> lists:reverse(lists:keysort(Pos, L)).
51 percent(A, 0) -> 0;
52 percent(A, B) -> A/B*100.
54 key('') -> '';
55 key(Reg) when atom(Reg) ->
56 key([Reg, 1]);
57 key(MFA) when tuple(MFA) ->
58 key([MFA, 1]);
59 key([PID, N]) ->
60 Pids = ets:match(panScan, {{'$1',registered_name},PID}),
61 case length(Pids) of
62 0 ->
63 exit({{?MODULE, ?LINE}, no_such_process, PID});
64 L when L < N ->
65 io:fwrite("only ~w procs with this tag~n", [length(Pids)]),
66 key({PID, 1});
67 _ ->
68 [Pid] = lists:nth(N, Pids),
69 Pid
70 end.
71 ets_lup(Tab, Tag) ->
72 case catch ets:lookup(Tab, Tag) of
73 [{Tag, Val}] -> Val;
74 {'EXIT',_} -> [];
75 [X] -> X
76 end.