Manage global reductions delta ourselves
[beam_stats.git] / src / beam_stats_delta.erl
CommitLineData
b2c364fd
SK
1-module(beam_stats_delta).
2
3-export_type(
4 [ t/0
5 ]).
6
7-export(
8 [ start/0
9 , stop/1
10 , of_context_switches/1
11 , of_io/1
11e1cb97 12 , of_reductions/1
b2c364fd
SK
13 ]).
14
15-record(?MODULE,
16 { erlang_statistics :: ets:tid()
17 }).
18
19-define(T, #?MODULE).
20
21-opaque t() ::
22 ?T{}.
23
24-spec start() ->
25 t().
26start() ->
27 Options =
28 [ set
29 , public
30 ],
31 ?T
32 { erlang_statistics = ets:new(beam_stats_delta_erlang_statistics, Options)
33 }.
34
35-spec stop(t()) ->
36 {}.
37stop(?T
38 { erlang_statistics = TidErlangStatistics
39 }
40) ->
41 true = ets:delete(TidErlangStatistics),
42 {}.
43
44-spec of_context_switches(t()) ->
45 non_neg_integer().
46of_context_switches(?T{erlang_statistics=Table}) ->
47 Key = context_switches,
48 {Current, 0} = beam_stats_source:erlang_statistics(Key),
49 delta(Table, Key, Current).
50
51-spec of_io(t()) ->
52 { {io_bytes_in , non_neg_integer()}
53 , {io_bytes_out , non_neg_integer()}
54 }.
55of_io(?T{erlang_statistics=Table}) ->
56 Key = io,
57 { {input , CurrentIn}
58 , {output , CurrentOut}
59 } = beam_stats_source:erlang_statistics(Key),
60 DeltaIn = delta(Table, io_bytes_in , CurrentIn),
61 DeltaOut = delta(Table, io_bytes_out, CurrentOut),
62 { {io_bytes_in , DeltaIn}
63 , {io_bytes_out , DeltaOut}
64 }.
65
11e1cb97
SK
66% We can get between-calls-delta directly from erlang:statistics(reductions),
67% but then if some other process also calls it - we'll get incorrect data on
68% the next call.
69% Managing deltas ourselves here, will at least reduce the possible callers to
70% only those with knowledge of our table ID.
71-spec of_reductions(t()) ->
72 non_neg_integer().
73of_reductions(?T{erlang_statistics=Table}) ->
74 Key = reductions,
75 {Current, _} = beam_stats_source:erlang_statistics(Key),
76 delta(Table, Key, Current).
77
b2c364fd
SK
78-spec delta(ets:tid(), atom(), non_neg_integer()) ->
79 non_neg_integer().
80delta(Table, Key, CurrentTotal) ->
81 PreviousTotalOpt = find(Table, Key),
82 PreviousTotal = hope_option:get(PreviousTotalOpt, 0),
83 save(Table, Key, CurrentTotal),
84 CurrentTotal - PreviousTotal.
85
86-spec find(ets:tid(), term()) ->
87 hope_option:t(term()).
88find(Table, K) ->
89 case ets:lookup(Table, K)
90 of [] -> none
91 ; [{K, V}] -> {some, V}
92 end.
93
94-spec save(ets:tid(), term(), term()) ->
95 {}.
96save(Table, K, V) ->
97 true = ets:insert(Table, {K, V}),
98 {}.
This page took 0.034774 seconds and 4 git commands to generate.