xref: /inferno-os/appl/cmd/time.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Time;
2
3include "sys.m";
4include "draw.m";
5include "sh.m";
6
7FD: import Sys;
8Context: import Draw;
9
10Time: module
11{
12	init:	fn(ctxt: ref Context, argv: list of string);
13};
14
15sys: Sys;
16stderr, waitfd: ref FD;
17
18init(ctxt: ref Context, argv: list of string)
19{
20	sys = load Sys Sys->PATH;
21
22	stderr = sys->fildes(2);
23
24	waitfd = sys->open("#p/"+string sys->pctl(0, nil)+"/wait", sys->OREAD);
25	if(waitfd == nil){
26		sys->fprint(stderr, "time: open wait: %r\n");
27		return;
28	}
29
30	argv = tl argv;
31
32	if(argv == nil) {
33		sys->fprint(stderr, "usage: time cmd ...\n");
34		return;
35	}
36
37	file := hd argv;
38
39	if(len file<4 || file[len file-4:]!=".dis")
40		file += ".dis";
41
42	t0 := sys->millisec();
43
44	c := load Command file;
45	if(c == nil) {
46		err := sys->sprint("%r");
47		if(1){
48			c = load Command "/dis/"+file;
49			if(c == nil)
50				err = sys->sprint("%r");
51		}
52		if(c == nil) {
53			sys->fprint(stderr, "time: %s: %s\n", hd argv, err);
54			return;
55		}
56	}
57
58	t1 := sys->millisec();
59
60	pidc := chan of int;
61
62	spawn cmd(ctxt, c, pidc, argv);
63	waitfor(<-pidc);
64
65	t2 := sys->millisec();
66
67	f1 := real (t1 - t0) /1000.;
68	f2 := real (t2 - t1) /1000.;
69	sys->fprint(stderr, "%.4gl %.4gr %.4gt\n", f1, f2, f1+f2);
70}
71
72cmd(ctxt: ref Context, c: Command, pidc: chan of int, argv: list of string)
73{
74	pidc <-= sys->pctl(0, nil);
75	c->init(ctxt, argv);
76}
77
78waitfor(pid: int)
79{
80	buf := array[sys->WAITLEN] of byte;
81	status := "";
82	for(;;){
83		n := sys->read(waitfd, buf, len buf);
84		if(n < 0) {
85			sys->fprint(stderr, "sh: read wait: %r\n");
86			return;
87		}
88		status = string buf[0:n];
89		if(status[len status-1] != ':')
90			sys->fprint(stderr, "%s\n", status);
91		who := int status;
92		if(who != 0) {
93			if(who == pid)
94				return;
95		}
96	}
97}
98