-let read_procmem pid =
- let cin = open_in (Printf.sprintf "/proc/%i/status" pid) in
- let matchline s =
- try
- Scanf.sscanf s " VmRSS: %i kB" (fun i -> Some i)
- with
- | _ -> None
- in
- let rec loop () =
- match matchline (input_line cin) with
- Some i -> i
- | None -> loop ()
- in
- let s = try loop() with _ -> -1 in
- Printf.eprintf "Memory: %i\n%!" s;
- close_in cin;
- s
+open Format
+
+module Options =
+ struct
+ let outfile = ref "/dev/stderr"
+ let page_size = ref ~-1
+ let timeout = ref 30
+ let max_mem = ref (512*1024)
+ let interval = ref 250
+ let quiet = ref false
+
+ let spec = Arg.align [
+ "-o", Arg.Set_string outfile, " output file (default stderr)";
+ "-p", Arg.Set_int page_size, " page size in bytes (default autodetect)";
+ "-t", Arg.Set_int timeout, " timeout in s (default 30s)";
+ "-m", Arg.Set_int max_mem, " maximum memory in kiB (default 512 MiB)";
+ "-i", Arg.Set_int interval, " refresh interval in ms (default 250ms)";
+ "-q", Arg.Set(quiet), " don't print messages while running";
+ ]
+ let usage_msg = sprintf "usage: %s [options] -- <program> [arguments ...]" Sys.argv.(0)
+ let find_dash a =
+ let rec loop i len =
+ if i < len then
+ if a.(i) = "--" then i
+ else loop (i+1) len
+ else
+ raise Not_found
+ in
+ loop 0 (Array.length a)
+
+ let parse_cmdline () =
+ try
+ let idash = find_dash Sys.argv in
+ let argv = Array.sub Sys.argv 0 idash in
+ let cmd = Array.sub Sys.argv (idash+1) (Array.length Sys.argv - idash - 1) in
+ let () =
+ Arg.parse_argv argv spec ignore usage_msg
+ in
+ if Array.length cmd = 0 then (Arg.usage spec usage_msg; exit 1);
+ cmd
+ with
+ Arg.Bad(s) -> Printf.eprintf "%s\n" s; exit 1
+ | Arg.Help(s) -> Printf.printf "%s\n" s; exit 0
+ | Not_found -> Arg.usage spec usage_msg; exit 1
+
+ end
+
+
+(* Utility functions *)
+open Unix
+
+let get_page_size () =
+ let cin = open_process_in "getconf PAGESIZE" in
+ let s = input_line cin in
+ match close_process_in cin with
+ WEXITED 0 -> (try int_of_string s with _ -> ~-1)
+ | _ -> ~-1