Merge branch 'pu'
[jungerl.git] / lib / pan / src / cb_perf.erl
blob558a630d665abb19e1a0cfdc9d5fd21a10be6746
1 %%%----------------------------------------------------------------------
2 %%% File : cb_perf.erl
3 %%% Author : Mats Cronqvist <etxmacr@avc386>
4 %%% Purpose : cpu time per pid
5 %%% Created : 28 Feb 2000 by Mats Cronqvist <etxmacr@avc386>
6 %%%----------------------------------------------------------------------
8 -module(cb_perf).
9 -author('etxmacr@avc386').
11 -export([go/1, requires/0, doc/0]).
13 -record(state, {tab, in = init, gc = init, fd = init, prev}).
15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16 requires() -> [{flags, [garbage_collection,procs,running]}, {tps, []}].
17 doc() -> "populates the cpu time table. "
18 "not useful on its own. run from pan:perf".
20 %%% obsoleted
21 %%%go([Msg, Line, Out, initial, Tab|_]) when atom(Tab) ->
22 %%% go([Msg, Line, Out, #state{tab = Tab}]);
23 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24 go([Msg, Line, Out, initial|_]) ->
25 panEts:new(?MODULE),
26 go([Msg, Line, Out, #state{tab = ?MODULE}]);
27 go([end_of_trace, Line, Out, State|_]) ->
28 State;
29 go([Msg, Line, Out, State|_]) ->
30 (handle(Msg, State))#state{prev = element(4,Msg)}.
32 handle(Msg, State = #state{tab = Tab, in = In, prev = Prev}) ->
33 case Msg of
34 {out, _, 0, Now} ->
35 ets_upd(Tab, {file_driver, in}, 1),
36 State#state{fd = {Now}};
37 {out, P, _, Prev} -> %early r7b emu behaviour
38 handle({out, P, 0, Prev}, State);
39 {in, _, 0, Now} ->
40 do_fd_out(Tab, Now, State);
41 {in, P, _, Now} when tuple(State#state.fd) -> %early r7b emu behaviour
42 handle({in, P, 0, Now}, State);
43 {gc_start, {Pid, ID}, Info, Now} ->
44 ets_upd(Tab, {Pid, gc}, 1),
45 State#state{gc = {Pid, Now}};
46 {gc_end, {Pid, ID}, Info, Now} ->
47 do_gc_out(Tab, Pid, Now, State);
48 {in, {Pid, ID}, CurrF, Now} ->
49 ets_upd(Tab, {Pid, in}, 1),
50 State#state{in = {Pid, Now}};
51 {out, {Pid, ID}, CurrF, Now} ->
52 do_out(Tab, Pid, Now, State);
53 {exit, {Pid, ID}, Reason, Now} ->
54 case In of
55 {Pid,_} -> do_out(Tab, Pid, Now, State);
56 _ -> State
57 end;
58 _ ->
59 State
60 end.
62 do_out(Tab, Pid, Now, State = #state{in = In}) ->
63 case In of
64 {InPid, InNow} ->
65 Ntd = ntdiff(Now, InNow),
66 ets_upd(Tab, total, Ntd),
67 ets_upd(Tab, {Pid, cpu}, Ntd),
68 State#state{in = no};
69 init ->
70 State;
71 Err ->
72 io:fwrite("~p - out_err~n~p~n", [?MODULE, {Err, Pid, Now, State}]),
73 State
74 end.
75 do_gc_out(Tab, Pid, Now, State = #state{in = In, gc = GC}) ->
76 case {In, GC} of
77 {{InPid, _}, {GcPid, GcNow}} ->
78 Ntd = ntdiff(Now, GcNow),
79 ets_upd(Tab, {InPid, cpu}, -Ntd),
80 ets_upd(Tab, {GcPid, gcpu}, Ntd),
81 State#state{gc = no};
82 {_, {GcPid, GcNow}} ->
83 Ntd = ntdiff(Now, GcNow),
84 ets_upd(Tab, total, Ntd),
85 ets_upd(Tab, {Pid, gcpu}, Ntd),
86 State#state{gc = no};
87 {_, init} ->
88 State;
89 Err ->
90 io:fwrite("~p - gc_out_err~n~p~n", [?MODULE,{Err, Pid, Now, State}]),
91 State
92 end.
93 do_fd_out(Tab, Now, State = #state{in = In, gc = GC, fd = FD}) ->
94 case {In, GC, FD} of
95 {{InPid, _}, {GcPid, _}, {FdNow}} ->
96 Ntd = ntdiff(Now, FdNow),
97 ets_upd(Tab, total, -Ntd),
98 ets_upd(Tab, {GcPid, gcpu}, -Ntd),
99 ets_upd(Tab, {file_driver, cpu}, Ntd),
100 State#state{fd = no};
101 {{InPid, _}, _, {FdNow}} ->
102 Ntd = ntdiff(Now, FdNow),
103 ets_upd(Tab, total, -Ntd),
104 ets_upd(Tab, {InPid, cpu}, -Ntd),
105 ets_upd(Tab, {file_driver, cpu}, Ntd),
106 State#state{fd = no};
107 {_, {GcPid, _}, {FdNow}} ->
108 Ntd = ntdiff(Now, FdNow),
109 ets_upd(Tab, total, -Ntd),
110 ets_upd(Tab, {GcPid, gcpu}, -Ntd),
111 ets_upd(Tab, {file_driver, cpu}, Ntd),
112 State#state{fd = no};
113 {_, _, {FdNow}} ->
114 Ntd = ntdiff(Now, FdNow),
115 ets_upd(Tab, {file_driver, cpu}, Ntd),
116 State#state{fd = no};
117 {_,_,init} -> State;
118 Err ->
119 io:fwrite("~p - fd_out_err~n~p~n", [?MODULE, {Err, Now, State}]),
120 State
121 end.
122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123 ets_upd(Tab, Key, Inc) ->
124 case catch ets:update_counter(Tab, Key, Inc) of
125 {'EXIT', _ } -> ets:insert(Tab, {Key, Inc});
126 _ -> ok
127 end.
129 ntdiff({MS, S, USo}, {MS, S, USi}) ->
130 (USo-USi);
131 ntdiff({MS, So, USo}, {MS, Si, USi}) ->
132 (USo-USi)+(So-Si)*1000000;
133 ntdiff({MSo, So, USo}, {MSi, Si, USi}) ->
134 (USo-USi)+(So-Si)*1000000+(MSo-MSi)*1000000000000.