Merge pull request #3034 from emqx/rm-vm-module

Improve the emqx_vm module and update test cases
This commit is contained in:
tigercl 2019-11-18 10:51:54 +08:00 committed by GitHub
commit d793c4256f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 203 deletions

View File

@ -19,6 +19,7 @@
-export([ schedulers/0 -export([ schedulers/0
, scheduler_usage/1 , scheduler_usage/1
, microsecs/0 , microsecs/0
, system_info_keys/0
, get_system_info/0 , get_system_info/0
, get_system_info/1 , get_system_info/1
, get_memory/0 , get_memory/0
@ -26,11 +27,12 @@
, loads/0 , loads/0
]). ]).
-export([ get_process_list/0 -export([ process_info_keys/0
, get_process_info/0 , get_process_info/0
, get_process_info/1 , get_process_info/1
, get_process_gc/0 , process_gc_info_keys/0
, get_process_gc/1 , get_process_gc_info/0
, get_process_gc_info/1
, get_process_group_leader_info/1 , get_process_group_leader_info/1
, get_process_limit/0 , get_process_limit/0
]). ]).
@ -62,86 +64,83 @@
sl_alloc, sl_alloc,
ll_alloc, ll_alloc,
fix_alloc, fix_alloc,
std_alloc]). std_alloc
]).
-define(PROCESS_LIST, [initial_call, -define(PROCESS_INFO_KEYS, [initial_call,
reductions, current_function,
memory, registered_name,
message_queue_len, status,
current_function]). message_queue_len,
group_leader,
priority,
trap_exit,
reductions,
%%binary,
last_calls,
catchlevel,
trace,
suspending,
sequential_trace_token,
error_handler
]).
-define(PROCESS_INFO, [initial_call, -define(PROCESS_GC_KEYS, [memory,
current_function, total_heap_size,
registered_name, heap_size,
status, stack_size,
message_queue_len, min_heap_size
group_leader, ]).
priority,
trap_exit,
reductions,
%%binary,
last_calls,
catchlevel,
trace,
suspending,
sequential_trace_token,
error_handler]).
-define(PROCESS_GC, [memory, -define(SYSTEM_INFO_KEYS, [allocated_areas,
total_heap_size, allocator,
heap_size, alloc_util_allocators,
stack_size, build_type,
min_heap_size]). check_io,
%fullsweep_after]). compat_rel,
creation,
-define(SYSTEM_INFO, [allocated_areas, debug_compiled,
allocator, dist,
alloc_util_allocators, dist_ctrl,
build_type, driver_version,
check_io, elib_malloc,
compat_rel, dist_buf_busy_limit,
creation, %fullsweep_after, % included in garbage_collection
debug_compiled, garbage_collection,
dist, %global_heaps_size, % deprecated
dist_ctrl, heap_sizes,
driver_version, heap_type,
elib_malloc, info,
dist_buf_busy_limit, kernel_poll,
%fullsweep_after, % included in garbage_collection loaded,
garbage_collection, logical_processors,
%global_heaps_size, % deprecated logical_processors_available,
heap_sizes, logical_processors_online,
heap_type, machine,
info, %min_heap_size, % included in garbage_collection
kernel_poll, %min_bin_vheap_size, % included in garbage_collection
loaded, modified_timing_level,
logical_processors, multi_scheduling,
logical_processors_available, multi_scheduling_blockers,
logical_processors_online, otp_release,
machine, port_count,
%min_heap_size, % included in garbage_collection process_count,
%min_bin_vheap_size, % included in garbage_collection process_limit,
modified_timing_level, scheduler_bind_type,
multi_scheduling, scheduler_bindings,
multi_scheduling_blockers, scheduler_id,
otp_release, schedulers,
port_count, schedulers_online,
process_count, smp_support,
process_limit, system_version,
scheduler_bind_type, system_architecture,
scheduler_bindings, threads,
scheduler_id, thread_pool_size,
schedulers, trace_control_word,
schedulers_online, update_cpu_info,
smp_support, version,
system_version, wordsize
system_architecture, ]).
threads,
thread_pool_size,
trace_control_word,
update_cpu_info,
version,
wordsize]).
-define(SOCKET_OPTS, [active, -define(SOCKET_OPTS, [active,
broadcast, broadcast,
@ -166,7 +165,8 @@
send_timeout, send_timeout,
send_timeout_close, send_timeout_close,
sndbuf, sndbuf,
tos]). tos
]).
schedulers() -> schedulers() ->
erlang:system_info(schedulers). erlang:system_info(schedulers).
@ -178,16 +178,16 @@ microsecs() ->
loads() -> loads() ->
[{load1, ftos(avg1()/256)}, [{load1, ftos(avg1()/256)},
{load5, ftos(avg5()/256)}, {load5, ftos(avg5()/256)},
{load15, ftos(avg15()/256)}]. {load15, ftos(avg15()/256)}
].
system_info_keys() -> ?SYSTEM_INFO_KEYS.
get_system_info() -> get_system_info() ->
[{Key, format_system_info(Key, get_system_info(Key))} || Key <- ?SYSTEM_INFO]. [{Key, format_system_info(Key, get_system_info(Key))} || Key <- ?SYSTEM_INFO_KEYS].
get_system_info(Key) -> get_system_info(Key) ->
try erlang:system_info(Key) catch try erlang:system_info(Key) catch error:badarg-> undefined end.
error:badarg->undefined
end.
%% conversion functions for erlang:system_info(Key)
format_system_info(allocated_areas, List) -> format_system_info(allocated_areas, List) ->
[convert_allocated_areas(Value) || Value <- List]; [convert_allocated_areas(Value) || Value <- List];
@ -221,8 +221,9 @@ convert_allocated_areas({Key, Value}) ->
mem_info() -> mem_info() ->
Dataset = memsup:get_system_memory_data(), Dataset = memsup:get_system_memory_data(),
[{total_memory, proplists:get_value(total_memory, Dataset)}, Total = proplists:get_value(total_memory, Dataset),
{used_memory, proplists:get_value(total_memory, Dataset) - proplists:get_value(free_memory, Dataset)}]. Free = proplists:get_value(free_memory, Dataset),
[{total_memory, Total}, {used_memory, Total - Free}].
ftos(F) -> ftos(F) ->
S = io_lib:format("~.2f", [F]), S. S = io_lib:format("~.2f", [F]), S.
@ -300,24 +301,24 @@ container_value(Props, Pos, Type, Container) ->
TypeProps = proplists:get_value(Type, Props), TypeProps = proplists:get_value(Type, Props),
element(Pos, lists:keyfind(Container, 1, TypeProps)). element(Pos, lists:keyfind(Container, 1, TypeProps)).
get_process_list()-> process_info_keys() ->
[get_process_list(Pid) || Pid <- processes()]. ?PROCESS_INFO_KEYS.
get_process_list(Pid) when is_pid(Pid) ->
[{pid, Pid} | [process_info(Pid, Key) || Key <- ?PROCESS_LIST]].
get_process_info() -> get_process_info() ->
[get_process_info(Pid) || Pid <- processes()]. get_process_info(self()).
get_process_info(Pid) when is_pid(Pid) -> get_process_info(Pid) when is_pid(Pid) ->
process_info(Pid, ?PROCESS_INFO). process_info(Pid, ?PROCESS_INFO_KEYS).
get_process_gc() -> process_gc_info_keys() ->
[get_process_gc(Pid) || Pid <- processes()]. ?PROCESS_GC_KEYS.
get_process_gc(Pid) when is_pid(Pid) ->
process_info(Pid, ?PROCESS_GC). get_process_gc_info() ->
get_process_gc_info(self()).
get_process_gc_info(Pid) when is_pid(Pid) ->
process_info(Pid, ?PROCESS_GC_KEYS).
get_process_group_leader_info(LeaderPid) when is_pid(LeaderPid) -> get_process_group_leader_info(LeaderPid) when is_pid(LeaderPid) ->
[{Key, Value}|| {Key, Value} <- process_info(LeaderPid), lists:member(Key, ?PROCESS_INFO)]. [{Key, Value}|| {Key, Value} <- process_info(LeaderPid), lists:member(Key, ?PROCESS_INFO_KEYS)].
get_process_limit() -> get_process_limit() ->
erlang:system_info(process_limit). erlang:system_info(process_limit).
@ -446,8 +447,7 @@ ports_type_count(Types) ->
mapping(Entries) -> mapping(Entries) ->
mapping(Entries, []). mapping(Entries, []).
mapping([], Acc) -> mapping([], Acc) -> Acc;
Acc;
mapping([{owner, V}|Entries], Acc) when is_pid(V) -> mapping([{owner, V}|Entries], Acc) when is_pid(V) ->
OwnerInfo = process_info(V), OwnerInfo = process_info(V),
Owner = proplists:get_value(registered_name, OwnerInfo, undefined), Owner = proplists:get_value(registered_name, OwnerInfo, undefined),
@ -470,10 +470,10 @@ cpu_util() ->
compat_windows(Fun) -> compat_windows(Fun) ->
case os:type() of case os:type() of
{win32, nt} -> 0; {win32, nt} -> 0;
_Other -> handle_error(Fun()) _Type ->
case catch Fun() of
Val when is_number(Val) -> Val;
_Error -> 0
end
end. end.
handle_error(Value) when is_number(Value) ->
Value;
handle_error({error, _Reason}) ->
0.

View File

@ -21,115 +21,29 @@
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-define(SYSTEM_INFO, [allocated_areas,
allocator,
alloc_util_allocators,
build_type,
check_io,
compat_rel,
creation,
debug_compiled,
dist,
dist_ctrl,
driver_version,
elib_malloc,
dist_buf_busy_limit,
%fullsweep_after, % included in garbage_collection
garbage_collection,
%global_heaps_size, % deprecated
heap_sizes,
heap_type,
info,
kernel_poll,
loaded,
logical_processors,
logical_processors_available,
logical_processors_online,
machine,
%min_heap_size, % included in garbage_collection
%min_bin_vheap_size, % included in garbage_collection
modified_timing_level,
multi_scheduling,
multi_scheduling_blockers,
otp_release,
port_count,
process_count,
process_limit,
scheduler_bind_type,
scheduler_bindings,
scheduler_id,
schedulers,
schedulers_online,
smp_support,
system_version,
system_architecture,
threads,
thread_pool_size,
trace_control_word,
update_cpu_info,
version,
wordsize]).
-define(PROCESS_INFO, [initial_call,
current_function,
registered_name,
status,
message_queue_len,
group_leader,
priority,
trap_exit,
reductions,
%%binary,
last_calls,
catchlevel,
trace,
suspending,
sequential_trace_token,
error_handler]).
-define(PROCESS_GC, [memory,
total_heap_size,
heap_size,
stack_size,
min_heap_size]).
%fullsweep_after]).
all() -> emqx_ct:all(?MODULE). all() -> emqx_ct:all(?MODULE).
t_load(_Config) -> t_load(_Config) ->
?assertMatch([{load1, _}, ?assertMatch([{load1, _}, {load5, _}, {load15, _}], emqx_vm:loads()).
{load5, _},
{load15, _}
], emqx_vm:loads()).
t_systeminfo(_Config) -> t_systeminfo(_Config) ->
Keys = [Key || {Key, _} <- emqx_vm:get_system_info()], ?assertEqual(emqx_vm:system_info_keys(),
?SYSTEM_INFO = Keys, [Key || {Key, _} <- emqx_vm:get_system_info()]),
?assertEqual(undefined, emqx_vm:get_system_info(undefined)). ?assertEqual(undefined, emqx_vm:get_system_info(undefined)).
t_mem_info(_Config) -> t_mem_info(_Config) ->
application:ensure_all_started(os_mon), application:ensure_all_started(os_mon),
MemInfo = emqx_vm:mem_info(), MemInfo = emqx_vm:mem_info(),
[{total_memory, _}, [{total_memory, _}, {used_memory, _}]= MemInfo,
{used_memory, _}]= MemInfo,
application:stop(os_mon). application:stop(os_mon).
t_process_list(_Config) ->
Pid = self(),
ProcessInfo = emqx_vm:get_process_list(),
true = lists:member({pid, Pid}, lists:concat(ProcessInfo)).
t_process_info(_Config) -> t_process_info(_Config) ->
ProcessInfos = emqx_vm:get_process_info(), ProcessInfo = emqx_vm:get_process_info(),
ProcessInfo = lists:last(ProcessInfos), ?assertEqual(emqx_vm:process_info_keys(), [K || {K, _V}<- ProcessInfo]).
Keys = [K || {K, _V}<- ProcessInfo],
?PROCESS_INFO = Keys.
t_process_gc(_Config) -> t_process_gc(_Config) ->
ProcessGcs = emqx_vm:get_process_gc(), GcInfo = emqx_vm:get_process_gc_info(),
ProcessGc = lists:last(ProcessGcs), ?assertEqual(emqx_vm:process_gc_info_keys(), [K || {K, _V}<- GcInfo]).
Keys = [K || {K, _V}<- ProcessGc],
?PROCESS_GC = Keys.
t_get_ets_list(_Config) -> t_get_ets_list(_Config) ->
ets:new(test, [named_table]), ets:new(test, [named_table]),