Repository: go
Issue: time: macOS monotonic time paused during sleep
Labels: Documentation,OS-Darwin,NeedsInvestigation

### Go version

go version go1.22.1 darwin/amd64

### Output of `go env` in your module/workspace:

```shell
GO111MODULE=''
GOARCH='amd64'
GOBIN=''


GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''


GONOSUMDB=''
GOOS='darwin'

GOPRIVATE=''
GOPROXY='https://goproxy.cn,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.22.1'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/2x/l_3w120j35sgp9mpf4zlcjb40000gr/T/go-build2833465807=/tmp/go-build -gno-record-gcc-switches -fno-common'
```


### What did you do?

The issue happens in both `go run main.go` and vscode debug mode, on my macbook.
The code is running as expected on a Linux server.
Maybe this is an OS bug
No `unsafe` code.

Two variables:
`expiresAt`: a `time.Time` variable that stores the token when to expire, created like `time.Now().After(expiresIn)`
`now`: a `time.Time` variable that stores token checking time.

Then I use `now.Before(expiresAt)` to decide if I should renew the token.

### What did you see happen?

`now` is after `expiresAt`, means token already expired, but `now.Before(expiresAt)` returns true. Below is a screenshot in vscode debug console:

<img width="405" alt="IMG_6613" src="https://github.com/golang/go/assets/13704796/a2f2c0c9-f032-431d-8040-530ffdb95b13">

Both `now` and `expiresAt` are created in the same process, and `hasMonotonic` bit is set to 1. So they just compare by `ext`:

`time.Time` defines here:
https://github.com/golang/go/blob/d6c972ad41043f38bfa31f3c7036e6d8a3361f2d/src/time/time.go#L135-L156

`Time.Before` defines here:
https://github.com/golang/go/blob/d6c972ad41043f38bfa31f3c7036e6d8a3361f2d/src/time/time.go#L265-L273

From the screenshot we can see there is a monotonic clock rollback issue, the `m` printed is not as expected. `now` is after `expiresAt`, but its `m` is smaller. This is a breakpoint hit in debug mode(after I send an API call), two variables surely created in the same process.

The issue is not always happen, unless I close the screen and a night passed. 
**Seems that while the computer sleep and awake, it will reset the monotonic clock to zero**.

I wrote some code to reproduce quickly, but failed. The monotonic clock only stopped, but not reset, while the computer sleep for two hours when I go out for a launch.

"Monotonic clock may stop" is mentioned here in doc [monotonic clock](https://golang.google.cn/pkg/time/#hdr-Monotonic_Clocks), but seems like it won't rollback (if it can, it's not monotonic)

The failed reproduce code is written as here in [playground](https://go.dev/play/p/Bt8MfuJRoqP)

And the output:
![image](https://github.com/golang/go/assets/13704796/75cc83e5-1865-40b5-b340-b74372858953)
We can see the monotonic clock is only just stopped, but not reset (no rollback). I'll keep testing to let it pass a whole night to see if it could be reproduced.

Besides, more info:
The value of monotonic clock (stored as `Time.ext`) eventually comes from here [`nanotime1`] on mac os: https://github.com/golang/go/blob/d6c972ad41043f38bfa31f3c7036e6d8a3361f2d/src/runtime/sys_darwin.go#L332-L350


### What did you expect to see?

I expect to see `now.Before(expiresAt)` should return false, then token can renew as expected.