6 let font = Glut.BITMAP_HELVETICA_12
7 let draw_string ?
(font=font) x y s
=
8 GlPix.raster_pos ~x ~y
();
9 String.iter
(fun c
-> Glut.bitmapCharacter ~
font ~c
:(Char.code c
)) s
14 ; loads
: int64
* int64
* int64
24 external get_nprocs
: unit -> int = "ml_get_nprocs"
25 external idletimeofday
: Unix.file_descr
-> int -> float array
27 external sysinfo
: unit -> sysinfo
= "ml_sysinfo"
28 external waitalrm
: unit -> unit = "ml_waitalrm"
29 external get_hz
: unit -> int = "ml_get_hz"
30 external setnice
: int -> unit = "ml_nice"
40 let hz = get_hz
() |> float
42 let jiffies_to_sec j
=
45 let nprocs = get_nprocs
()
47 let rec parse_int_cont s pos
=
48 let slen = String.length s
in
54 if String.get s
pos = ' '
55 then succ
pos |> skipws
60 try String.index_from s
pos ' '
61 with Not_found
-> slen
63 let i = endpos - pos |> String.sub s
pos |> int_of_string
in
68 `more
(i, fun () -> succ
endpos |> parse_int_cont s
)
71 let rec tolist accu
= function
72 | `last
i -> i :: accu
73 | `more
(i, f
) -> f
() |> tolist (i :: accu
)
75 let index = String.index s ' '
in
76 let cpuname = String.sub s
0 index in
77 let vals = parse_int_cont s
(succ
index) |> tolist [] in
78 let vals = List.rev
|<
79 if List.length
vals < 7
81 0 :: 0 :: 0 :: 0 :: vals
85 cpuname, Array.of_list
vals
89 let ic = open_in
"/proc/stat" in
93 else (input_line
ic |> parse_cpul) :: accu
|> loop (pred
i)
95 let ret = loop nprocs [] in
101 Filename.dirname
|< Unix.readlink
"/proc/self/exe"
107 for i = 0 to pred
nprocs
112 let rec loop i = succ
i |> loop in loop 0
119 [ "Amazing Piece of Code by insanely gifted programmer, Version 0.90"
120 ; "Motivation by: gzh and afs"
122 ] |> String.concat
"\n"
125 let interval = ref 15.0
126 let devpath = NP.getselfdir () |> Filename.concat
|< "itc" |> ref
131 let verbose = ref false
133 let ksampler = ref true
136 let sigway = ref true
140 let dA tos s
{contents
=v
} = s ^
" (" ^ tos v ^
")"
141 let dF = dA string_of_float
142 let dB = dA string_of_bool
143 let dI = dA string_of_int
144 let dS = dA (fun s
-> "`" ^
String.escaped s ^
"'")
147 let l = String.length s
in
152 let d = String.make n ' '
in
153 StringLabels.blit ~src
:s ~dst
:d
159 "-" ^ opt
, Arg.Set_float r
, pad 9 "<float> " ^ doc
|> dF |< r
162 "-" ^ opt
, Arg.Set_int r
, pad 9 "<int> " ^ doc
|> dI |< r
165 "-" ^ opt
, Arg.Set r
, pad 9 "" ^ doc
|> dB |< r
168 "-" ^ opt
, Arg.Clear r
, pad 9 "" ^ doc
|> dB |< r
171 "-" ^ opt
, Arg.Set_string r
, pad 9 "<string> " ^ doc
|> dS |< r
175 [ sF "f" freq "update frequency"
176 ; sF "D" delay "refresh delay"
177 ; sF "i" interval "interval"
178 ; sI "p" pgrid "pgrid"
179 ; sI "s" sgrid "sgrid"
182 ; sI "b" barw "bar width"
183 ; sI "B" bars "number of CPU bars"
184 ; sI "n" niceval "value to renice self on init"
185 ; sS "d" devpath "path to itc device"
186 ; sBc "k" ksampler "do not show kernel view"
187 ; sB "v" verbose "verbose"
188 ; sB "S" sigway "sigwait delay method"
191 "don't know what to do with " ^ s
|> prerr_endline
;
198 let prev = ref 0.0 in
201 let b = Unix.gettimeofday
() in
209 module Delay
= struct
210 let sighandler signr
= ()
214 Sys.Signal_handle
sighandler |> Sys.set_signal
Sys.sigalrm
;
217 Unix.sigprocmask
Unix.SIG_BLOCK
[Sys.sigalrm
] |> ignore
220 let v = 1e-6 /. !Args.freq in
221 let t = { Unix.it_interval
= v; it_value
= v } in
222 let _ = Unix.setitimer
Unix.ITIMER_REAL
t in
229 try let _ = Unix.select
[] [] [] ~
-.1.0 in ()
230 with Unix.Unix_error
(Unix.EINTR
, _, _) -> ()
233 module Sampler
(T
: sig val nsamples
: int val freq : float end) =
235 let nsamples = T.nsamples
236 let samples = Array.create
nsamples 0.0
241 let n = min
nsamples n in
246 let i = if i = nsamples then 0 else i in
247 Array.set
samples i v;
248 loop (succ
i) (pred j
)
250 let () = loop !head n in
251 let () = head := (!head + n) mod nsamples in
252 let () = active := min
(!active + n) nsamples in
257 let d = !head - !active in
262 let ry = ref (fun () -> assert false) in
268 ry := succ
i |> yield;
269 Some
((i + tail) mod nsamples |> Array.get
samples)
275 let update t1 t2 i1 i2
=
278 let isamples = truncate
(d /. T.freq) in
279 let l = 1.0 -. (i /. d) in
283 module type ViewSampler
=
285 val getyielder : unit -> unit -> float option
286 val update : float -> float -> float -> float -> unit
291 getyielder : unit -> unit -> float option;
292 update : float -> float -> float -> float -> unit;
305 val samplers
: sampler list
308 module View
(V
: sig val w : int val h : int end) = struct
313 let keyboard ~key ~x ~y
=
314 if key
= 27 || key
= Char.code 'q'
321 GlClear.clear
[`color
];
322 List.iter
(fun (display, _) -> display ()) !funcs;
328 List.iter
(fun (_, reshape) -> reshape w h) !funcs;
329 GlClear.clear
[`color
];
330 GlMat.mode `modelview
;
331 GlMat.load_identity
();
332 GlMat.mode `projection
;
333 GlMat.load_identity
();
334 GlMat.rotate ~y
:1.0 ~angle
:180.0 ();
335 GlMat.translate ~x
:~
-.1.0 ~y
:~
-.1.0 ();
336 GlMat.scale ~x
:2.0 ~y
:2.0 ();
337 Glut.postRedisplay
()
341 Glut.initDisplayMode ~double_buffer
:true ();
342 Glut.initWindowSize
V.w V.h
344 let _ = Glut.createWindow
"APC" in
345 Glut.displayFunc
display;
346 Glut.reshapeFunc
reshape;
347 Glut.keyboardFunc
keyboard;
348 GlDraw.color
(1.0, 1.0, 0.0)
353 let func = Glut.idleFunc
355 let run = Glut.mainLoop
358 module Bar
(T
: sig val barw : int val bars : int end) = struct
364 let sw = float T.barw /. float !Args.w
367 let fw = 3 * Glut.bitmapWidth
font (Char.code 'W'
)
372 bw := (float w *. sw |> truncate
) - m;
376 let kload = min
!kload 1.0 |> max
0.0 in
377 let iload = min
!iload 1.0 |> max
0.0 in
379 GlDraw.viewport
m 0 !bw 15;
380 GlDraw.color
(1.0, 1.0, 1.0);
381 let kload = 100.0 *. kload in
382 let iload = 100.0 *. iload in
385 GlMat.load_identity
();
386 GlMat.scale ~x
:(1.0/.float !bw) ~y
:(1.0/.30.0) ();
388 let ix = !bw / 2 - fw |> float in
389 let kx = - (fw + !bw / 2) |> float in
390 sprintf
"%5.2f" iload |> draw_string ix 0.0;
391 sprintf
"%5.2f" kload |> draw_string kx 0.0;
396 let h = !vh - 15 - y in
397 let () = GlDraw.viewport
m y !bw h in
401 GlMat.load_identity
();
402 GlMat.rotate ~
y:1.0 ~angle
:180.0 ();
403 GlMat.translate ~x
:~
-.1.0 ~
y:~
-.1.0 ();
404 GlMat.scale ~x
:2.0 ~
y:(2.0 /. float h) ()
408 let mspace = barm * nbars in
409 let barh = (h + 66 - mspace / 2) / nbars |> float in
410 let barm = float barm in
413 let drawbar xl xr load
=
414 let drawquads start lim
yb : float =
419 let yt = yb +. barh in
420 let yn = yt +. barm in
421 GlDraw.vertex2
(xl
, yb);
422 GlDraw.vertex2
(xl
, yt);
423 GlDraw.vertex2
(xr
, yt);
424 GlDraw.vertex2
(xr
, yb);
427 GlDraw.begins `quads
;
428 let yt = loop start
yb in
432 let lim = load
*. float nbars |> truncate
in
433 let yb = drawquads 0 lim yb in
434 GlDraw.color
(0.5, 0.5, 0.5);
435 ignore
(drawquads lim nbars yb)
439 GlDraw.color
(1.0, 1.0, 0.0);
443 GlDraw.color
(1.0, 0.0, 0.0);
445 GlDraw.color
(1.0, 1.0, 1.0);
449 let update kload'
iload'
=
450 kload := kload'
/. float NP.nprocs;
451 iload := iload'
/. float NP.nprocs;
455 module Graph
(V
: View
) = struct
456 let sw = float V.w /. float !Args.w
457 let sh = float V.h /. float !Args.h
458 let sx = float V.x
/. float V.w
459 let sy = float V.y /. float V.h
464 let fw = 3 * Glut.bitmapWidth
font (Char.code '
%'
)
466 let scale = V.freq /. V.interval
468 let base = GlList.gen_lists ~len
:1 in
469 GlList.nth
base ~
pos:0
474 | `labels
-> (!vx, !vy + 5, fw, !vh - 20)
475 | `graph
-> (!vx + fw + 5, !vy + 5, !vw - fw - 10, !vh - 20)
477 GlDraw.viewport x y w h
480 let scale = 1.0 /. float V.sgrid in
482 GlDraw.line_width
1.0;
483 GlDraw.color
(0.0, 1.0, 0.0);
484 GlDraw.begins `lines
;
487 let x = float i *. scale in
488 let x = if i = 0 then 0.0009 else x in
489 GlDraw.vertex ~
x ~
y:0.0 ();
490 GlDraw.vertex ~
x ~
y:1.0 ();
492 let lim = 100 / V.pgrid in
496 let y = (i * V.pgrid |> float) /. 100.0 in
497 let y = if i = lim then y -. 0.0009 else y in
498 GlDraw.vertex ~
x:0.0 ~
y ();
499 GlDraw.vertex ~
x:1.0 ~
y ();
505 GlDraw.color
(1.0, 1.0, 1.0);
508 for i = 0 to 100 / V.pgrid
510 let p = i * V.pgrid in
511 let y = float p /. ohp in
512 let s = Printf.sprintf
"%3d%%" p in
518 let wxsw = float w *. sw
519 and hxsh
= float h *. sh in
520 vw := wxsw |> truncate
;
521 vh := hxsh
|> truncate
;
522 vx := wxsw *. sx |> truncate
;
523 vy := hxsh
*. sy |> truncate
;
524 GlList.begins
gridlist `compile
;
530 Glut.swapBuffers
|> oohz !Args.delay;
535 GlList.call
gridlist;
536 GlDraw.line_width
1.5;
540 GlDraw.color sampler
.color
;
541 GlDraw.begins `line_strip
;
542 let yield = sampler
.getyielder () in
543 let rec loop last
i =
546 let x = float i *. scale in
547 GlDraw.vertex ~
x ~
y ();
549 | None
-> last
, succ
i
552 match loop None
0 with
555 let x = float i *. scale in
556 GlDraw.vertex ~
x ~
y ()
560 List.iter
sample V.samplers
562 let funcs = display, reshape
565 let getplacements w h n barw =
566 let sr = float n |> sqrt
|> ceil
|> truncate
in
568 let r = if n mod sr = 0 then 0 else 1 in
580 let rec loop accu
i =
586 let xc = xc * vw + barw in
588 (i, xc, yc) :: accu
|> loop |< succ
i
595 let freq = !Args.freq
596 let nsamples = !Args.interval /. freq |> ceil
|> truncate
599 let placements, vw, vh = getplacements w h NP.nprocs !Args.barw in
601 let iget () = NP.idletimeofday fd
NP.nprocs in
605 let gks = NP.parse_stat () in
606 gks () |> Array.of_list
610 let crgraph (kaccu
, iaccu
) (i, x, y) =
611 let module Si
= Sampler
(S
) in
613 { getyielder = Si.getyielder
614 ; color
= (1.0, 1.0, 0.0)
618 let (kcalc
, ksampler) =
619 let module Sc
= Sampler
(S
) in
621 { getyielder = Sc.getyielder
622 ; color
= (1.0, 0.0, 0.0)
627 let i'
= if i = NP.nprocs then 0 else succ
i in
631 let ks = Array.get
ks i'
|> snd
in
632 let user = Array.get
ks NP.user in
633 let nice = Array.get
ks NP.nice in
634 let _idle = Array.get
ks NP.idle in
635 NP.jiffies_to_sec (nice - user)
637 let i1 = g ks |> ref in
643 0.0, 1.0 -. (i2'
-. i1'
)
646 let g ks = Array.get
ks i'
|> snd
|> Array.get
|< n in
647 let i1 = g ks |> ref in
650 let i1'
= NP.jiffies_to_sec !i1
651 and i2'
= NP.jiffies_to_sec i2 in
664 let interval = !Args.interval
665 let pgrid = !Args.pgrid
666 let sgrid = !Args.sgrid
669 then [isampler; ksampler]
673 let module Graph
= Graph
(V
) in
675 let i1 = Array.get
is i |> ref in
677 let i2 = Array.get
is i in
681 let () = i1 := !i1 +. (t2
-. t1
) in
692 then (i, kcalc
, ksampler, Graph.funcs) :: kaccu
695 kaccu, (i, icalc, isampler, Graph.funcs) :: iaccu
697 let kl, il
= List.fold_left
crgraph ([], []) placements in
698 ((if kl == [] then (fun () -> [||]) else kget), kl), (iget, il
)
702 Unix.openfile path
[Unix.O_RDONLY
] 0
704 | Unix.Unix_error
(Unix.ENODEV
, s1
, s2
) ->
705 eprintf
"Could not open ITC device %S:\n%s(%s): %s)\n"
706 path s1 s2
|< Unix.error_message
Unix.ENODEV
;
707 eprintf
"(perhaps the module is not loaded?)@.";
710 | Unix.Unix_error
(Unix.ENOENT
, s1
, s2
) ->
711 eprintf
"Could not open ITC device %S:\n%s(%s): %s\n"
712 path s1 s2
|< Unix.error_message
Unix.ENOENT
;
716 let _ = Glut.init [|""|] in
717 let () = Args.init () in
718 let () = Delay.init () in
719 let () = if !Args.niceval != 0 then NP.setnice
!Args.niceval in
720 let () = if !Args.gzh then niceth NP.nprocs in
723 let fd = opendev !Args.devpath in
724 let module FullV
= View
(struct let w = w let h = h end) in
725 let () = FullV.init () in
726 let (kget, kfuncs
), (iget, ifuncs
) = create fd w h in
728 Bar
(struct let barw = !Args.barw let bars = !Args.bars end)
731 FullV.add (Bar.display, Bar.reshape);
732 List.iter
(fun (_, _, _, gfuncs
) -> FullV.add gfuncs
) kfuncs
;
733 List.iter
(fun (_, _, _, gfuncs
) -> FullV.add gfuncs
) ifuncs
;
736 let t2 = Unix.gettimeofday
() in
742 let rec loop2 load
s = function
744 | (nr
, calc, sampler, _) :: rest
->
745 let i1, i2 = calc s t1
t2 in
749 ("cpu load(" ^ string_of_int nr ^
"): "
750 ^
(100.0 -. ((i2 -. i1) /. d) *. 100.0 |> string_of_float
)
753 let load = load +. (1.0 -. ((i2 -. i1) /. d)) in
754 sampler.update t1
t2 i1 i2;
757 let iload = loop2 0.0 is ifuncs
in
758 let kload = loop2 0.0 ks kfuncs
in
759 Bar.update kload iload;
761 FullV.func (Some
(loop t2))
765 FullV.func (Some
(Unix.gettimeofday
() |> loop));
771 | Unix.Unix_error
(e
, s1
, s2
) ->
772 eprintf
"%s(%s): %s@." s1 s2
|< Unix.error_message e
775 Printexc.to_string exn
|> eprintf
"Exception: %s@."