diff options
Diffstat (limited to 'appl/grid/demo/block.b')
| -rw-r--r-- | appl/grid/demo/block.b | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/appl/grid/demo/block.b b/appl/grid/demo/block.b new file mode 100644 index 00000000..7f091289 --- /dev/null +++ b/appl/grid/demo/block.b @@ -0,0 +1,212 @@ +implement Block; + +include "sys.m"; + sys : Sys; +include "daytime.m"; + daytime: Daytime; +include "draw.m"; + draw: Draw; + Chans, Context, Display, Point, Rect, Image, Screen, Font: import draw; +include "readdir.m"; + readdir: Readdir; +include "grid/demo/exproc.m"; + exproc: Exproc; +include "grid/demo/block.m"; + +timeout := 50; +WAITING: con -1; +DONE: con -2; +path := ""; + +init(pathname: string, ep: Exproc) +{ + sys = load Sys Sys->PATH; + if (sys == nil) + badmod(Sys->PATH); + draw = load Draw Draw->PATH; + if (draw == nil) + badmod(Draw->PATH); + daytime = load Daytime Daytime->PATH; + if (daytime == nil) + badmod(Daytime->PATH); + readdir = load Readdir Readdir->PATH; + if (readdir == nil) + badmod(Readdir->PATH); + if (pathname == "") + err("no path given"); + if (pathname[len pathname - 1] != '/') + pathname[len pathname] = '/'; + path = pathname; + exproc = ep; + if (exproc == nil) + badmod("Exproc"); + sys->create(path, sys->OREAD, 8r777 | sys->DMDIR); + (n, nil) := sys->stat(path); + if (n == -1) + sys->print("Cannot find path: %s\n",path); +} + +slave() +{ + buf := array[8192] of byte; + for(;;) { + (n, nil) := sys->stat(path+"working"); + if (n == -1) + sys->sleep(1000); + else { + fd := sys->open(path + "data.dat", sys->OREAD); + if (fd != nil) { + s := ""; + for (;;) { + i := sys->read(fd, buf, len buf); + if (i < 1) + break; + s += string buf[:i]; + } + (nil, lst) := sys->tokenize(s, "\n"); + exproc->getslavedata(lst); + break; + } + } + } + doneblocks := 0; + loop: for (;;) { + (dirs, nil) := readdir->init(path+"todo", readdir->NAME); + if (len dirs == 0) { + (n, nil) := sys->stat(path + "working"); + if (n == -1) + break loop; + sys->sleep(2000); + } + for (i := 0; i < len dirs; i++) { + fd := sys->create(path+dirs[i].name, sys->OREAD, 8r777 | sys->DMDIR); + if (fd != nil) { + (nil, lst) := sys->tokenize(dirs[i].name, "."); + exproc->doblock(int hd tl lst, dirs[i].name); + doneblocks++; + } + (n, nil) := sys->stat(path + "working"); + if (n == -1) + break loop; + } + } + sys->print("Finished: %d blocks\n",doneblocks); +} + +writedata(s: string) +{ + fd := sys->create(path+"data.dat", sys->OWRITE, 8r666); + if (fd != nil) + sys->fprint(fd, "%s", s); + else + err("could not create data.dat"); + fd = nil; +} + +masterinit(noblocks: int) +{ + sys->create(path+"todo", sys->OREAD, 8r777 | sys->DMDIR); + sys->create(path+"working", sys->OWRITE, 8r666); + for (i := 0; i < noblocks; i++) + makefile(i, ""); +} + +reader(noblocks: int, chanout: chan of string, sync: chan of int) +{ + sync <-= sys->pctl(0,nil); + starttime := daytime->now(); + times := array[noblocks] of { * => WAITING }; + let := array[noblocks] of { * => "a" }; + buf := array[50] of byte; + result := 0; + for (;;) { + nodone := 0; + for (i := 0; i < noblocks; i++) { + if (times[i] != DONE) { + (n,nil) := sys->stat(path+"block."+string i+"."+let[i]+"/done"); + if (n == -1) { + (n2, nil) := sys->stat(path+"block."+string i+"."+let[i]); + if (n2 != -1) { + now := daytime->now(); + if (times[i] == WAITING) + times[i] = now; + else if (now - times[i] > timeout) { + let[i] = makefile(i, let[i]); + times[i] = WAITING; + } + } + } + else { + sys->remove(path +"todo/block."+string i+"."+let[i]); + if (exproc->readblock(i, path+"block."+string i+"."+let[i]+"/", chanout) == -1) { + let[i] = makefile(i, let[i]); + times[i] = WAITING; + } + else { + times[i] = DONE; + nodone++; + } + } + } + else + nodone++; + } + if (nodone == noblocks) + break; + chanout <-= string ((nodone*100)/noblocks); + sys->sleep(1000); + } + endtime := daytime->now(); + chanout <-= "100"; + spawn exproc->finish(endtime - starttime, chanout); +} + +makefile(block: int, let: string): string +{ + if (let == "") + let = "a"; + else { + sys->remove(path +"todo/block."+string block+"."+let); + let[0]++; + } + name := path+"todo/block."+string block+"."+let; + fd := sys->create(name, sys->OREAD, 8r666); + if (fd == nil) + sys->print("Error creating: '%s'\n",name); + return let; +} + +err(s: string) +{ + sys->print("Error: '%s'\n",s); + exit; +} + +cleanfiles(delpath: string) +{ + buf := array[8192] of byte; + if (delpath == "") + return; + if (delpath[len delpath - 1] != '/') + delpath[len delpath] = '/'; + (dirs, n) := readdir->init(delpath, readdir->NAME); + for (i := 0; i < len dirs; i++) { + if (dirs[i].mode & sys->DMDIR) + cleanfiles(delpath+dirs[i].name+"/"); + sys->remove(delpath+dirs[i].name); + } +} + +isin(l: list of string, s: string): int +{ + for(tmpl := l; tmpl != nil; tmpl = tl tmpl) + if (hd tmpl == s) + return 1; + return 0; +} + +badmod(path: string) +{ + sys->print("Block: failed to load: %s\n",path); + exit; +}
\ No newline at end of file |
