|
13 | 13 | term_to_port/1, |
14 | 14 | time_map/5, time_fold/6, |
15 | 15 | scheduler_usage_diff/2, |
16 | | - sublist_top_n_attrs/2]). |
| 16 | + sublist_top_n_attrs/2, |
| 17 | + fold_processes/2]). |
17 | 18 | %% private exports |
18 | 19 | -export([binary_memory/1]). |
19 | 20 |
|
@@ -73,15 +74,45 @@ port_list(Attr, Val) -> |
73 | 74 | [Port || Port <- erlang:ports(), |
74 | 75 | {Attr, Val} =:= erlang:port_info(Port, Attr)]. |
75 | 76 |
|
| 77 | +%% @doc Fold over all processes, using efficient iterator when available (OTP 28+). |
| 78 | +-spec fold_processes(Fun, Acc0) -> Acc when |
| 79 | + Fun :: fun((pid(), Acc) -> Acc), |
| 80 | + Acc0 :: Acc, |
| 81 | + Acc :: term(). |
| 82 | +fold_processes(Fun, Acc0) -> |
| 83 | + try |
| 84 | + Iter = erlang:processes_iterator(), |
| 85 | + fold_processes_iter(Fun, Acc0, Iter) |
| 86 | + catch |
| 87 | + error:undef -> |
| 88 | + lists:foldl(Fun, Acc0, processes()) |
| 89 | + end. |
| 90 | + |
| 91 | +fold_processes_iter(Fun, Acc, Iter) -> |
| 92 | + case erlang:processes_next(Iter) of |
| 93 | + {Pid, NewIter} -> |
| 94 | + NewAcc = Fun(Pid, Acc), |
| 95 | + fold_processes_iter(Fun, NewAcc, NewIter); |
| 96 | + none -> |
| 97 | + Acc |
| 98 | + end. |
| 99 | + |
76 | 100 | %% @doc Returns the attributes ({@link recon:proc_attrs()}) of |
77 | 101 | %% all processes of the node, except the caller. |
78 | 102 | -spec proc_attrs(term()) -> [recon:proc_attrs()]. |
79 | 103 | proc_attrs(AttrName) -> |
80 | 104 | Self = self(), |
81 | | - [Attrs || Pid <- processes(), |
82 | | - Pid =/= Self, |
83 | | - {ok, Attrs} <- [proc_attrs(AttrName, Pid)] |
84 | | - ]. |
| 105 | + fold_processes( |
| 106 | + fun(Pid, Acc) when Pid =/= Self -> |
| 107 | + case proc_attrs(AttrName, Pid) of |
| 108 | + {ok, Attrs} -> [Attrs | Acc]; |
| 109 | + {error, _} -> Acc |
| 110 | + end; |
| 111 | + (_, Acc) -> |
| 112 | + Acc |
| 113 | + end, |
| 114 | + [] |
| 115 | + ). |
85 | 116 |
|
86 | 117 | %% @doc Returns the attributes of a given process. This form of attributes |
87 | 118 | %% is standard for most comparison functions for processes in recon. |
@@ -288,5 +319,3 @@ merge(H1, [E2|H2]) -> [E2, H1|H2]. |
288 | 319 | merge_pairs([]) -> []; |
289 | 320 | merge_pairs([H]) -> H; |
290 | 321 | merge_pairs([A, B|T]) -> merge(merge(A, B), merge_pairs(T)). |
291 | | - |
292 | | - |
|
0 commit comments