gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/kernel/time/time.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package time defines the Timer type, which provides a periodic timer that
    16  // works by sampling a user-provided clock.
    17  package time
    18  
    19  import (
    20  	"fmt"
    21  	"math"
    22  	"time"
    23  
    24  	"gvisor.dev/gvisor/pkg/abi/linux"
    25  	"gvisor.dev/gvisor/pkg/errors/linuxerr"
    26  	"gvisor.dev/gvisor/pkg/sync"
    27  	"gvisor.dev/gvisor/pkg/waiter"
    28  )
    29  
    30  // Events that may be generated by a Clock.
    31  const (
    32  	// ClockEventSet occurs when a Clock undergoes a discontinuous change.
    33  	ClockEventSet waiter.EventMask = 1 << iota
    34  
    35  	// ClockEventRateIncrease occurs when the rate at which a Clock advances
    36  	// increases significantly, such that values returned by previous calls to
    37  	// Clock.WallTimeUntil may be too large.
    38  	ClockEventRateIncrease
    39  )
    40  
    41  // Time represents an instant in time with nanosecond precision.
    42  //
    43  // Time may represent time with respect to any clock and may not have any
    44  // meaning in the real world.
    45  //
    46  // +stateify savable
    47  type Time struct {
    48  	ns int64
    49  }
    50  
    51  var (
    52  	// MinTime is the zero time instant, the lowest possible time that can
    53  	// be represented by Time.
    54  	MinTime = Time{ns: math.MinInt64}
    55  
    56  	// MaxTime is the highest possible time that can be represented by
    57  	// Time.
    58  	MaxTime = Time{ns: math.MaxInt64}
    59  
    60  	// ZeroTime represents the zero time in an unspecified Clock's domain.
    61  	ZeroTime = Time{ns: 0}
    62  )
    63  
    64  const (
    65  	// MinDuration is the minimum duration representable by time.Duration.
    66  	MinDuration = time.Duration(math.MinInt64)
    67  
    68  	// MaxDuration is the maximum duration representable by time.Duration.
    69  	MaxDuration = time.Duration(math.MaxInt64)
    70  )
    71  
    72  // FromNanoseconds returns a Time representing the point ns nanoseconds after
    73  // an unspecified Clock's zero time.
    74  func FromNanoseconds(ns int64) Time {
    75  	return Time{ns}
    76  }
    77  
    78  // FromSeconds returns a Time representing the point s seconds after an
    79  // unspecified Clock's zero time.
    80  func FromSeconds(s int64) Time {
    81  	if s > math.MaxInt64/time.Second.Nanoseconds() {
    82  		return MaxTime
    83  	}
    84  	return Time{s * 1e9}
    85  }
    86  
    87  // FromUnix converts from Unix seconds and nanoseconds to Time, assuming a real
    88  // time Unix clock domain.
    89  func FromUnix(s int64, ns int64) Time {
    90  	if s > math.MaxInt64/time.Second.Nanoseconds() {
    91  		return MaxTime
    92  	}
    93  	t := s * 1e9
    94  	if t > math.MaxInt64-ns {
    95  		return MaxTime
    96  	}
    97  	return Time{t + ns}
    98  }
    99  
   100  // FromTimespec converts from Linux Timespec to Time.
   101  func FromTimespec(ts linux.Timespec) Time {
   102  	return Time{ts.ToNsecCapped()}
   103  }
   104  
   105  // FromTimeval converts a Linux Timeval to Time.
   106  func FromTimeval(tv linux.Timeval) Time {
   107  	return Time{tv.ToNsecCapped()}
   108  }
   109  
   110  // Nanoseconds returns nanoseconds elapsed since the zero time in t's Clock
   111  // domain. If t represents walltime, this is nanoseconds since the Unix epoch.
   112  func (t Time) Nanoseconds() int64 {
   113  	return t.ns
   114  }
   115  
   116  // Microseconds returns microseconds elapsed since the zero time in t's Clock
   117  // domain. If t represents walltime, this is microseconds since the Unix epoch.
   118  func (t Time) Microseconds() int64 {
   119  	return t.ns / 1000
   120  }
   121  
   122  // Seconds returns seconds elapsed since the zero time in t's Clock domain. If
   123  // t represents walltime, this is seconds since Unix epoch.
   124  func (t Time) Seconds() int64 {
   125  	return t.Nanoseconds() / time.Second.Nanoseconds()
   126  }
   127  
   128  // Timespec converts Time to a Linux timespec.
   129  func (t Time) Timespec() linux.Timespec {
   130  	return linux.NsecToTimespec(t.Nanoseconds())
   131  }
   132  
   133  // Unix returns the (seconds, nanoseconds) representation of t such that
   134  // seconds*1e9 + nanoseconds = t.
   135  func (t Time) Unix() (s int64, ns int64) {
   136  	s = t.ns / 1e9
   137  	ns = t.ns % 1e9
   138  	return
   139  }
   140  
   141  // TimeT converts Time to a Linux time_t.
   142  func (t Time) TimeT() linux.TimeT {
   143  	return linux.NsecToTimeT(t.Nanoseconds())
   144  }
   145  
   146  // Timeval converts Time to a Linux timeval.
   147  func (t Time) Timeval() linux.Timeval {
   148  	return linux.NsecToTimeval(t.Nanoseconds())
   149  }
   150  
   151  // StatxTimestamp converts Time to a Linux statx_timestamp.
   152  func (t Time) StatxTimestamp() linux.StatxTimestamp {
   153  	return linux.NsecToStatxTimestamp(t.Nanoseconds())
   154  }
   155  
   156  // Add adds the duration of d to t.
   157  func (t Time) Add(d time.Duration) Time {
   158  	if t.ns > 0 && d.Nanoseconds() > math.MaxInt64-int64(t.ns) {
   159  		return MaxTime
   160  	}
   161  	if t.ns < 0 && d.Nanoseconds() < math.MinInt64-int64(t.ns) {
   162  		return MinTime
   163  	}
   164  	return Time{int64(t.ns) + d.Nanoseconds()}
   165  }
   166  
   167  // AddTime adds the duration of u to t.
   168  func (t Time) AddTime(u Time) Time {
   169  	return t.Add(time.Duration(u.ns))
   170  }
   171  
   172  // Equal reports whether the two times represent the same instant in time.
   173  func (t Time) Equal(u Time) bool {
   174  	return t.ns == u.ns
   175  }
   176  
   177  // Before reports whether the instant t is before the instant u.
   178  func (t Time) Before(u Time) bool {
   179  	return t.ns < u.ns
   180  }
   181  
   182  // After reports whether the instant t is after the instant u.
   183  func (t Time) After(u Time) bool {
   184  	return t.ns > u.ns
   185  }
   186  
   187  // Sub returns the duration of t - u.
   188  //
   189  // N.B. This measure may not make sense for every Time returned by ktime.Clock.
   190  // Callers who need wall time duration can use ktime.Clock.WallTimeUntil to
   191  // estimate that wall time.
   192  func (t Time) Sub(u Time) time.Duration {
   193  	dur := time.Duration(int64(t.ns)-int64(u.ns)) * time.Nanosecond
   194  	switch {
   195  	case u.Add(dur).Equal(t):
   196  		return dur
   197  	case t.Before(u):
   198  		return MinDuration
   199  	default:
   200  		return MaxDuration
   201  	}
   202  }
   203  
   204  // IsMin returns whether t represents the lowest possible time instant.
   205  func (t Time) IsMin() bool {
   206  	return t == MinTime
   207  }
   208  
   209  // IsZero returns whether t represents the zero time instant in t's Clock domain.
   210  func (t Time) IsZero() bool {
   211  	return t == ZeroTime
   212  }
   213  
   214  // String returns the time represented in nanoseconds as a string.
   215  func (t Time) String() string {
   216  	return fmt.Sprintf("%dns", t.Nanoseconds())
   217  }
   218  
   219  // A Clock is an abstract time source.
   220  type Clock interface {
   221  	// Now returns the current time in nanoseconds according to the Clock.
   222  	Now() Time
   223  
   224  	// WallTimeUntil returns the estimated wall time until Now will return a
   225  	// value greater than or equal to t, given that a recent call to Now
   226  	// returned now. If t has already passed, WallTimeUntil may return 0 or a
   227  	// negative value.
   228  	//
   229  	// WallTimeUntil must be abstract to support Clocks that do not represent
   230  	// wall time (e.g. thread group execution timers). Clocks that represent
   231  	// wall times may embed the WallRateClock type to obtain an appropriate
   232  	// trivial implementation of WallTimeUntil.
   233  	//
   234  	// WallTimeUntil is used to determine when associated Timers should next
   235  	// check for expirations. Returning too small a value may result in
   236  	// spurious Timer goroutine wakeups, while returning too large a value may
   237  	// result in late expirations. Implementations should usually err on the
   238  	// side of underestimating.
   239  	WallTimeUntil(t, now Time) time.Duration
   240  
   241  	// Waitable methods may be used to subscribe to Clock events. Waiters will
   242  	// not be preserved by Save and must be re-established during restore.
   243  	//
   244  	// Since Clock events are transient, implementations of
   245  	// waiter.Waitable.Readiness should return 0.
   246  	waiter.Waitable
   247  }
   248  
   249  // WallRateClock implements Clock.WallTimeUntil for Clocks that elapse at the
   250  // same rate as wall time.
   251  type WallRateClock struct{}
   252  
   253  // WallTimeUntil implements Clock.WallTimeUntil.
   254  func (*WallRateClock) WallTimeUntil(t, now Time) time.Duration {
   255  	return t.Sub(now)
   256  }
   257  
   258  // NoClockEvents implements waiter.Waitable for Clocks that do not generate
   259  // events.
   260  type NoClockEvents struct{}
   261  
   262  // Readiness implements waiter.Waitable.Readiness.
   263  func (*NoClockEvents) Readiness(mask waiter.EventMask) waiter.EventMask {
   264  	return 0
   265  }
   266  
   267  // EventRegister implements waiter.Waitable.EventRegister.
   268  func (*NoClockEvents) EventRegister(e *waiter.Entry) error {
   269  	return nil
   270  }
   271  
   272  // EventUnregister implements waiter.Waitable.EventUnregister.
   273  func (*NoClockEvents) EventUnregister(e *waiter.Entry) {
   274  }
   275  
   276  // ClockEventsQueue implements waiter.Waitable by wrapping waiter.Queue and
   277  // defining waiter.Waitable.Readiness as required by Clock.
   278  type ClockEventsQueue struct {
   279  	waiter.Queue
   280  }
   281  
   282  // EventRegister implements waiter.Waitable.
   283  func (c *ClockEventsQueue) EventRegister(e *waiter.Entry) error {
   284  	c.Queue.EventRegister(e)
   285  	return nil
   286  }
   287  
   288  // Readiness implements waiter.Waitable.Readiness.
   289  func (*ClockEventsQueue) Readiness(mask waiter.EventMask) waiter.EventMask {
   290  	return 0
   291  }
   292  
   293  // Listener receives expirations from a Timer.
   294  type Listener interface {
   295  	// NotifyTimer is called when its associated Timer expires. exp is the number
   296  	// of expirations. setting is the next timer Setting.
   297  	//
   298  	// Notify is called with the associated Timer's mutex locked, so Notify
   299  	// must not take any locks that precede Timer.mu in lock order.
   300  	//
   301  	// If Notify returns true, the timer will use the returned setting
   302  	// rather than the passed one.
   303  	//
   304  	// Preconditions: exp > 0.
   305  	NotifyTimer(exp uint64, setting Setting) (newSetting Setting, update bool)
   306  }
   307  
   308  // Setting contains user-controlled mutable Timer properties.
   309  //
   310  // +stateify savable
   311  type Setting struct {
   312  	// Enabled is true if the timer is running.
   313  	Enabled bool
   314  
   315  	// Next is the time in nanoseconds of the next expiration.
   316  	Next Time
   317  
   318  	// Period is the time in nanoseconds between expirations. If Period is
   319  	// zero, the timer will not automatically restart after expiring.
   320  	//
   321  	// Invariant: Period >= 0.
   322  	Period time.Duration
   323  }
   324  
   325  // SettingFromSpec converts a (value, interval) pair to a Setting based on a
   326  // reading from c. value is interpreted as a time relative to c.Now().
   327  func SettingFromSpec(value time.Duration, interval time.Duration, c Clock) (Setting, error) {
   328  	return SettingFromSpecAt(value, interval, c.Now())
   329  }
   330  
   331  // SettingFromSpecAt converts a (value, interval) pair to a Setting. value is
   332  // interpreted as a time relative to now.
   333  func SettingFromSpecAt(value time.Duration, interval time.Duration, now Time) (Setting, error) {
   334  	if value < 0 {
   335  		return Setting{}, linuxerr.EINVAL
   336  	}
   337  	if value == 0 {
   338  		return Setting{Period: interval}, nil
   339  	}
   340  	return Setting{
   341  		Enabled: true,
   342  		Next:    now.Add(value),
   343  		Period:  interval,
   344  	}, nil
   345  }
   346  
   347  // SettingFromAbsSpec converts a (value, interval) pair to a Setting. value is
   348  // interpreted as an absolute time.
   349  func SettingFromAbsSpec(value Time, interval time.Duration) (Setting, error) {
   350  	if value.Before(ZeroTime) {
   351  		return Setting{}, linuxerr.EINVAL
   352  	}
   353  	if value.IsZero() {
   354  		return Setting{Period: interval}, nil
   355  	}
   356  	return Setting{
   357  		Enabled: true,
   358  		Next:    value,
   359  		Period:  interval,
   360  	}, nil
   361  }
   362  
   363  // SettingFromItimerspec converts a linux.Itimerspec to a Setting. If abs is
   364  // true, its.Value is interpreted as an absolute time. Otherwise, it is
   365  // interpreted as a time relative to c.Now().
   366  func SettingFromItimerspec(its linux.Itimerspec, abs bool, c Clock) (Setting, error) {
   367  	if abs {
   368  		return SettingFromAbsSpec(FromTimespec(its.Value), its.Interval.ToDuration())
   369  	}
   370  	return SettingFromSpec(its.Value.ToDuration(), its.Interval.ToDuration(), c)
   371  }
   372  
   373  // SpecFromSetting converts a timestamp and a Setting to a (relative value,
   374  // interval) pair, as used by most Linux syscalls that return a struct
   375  // itimerval or struct itimerspec.
   376  func SpecFromSetting(now Time, s Setting) (value, period time.Duration) {
   377  	if !s.Enabled {
   378  		return 0, s.Period
   379  	}
   380  	return s.Next.Sub(now), s.Period
   381  }
   382  
   383  // ItimerspecFromSetting converts a Setting to a linux.Itimerspec.
   384  func ItimerspecFromSetting(now Time, s Setting) linux.Itimerspec {
   385  	val, iv := SpecFromSetting(now, s)
   386  	return linux.Itimerspec{
   387  		Interval: linux.DurationToTimespec(iv),
   388  		Value:    linux.DurationToTimespec(val),
   389  	}
   390  }
   391  
   392  // At returns an updated Setting and a number of expirations after the
   393  // associated Clock indicates a time of now.
   394  //
   395  // Settings may be created by successive calls to At with decreasing
   396  // values of now (i.e. time may appear to go backward). Supporting this is
   397  // required to support non-monotonic clocks, as well as allowing
   398  // Timer.clock.Now() to be called without holding Timer.mu.
   399  func (s Setting) At(now Time) (Setting, uint64) {
   400  	if !s.Enabled {
   401  		return s, 0
   402  	}
   403  	if s.Next.After(now) {
   404  		return s, 0
   405  	}
   406  	if s.Period == 0 {
   407  		s.Enabled = false
   408  		return s, 1
   409  	}
   410  	exp := 1 + uint64(now.Sub(s.Next).Nanoseconds())/uint64(s.Period)
   411  	s.Next = s.Next.Add(time.Duration(uint64(s.Period) * exp))
   412  	return s, exp
   413  }
   414  
   415  // Timer is an optionally-periodic timer driven by sampling a user-specified
   416  // Clock. Timer's semantics support the requirements of Linux's interval timers
   417  // (setitimer(2), timer_create(2), timerfd_create(2)).
   418  //
   419  // Timers should be created using NewTimer and must be cleaned up by calling
   420  // Timer.Destroy when no longer used.
   421  //
   422  // +stateify savable
   423  type Timer struct {
   424  	// clock is the time source. clock is protected by mu and clockSeq.
   425  	clockSeq sync.SeqCount `state:"nosave"`
   426  	clock    Clock
   427  
   428  	// listener is notified of expirations. listener is immutable.
   429  	listener Listener
   430  
   431  	// mu protects the following mutable fields.
   432  	mu sync.Mutex `state:"nosave"`
   433  
   434  	// setting is the timer setting. setting is protected by mu.
   435  	setting Setting
   436  
   437  	// paused is true if the Timer is paused. paused is protected by mu.
   438  	paused bool
   439  
   440  	// kicker is used to wake the Timer goroutine. The kicker pointer is
   441  	// immutable, but its state is protected by mu.
   442  	kicker *time.Timer `state:"nosave"`
   443  
   444  	// entry is registered with clock.EventRegister. entry is immutable.
   445  	//
   446  	// Per comment in Clock, entry must be re-registered after restore; per
   447  	// comment in Timer.Load, this is done in Timer.Resume.
   448  	entry waiter.Entry `state:"nosave"`
   449  
   450  	// events is the channel that will be notified whenever entry receives an
   451  	// event. It is also closed by Timer.Destroy to instruct the Timer
   452  	// goroutine to exit.
   453  	events chan struct{} `state:"nosave"`
   454  }
   455  
   456  // timerTickEvents are Clock events that require the Timer goroutine to Tick
   457  // prematurely.
   458  const timerTickEvents = ClockEventSet | ClockEventRateIncrease
   459  
   460  // NewTimer returns a new Timer that will obtain time from clock and send
   461  // expirations to listener. The Timer is initially stopped and has no first
   462  // expiration or period configured.
   463  func NewTimer(clock Clock, listener Listener) *Timer {
   464  	t := &Timer{
   465  		clock:    clock,
   466  		listener: listener,
   467  	}
   468  	t.init()
   469  	return t
   470  }
   471  
   472  // init initializes Timer state that is not preserved across save/restore. If
   473  // init has already been called, calling it again is a no-op.
   474  //
   475  // Preconditions: t.mu must be locked, or the caller must have exclusive access
   476  // to t.
   477  func (t *Timer) init() {
   478  	if t.kicker != nil {
   479  		return
   480  	}
   481  	// If t.kicker is nil, the Timer goroutine can't be running, so we can't
   482  	// race with it.
   483  	t.kicker = time.NewTimer(0)
   484  	t.entry, t.events = waiter.NewChannelEntry(timerTickEvents)
   485  	if err := t.clock.EventRegister(&t.entry); err != nil {
   486  		panic(err)
   487  	}
   488  	go t.runGoroutine() // S/R-SAFE: synchronized by t.mu
   489  }
   490  
   491  // Destroy releases resources owned by the Timer. A Destroyed Timer must not be
   492  // used again; in particular, a Destroyed Timer should not be Saved.
   493  func (t *Timer) Destroy() {
   494  	// Stop the Timer, ensuring that the Timer goroutine will not call
   495  	// t.kicker.Reset, before calling t.kicker.Stop.
   496  	t.mu.Lock()
   497  	t.setting.Enabled = false
   498  	t.mu.Unlock()
   499  	t.kicker.Stop()
   500  	// Unregister t.entry, ensuring that the Clock will not send to t.events,
   501  	// before closing t.events to instruct the Timer goroutine to exit.
   502  	t.clock.EventUnregister(&t.entry)
   503  	close(t.events)
   504  }
   505  
   506  func (t *Timer) runGoroutine() {
   507  	for {
   508  		select {
   509  		case <-t.kicker.C:
   510  		case _, ok := <-t.events:
   511  			if !ok {
   512  				// Channel closed by Destroy.
   513  				return
   514  			}
   515  		}
   516  		t.Tick()
   517  	}
   518  }
   519  
   520  // Tick requests that the Timer immediately check for expirations and
   521  // re-evaluate when it should next check for expirations.
   522  func (t *Timer) Tick() {
   523  	// Optimistically read t.Clock().Now() before locking t.mu, as t.clock is
   524  	// unlikely to change.
   525  	unlockedClock := t.Clock()
   526  	now := unlockedClock.Now()
   527  	t.mu.Lock()
   528  	defer t.mu.Unlock()
   529  	if t.paused {
   530  		return
   531  	}
   532  	if t.clock != unlockedClock {
   533  		now = t.clock.Now()
   534  	}
   535  	s, exp := t.setting.At(now)
   536  	t.setting = s
   537  	if exp > 0 {
   538  		if newS, ok := t.listener.NotifyTimer(exp, t.setting); ok {
   539  			t.setting = newS
   540  		}
   541  	}
   542  	t.resetKickerLocked(now)
   543  }
   544  
   545  // Pause pauses the Timer, ensuring that it does not generate any further
   546  // expirations until Resume is called. If the Timer is already paused, Pause
   547  // has no effect.
   548  func (t *Timer) Pause() {
   549  	t.mu.Lock()
   550  	defer t.mu.Unlock()
   551  	t.paused = true
   552  	// t.kicker may be nil if we were restored but never resumed.
   553  	if t.kicker != nil {
   554  		t.kicker.Stop()
   555  	}
   556  }
   557  
   558  // Resume ends the effect of Pause. If the Timer is not paused, Resume has no
   559  // effect.
   560  func (t *Timer) Resume() {
   561  	t.mu.Lock()
   562  	defer t.mu.Unlock()
   563  	if !t.paused {
   564  		return
   565  	}
   566  	t.paused = false
   567  
   568  	// Lazily initialize the Timer. We can't call Timer.init until Timer.Resume
   569  	// because save/restore will restore Timers before
   570  	// kernel.Timekeeper.SetClocks() has been called, so if t.clock is backed
   571  	// by a kernel.Timekeeper then the Timer goroutine will panic if it calls
   572  	// t.clock.Now().
   573  	t.init()
   574  
   575  	// Kick the Timer goroutine in case it was already initialized, but the
   576  	// Timer goroutine was sleeping.
   577  	t.kicker.Reset(0)
   578  }
   579  
   580  // Get returns a snapshot of the Timer's current Setting and the time
   581  // (according to the Timer's Clock) at which the snapshot was taken.
   582  //
   583  // Preconditions: The Timer must not be paused (since its Setting cannot
   584  // be advanced to the current time while it is paused.)
   585  func (t *Timer) Get() (Time, Setting) {
   586  	// Optimistically read t.Clock().Now() before locking t.mu, as t.clock is
   587  	// unlikely to change.
   588  	unlockedClock := t.Clock()
   589  	now := unlockedClock.Now()
   590  	t.mu.Lock()
   591  	defer t.mu.Unlock()
   592  	if t.paused {
   593  		panic(fmt.Sprintf("Timer.Get called on paused Timer %p", t))
   594  	}
   595  	if t.clock != unlockedClock {
   596  		now = t.clock.Now()
   597  	}
   598  	s, exp := t.setting.At(now)
   599  	t.setting = s
   600  	if exp > 0 {
   601  		if newS, ok := t.listener.NotifyTimer(exp, t.setting); ok {
   602  			t.setting = newS
   603  		}
   604  	}
   605  	t.resetKickerLocked(now)
   606  	return now, s
   607  }
   608  
   609  // Swap atomically changes the Timer's Setting and returns the Timer's previous
   610  // Setting and the time (according to the Timer's Clock) at which the snapshot
   611  // was taken. Setting s.Enabled to true starts the Timer, while setting
   612  // s.Enabled to false stops it.
   613  //
   614  // Preconditions: The Timer must not be paused.
   615  func (t *Timer) Swap(s Setting) (Time, Setting) {
   616  	return t.SwapAnd(s, nil)
   617  }
   618  
   619  // SwapAnd atomically changes the Timer's Setting, calls f if it is not nil,
   620  // and returns the Timer's previous Setting and the time (according to the
   621  // Timer's Clock) at which the Setting was changed. Setting s.Enabled to true
   622  // starts the timer, while setting s.Enabled to false stops it.
   623  //
   624  // Preconditions:
   625  //   - The Timer must not be paused.
   626  //   - f cannot call any Timer methods since it is called with the Timer mutex
   627  //     locked.
   628  func (t *Timer) SwapAnd(s Setting, f func()) (Time, Setting) {
   629  	// Optimistically read t.Clock().Now() before locking t.mu, as t.clock is
   630  	// unlikely to change.
   631  	unlockedClock := t.Clock()
   632  	now := unlockedClock.Now()
   633  	t.mu.Lock()
   634  	defer t.mu.Unlock()
   635  	if t.paused {
   636  		panic(fmt.Sprintf("Timer.SwapAnd called on paused Timer %p", t))
   637  	}
   638  	if t.clock != unlockedClock {
   639  		now = t.clock.Now()
   640  	}
   641  	oldS, oldExp := t.setting.At(now)
   642  	if oldExp > 0 {
   643  		t.listener.NotifyTimer(oldExp, oldS)
   644  		// N.B. The returned Setting doesn't matter because we're about
   645  		// to overwrite.
   646  	}
   647  	if f != nil {
   648  		f()
   649  	}
   650  	newS, newExp := s.At(now)
   651  	t.setting = newS
   652  	if newExp > 0 {
   653  		if newS, ok := t.listener.NotifyTimer(newExp, t.setting); ok {
   654  			t.setting = newS
   655  		}
   656  	}
   657  	t.resetKickerLocked(now)
   658  	return now, oldS
   659  }
   660  
   661  // SetClock atomically changes a Timer's Clock and Setting.
   662  func (t *Timer) SetClock(c Clock, s Setting) {
   663  	var now Time
   664  	if s.Enabled {
   665  		now = c.Now()
   666  	}
   667  	t.mu.Lock()
   668  	defer t.mu.Unlock()
   669  	t.setting = s
   670  	if oldC := t.clock; oldC != c {
   671  		oldC.EventUnregister(&t.entry)
   672  		c.EventRegister(&t.entry)
   673  		t.clockSeq.BeginWrite()
   674  		t.clock = c
   675  		t.clockSeq.EndWrite()
   676  	}
   677  	t.resetKickerLocked(now)
   678  }
   679  
   680  // Preconditions: t.mu must be locked.
   681  func (t *Timer) resetKickerLocked(now Time) {
   682  	if t.setting.Enabled {
   683  		// Clock.WallTimeUntil may return a negative value. This is fine;
   684  		// time.when treats negative Durations as 0.
   685  		t.kicker.Reset(t.clock.WallTimeUntil(t.setting.Next, now))
   686  	}
   687  	// We don't call t.kicker.Stop if !t.setting.Enabled because in most cases
   688  	// resetKickerLocked will be called from the Timer goroutine itself, in
   689  	// which case t.kicker has already fired and t.kicker.Stop will be an
   690  	// expensive no-op (time.Timer.Stop => time.stopTimer => runtime.stopTimer
   691  	// => runtime.deltimer).
   692  }
   693  
   694  // Clock returns the Clock used by t.
   695  func (t *Timer) Clock() Clock {
   696  	return SeqAtomicLoadClock(&t.clockSeq, &t.clock)
   697  }
   698  
   699  // ChannelNotifier is a Listener that sends on a channel.
   700  //
   701  // ChannelNotifier cannot be saved or loaded.
   702  type ChannelNotifier chan struct{}
   703  
   704  // NewChannelNotifier creates a new channel notifier.
   705  //
   706  // If the notifier is used with a timer, Timer.Destroy will close the channel
   707  // returned here.
   708  func NewChannelNotifier() (Listener, <-chan struct{}) {
   709  	tchan := make(chan struct{}, 1)
   710  	return ChannelNotifier(tchan), tchan
   711  }
   712  
   713  // NotifyTimer implements Listener.NotifyTimer.
   714  func (c ChannelNotifier) NotifyTimer(uint64, Setting) (Setting, bool) {
   715  	select {
   716  	case c <- struct{}{}:
   717  	default:
   718  	}
   719  
   720  	return Setting{}, false
   721  }