add time.Tick()

R=r
DELTA=130  (115 added, 1 deleted, 14 changed)
OCL=20376
CL=20385
diff --git a/src/lib/syscall/time_amd64_darwin.go b/src/lib/syscall/time_amd64_darwin.go
index 011933b..7be6d66 100644
--- a/src/lib/syscall/time_amd64_darwin.go
+++ b/src/lib/syscall/time_amd64_darwin.go
@@ -16,3 +16,9 @@
 	}
 	return r1, r2*1000, 0
 }
+
+export func nstotimeval(ns int64, tv *Timeval) {
+	ns += 999;	// round up
+	tv.sec = int64(ns/1000000000);
+	tv.usec = uint32(ns%1000000000 / 1000);
+}
diff --git a/src/lib/syscall/time_amd64_linux.go b/src/lib/syscall/time_amd64_linux.go
index 43b0501..f9b5f01 100644
--- a/src/lib/syscall/time_amd64_linux.go
+++ b/src/lib/syscall/time_amd64_linux.go
@@ -14,3 +14,9 @@
 	}
 	return int64(tv.sec), int64(tv.usec*1000), 0
 }
+
+export func nstotimeval(ns int64, tv *Timeval) {
+	ns += 999;	// round up
+	tv.sec = int64(ns/1000000000);
+	tv.usec = uint64(ns%1000000000 / 1000);
+}
diff --git a/src/lib/time/Makefile b/src/lib/time/Makefile
index d397be1..9f42265a 100644
--- a/src/lib/time/Makefile
+++ b/src/lib/time/Makefile
@@ -2,34 +2,70 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
+# DO NOT EDIT.  Automatically generated by gobuild.
+# gobuild -m >Makefile
 O=6
 GC=$(O)g
+CC=$(O)c -w
+AS=$(O)a
+AR=$(O)ar
 
-PKG=$(GOROOT)/pkg/time.a
+default: packages
+
+clean:
+	rm -f *.$O *.a $O.out
+
+test: packages
+	gotest
+
+coverage: packages
+	gotest
+	6cov -g `pwd` | grep -v '_test\.go:'
+
+%.$O: %.go
+	$(GC) $*.go
+
+%.$O: %.c
+	$(CC) $*.c
+
+%.$O: %.s
+	$(AS) $*.s
 
 O1=\
-	zoneinfo.$O
+	zoneinfo.$O\
+
 O2=\
 	time.$O\
 
-install: nuke $(PKG)
+O3=\
+	tick.$O\
 
-$(PKG): a1 a2
+time.a: a1 a2 a3
 
-a1: 	$(O1)
-	$(O)ar grc $(PKG) $(O1)
+a1:	$(O1)
+	$(AR) grc time.a zoneinfo.$O
+	rm -f $(O1)
 
-a2: 	$(O2)
-	$(O)ar grc $(PKG) $(O2)
+a2:	$(O2)
+	$(AR) grc time.a time.$O
+	rm -f $(O2)
 
-$(O1): nuke
+a3:	$(O3)
+	$(AR) grc time.a tick.$O
+	rm -f $(O3)
+
+newpkg: clean
+	$(AR) grc time.a
+
+$(O1): newpkg
 $(O2): a1
+$(O3): a2
 
-nuke:
-	rm -f *.$(O) *.a $(PKG)
+nuke: clean
+	rm -f $(GOROOT)/pkg/time.a
 
-clean:
-	rm -f *.$(O) *.a
+packages: time.a
 
-%.$O:	%.go
-	$(GC) $<
+install: packages
+	cp time.a $(GOROOT)/pkg/time.a
+
diff --git a/src/lib/time/tick.go b/src/lib/time/tick.go
new file mode 100644
index 0000000..efd5ceb
--- /dev/null
+++ b/src/lib/time/tick.go
@@ -0,0 +1,42 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time
+
+import (
+	"syscall";
+	"time"
+)
+
+// TODO(rsc): This implementation of time.Tick is a
+// simple placeholder.  Eventually, there will need to be
+// a single central time server no matter how many tickers
+// are active.  There also needs to be a way to cancel a ticker.
+//
+// Also, if timeouts become part of the select statement,
+// perhaps the Ticker is just:
+//
+//	func Ticker(ns int64, c *chan int64) {
+//		for {
+//			select { timeout ns: }
+//			nsec, err := time.Nanoseconds();
+//			c <- nsec;
+//		}
+
+func Ticker(ns int64, c *chan int64) {
+	var tv syscall.Timeval;
+	for {
+		syscall.nstotimeval(ns, &tv);
+		syscall.Syscall6(syscall.SYS_SELECT, 0, 0, 0, 0, syscall.TimevalPtr(&tv), 0);
+		nsec, err := time.Nanoseconds();
+		c <- nsec;
+	}
+}
+
+export func Tick(ns int64) *chan int64 {
+	c := new(chan int64);
+	go Ticker(ns, c);
+	return c;
+}
+
diff --git a/src/lib/time/tick_test.go b/src/lib/time/tick_test.go
new file mode 100644
index 0000000..9530f62
--- /dev/null
+++ b/src/lib/time/tick_test.go
@@ -0,0 +1,29 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time
+
+import (
+	"testing";
+	"time";
+)
+
+export func TestTick(t *testing.T) {
+	const (
+		Delta uint64 = 10*1e6;
+		Count uint64 = 10;
+	);
+	c := Tick(Delta);
+	t0, err := Nanoseconds();
+	for i := 0; i < Count; i++ {
+		<-c;
+	}
+	t1, err1 := Nanoseconds();
+	ns := t1 - t0;
+	target := int64(Delta*Count);
+	slop := target*2/10;
+	if ns < target - slop || ns > target + slop {
+		t.Fatalf("%d ticks of %d ns took %d ns, expected %d", Count, Delta, ns, target);
+	}
+}