blob: d8f7eae09d60791884600f8c8307dddc704f6094 [file] [log] [blame]
Russ Coxc7bab462008-12-03 16:40:00 -08001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package time
6
7import (
8 "syscall";
9 "time"
10)
11
12// TODO(rsc): This implementation of time.Tick is a
13// simple placeholder. Eventually, there will need to be
14// a single central time server no matter how many tickers
15// are active. There also needs to be a way to cancel a ticker.
16//
17// Also, if timeouts become part of the select statement,
18// perhaps the Ticker is just:
19//
20// func Ticker(ns int64, c *chan int64) {
21// for {
22// select { timeout ns: }
23// nsec, err := time.Nanoseconds();
24// c <- nsec;
25// }
26
27func Ticker(ns int64, c *chan int64) {
28 var tv syscall.Timeval;
Russ Cox6478df12008-12-08 17:45:50 -080029 now := time.Nanoseconds();
30 when := now;
Russ Coxc7bab462008-12-03 16:40:00 -080031 for {
Russ Cox6478df12008-12-08 17:45:50 -080032 when += ns; // next alarm
33
34 // if c <- now took too long, skip ahead
35 if when < now {
36 // one big step
37 when += (now-when)/ns * ns;
38 }
39 for when <= now {
40 // little steps until when > now
41 when += ns
42 }
43
44 syscall.nstotimeval(when - now, &tv);
Russ Coxc7bab462008-12-03 16:40:00 -080045 syscall.Syscall6(syscall.SYS_SELECT, 0, 0, 0, 0, syscall.TimevalPtr(&tv), 0);
Russ Cox6478df12008-12-08 17:45:50 -080046 now = time.Nanoseconds();
47 c <- now;
Russ Coxc7bab462008-12-03 16:40:00 -080048 }
49}
50
51export func Tick(ns int64) *chan int64 {
Russ Cox6478df12008-12-08 17:45:50 -080052 if ns <= 0 {
53 return nil
54 }
Russ Coxc7bab462008-12-03 16:40:00 -080055 c := new(chan int64);
56 go Ticker(ns, c);
57 return c;
58}
59