24
24
get_check_interval/0, set_check_interval/1,
25
25
get_procmem_high_watermark/0, set_procmem_high_watermark/1,
26
26
get_sysmem_high_watermark/0, set_sysmem_high_watermark/1,
27
get_helper_timeout/0, set_helper_timeout/1]).
27
get_helper_timeout/0, set_helper_timeout/1,
28
29
-export([dummy_reply/1, param_type/2, param_default/1]).
30
31
%% gen_server callbacks
64
65
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
68
os_mon:call(memsup, get_os_wordsize, infinity).
66
70
get_memory_data() ->
67
71
os_mon:call(memsup, get_memory_data, infinity).
117
121
os_mon:get_env(memsup, memsup_system_only));
118
122
dummy_reply(get_system_memory_data) ->
124
dummy_reply(get_os_wordsize) ->
120
126
dummy_reply(get_check_interval) ->
121
127
minutes_to_ms(os_mon:get_env(memsup, memory_check_interval));
122
128
dummy_reply({set_check_interval, _}) ->
216
handle_call(get_os_wordsize, _From, State) ->
217
Wordsize = get_os_wordsize(State#state.os),
218
{reply, Wordsize, State};
210
219
handle_call(get_memory_data, From, State) ->
211
220
%% Return result of latest memory check
212
221
case State#state.mem_usage of
666
675
%% Internal functions
667
676
%%----------------------------------------------------------------------
678
%%-- Fetching kernel bit support ---------------------------------------
680
get_os_wordsize({unix, sunos}) ->
681
String = clean_string(os:cmd("isainfo -b")),
682
erlang:list_to_integer(String);
683
get_os_wordsize({unix, irix64}) -> 64;
684
get_os_wordsize({unix, irix}) -> 32;
685
get_os_wordsize({unix, linux}) -> get_os_wordsize_with_uname();
686
get_os_wordsize({unix, darwin}) -> get_os_wordsize_with_uname();
687
get_os_wordsize({unix, netbsd}) -> get_os_wordsize_with_uname();
688
get_os_wordsize({unix, freebsd}) -> get_os_wordsize_with_uname();
689
get_os_wordsize({unix, openbsd}) -> get_os_wordsize_with_uname();
690
get_os_wordsize(_) -> unsupported_os.
692
get_os_wordsize_with_uname() ->
693
String = clean_string(os:cmd("uname -m")),
700
clean_string(String) -> lists:flatten(string:tokens(String,"\r\n\t ")).
669
703
%%--Replying to pending clients-----------------------------------------
671
705
reply(Pending, MemUsage, SysMemUsage) ->
709
743
NMemTotal = PageCount * PageSize,
710
744
{NMemUsed, NMemTotal};
712
%% Deprecated: Linux uses port (sysconf)
714
get_memory_usage({unix,linux}) ->
715
get_memory_usage_linux();
717
746
%% Win32: Find out how much memory is in use by asking
718
747
%% the os_mon_sysinfo process.
719
748
get_memory_usage({win32,_OSname}) ->
723
752
io_lib:fread("~d~d~d~d~d~d~d", Result),
724
753
{TotPhys-AvailPhys, TotPhys}.
726
%% Linux: Read pseudo file /proc/meminfo
727
%% If unavailable, wait and try again (until success or killed due
728
%% to a reg_collection_timeout in memsup)
729
get_memory_usage_linux() ->
730
Res = os:cmd("cat /proc/meminfo"),
731
case get_memory_usage_linux(Res, undef, undef) of
732
{MemTotal, MemFree} ->
733
{MemTotal-MemFree, MemTotal};
736
get_memory_usage_linux()
739
get_memory_usage_linux(_Str, Tot, Free) when is_integer(Tot),
742
get_memory_usage_linux("MemTotal:"++T, _Tot0, Free0) ->
743
{ok, [N], Rest} = io_lib:fread("~d", T),
745
get_memory_usage_linux(skip_to_eol(Rest), Tot, Free0);
746
get_memory_usage_linux("MemFree:"++T, Tot0, _Free0) ->
747
{ok, [N], Rest} = io_lib:fread("~d", T),
749
get_memory_usage_linux(skip_to_eol(Rest), Tot0, Free);
750
get_memory_usage_linux("", _Tot0, _Free0) ->
752
get_memory_usage_linux(Str, Tot0, Free0) ->
753
get_memory_usage_linux(skip_to_eol(Str), Tot0, Free0).
755
755
skip_to_eol([]) ->
757
757
skip_to_eol([$\n | T]) ->
792
792
start_portprogram() ->
793
Command = filename:join([code:priv_dir("os_mon"), "bin", "memsup"]),
793
Command = filename:join([code:priv_dir(os_mon), "bin", "memsup"]),
794
794
open_port({spawn, Command}, [{packet, 1}]).
796
796
%% The connected process loops are a bit awkward (several different
804
804
port_idle(Port) ->
806
806
{Memsup, collect_sys} ->
807
Port ! {self(), {command, [?MEM_SHOW]}},
807
Port ! {self(), {command, [?SHOW_MEM]}},
808
808
get_memory_usage(Port, undefined, Memsup);
809
809
{Memsup, collect_ext_sys} ->
810
Port ! {self(), {command, [?SYSTEM_MEM_SHOW]}},
810
Port ! {self(), {command, [?SHOW_SYSTEM_MEM]}},
811
811
get_ext_memory_usage(Port, [], Memsup);
813
813
%% Received after reply already has been delivered...
859
859
get_ext_memory_usage(Port, Accum, Memsup) ->
860
Tab = [{?SYSTEM_TOTAL_MEMORY, system_total_memory},
861
{?TOTAL_MEMORY, total_memory},
862
{?FREE_MEMORY, free_memory},
863
{?LARGEST_FREE, largest_free},
864
{?NUMBER_OF_FREE, number_of_free}],
861
{?MEM_SYSTEM_TOTAL, system_total_memory},
862
{?MEM_TOTAL, total_memory},
863
{?MEM_FREE, free_memory},
864
{?MEM_BUFFERS, buffered_memory},
865
{?MEM_CACHED, cached_memory},
866
{?MEM_SHARED, shared_memory},
867
{?MEM_LARGEST_FREE, largest_free},
868
{?MEM_NUMBER_OF_FREE, number_of_free},
869
{?SWAP_TOTAL, total_swap},
870
{?SWAP_FREE, free_swap}
866
{Port, {data, [?SYSTEM_MEM_SHOW_END]}} ->
873
{Port, {data, [?SHOW_SYSTEM_MEM_END]}} ->
867
874
Memsup ! {collected_ext_sys, Accum},
869
876
{Port, {data, [Tag]}} ->
885
892
get_ext_memory_usage_cancelled(Port) ->
886
Tab = [{?SYSTEM_TOTAL_MEMORY, system_total_memory},
887
{?TOTAL_MEMORY, total_memory},
888
{?FREE_MEMORY, free_memory},
889
{?LARGEST_FREE, largest_free},
890
{?NUMBER_OF_FREE, number_of_free}],
894
{?MEM_SYSTEM_TOTAL, system_total_memory},
895
{?MEM_TOTAL, total_memory},
896
{?MEM_FREE, free_memory},
897
{?MEM_BUFFERS, buffered_memory},
898
{?MEM_CACHED, cached_memory},
899
{?MEM_SHARED, shared_memory},
900
{?MEM_LARGEST_FREE, largest_free},
901
{?MEM_NUMBER_OF_FREE, number_of_free},
902
{?SWAP_TOTAL, total_swap},
903
{?SWAP_FREE, free_swap}
892
{Port, {data, [?SYSTEM_MEM_SHOW_END]}} ->
906
{Port, {data, [?SHOW_SYSTEM_MEM_END]}} ->
894
908
{Port, {data, [Tag]}} ->
895
909
case lists:keysearch(Tag, 1, Tab) of