time: handle very large sleep durations

Fixes #4903.

R=golang-dev, daniel.morsing, dave, r
CC=golang-dev
https://golang.org/cl/7388056
diff --git a/src/pkg/time/sleep.go b/src/pkg/time/sleep.go
index 657b669..591fa27 100644
--- a/src/pkg/time/sleep.go
+++ b/src/pkg/time/sleep.go
@@ -22,6 +22,21 @@
 	arg    interface{}
 }
 
+// when is a helper function for setting the 'when' field of a runtimeTimer.
+// It returns what the time will be, in nanoseconds, Duration d in the future.
+// If d is negative, it is ignored.  If the returned value would be less than
+// zero because of an overflow, MaxInt64 is returned.
+func when(d Duration) int64 {
+	if d <= 0 {
+		return nano()
+	}
+	t := nano() + int64(d)
+	if t < 0 {
+		t = 1<<63 - 1 // math.MaxInt64
+	}
+	return t
+}
+
 func startTimer(*runtimeTimer)
 func stopTimer(*runtimeTimer) bool
 
@@ -49,7 +64,7 @@
 	t := &Timer{
 		C: c,
 		r: runtimeTimer{
-			when: nano() + int64(d),
+			when: when(d),
 			f:    sendTime,
 			arg:  c,
 		},
@@ -62,9 +77,9 @@
 // It returns true if the timer had been active, false if the timer had
 // expired or been stopped.
 func (t *Timer) Reset(d Duration) bool {
-	when := nano() + int64(d)
+	w := when(d)
 	active := stopTimer(&t.r)
-	t.r.when = when
+	t.r.when = w
 	startTimer(&t.r)
 	return active
 }
@@ -94,7 +109,7 @@
 func AfterFunc(d Duration, f func()) *Timer {
 	t := &Timer{
 		r: runtimeTimer{
-			when: nano() + int64(d),
+			when: when(d),
 			f:    goFunc,
 			arg:  f,
 		},