Merge branch 'pu'
[jungerl.git] / lib / pan / src / cb_gc.erl
blob924b83ce07292c44208db2061f31efe05ac170ea
1 %%%----------------------------------------------------------------------
2 %%% File : cb_template.erl
3 %%% Author : Mats Cronqvist <etxmacr@avc386>
4 %%% Purpose : template for panScan callback function
5 %%% Created : 2 Mar 2001 by Mats Cronqvist <etxmacr@avc386>
6 %%%----------------------------------------------------------------------
7 %%% Message - {Tag, {Pid, Name}, Data, TimeStamp}
8 %%%
9 %%% Tag Data
10 %%% 'receive', Message
11 %%% call, {M,F,A}
12 %%% exit, Reason
13 %%% return_to, {M,F,A}
14 %%% spawn, Pid2
15 %%% link, Pid2
16 %%% unlink, Pid2
17 %%% getting_linked, Pid2
18 %%% in, {M,F,A}
19 %%% out, {M,F,A}
20 %%% gc_start, Info
21 %%% gc_end, Info
22 %%% send, {Pid2, Msg}
23 %%% send_to_non_existing_process, {Msg, Pid2}
24 %%% return_from, {{M,F,A}, ReturnValue}
25 %%%----------------------------------------------------------------------
27 -module(cb_gc).
28 -author('etxmacr@avc386').
30 -define(UPD_FIELD(XLD, XField, XDiff),
31 case (XLD)#ld.XField of
32 no -> XLD;
33 _ -> (XLD)#ld{XField = ntadd((XLD)#ld.XField,{0,0,XDiff})}
34 end).
37 -export([go/1, requires/0, doc/0]).
39 -record(ld, {diff = 500000, out, pid = no, in = no, gc = no, file_driver = no}).
41 requires() -> [{flags, [garbage_collection,running,procs]}, {tps, []}].
42 doc() -> "picks out gc's longer than 500 ms".
44 go([Message, Line, Out, initial|_]) ->
45 go([Message, Line, Out, initial_state(Out)]);
46 go([end_of_trace, Line, Out, LD|_]) ->
47 ok;
49 go([{out,_,0,TS}, Line, Out, LD|_]) -> %filedriver
50 LD#ld{file_driver = TS};
51 go([{in,_,0,TS}, Line, Out, LD|_]) -> %filedriver
52 Diff = out(LD, Line, file_driver, "file_driver", TS, LD#ld.file_driver),
53 ?UPD_FIELD(?UPD_FIELD(LD#ld{file_driver = no}, gc, Diff), in, Diff);
55 go([{in,{Pid,PI},_,TS}, Line, Out, LD|_]) ->
56 LD#ld{in = TS, pid = Pid};
57 go([{out,{Pid,PI},_,TS}, Line, Out, LD|_]) ->
58 out(LD, Line, PI, "sched", TS, LD#ld.in),
59 LD#ld{in = no, pid = no};
60 go([{exit,{Pid,PI},_,TS}, Line, Out, LD = #ld{pid = Pid}|_]) ->
61 out(LD, Line, PI, "schedx", TS, LD#ld.in),
62 LD#ld{in = no, pid = no};
64 go([{gc_start,{Pid,PI},_,TS}, Line, Out, LD|_]) -> %gc
65 LD#ld{gc = TS};
66 go([{gc_end,{Pid,PI},_,TS}, Line, Out, LD = #ld{gc = Gc}|_]) -> %gc
67 Diff = out(LD, Line, PI, "gc", TS, Gc),
68 ?UPD_FIELD(LD#ld{gc = no}, in, Diff);
70 go(X = [_,_,_,LD|_]) -> %% io:fwrite("~p: ~w~n", [?MODULE, X]),
71 LD.
73 initial_state(Out) ->
74 #ld{out = Out}.
76 out(#ld{diff = Diff, out = Out}, Line, PI, Lab, Now, In) ->
77 case catch ntdiff(Now, In) of
78 {'EXIT', R} -> 0;
79 D when D > Diff ->
80 io:fwrite(Out, "~p: ~w ~s ~s ~w - ~w ms~n",
81 [?MODULE, Line, ntform(Now), Lab, PI, D/1000]),
83 D -> D
84 end.
86 ntadd({MSo, So, USo}, {MSi, Si, USi}) ->
87 case USi+USo of
88 US when US > 999999 ->
89 case So+Si+1 of
90 S when S > 999999 -> {MSo+MSi+1, S-1000000, US-1000000};
91 S -> {MSo+MSi, S, US-1000000}
92 end;
93 US ->
94 case So+Si of
95 S when S > 999999 -> {MSo+MSi+1, S-1000000,US};
96 S -> {MSo+MSi, S,US}
97 end
98 end.
101 ntdiff({MS, S, USo}, {MS, S, USi}) ->
102 (USo-USi);
103 ntdiff({MS, So, USo}, {MS, Si, USi}) ->
104 (USo-USi)+(So-Si)*1000000;
105 ntdiff({MSo, So, USo}, {MSi, Si, USi}) ->
106 (USo-USi)+(So-Si)*1000000+(MSo-MSi)*1000000000000.
107 ntform({Msec, Sec, Usec} = Now) ->
108 T = tuple_to_list(element(2,calendar:now_to_datetime(Now)))++[Usec],
109 io_lib:fwrite("~2.2.0w:~2.2.0w:~2.2.0w.~6.6.0w", T).