Update alignments.
[beam_stats.git] / src / beam_stats_delta.erl
index d563507..fae6c63 100644 (file)
@@ -7,12 +7,16 @@
 -export(
     [ start/0
     , stop/1
+    , gc/1
     , of_context_switches/1
     , of_io/1
+    , of_reductions/1
+    , of_process_info_reductions/2
     ]).
 
 -record(?MODULE,
     { erlang_statistics :: ets:tid()
+    , erlang_process_info_reductions :: ets:tid()
     }).
 
 -define(T, #?MODULE).
@@ -28,18 +32,48 @@ start() ->
         , public
         ],
     ?T
-    { erlang_statistics = ets:new(beam_stats_delta_erlang_statistics, Options)
+    { erlang_statistics =
+        ets:new(beam_stats_delta_erlang_statistics, Options)
+    , erlang_process_info_reductions =
+        ets:new(beam_stats_delta_erlang_process_info_reductions, Options)
     }.
 
 -spec stop(t()) ->
     {}.
 stop(?T
-    { erlang_statistics = TidErlangStatistics
+    { erlang_statistics              = TidErlangStatistics
+    , erlang_process_info_reductions = TidErlangProcessInfoReductions
     }
 ) ->
     true = ets:delete(TidErlangStatistics),
+    true = ets:delete(TidErlangProcessInfoReductions),
     {}.
 
+-spec gc(t()) ->
+    {}.
+gc(?T{erlang_process_info_reductions=Table}=T) ->
+    case ets:first(Table)
+    of  '$end_of_table' ->
+            {}
+    ;   FirstPid when is_pid(FirstPid) ->
+            gc(T, FirstPid)
+    end.
+
+-spec gc(t(), pid()) ->
+    {}.
+gc(?T{erlang_process_info_reductions=Table}=T, Pid) ->
+    Next = ets:next(Table, Pid),
+    case beam_stats_source:erlang_is_process_alive(Pid)
+    of  true  -> true
+    ;   false -> ets:delete(Table, Pid)
+    end,
+    case Next
+    of  '$end_of_table' ->
+            {}
+    ;   NextPid when is_pid(NextPid) ->
+            gc(T, NextPid)
+    end.
+
 -spec of_context_switches(t()) ->
     non_neg_integer().
 of_context_switches(?T{erlang_statistics=Table}) ->
@@ -62,8 +96,32 @@ of_io(?T{erlang_statistics=Table}) ->
     , {io_bytes_out , DeltaOut}
     }.
 
--spec delta(ets:tid(), atom(), non_neg_integer()) ->
+% We can get between-calls-delta directly from erlang:statistics(reductions),
+% but then if some other process also calls it - we'll get incorrect data on
+% the next call.
+% Managing deltas ourselves here, will at least reduce the possible callers to
+% only those with knowledge of our table ID.
+-spec of_reductions(t()) ->
     non_neg_integer().
+of_reductions(?T{erlang_statistics=Table}) ->
+    Key = reductions,
+    {Current, _} = beam_stats_source:erlang_statistics(Key),
+    delta(Table, Key, Current).
+
+-spec of_process_info_reductions(t(), pid()) ->
+    hope_option:t(non_neg_integer()).
+of_process_info_reductions(?T{erlang_process_info_reductions=Table}, Pid) ->
+    case beam_stats_source:erlang_process_info(Pid, reductions)
+    of  undefined ->
+            none
+    ;   {reductions, Current} ->
+            Delta = delta(Table, Pid, Current),
+            {some, Delta}
+    end.
+
+-spec delta(ets:tid(), Key, non_neg_integer()) ->
+    non_neg_integer()
+    when Key :: atom() | pid().
 delta(Table, Key, CurrentTotal) ->
     PreviousTotalOpt = find(Table, Key),
     PreviousTotal = hope_option:get(PreviousTotalOpt, 0),
This page took 0.029185 seconds and 4 git commands to generate.