summaryrefslogtreecommitdiff
path: root/src/lib/time/tick.go
blob: 53e2234f89c80fa243ba9deefc465b0c9acd06ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 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";
	"unsafe";
)

// 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;
	now := time.Nanoseconds();
	when := now;
	for {
		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
		}

		time.Sleep(when - now);
		now = time.Nanoseconds();
		c <- now;
	}
}

// Tick creates a synchronous channel that will send the time, in nanoseconds,
// every ns nanoseconds.  It adjusts the intervals to make up for pauses in
// delivery of the ticks.
func Tick(ns int64) chan int64 {
	if ns <= 0 {
		return nil
	}
	c := make(chan int64);
	go ticker(ns, c);
	return c;
}