Browse Source

Merge pull request #8507 from lorneli/lease_monotime

lease: use monotime in time.Time for Go 1.9
Anthony Romano 8 years ago
parent
commit
eb55917ef6
5 changed files with 23 additions and 93 deletions
  1. 23 15
      lease/lessor.go
  2. 0 6
      pkg/monotime/issue15006.s
  3. 0 26
      pkg/monotime/monotime.go
  4. 0 24
      pkg/monotime/nanotime.go
  5. 0 22
      pkg/monotime/nanotime_test.go

+ 23 - 15
lease/lessor.go

@@ -20,22 +20,18 @@ import (
 	"math"
 	"sort"
 	"sync"
-	"sync/atomic"
 	"time"
 
 	"github.com/coreos/etcd/lease/leasepb"
 	"github.com/coreos/etcd/mvcc/backend"
-	"github.com/coreos/etcd/pkg/monotime"
 )
 
-const (
-	// NoLease is a special LeaseID representing the absence of a lease.
-	NoLease = LeaseID(0)
-
-	forever = monotime.Time(math.MaxInt64)
-)
+// NoLease is a special LeaseID representing the absence of a lease.
+const NoLease = LeaseID(0)
 
 var (
+	forever = time.Time{}
+
 	leaseBucketName = []byte("lease")
 
 	// maximum number of leases to revoke per second; configurable for tests
@@ -564,8 +560,10 @@ func (le *lessor) initAndRecover() {
 type Lease struct {
 	ID  LeaseID
 	ttl int64 // time to live in seconds
-	// expiry is time when lease should expire; must be 64-bit aligned.
-	expiry monotime.Time
+	// expiryMu protects concurrent accesses to expiry
+	expiryMu sync.RWMutex
+	// expiry is time when lease should expire. no expiration when expiry.IsZero() is true
+	expiry time.Time
 
 	// mu protects concurrent accesses to itemSet
 	mu      sync.RWMutex
@@ -598,12 +596,18 @@ func (l *Lease) TTL() int64 {
 
 // refresh refreshes the expiry of the lease.
 func (l *Lease) refresh(extend time.Duration) {
-	t := monotime.Now().Add(extend + time.Duration(l.ttl)*time.Second)
-	atomic.StoreUint64((*uint64)(&l.expiry), uint64(t))
+	newExpiry := time.Now().Add(extend + time.Duration(l.ttl)*time.Second)
+	l.expiryMu.Lock()
+	defer l.expiryMu.Unlock()
+	l.expiry = newExpiry
 }
 
 // forever sets the expiry of lease to be forever.
-func (l *Lease) forever() { atomic.StoreUint64((*uint64)(&l.expiry), uint64(forever)) }
+func (l *Lease) forever() {
+	l.expiryMu.Lock()
+	defer l.expiryMu.Unlock()
+	l.expiry = forever
+}
 
 // Keys returns all the keys attached to the lease.
 func (l *Lease) Keys() []string {
@@ -618,8 +622,12 @@ func (l *Lease) Keys() []string {
 
 // Remaining returns the remaining time of the lease.
 func (l *Lease) Remaining() time.Duration {
-	t := monotime.Time(atomic.LoadUint64((*uint64)(&l.expiry)))
-	return time.Duration(t - monotime.Now())
+	l.expiryMu.RLock()
+	defer l.expiryMu.RUnlock()
+	if l.expiry.IsZero() {
+		return time.Duration(math.MaxInt64)
+	}
+	return l.expiry.Sub(time.Now())
 }
 
 type LeaseItem struct {

+ 0 - 6
pkg/monotime/issue15006.s

@@ -1,6 +0,0 @@
-// Copyright (C) 2016  Arista Networks, Inc.
-// Use of this source code is governed by the Apache License 2.0
-// that can be found in the COPYING file.
-
-// This file is intentionally empty.
-// It's a workaround for https://github.com/golang/go/issues/15006

+ 0 - 26
pkg/monotime/monotime.go

@@ -1,26 +0,0 @@
-// Copyright 2016 The etcd Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package monotime
-
-import (
-	"time"
-)
-
-// Time represents a point in monotonic time
-type Time uint64
-
-func (t Time) Add(d time.Duration) Time {
-	return Time(uint64(t) + uint64(d.Nanoseconds()))
-}

+ 0 - 24
pkg/monotime/nanotime.go

@@ -1,24 +0,0 @@
-// Copyright (C) 2016  Arista Networks, Inc.
-// Use of this source code is governed by the Apache License 2.0
-// that can be found in the COPYING file.
-
-// Package monotime provides a fast monotonic clock source.
-package monotime
-
-import (
-	_ "unsafe" // required to use //go:linkname
-)
-
-//go:noescape
-//go:linkname nanotime runtime.nanotime
-func nanotime() int64
-
-// Now returns the current time in nanoseconds from a monotonic clock.
-// The time returned is based on some arbitrary platform-specific point in the
-// past.  The time returned is guaranteed to increase monotonically at a
-// constant rate, unlike time.Now() from the Go standard library, which may
-// slow down, speed up, jump forward or backward, due to NTP activity or leap
-// seconds.
-func Now() Time {
-	return Time(nanotime())
-}

+ 0 - 22
pkg/monotime/nanotime_test.go

@@ -1,22 +0,0 @@
-// Copyright (C) 2016  Arista Networks, Inc.
-// Use of this source code is governed by the Apache License 2.0
-
-// Package monotime provides a fast monotonic clock source.
-
-package monotime
-
-import (
-	"testing"
-)
-
-func TestNow(t *testing.T) {
-	for i := 0; i < 100; i++ {
-		t1 := Now()
-		t2 := Now()
-		// I honestly thought that we needed >= here, but in some environments
-		// two consecutive calls can return the same value!
-		if t1 > t2 {
-			t.Fatalf("t1=%d should have been less than or equal to t2=%d", t1, t2)
-		}
-	}
-}