~rdoering/ubuntu/karmic/erlang/fix-535090

« back to all changes in this revision

Viewing changes to lib/os_mon/src/memsup.erl

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-02-15 16:42:52 UTC
  • mfrom: (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090215164252-q5x4rcf8a5pbesb1
Tags: 1:12.b.5-dfsg-2
Upload to unstable after lenny is released.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
         get_os_wordsize/0]).
28
29
-export([dummy_reply/1, param_type/2, param_default/1]).
29
30
 
30
31
%% gen_server callbacks
63
64
start_link() ->
64
65
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
65
66
 
 
67
get_os_wordsize() ->
 
68
    os_mon:call(memsup, get_os_wordsize, infinity).
 
69
 
66
70
get_memory_data() ->
67
71
    os_mon:call(memsup, get_memory_data, infinity).
68
72
 
117
121
                os_mon:get_env(memsup, memsup_system_only));
118
122
dummy_reply(get_system_memory_data) ->
119
123
    [];
 
124
dummy_reply(get_os_wordsize) ->
 
125
    0;
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, _}) ->
207
213
 
208
214
                pid=Pid}}.
209
215
 
 
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
%%----------------------------------------------------------------------
668
677
 
 
678
%%-- Fetching kernel bit support ---------------------------------------
 
679
 
 
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.
 
691
 
 
692
get_os_wordsize_with_uname() ->
 
693
    String = clean_string(os:cmd("uname -m")),
 
694
    case String of
 
695
        "x86_64"  -> 64;
 
696
        "sparc64" -> 64;
 
697
        _         -> 32
 
698
    end.
 
699
 
 
700
clean_string(String) -> lists:flatten(string:tokens(String,"\r\n\t ")).
 
701
    
 
702
 
669
703
%%--Replying to pending clients-----------------------------------------
670
704
 
671
705
reply(Pending, MemUsage, SysMemUsage) ->
709
743
    NMemTotal = PageCount * PageSize,
710
744
    {NMemUsed, NMemTotal};
711
745
 
712
 
%% Deprecated: Linux uses port (sysconf)
713
 
%% Linux: see below
714
 
get_memory_usage({unix,linux}) ->
715
 
    get_memory_usage_linux();
716
 
 
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}.
725
754
 
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};
734
 
        error ->
735
 
            timer:sleep(1000),
736
 
            get_memory_usage_linux()
737
 
    end.
738
 
 
739
 
get_memory_usage_linux(_Str, Tot, Free) when is_integer(Tot),
740
 
                                             is_integer(Free) ->
741
 
    {Tot, Free};
742
 
get_memory_usage_linux("MemTotal:"++T, _Tot0, Free0) ->
743
 
    {ok, [N], Rest} = io_lib:fread("~d", T),
744
 
    Tot = N*1024,
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),
748
 
    Free = N*1024,
749
 
    get_memory_usage_linux(skip_to_eol(Rest), Tot0, Free);
750
 
get_memory_usage_linux("", _Tot0, _Free0) ->
751
 
    error;
752
 
get_memory_usage_linux(Str, Tot0, Free0) ->
753
 
    get_memory_usage_linux(skip_to_eol(Str), Tot0, Free0).
754
 
 
755
755
skip_to_eol([]) ->
756
756
    [];
757
757
skip_to_eol([$\n | T]) ->
790
790
    port_idle(Port).
791
791
 
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}]).
795
795
 
796
796
%% The connected process loops are a bit awkward (several different
804
804
port_idle(Port) ->
805
805
    receive
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);
812
812
        cancel ->
813
813
            %% Received after reply already has been delivered...
857
857
    end.
858
858
 
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}],
 
860
    Tab = [
 
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}
 
871
        ],
865
872
    receive
866
 
        {Port, {data, [?SYSTEM_MEM_SHOW_END]}} ->
 
873
        {Port, {data, [?SHOW_SYSTEM_MEM_END]}} ->
867
874
            Memsup ! {collected_ext_sys, Accum},
868
875
            port_idle(Port);
869
876
        {Port, {data, [Tag]}} ->
883
890
            port_close(Port)
884
891
    end.
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}],
 
893
    Tab = [
 
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}
 
904
        ],
891
905
    receive
892
 
        {Port, {data, [?SYSTEM_MEM_SHOW_END]}} ->
 
906
        {Port, {data, [?SHOW_SYSTEM_MEM_END]}} ->
893
907
            port_idle(Port);
894
908
        {Port, {data, [Tag]}} ->
895
909
            case lists:keysearch(Tag, 1, Tab) of