]> Cypherpunks repositories - gostls13.git/commitdiff
avoid skew in time.Tick; remove errors from time.Seconds, time.Nanoseconds
authorRuss Cox <rsc@golang.org>
Tue, 9 Dec 2008 01:45:50 +0000 (17:45 -0800)
committerRuss Cox <rsc@golang.org>
Tue, 9 Dec 2008 01:45:50 +0000 (17:45 -0800)
R=r
DELTA=46  (21 added, 10 deleted, 15 changed)
OCL=20785
CL=20787

src/lib/time/tick.go
src/lib/time/tick_test.go
src/lib/time/time.go

index efd5ceb256735c10e9e6078e2f3b01381615741e..d8f7eae09d60791884600f8c8307dddc704f6094 100644 (file)
@@ -26,15 +26,32 @@ import (
 
 func Ticker(ns int64, c *chan int64) {
        var tv syscall.Timeval;
+       now := time.Nanoseconds();
+       when := now;
        for {
-               syscall.nstotimeval(ns, &tv);
+               when += ns;     // next alarm
+               
+               // if c <- now took too long, skip ahead
+               if when < now {
+                       // one big step
+                       when += (now-when)/ns * ns;
+               }
+               for when <= now {
+                       // little steps until when > now
+                       when += ns
+               }
+
+               syscall.nstotimeval(when - now, &tv);
                syscall.Syscall6(syscall.SYS_SELECT, 0, 0, 0, 0, syscall.TimevalPtr(&tv), 0);
-               nsec, err := time.Nanoseconds();
-               c <- nsec;
+               now = time.Nanoseconds();
+               c <- now;
        }
 }
 
 export func Tick(ns int64) *chan int64 {
+       if ns <= 0 {
+               return nil
+       }
        c := new(chan int64);
        go Ticker(ns, c);
        return c;
index 9530f627789740c8f4c20f8c71e408b5e3f10e50..f9b18fc1d9e636ba48a59b4b01ae5f8f59ea8322 100644 (file)
@@ -15,11 +15,11 @@ export func TestTick(t *testing.T) {
                Count uint64 = 10;
        );
        c := Tick(Delta);
-       t0, err := Nanoseconds();
+       t0 := Nanoseconds();
        for i := 0; i < Count; i++ {
                <-c;
        }
-       t1, err1 := Nanoseconds();
+       t1 := Nanoseconds();
        ns := t1 - t0;
        target := int64(Delta*Count);
        slop := target*2/10;
index b539c385a6b78f30880a9f268f902de3ba3a03e1..e71e73b2eff552cbd7a0c681ac04b91e03d967e4 100644 (file)
@@ -10,17 +10,21 @@ import (
 )
 
 // Seconds since January 1, 1970 00:00:00 GMT
-export func Seconds() (sec int64, err *os.Error) {
-       var nsec int64;
-       sec, nsec, err = os.Time();
-       return sec, err
+export func Seconds() int64 {
+       sec, nsec, err := os.Time();
+       if err != nil {
+               panic("time: os.Time: ", err.String());
+       }
+       return sec
 }
 
 // Nanoseconds since January 1, 1970 00:00:00 GMT
-export func Nanoseconds() (nsec int64, err *os.Error) {
-       var sec int64;
-       sec, nsec, err = os.Time();
-       return sec*1e9 + nsec, err
+export func Nanoseconds() int64 {
+       sec, nsec, err := os.Time();
+       if err != nil {
+               panic("time: os.Time: ", err.String());
+       }
+       return sec*1e9 + nsec
 }
 
 export const (
@@ -142,12 +146,7 @@ export func SecondsToUTC(sec int64) *Time {
 }
 
 export func UTC() (t *Time, err *os.Error) {
-       var sec int64;
-       sec, err = Seconds();
-       if err != nil {
-               return nil, err
-       }
-       return SecondsToUTC(sec), nil
+       return SecondsToUTC(Seconds()), nil
 }
 
 // TODO: Should this return an error?
@@ -163,12 +162,7 @@ export func SecondsToLocalTime(sec int64) *Time {
 }
 
 export func LocalTime() (t *Time, err *os.Error) {
-       var sec int64;
-       sec, err = Seconds();
-       if err != nil {
-               return nil, err
-       }
-       return SecondsToLocalTime(sec), nil
+       return SecondsToLocalTime(Seconds()), nil
 }
 
 // Compute number of seconds since January 1, 1970.