summaryrefslogtreecommitdiff
path: root/appl/wm/memory.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/wm/memory.b')
-rw-r--r--appl/wm/memory.b246
1 files changed, 246 insertions, 0 deletions
diff --git a/appl/wm/memory.b b/appl/wm/memory.b
new file mode 100644
index 00000000..6bbfa68b
--- /dev/null
+++ b/appl/wm/memory.b
@@ -0,0 +1,246 @@
+implement WmMemory;
+
+include "sys.m";
+ sys: Sys;
+
+include "draw.m";
+ draw: Draw;
+ Display, Image, Rect: import draw;
+
+include "tk.m";
+ tk: Tk;
+ t: ref Tk->Toplevel;
+
+include "tkclient.m";
+ tkclient: Tkclient;
+
+WmMemory: module
+{
+ init: fn(ctxt: ref Draw->Context, argv: list of string);
+};
+
+Arena: adt
+{
+ name: string;
+ limit: int;
+ size: int;
+ hw: int;
+ allocs: int;
+ frees: int;
+ exts: int;
+ chunk: int;
+ y: int;
+ tag: string;
+ tagsz: string;
+ taghw: string;
+ tagiu: string;
+};
+a := array[10] of Arena;
+
+mem_cfg := array[] of {
+ "canvas .c -width 240 -height 45",
+ "pack .c",
+ "update",
+};
+
+init(ctxt: ref Draw->Context, nil: list of string)
+{
+ spawn realinit(ctxt);
+}
+
+realinit(ctxt: ref Draw->Context)
+{
+ sys = load Sys Sys->PATH;
+ if (ctxt == nil) {
+ sys->fprint(sys->fildes(2), "memory: no window context\n");
+ raise "fail:bad context";
+ }
+ draw = load Draw Draw->PATH;
+ tk = load Tk Tk->PATH;
+ tkclient = load Tkclient Tkclient->PATH;
+ sys->pctl(Sys->NEWPGRP, nil);
+ tkclient->init();
+
+ menubut := chan of string;
+ (t, menubut) = tkclient->toplevel(ctxt, "", "Memory", 0);
+ for(j := 0; j < len mem_cfg; j++)
+ cmd(t, mem_cfg[j]);
+ tkclient->startinput(t, "ptr"::nil);
+ tkclient->onscreen(t, nil);
+
+ tick := chan of int;
+ spawn ticker(tick);
+
+ mfd := sys->open("/dev/memory", sys->OREAD);
+
+ n := getmem(mfd);
+ maxx := initdraw(n);
+
+ pid: int;
+ for(;;) alt {
+ s := <-t.ctxt.ptr =>
+ tk->pointer(t, *s);
+ s := <-t.ctxt.ctl or
+ s = <-t.wreq or
+ s = <-menubut =>
+ if(s == "exit"){
+ kill(pid);
+ return;
+ }
+ tkclient->wmctl(t, s);
+ pid = <-tick =>
+ update(mfd);
+ for(i := 0; i < n; i++) {
+ if(a[i].limit <= 0)
+ continue;
+ x := int ((big a[i].size * big (230-maxx)) / big a[i].limit);
+ s := sys->sprint(".c coords %s %d %d %d %d",
+ a[i].tag,
+ maxx,
+ a[i].y + 4,
+ maxx + x,
+ a[i].y + 8);
+ cmd(t, s);
+ x = int ((big a[i].hw * big (230-maxx)) / big a[i].limit);
+ s = sys->sprint(".c coords %s %d %d %d %d",
+ a[i].taghw,
+ maxx,
+ a[i].y + 4,
+ maxx+x,
+ a[i].y + 8);
+ cmd(t, s);
+ s = sys->sprint(".c itemconfigure %s -text '%s", a[i].tagsz, string a[i].size);
+ cmd(t, s);
+ s = sys->sprint(".c itemconfigure %s -text '%d", a[i].tagiu, a[i].allocs-a[i].frees);
+ cmd(t, s);
+ }
+ cmd(t, "update");
+ }
+}
+
+ticker(c: chan of int)
+{
+ pid := sys->pctl(0, nil);
+ for(;;) {
+ c <-= pid;
+ sys->sleep(1000);
+ }
+}
+
+initdraw(n: int): int
+{
+ y := 15;
+ maxx := 0;
+ for (i := 0; i < n; i++) {
+ id := cmd(t, ".c create text 5 "+string y+" -anchor w -text "+a[i].name);
+ r := s2r(cmd(t, ".c bbox " + id));
+ if (r.max.x > maxx)
+ maxx = r.max.x;
+ y += 20;
+ }
+ maxx += 5;
+ y = 15;
+ for(i = 0; i < n; i++) {
+ s := sys->sprint(".c create rectangle %d %d 230 %d -fill white", maxx, y+4, y+8);
+ cmd(t, s);
+ s = sys->sprint(".c create rectangle %d %d 230 %d -fill white", maxx, y+4, y+8);
+ a[i].taghw = cmd(t, s);
+ s = sys->sprint(".c create rectangle %d %d 230 %d -fill red", maxx, y+4, y+8);
+ a[i].tag = cmd(t, s);
+ s = sys->sprint(".c create text 230 %d -anchor e -text '%s", y - 2, sizestr(a[i].limit));
+ cmd(t, s);
+ s = sys->sprint(".c create text %d %d -anchor w -text '%s", maxx, y - 2, string a[i].size);
+ a[i].tagsz = cmd(t, s);
+ s = sys->sprint(".c create text 120 %d -fill red -anchor w -text '%d", y - 2, a[i].allocs-a[i].frees);
+ a[i].tagiu = cmd(t, s);
+ a[i].y = y;
+ y += 20;
+ }
+ cmd(t, ".c configure -height "+string y);
+ cmd(t, "update");
+ return maxx;
+}
+
+sizestr(n: int): string
+{
+ if ((n / 1024) % 1024 == 0)
+ return string (n / (1024 * 1024)) + "M";
+ return string (n / 1024) + "K";
+}
+
+buf := array[8192] of byte;
+
+update(mfd: ref Sys->FD): int
+{
+ sys->seek(mfd, big 0, Sys->SEEKSTART);
+ n := sys->read(mfd, buf, len buf);
+ if(n <= 0)
+ exit;
+ (nil, l) := sys->tokenize(string buf[0:n], "\n");
+ i := 0;
+ while(l != nil) {
+ s := hd l;
+ a[i].size = int s[0:];
+ a[i].hw = int s[24:];
+ a[i].allocs = int s[3*12:];
+ a[i].frees = int s[4*12:];
+ a[i].exts = int s[5*12:];
+ a[i++].chunk = int s[6*12:];
+ l = tl l;
+ }
+ return i;
+}
+
+getmem(mfd: ref Sys->FD): int
+{
+ n := sys->read(mfd, buf, len buf);
+ if(n <= 0)
+ exit;
+ (nil, l) := sys->tokenize(string buf[0:n], "\n");
+ i := 0;
+ while(l != nil) {
+ s := hd l;
+ a[i].size = int s[0:];
+ a[i].limit = int s[12:];
+ a[i].hw = int s[2*12:];
+ a[i].allocs = int s[3*12:];
+ a[i].frees = int s[4*12:];
+ a[i].exts = int s[5*12:];
+ a[i].chunk = int s[6*12:];
+ a[i].name = s[7*12:];
+ i++;
+ l = tl l;
+ }
+ return i;
+}
+
+s2r(s: string): Rect
+{
+ (n, toks) := sys->tokenize(s, " ");
+ if (n != 4) {
+ sys->print("'%s' is not a rectangle!\n", s);
+ raise "bad conversion";
+ }
+ r: Rect;
+ (r.min.x, toks) = (int hd toks, tl toks);
+ (r.min.y, toks) = (int hd toks, tl toks);
+ (r.max.x, toks) = (int hd toks, tl toks);
+ (r.max.y, toks) = (int hd toks, tl toks);
+ return r;
+}
+
+kill(pid: int)
+{
+ fd := sys->open("#p/"+string pid+"/ctl", sys->OWRITE);
+ if(fd != nil)
+ sys->fprint(fd, "kill");
+}
+
+
+cmd(top: ref Tk->Toplevel, s: string): string
+{
+ e := tk->cmd(top, s);
+ if (e != nil && e[0] == '!')
+ sys->print("memory: tk error on '%s': %s\n", s, e);
+ return e;
+}