diff options
Diffstat (limited to 'appl/wm/memory.b')
| -rw-r--r-- | appl/wm/memory.b | 246 |
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; +} |
