runtime: convert p.timerModifiedEarliest to atomic type

Updates #53821

Change-Id: Iac0d7a3871d9e3ee0ba38ee7ab989faca9c89666
Reviewed-on: https://go-review.googlesource.com/c/go/+/424397
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index f100e32..01f9ed5 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -3330,7 +3330,7 @@
 	// If it's not yet time for the first timer, or the first adjusted
 	// timer, then there is nothing to do.
 	next := int64(pp.timer0When.Load())
-	nextAdj := int64(atomic.Load64(&pp.timerModifiedEarliest))
+	nextAdj := int64(pp.timerModifiedEarliest.Load())
 	if next == 0 || (nextAdj != 0 && nextAdj < next) {
 		next = nextAdj
 	}
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 34638d9..79c8ccb 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -676,9 +676,8 @@
 	// The earliest known nextwhen field of a timer with
 	// timerModifiedEarlier status. Because the timer may have been
 	// modified again, there need not be any timer with this value.
-	// This is updated using atomic functions.
 	// This is 0 if there are no timerModifiedEarlier timers.
-	timerModifiedEarliest uint64
+	timerModifiedEarliest atomic.Uint64
 
 	// Per-P GC state
 	gcAssistTime         int64 // Nanoseconds in assistAlloc
diff --git a/src/runtime/time.go b/src/runtime/time.go
index 0ab2c9c..7ce3caf 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -400,7 +400,7 @@
 	n := atomic.Xadd(&pp.numTimers, -1)
 	if n == 0 {
 		// If there are no timers, then clearly none are modified.
-		atomic.Store64(&pp.timerModifiedEarliest, 0)
+		pp.timerModifiedEarliest.Store(0)
 	}
 	return smallestChanged
 }
@@ -428,7 +428,7 @@
 	n := atomic.Xadd(&pp.numTimers, -1)
 	if n == 0 {
 		// If there are no timers, then clearly none are modified.
-		atomic.Store64(&pp.timerModifiedEarliest, 0)
+		pp.timerModifiedEarliest.Store(0)
 	}
 }
 
@@ -671,7 +671,7 @@
 	// a lot of timers back and forth if the timers rarely expire.
 	// We'll postpone looking through all the adjusted timers until
 	// one would actually expire.
-	first := atomic.Load64(&pp.timerModifiedEarliest)
+	first := pp.timerModifiedEarliest.Load()
 	if first == 0 || int64(first) > now {
 		if verifyTimers {
 			verifyTimerHeap(pp)
@@ -680,7 +680,7 @@
 	}
 
 	// We are going to clear all timerModifiedEarlier timers.
-	atomic.Store64(&pp.timerModifiedEarliest, 0)
+	pp.timerModifiedEarliest.Store(0)
 
 	var moved []*timer
 	for i := 0; i < len(pp.timers); i++ {
@@ -755,7 +755,7 @@
 //go:nowritebarrierrec
 func nobarrierWakeTime(pp *p) int64 {
 	next := int64(pp.timer0When.Load())
-	nextAdj := int64(atomic.Load64(&pp.timerModifiedEarliest))
+	nextAdj := int64(pp.timerModifiedEarliest.Load())
 	if next == 0 || (nextAdj != 0 && nextAdj < next) {
 		next = nextAdj
 	}
@@ -903,7 +903,7 @@
 func clearDeletedTimers(pp *p) {
 	// We are going to clear all timerModifiedEarlier timers.
 	// Do this now in case new ones show up while we are looping.
-	atomic.Store64(&pp.timerModifiedEarliest, 0)
+	pp.timerModifiedEarliest.Store(0)
 
 	cdel := int32(0)
 	to := 0
@@ -1014,11 +1014,12 @@
 // The timers for pp will not be locked.
 func updateTimerModifiedEarliest(pp *p, nextwhen int64) {
 	for {
-		old := atomic.Load64(&pp.timerModifiedEarliest)
+		old := pp.timerModifiedEarliest.Load()
 		if old != 0 && int64(old) < nextwhen {
 			return
 		}
-		if atomic.Cas64(&pp.timerModifiedEarliest, old, uint64(nextwhen)) {
+
+		if pp.timerModifiedEarliest.CompareAndSwap(old, uint64(nextwhen)) {
 			return
 		}
 	}
@@ -1044,7 +1045,7 @@
 			next = w
 		}
 
-		w = int64(atomic.Load64(&pp.timerModifiedEarliest))
+		w = int64(pp.timerModifiedEarliest.Load())
 		if w != 0 && w < next {
 			next = w
 		}