Source file src/runtime/time.go
1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Time-related runtime and pieces of package time. 6 7 package runtime 8 9 import ( 10 "internal/abi" 11 "internal/runtime/atomic" 12 "internal/runtime/sys" 13 "unsafe" 14 ) 15 16 //go:linkname time_runtimeNow time.runtimeNow 17 func time_runtimeNow() (sec int64, nsec int32, mono int64) { 18 if sg := getg().syncGroup; sg != nil { 19 sec = sg.now / (1000 * 1000 * 1000) 20 nsec = int32(sg.now % (1000 * 1000 * 1000)) 21 return sec, nsec, sg.now 22 } 23 return time_now() 24 } 25 26 //go:linkname time_runtimeNano time.runtimeNano 27 func time_runtimeNano() int64 { 28 gp := getg() 29 if gp.syncGroup != nil { 30 return gp.syncGroup.now 31 } 32 return nanotime() 33 } 34 35 // A timer is a potentially repeating trigger for calling t.f(t.arg, t.seq). 36 // Timers are allocated by client code, often as part of other data structures. 37 // Each P has a heap of pointers to timers that it manages. 38 // 39 // A timer is expected to be used by only one client goroutine at a time, 40 // but there will be concurrent access by the P managing that timer. 41 // Timer accesses are protected by the lock t.mu, with a snapshot of 42 // t's state bits published in t.astate to enable certain fast paths to make 43 // decisions about a timer without acquiring the lock. 44 type timer struct { 45 // mu protects reads and writes to all fields, with exceptions noted below. 46 mu mutex 47 48 astate atomic.Uint8 // atomic copy of state bits at last unlock 49 state uint8 // state bits 50 isChan bool // timer has a channel; immutable; can be read without lock 51 isFake bool // timer is using fake time; immutable; can be read without lock 52 53 blocked uint32 // number of goroutines blocked on timer's channel 54 55 // Timer wakes up at when, and then at when+period, ... (period > 0 only) 56 // each time calling f(arg, seq, delay) in the timer goroutine, so f must be 57 // a well-behaved function and not block. 58 // 59 // The arg and seq are client-specified opaque arguments passed back to f. 60 // When used from netpoll, arg and seq have meanings defined by netpoll 61 // and are completely opaque to this code; in that context, seq is a sequence 62 // number to recognize and squelch stale function invocations. 63 // When used from package time, arg is a channel (for After, NewTicker) 64 // or the function to call (for AfterFunc) and seq is unused (0). 65 // 66 // Package time does not know about seq, but if this is a channel timer (t.isChan == true), 67 // this file uses t.seq as a sequence number to recognize and squelch 68 // sends that correspond to an earlier (stale) timer configuration, 69 // similar to its use in netpoll. In this usage (that is, when t.isChan == true), 70 // writes to seq are protected by both t.mu and t.sendLock, 71 // so reads are allowed when holding either of the two mutexes. 72 // 73 // The delay argument is nanotime() - t.when, meaning the delay in ns between 74 // when the timer should have gone off and now. Normally that amount is 75 // small enough not to matter, but for channel timers that are fed lazily, 76 // the delay can be arbitrarily long; package time subtracts it out to make 77 // it look like the send happened earlier than it actually did. 78 // (No one looked at the channel since then, or the send would have 79 // not happened so late, so no one can tell the difference.) 80 when int64 81 period int64 82 f func(arg any, seq uintptr, delay int64) 83 arg any 84 seq uintptr 85 86 // If non-nil, the timers containing t. 87 ts *timers 88 89 // sendLock protects sends on the timer's channel. 90 // Not used for async (pre-Go 1.23) behavior when debug.asynctimerchan.Load() != 0. 91 sendLock mutex 92 93 // isSending is used to handle races between running a 94 // channel timer and stopping or resetting the timer. 95 // It is used only for channel timers (t.isChan == true). 96 // It is not used for tickers. 97 // The value is incremented when about to send a value on the channel, 98 // and decremented after sending the value. 99 // The stop/reset code uses this to detect whether it 100 // stopped the channel send. 101 // 102 // isSending is incremented only when t.mu is held. 103 // isSending is decremented only when t.sendLock is held. 104 // isSending is read only when both t.mu and t.sendLock are held. 105 isSending atomic.Int32 106 } 107 108 // init initializes a newly allocated timer t. 109 // Any code that allocates a timer must call t.init before using it. 110 // The arg and f can be set during init, or they can be nil in init 111 // and set by a future call to t.modify. 112 func (t *timer) init(f func(arg any, seq uintptr, delay int64), arg any) { 113 lockInit(&t.mu, lockRankTimer) 114 t.f = f 115 t.arg = arg 116 } 117 118 // A timers is a per-P set of timers. 119 type timers struct { 120 // mu protects timers; timers are per-P, but the scheduler can 121 // access the timers of another P, so we have to lock. 122 mu mutex 123 124 // heap is the set of timers, ordered by heap[i].when. 125 // Must hold lock to access. 126 heap []timerWhen 127 128 // len is an atomic copy of len(heap). 129 len atomic.Uint32 130 131 // zombies is the number of timers in the heap 132 // that are marked for removal. 133 zombies atomic.Int32 134 135 // raceCtx is the race context used while executing timer functions. 136 raceCtx uintptr 137 138 // minWhenHeap is the minimum heap[i].when value (= heap[0].when). 139 // The wakeTime method uses minWhenHeap and minWhenModified 140 // to determine the next wake time. 141 // If minWhenHeap = 0, it means there are no timers in the heap. 142 minWhenHeap atomic.Int64 143 144 // minWhenModified is a lower bound on the minimum 145 // heap[i].when over timers with the timerModified bit set. 146 // If minWhenModified = 0, it means there are no timerModified timers in the heap. 147 minWhenModified atomic.Int64 148 149 syncGroup *synctestGroup 150 } 151 152 type timerWhen struct { 153 timer *timer 154 when int64 155 } 156 157 func (ts *timers) lock() { 158 lock(&ts.mu) 159 } 160 161 func (ts *timers) unlock() { 162 // Update atomic copy of len(ts.heap). 163 // We only update at unlock so that the len is always 164 // the most recent unlocked length, not an ephemeral length. 165 // This matters if we lock ts, delete the only timer from the heap, 166 // add it back, and unlock. We want ts.len.Load to return 1 the 167 // entire time, never 0. This is important for pidleput deciding 168 // whether ts is empty. 169 ts.len.Store(uint32(len(ts.heap))) 170 171 unlock(&ts.mu) 172 } 173 174 // Timer state field. 175 const ( 176 // timerHeaped is set when the timer is stored in some P's heap. 177 timerHeaped uint8 = 1 << iota 178 179 // timerModified is set when t.when has been modified 180 // but the heap's heap[i].when entry still needs to be updated. 181 // That change waits until the heap in which 182 // the timer appears can be locked and rearranged. 183 // timerModified is only set when timerHeaped is also set. 184 timerModified 185 186 // timerZombie is set when the timer has been stopped 187 // but is still present in some P's heap. 188 // Only set when timerHeaped is also set. 189 // It is possible for timerModified and timerZombie to both 190 // be set, meaning that the timer was modified and then stopped. 191 // A timer sending to a channel may be placed in timerZombie 192 // to take it out of the heap even though the timer is not stopped, 193 // as long as nothing is reading from the channel. 194 timerZombie 195 ) 196 197 // timerDebug enables printing a textual debug trace of all timer operations to stderr. 198 const timerDebug = false 199 200 func (t *timer) trace(op string) { 201 if timerDebug { 202 t.trace1(op) 203 } 204 } 205 206 func (t *timer) trace1(op string) { 207 if !timerDebug { 208 return 209 } 210 bits := [4]string{"h", "m", "z", "c"} 211 for i := range 3 { 212 if t.state&(1<<i) == 0 { 213 bits[i] = "-" 214 } 215 } 216 if !t.isChan { 217 bits[3] = "-" 218 } 219 print("T ", t, " ", bits[0], bits[1], bits[2], bits[3], " b=", t.blocked, " ", op, "\n") 220 } 221 222 func (ts *timers) trace(op string) { 223 if timerDebug { 224 println("TS", ts, op) 225 } 226 } 227 228 // lock locks the timer, allowing reading or writing any of the timer fields. 229 func (t *timer) lock() { 230 lock(&t.mu) 231 t.trace("lock") 232 } 233 234 // unlock updates t.astate and unlocks the timer. 235 func (t *timer) unlock() { 236 t.trace("unlock") 237 // Let heap fast paths know whether heap[i].when is accurate. 238 // Also let maybeRunChan know whether channel is in heap. 239 t.astate.Store(t.state) 240 unlock(&t.mu) 241 } 242 243 // hchan returns the channel in t.arg. 244 // t must be a timer with a channel. 245 func (t *timer) hchan() *hchan { 246 if !t.isChan { 247 badTimer() 248 } 249 // Note: t.arg is a chan time.Time, 250 // and runtime cannot refer to that type, 251 // so we cannot use a type assertion. 252 return (*hchan)(efaceOf(&t.arg).data) 253 } 254 255 // updateHeap updates t as directed by t.state, updating t.state 256 // and returning a bool indicating whether the state (and ts.heap[0].when) changed. 257 // The caller must hold t's lock, or the world can be stopped instead. 258 // The timer set t.ts must be non-nil and locked, t must be t.ts.heap[0], and updateHeap 259 // takes care of moving t within the timers heap to preserve the heap invariants. 260 // If ts == nil, then t must not be in a heap (or is in a heap that is 261 // temporarily not maintaining its invariant, such as during timers.adjust). 262 func (t *timer) updateHeap() (updated bool) { 263 assertWorldStoppedOrLockHeld(&t.mu) 264 t.trace("updateHeap") 265 ts := t.ts 266 if ts == nil || t != ts.heap[0].timer { 267 badTimer() 268 } 269 assertLockHeld(&ts.mu) 270 if t.state&timerZombie != 0 { 271 // Take timer out of heap. 272 t.state &^= timerHeaped | timerZombie | timerModified 273 ts.zombies.Add(-1) 274 ts.deleteMin() 275 return true 276 } 277 278 if t.state&timerModified != 0 { 279 // Update ts.heap[0].when and move within heap. 280 t.state &^= timerModified 281 ts.heap[0].when = t.when 282 ts.siftDown(0) 283 ts.updateMinWhenHeap() 284 return true 285 } 286 287 return false 288 } 289 290 // maxWhen is the maximum value for timer's when field. 291 const maxWhen = 1<<63 - 1 292 293 // verifyTimers can be set to true to add debugging checks that the 294 // timer heaps are valid. 295 const verifyTimers = false 296 297 // Package time APIs. 298 // Godoc uses the comments in package time, not these. 299 300 // time.now is implemented in assembly. 301 302 // timeSleep puts the current goroutine to sleep for at least ns nanoseconds. 303 // 304 //go:linkname timeSleep time.Sleep 305 func timeSleep(ns int64) { 306 if ns <= 0 { 307 return 308 } 309 310 gp := getg() 311 t := gp.timer 312 if t == nil { 313 t = new(timer) 314 t.init(goroutineReady, gp) 315 if gp.syncGroup != nil { 316 t.isFake = true 317 } 318 gp.timer = t 319 } 320 var now int64 321 if sg := gp.syncGroup; sg != nil { 322 now = sg.now 323 } else { 324 now = nanotime() 325 } 326 when := now + ns 327 if when < 0 { // check for overflow. 328 when = maxWhen 329 } 330 gp.sleepWhen = when 331 if t.isFake { 332 // Call timer.reset in this goroutine, since it's the one in a syncGroup. 333 // We don't need to worry about the timer function running before the goroutine 334 // is parked, because time won't advance until we park. 335 resetForSleep(gp, nil) 336 gopark(nil, nil, waitReasonSleep, traceBlockSleep, 1) 337 } else { 338 gopark(resetForSleep, nil, waitReasonSleep, traceBlockSleep, 1) 339 } 340 } 341 342 // resetForSleep is called after the goroutine is parked for timeSleep. 343 // We can't call timer.reset in timeSleep itself because if this is a short 344 // sleep and there are many goroutines then the P can wind up running the 345 // timer function, goroutineReady, before the goroutine has been parked. 346 func resetForSleep(gp *g, _ unsafe.Pointer) bool { 347 gp.timer.reset(gp.sleepWhen, 0) 348 return true 349 } 350 351 // A timeTimer is a runtime-allocated time.Timer or time.Ticker 352 // with the additional runtime state following it. 353 // The runtime state is inaccessible to package time. 354 type timeTimer struct { 355 c unsafe.Pointer // <-chan time.Time 356 init bool 357 timer 358 } 359 360 // newTimer allocates and returns a new time.Timer or time.Ticker (same layout) 361 // with the given parameters. 362 // 363 //go:linkname newTimer time.newTimer 364 func newTimer(when, period int64, f func(arg any, seq uintptr, delay int64), arg any, c *hchan) *timeTimer { 365 t := new(timeTimer) 366 t.timer.init(nil, nil) 367 t.trace("new") 368 if raceenabled { 369 racerelease(unsafe.Pointer(&t.timer)) 370 } 371 if c != nil { 372 lockInit(&t.sendLock, lockRankTimerSend) 373 t.isChan = true 374 c.timer = &t.timer 375 if c.dataqsiz == 0 { 376 throw("invalid timer channel: no capacity") 377 } 378 } 379 if gr := getg().syncGroup; gr != nil { 380 t.isFake = true 381 } 382 t.modify(when, period, f, arg, 0) 383 t.init = true 384 return t 385 } 386 387 // stopTimer stops a timer. 388 // It reports whether t was stopped before being run. 389 // 390 //go:linkname stopTimer time.stopTimer 391 func stopTimer(t *timeTimer) bool { 392 if t.isFake && getg().syncGroup == nil { 393 panic("stop of synctest timer from outside bubble") 394 } 395 return t.stop() 396 } 397 398 // resetTimer resets an inactive timer, adding it to the timer heap. 399 // 400 // Reports whether the timer was modified before it was run. 401 // 402 //go:linkname resetTimer time.resetTimer 403 func resetTimer(t *timeTimer, when, period int64) bool { 404 if raceenabled { 405 racerelease(unsafe.Pointer(&t.timer)) 406 } 407 if t.isFake && getg().syncGroup == nil { 408 panic("reset of synctest timer from outside bubble") 409 } 410 return t.reset(when, period) 411 } 412 413 // Go runtime. 414 415 // Ready the goroutine arg. 416 func goroutineReady(arg any, _ uintptr, _ int64) { 417 goready(arg.(*g), 0) 418 } 419 420 // addHeap adds t to the timers heap. 421 // The caller must hold ts.lock or the world must be stopped. 422 // The caller must also have checked that t belongs in the heap. 423 // Callers that are not sure can call t.maybeAdd instead, 424 // but note that maybeAdd has different locking requirements. 425 func (ts *timers) addHeap(t *timer) { 426 assertWorldStoppedOrLockHeld(&ts.mu) 427 // Timers rely on the network poller, so make sure the poller 428 // has started. 429 if netpollInited.Load() == 0 { 430 netpollGenericInit() 431 } 432 433 if t.ts != nil { 434 throw("ts set in timer") 435 } 436 t.ts = ts 437 ts.heap = append(ts.heap, timerWhen{t, t.when}) 438 ts.siftUp(len(ts.heap) - 1) 439 if t == ts.heap[0].timer { 440 ts.updateMinWhenHeap() 441 } 442 } 443 444 // maybeRunAsync checks whether t needs to be triggered and runs it if so. 445 // The caller is responsible for locking the timer and for checking that we 446 // are running timers in async mode. If the timer needs to be run, 447 // maybeRunAsync will unlock and re-lock it. 448 // The timer is always locked on return. 449 func (t *timer) maybeRunAsync() { 450 assertLockHeld(&t.mu) 451 if t.state&timerHeaped == 0 && t.isChan && t.when > 0 { 452 // If timer should have triggered already (but nothing looked at it yet), 453 // trigger now, so that a receive after the stop sees the "old" value 454 // that should be there. 455 // (It is possible to have t.blocked > 0 if there is a racing receive 456 // in blockTimerChan, but timerHeaped not being set means 457 // it hasn't run t.maybeAdd yet; in that case, running the 458 // timer ourselves now is fine.) 459 if now := nanotime(); t.when <= now { 460 systemstack(func() { 461 t.unlockAndRun(now) // resets t.when 462 }) 463 t.lock() 464 } 465 } 466 } 467 468 // stop stops the timer t. It may be on some other P, so we can't 469 // actually remove it from the timers heap. We can only mark it as stopped. 470 // It will be removed in due course by the P whose heap it is on. 471 // Reports whether the timer was stopped before it was run. 472 func (t *timer) stop() bool { 473 async := debug.asynctimerchan.Load() != 0 474 if !async && t.isChan { 475 lock(&t.sendLock) 476 } 477 478 t.lock() 479 t.trace("stop") 480 if async { 481 t.maybeRunAsync() 482 } 483 if t.state&timerHeaped != 0 { 484 t.state |= timerModified 485 if t.state&timerZombie == 0 { 486 t.state |= timerZombie 487 t.ts.zombies.Add(1) 488 } 489 } 490 pending := t.when > 0 491 t.when = 0 492 493 if !async && t.isChan { 494 // Stop any future sends with stale values. 495 // See timer.unlockAndRun. 496 t.seq++ 497 498 // If there is currently a send in progress, 499 // incrementing seq is going to prevent that 500 // send from actually happening. That means 501 // that we should return true: the timer was 502 // stopped, even though t.when may be zero. 503 if t.period == 0 && t.isSending.Load() > 0 { 504 pending = true 505 } 506 } 507 t.unlock() 508 if !async && t.isChan { 509 unlock(&t.sendLock) 510 if timerchandrain(t.hchan()) { 511 pending = true 512 } 513 } 514 515 return pending 516 } 517 518 // deleteMin removes timer 0 from ts. 519 // ts must be locked. 520 func (ts *timers) deleteMin() { 521 assertLockHeld(&ts.mu) 522 t := ts.heap[0].timer 523 if t.ts != ts { 524 throw("wrong timers") 525 } 526 t.ts = nil 527 last := len(ts.heap) - 1 528 if last > 0 { 529 ts.heap[0] = ts.heap[last] 530 } 531 ts.heap[last] = timerWhen{} 532 ts.heap = ts.heap[:last] 533 if last > 0 { 534 ts.siftDown(0) 535 } 536 ts.updateMinWhenHeap() 537 if last == 0 { 538 // If there are no timers, then clearly there are no timerModified timers. 539 ts.minWhenModified.Store(0) 540 } 541 } 542 543 // modify modifies an existing timer. 544 // This is called by the netpoll code or time.Ticker.Reset or time.Timer.Reset. 545 // Reports whether the timer was modified before it was run. 546 // If f == nil, then t.f, t.arg, and t.seq are not modified. 547 func (t *timer) modify(when, period int64, f func(arg any, seq uintptr, delay int64), arg any, seq uintptr) bool { 548 if when <= 0 { 549 throw("timer when must be positive") 550 } 551 if period < 0 { 552 throw("timer period must be non-negative") 553 } 554 async := debug.asynctimerchan.Load() != 0 555 556 if !async && t.isChan { 557 lock(&t.sendLock) 558 } 559 560 t.lock() 561 if async { 562 t.maybeRunAsync() 563 } 564 t.trace("modify") 565 oldPeriod := t.period 566 t.period = period 567 if f != nil { 568 t.f = f 569 t.arg = arg 570 t.seq = seq 571 } 572 573 wake := false 574 pending := t.when > 0 575 t.when = when 576 if t.state&timerHeaped != 0 { 577 t.state |= timerModified 578 if t.state&timerZombie != 0 { 579 // In the heap but marked for removal (by a Stop). 580 // Unmark it, since it has been Reset and will be running again. 581 t.ts.zombies.Add(-1) 582 t.state &^= timerZombie 583 } 584 // The corresponding heap[i].when is updated later. 585 // See comment in type timer above and in timers.adjust below. 586 if min := t.ts.minWhenModified.Load(); min == 0 || when < min { 587 wake = true 588 // Force timerModified bit out to t.astate before updating t.minWhenModified, 589 // to synchronize with t.ts.adjust. See comment in adjust. 590 t.astate.Store(t.state) 591 t.ts.updateMinWhenModified(when) 592 } 593 } 594 595 add := t.needsAdd() 596 597 if !async && t.isChan { 598 // Stop any future sends with stale values. 599 // See timer.unlockAndRun. 600 t.seq++ 601 602 // If there is currently a send in progress, 603 // incrementing seq is going to prevent that 604 // send from actually happening. That means 605 // that we should return true: the timer was 606 // stopped, even though t.when may be zero. 607 if oldPeriod == 0 && t.isSending.Load() > 0 { 608 pending = true 609 } 610 } 611 t.unlock() 612 if !async && t.isChan { 613 if timerchandrain(t.hchan()) { 614 pending = true 615 } 616 unlock(&t.sendLock) 617 } 618 619 if add { 620 t.maybeAdd() 621 } 622 if wake { 623 wakeNetPoller(when) 624 } 625 626 return pending 627 } 628 629 // needsAdd reports whether t needs to be added to a timers heap. 630 // t must be locked. 631 func (t *timer) needsAdd() bool { 632 assertLockHeld(&t.mu) 633 need := t.state&timerHeaped == 0 && t.when > 0 && (!t.isChan || t.isFake || t.blocked > 0) 634 if need { 635 t.trace("needsAdd+") 636 } else { 637 t.trace("needsAdd-") 638 } 639 return need 640 } 641 642 // maybeAdd adds t to the local timers heap if it needs to be in a heap. 643 // The caller must not hold t's lock nor any timers heap lock. 644 // The caller probably just unlocked t, but that lock must be dropped 645 // in order to acquire a ts.lock, to avoid lock inversions. 646 // (timers.adjust holds ts.lock while acquiring each t's lock, 647 // so we cannot hold any t's lock while acquiring ts.lock). 648 // 649 // Strictly speaking it *might* be okay to hold t.lock and 650 // acquire ts.lock at the same time, because we know that 651 // t is not in any ts.heap, so nothing holding a ts.lock would 652 // be acquiring the t.lock at the same time, meaning there 653 // isn't a possible deadlock. But it is easier and safer not to be 654 // too clever and respect the static ordering. 655 // (If we don't, we have to change the static lock checking of t and ts.) 656 // 657 // Concurrent calls to time.Timer.Reset or blockTimerChan 658 // may result in concurrent calls to t.maybeAdd, 659 // so we cannot assume that t is not in a heap on entry to t.maybeAdd. 660 func (t *timer) maybeAdd() { 661 // Note: Not holding any locks on entry to t.maybeAdd, 662 // so the current g can be rescheduled to a different M and P 663 // at any time, including between the ts := assignment and the 664 // call to ts.lock. If a reschedule happened then, we would be 665 // adding t to some other P's timers, perhaps even a P that the scheduler 666 // has marked as idle with no timers, in which case the timer could 667 // go unnoticed until long after t.when. 668 // Calling acquirem instead of using getg().m makes sure that 669 // we end up locking and inserting into the current P's timers. 670 mp := acquirem() 671 var ts *timers 672 if t.isFake { 673 sg := getg().syncGroup 674 if sg == nil { 675 throw("invalid timer: fake time but no syncgroup") 676 } 677 ts = &sg.timers 678 } else { 679 ts = &mp.p.ptr().timers 680 } 681 ts.lock() 682 ts.cleanHead() 683 t.lock() 684 t.trace("maybeAdd") 685 when := int64(0) 686 wake := false 687 if t.needsAdd() { 688 t.state |= timerHeaped 689 when = t.when 690 wakeTime := ts.wakeTime() 691 wake = wakeTime == 0 || when < wakeTime 692 ts.addHeap(t) 693 } 694 t.unlock() 695 ts.unlock() 696 releasem(mp) 697 if wake { 698 wakeNetPoller(when) 699 } 700 } 701 702 // reset resets the time when a timer should fire. 703 // If used for an inactive timer, the timer will become active. 704 // Reports whether the timer was active and was stopped. 705 func (t *timer) reset(when, period int64) bool { 706 return t.modify(when, period, nil, nil, 0) 707 } 708 709 // cleanHead cleans up the head of the timer queue. This speeds up 710 // programs that create and delete timers; leaving them in the heap 711 // slows down heap operations. 712 // The caller must have locked ts. 713 func (ts *timers) cleanHead() { 714 ts.trace("cleanHead") 715 assertLockHeld(&ts.mu) 716 gp := getg() 717 for { 718 if len(ts.heap) == 0 { 719 return 720 } 721 722 // This loop can theoretically run for a while, and because 723 // it is holding timersLock it cannot be preempted. 724 // If someone is trying to preempt us, just return. 725 // We can clean the timers later. 726 if gp.preemptStop { 727 return 728 } 729 730 // Delete zombies from tail of heap. It requires no heap adjustments at all, 731 // and doing so increases the chances that when we swap out a zombie 732 // in heap[0] for the tail of the heap, we'll get a non-zombie timer, 733 // shortening this loop. 734 n := len(ts.heap) 735 if t := ts.heap[n-1].timer; t.astate.Load()&timerZombie != 0 { 736 t.lock() 737 if t.state&timerZombie != 0 { 738 t.state &^= timerHeaped | timerZombie | timerModified 739 t.ts = nil 740 ts.zombies.Add(-1) 741 ts.heap[n-1] = timerWhen{} 742 ts.heap = ts.heap[:n-1] 743 } 744 t.unlock() 745 continue 746 } 747 748 t := ts.heap[0].timer 749 if t.ts != ts { 750 throw("bad ts") 751 } 752 753 if t.astate.Load()&(timerModified|timerZombie) == 0 { 754 // Fast path: head of timers does not need adjustment. 755 return 756 } 757 758 t.lock() 759 updated := t.updateHeap() 760 t.unlock() 761 if !updated { 762 // Head of timers does not need adjustment. 763 return 764 } 765 } 766 } 767 768 // take moves any timers from src into ts 769 // and then clears the timer state from src, 770 // because src is being destroyed. 771 // The caller must not have locked either timers. 772 // For now this is only called when the world is stopped. 773 func (ts *timers) take(src *timers) { 774 ts.trace("take") 775 assertWorldStopped() 776 if len(src.heap) > 0 { 777 // The world is stopped, so we ignore the locking of ts and src here. 778 // That would introduce a sched < timers lock ordering, 779 // which we'd rather avoid in the static ranking. 780 for _, tw := range src.heap { 781 t := tw.timer 782 t.ts = nil 783 if t.state&timerZombie != 0 { 784 t.state &^= timerHeaped | timerZombie | timerModified 785 } else { 786 t.state &^= timerModified 787 ts.addHeap(t) 788 } 789 } 790 src.heap = nil 791 src.zombies.Store(0) 792 src.minWhenHeap.Store(0) 793 src.minWhenModified.Store(0) 794 src.len.Store(0) 795 ts.len.Store(uint32(len(ts.heap))) 796 } 797 } 798 799 // adjust looks through the timers in ts.heap for 800 // any timers that have been modified to run earlier, and puts them in 801 // the correct place in the heap. While looking for those timers, 802 // it also moves timers that have been modified to run later, 803 // and removes deleted timers. The caller must have locked ts. 804 func (ts *timers) adjust(now int64, force bool) { 805 ts.trace("adjust") 806 assertLockHeld(&ts.mu) 807 // If we haven't yet reached the time of the earliest modified 808 // timer, don't do anything. This speeds up programs that adjust 809 // a lot of timers back and forth if the timers rarely expire. 810 // We'll postpone looking through all the adjusted timers until 811 // one would actually expire. 812 if !force { 813 first := ts.minWhenModified.Load() 814 if first == 0 || first > now { 815 if verifyTimers { 816 ts.verify() 817 } 818 return 819 } 820 } 821 822 // minWhenModified is a lower bound on the earliest t.when 823 // among the timerModified timers. We want to make it more precise: 824 // we are going to scan the heap and clean out all the timerModified bits, 825 // at which point minWhenModified can be set to 0 (indicating none at all). 826 // 827 // Other P's can be calling ts.wakeTime concurrently, and we'd like to 828 // keep ts.wakeTime returning an accurate value throughout this entire process. 829 // 830 // Setting minWhenModified = 0 *before* the scan could make wakeTime 831 // return an incorrect value: if minWhenModified < minWhenHeap, then clearing 832 // it to 0 will make wakeTime return minWhenHeap (too late) until the scan finishes. 833 // To avoid that, we want to set minWhenModified to 0 *after* the scan. 834 // 835 // Setting minWhenModified = 0 *after* the scan could result in missing 836 // concurrent timer modifications in other goroutines; those will lock 837 // the specific timer, set the timerModified bit, and set t.when. 838 // To avoid that, we want to set minWhenModified to 0 *before* the scan. 839 // 840 // The way out of this dilemma is to preserve wakeTime a different way. 841 // wakeTime is min(minWhenHeap, minWhenModified), and minWhenHeap 842 // is protected by ts.lock, which we hold, so we can modify it however we like 843 // in service of keeping wakeTime accurate. 844 // 845 // So we can: 846 // 847 // 1. Set minWhenHeap = min(minWhenHeap, minWhenModified) 848 // 2. Set minWhenModified = 0 849 // (Other goroutines may modify timers and update minWhenModified now.) 850 // 3. Scan timers 851 // 4. Set minWhenHeap = heap[0].when 852 // 853 // That order preserves a correct value of wakeTime throughout the entire 854 // operation: 855 // Step 1 “locks in” an accurate wakeTime even with minWhenModified cleared. 856 // Step 2 makes sure concurrent t.when updates are not lost during the scan. 857 // Step 3 processes all modified timer values, justifying minWhenModified = 0. 858 // Step 4 corrects minWhenHeap to a precise value. 859 // 860 // The wakeTime method implementation reads minWhenModified *before* minWhenHeap, 861 // so that if the minWhenModified is observed to be 0, that means the minWhenHeap that 862 // follows will include the information that was zeroed out of it. 863 // 864 // Originally Step 3 locked every timer, which made sure any timer update that was 865 // already in progress during Steps 1+2 completed and was observed by Step 3. 866 // All that locking was too expensive, so now we do an atomic load of t.astate to 867 // decide whether we need to do a full lock. To make sure that we still observe any 868 // timer update already in progress during Steps 1+2, t.modify sets timerModified 869 // in t.astate *before* calling t.updateMinWhenModified. That ensures that the 870 // overwrite in Step 2 cannot lose an update: if it does overwrite an update, Step 3 871 // will see the timerModified and do a full lock. 872 ts.minWhenHeap.Store(ts.wakeTime()) 873 ts.minWhenModified.Store(0) 874 875 changed := false 876 for i := 0; i < len(ts.heap); i++ { 877 tw := &ts.heap[i] 878 t := tw.timer 879 if t.ts != ts { 880 throw("bad ts") 881 } 882 883 if t.astate.Load()&(timerModified|timerZombie) == 0 { 884 // Does not need adjustment. 885 continue 886 } 887 888 t.lock() 889 switch { 890 case t.state&timerHeaped == 0: 891 badTimer() 892 893 case t.state&timerZombie != 0: 894 ts.zombies.Add(-1) 895 t.state &^= timerHeaped | timerZombie | timerModified 896 n := len(ts.heap) 897 ts.heap[i] = ts.heap[n-1] 898 ts.heap[n-1] = timerWhen{} 899 ts.heap = ts.heap[:n-1] 900 t.ts = nil 901 i-- 902 changed = true 903 904 case t.state&timerModified != 0: 905 tw.when = t.when 906 t.state &^= timerModified 907 changed = true 908 } 909 t.unlock() 910 } 911 912 if changed { 913 ts.initHeap() 914 } 915 ts.updateMinWhenHeap() 916 917 if verifyTimers { 918 ts.verify() 919 } 920 } 921 922 // wakeTime looks at ts's timers and returns the time when we 923 // should wake up the netpoller. It returns 0 if there are no timers. 924 // This function is invoked when dropping a P, so it must run without 925 // any write barriers. 926 // 927 //go:nowritebarrierrec 928 func (ts *timers) wakeTime() int64 { 929 // Note that the order of these two loads matters: 930 // adjust updates minWhen to make it safe to clear minNextWhen. 931 // We read minWhen after reading minNextWhen so that 932 // if we see a cleared minNextWhen, we are guaranteed to see 933 // the updated minWhen. 934 nextWhen := ts.minWhenModified.Load() 935 when := ts.minWhenHeap.Load() 936 if when == 0 || (nextWhen != 0 && nextWhen < when) { 937 when = nextWhen 938 } 939 return when 940 } 941 942 // check runs any timers in ts that are ready. 943 // If now is not 0 it is the current time. 944 // It returns the passed time or the current time if now was passed as 0. 945 // and the time when the next timer should run or 0 if there is no next timer, 946 // and reports whether it ran any timers. 947 // If the time when the next timer should run is not 0, 948 // it is always larger than the returned time. 949 // We pass now in and out to avoid extra calls of nanotime. 950 // 951 //go:yeswritebarrierrec 952 func (ts *timers) check(now int64) (rnow, pollUntil int64, ran bool) { 953 ts.trace("check") 954 // If it's not yet time for the first timer, or the first adjusted 955 // timer, then there is nothing to do. 956 next := ts.wakeTime() 957 if next == 0 { 958 // No timers to run or adjust. 959 return now, 0, false 960 } 961 962 if now == 0 { 963 now = nanotime() 964 } 965 966 // If this is the local P, and there are a lot of deleted timers, 967 // clear them out. We only do this for the local P to reduce 968 // lock contention on timersLock. 969 zombies := ts.zombies.Load() 970 if zombies < 0 { 971 badTimer() 972 } 973 force := ts == &getg().m.p.ptr().timers && int(zombies) > int(ts.len.Load())/4 974 975 if now < next && !force { 976 // Next timer is not ready to run, and we don't need to clear deleted timers. 977 return now, next, false 978 } 979 980 ts.lock() 981 if len(ts.heap) > 0 { 982 ts.adjust(now, false) 983 for len(ts.heap) > 0 { 984 // Note that runtimer may temporarily unlock ts. 985 if tw := ts.run(now); tw != 0 { 986 if tw > 0 { 987 pollUntil = tw 988 } 989 break 990 } 991 ran = true 992 } 993 994 // Note: Delaying the forced adjustment until after the ts.run 995 // (as opposed to calling ts.adjust(now, force) above) 996 // is significantly faster under contention, such as in 997 // package time's BenchmarkTimerAdjust10000, 998 // though we do not fully understand why. 999 force = ts == &getg().m.p.ptr().timers && int(ts.zombies.Load()) > int(ts.len.Load())/4 1000 if force { 1001 ts.adjust(now, true) 1002 } 1003 } 1004 ts.unlock() 1005 1006 return now, pollUntil, ran 1007 } 1008 1009 // run examines the first timer in ts. If it is ready based on now, 1010 // it runs the timer and removes or updates it. 1011 // Returns 0 if it ran a timer, -1 if there are no more timers, or the time 1012 // when the first timer should run. 1013 // The caller must have locked ts. 1014 // If a timer is run, this will temporarily unlock ts. 1015 // 1016 //go:systemstack 1017 func (ts *timers) run(now int64) int64 { 1018 ts.trace("run") 1019 assertLockHeld(&ts.mu) 1020 Redo: 1021 if len(ts.heap) == 0 { 1022 return -1 1023 } 1024 tw := ts.heap[0] 1025 t := tw.timer 1026 if t.ts != ts { 1027 throw("bad ts") 1028 } 1029 1030 if t.astate.Load()&(timerModified|timerZombie) == 0 && tw.when > now { 1031 // Fast path: not ready to run. 1032 return tw.when 1033 } 1034 1035 t.lock() 1036 if t.updateHeap() { 1037 t.unlock() 1038 goto Redo 1039 } 1040 1041 if t.state&timerHeaped == 0 || t.state&timerModified != 0 { 1042 badTimer() 1043 } 1044 1045 if t.when > now { 1046 // Not ready to run. 1047 t.unlock() 1048 return t.when 1049 } 1050 1051 t.unlockAndRun(now) 1052 assertLockHeld(&ts.mu) // t is unlocked now, but not ts 1053 return 0 1054 } 1055 1056 // unlockAndRun unlocks and runs the timer t (which must be locked). 1057 // If t is in a timer set (t.ts != nil), the caller must also have locked the timer set, 1058 // and this call will temporarily unlock the timer set while running the timer function. 1059 // unlockAndRun returns with t unlocked and t.ts (re-)locked. 1060 // 1061 //go:systemstack 1062 func (t *timer) unlockAndRun(now int64) { 1063 t.trace("unlockAndRun") 1064 assertLockHeld(&t.mu) 1065 if t.ts != nil { 1066 assertLockHeld(&t.ts.mu) 1067 } 1068 if raceenabled { 1069 // Note that we are running on a system stack, 1070 // so there is no chance of getg().m being reassigned 1071 // out from under us while this function executes. 1072 tsLocal := &getg().m.p.ptr().timers 1073 if tsLocal.raceCtx == 0 { 1074 tsLocal.raceCtx = racegostart(abi.FuncPCABIInternal((*timers).run) + sys.PCQuantum) 1075 } 1076 raceacquirectx(tsLocal.raceCtx, unsafe.Pointer(t)) 1077 } 1078 1079 if t.state&(timerModified|timerZombie) != 0 { 1080 badTimer() 1081 } 1082 1083 f := t.f 1084 arg := t.arg 1085 seq := t.seq 1086 var next int64 1087 delay := now - t.when 1088 if t.period > 0 { 1089 // Leave in heap but adjust next time to fire. 1090 next = t.when + t.period*(1+delay/t.period) 1091 if next < 0 { // check for overflow. 1092 next = maxWhen 1093 } 1094 } else { 1095 next = 0 1096 } 1097 ts := t.ts 1098 t.when = next 1099 if t.state&timerHeaped != 0 { 1100 t.state |= timerModified 1101 if next == 0 { 1102 t.state |= timerZombie 1103 t.ts.zombies.Add(1) 1104 } 1105 t.updateHeap() 1106 } 1107 1108 async := debug.asynctimerchan.Load() != 0 1109 if !async && t.isChan && t.period == 0 { 1110 // Tell Stop/Reset that we are sending a value. 1111 if t.isSending.Add(1) < 0 { 1112 throw("too many concurrent timer firings") 1113 } 1114 } 1115 1116 t.unlock() 1117 1118 if raceenabled { 1119 // Temporarily use the current P's racectx for g0. 1120 gp := getg() 1121 if gp.racectx != 0 { 1122 throw("unexpected racectx") 1123 } 1124 gp.racectx = gp.m.p.ptr().timers.raceCtx 1125 } 1126 1127 if ts != nil { 1128 ts.unlock() 1129 } 1130 1131 if ts != nil && ts.syncGroup != nil { 1132 // Temporarily use the timer's synctest group for the G running this timer. 1133 gp := getg() 1134 if gp.syncGroup != nil { 1135 throw("unexpected syncgroup set") 1136 } 1137 gp.syncGroup = ts.syncGroup 1138 ts.syncGroup.changegstatus(gp, _Gdead, _Grunning) 1139 } 1140 1141 if !async && t.isChan { 1142 // For a timer channel, we want to make sure that no stale sends 1143 // happen after a t.stop or t.modify, but we cannot hold t.mu 1144 // during the actual send (which f does) due to lock ordering. 1145 // It can happen that we are holding t's lock above, we decide 1146 // it's time to send a time value (by calling f), grab the parameters, 1147 // unlock above, and then a t.stop or t.modify changes the timer 1148 // and returns. At that point, the send needs not to happen after all. 1149 // The way we arrange for it not to happen is that t.stop and t.modify 1150 // both increment t.seq while holding both t.mu and t.sendLock. 1151 // We copied the seq value above while holding t.mu. 1152 // Now we can acquire t.sendLock (which will be held across the send) 1153 // and double-check that t.seq is still the seq value we saw above. 1154 // If not, the timer has been updated and we should skip the send. 1155 // We skip the send by reassigning f to a no-op function. 1156 // 1157 // The isSending field tells t.stop or t.modify that we have 1158 // started to send the value. That lets them correctly return 1159 // true meaning that no value was sent. 1160 lock(&t.sendLock) 1161 1162 if t.period == 0 { 1163 // We are committed to possibly sending a value 1164 // based on seq, so no need to keep telling 1165 // stop/modify that we are sending. 1166 if t.isSending.Add(-1) < 0 { 1167 throw("mismatched isSending updates") 1168 } 1169 } 1170 1171 if t.seq != seq { 1172 f = func(any, uintptr, int64) {} 1173 } 1174 } 1175 1176 f(arg, seq, delay) 1177 1178 if !async && t.isChan { 1179 unlock(&t.sendLock) 1180 } 1181 1182 if ts != nil && ts.syncGroup != nil { 1183 gp := getg() 1184 ts.syncGroup.changegstatus(gp, _Grunning, _Gdead) 1185 gp.syncGroup = nil 1186 } 1187 1188 if ts != nil { 1189 ts.lock() 1190 } 1191 1192 if raceenabled { 1193 gp := getg() 1194 gp.racectx = 0 1195 } 1196 } 1197 1198 // verifyTimerHeap verifies that the timers is in a valid state. 1199 // This is only for debugging, and is only called if verifyTimers is true. 1200 // The caller must have locked ts. 1201 func (ts *timers) verify() { 1202 assertLockHeld(&ts.mu) 1203 for i, tw := range ts.heap { 1204 if i == 0 { 1205 // First timer has no parent. 1206 continue 1207 } 1208 1209 // The heap is timerHeapN-ary. See siftupTimer and siftdownTimer. 1210 p := int(uint(i-1) / timerHeapN) 1211 if tw.when < ts.heap[p].when { 1212 print("bad timer heap at ", i, ": ", p, ": ", ts.heap[p].when, ", ", i, ": ", tw.when, "\n") 1213 throw("bad timer heap") 1214 } 1215 } 1216 if n := int(ts.len.Load()); len(ts.heap) != n { 1217 println("timer heap len", len(ts.heap), "!= atomic len", n) 1218 throw("bad timer heap len") 1219 } 1220 } 1221 1222 // updateMinWhenHeap sets ts.minWhenHeap to ts.heap[0].when. 1223 // The caller must have locked ts or the world must be stopped. 1224 func (ts *timers) updateMinWhenHeap() { 1225 assertWorldStoppedOrLockHeld(&ts.mu) 1226 if len(ts.heap) == 0 { 1227 ts.minWhenHeap.Store(0) 1228 } else { 1229 ts.minWhenHeap.Store(ts.heap[0].when) 1230 } 1231 } 1232 1233 // updateMinWhenModified updates ts.minWhenModified to be <= when. 1234 // ts need not be (and usually is not) locked. 1235 func (ts *timers) updateMinWhenModified(when int64) { 1236 for { 1237 old := ts.minWhenModified.Load() 1238 if old != 0 && old < when { 1239 return 1240 } 1241 if ts.minWhenModified.CompareAndSwap(old, when) { 1242 return 1243 } 1244 } 1245 } 1246 1247 // timeSleepUntil returns the time when the next timer should fire. Returns 1248 // maxWhen if there are no timers. 1249 // This is only called by sysmon and checkdead. 1250 func timeSleepUntil() int64 { 1251 next := int64(maxWhen) 1252 1253 // Prevent allp slice changes. This is like retake. 1254 lock(&allpLock) 1255 for _, pp := range allp { 1256 if pp == nil { 1257 // This can happen if procresize has grown 1258 // allp but not yet created new Ps. 1259 continue 1260 } 1261 1262 if w := pp.timers.wakeTime(); w != 0 { 1263 next = min(next, w) 1264 } 1265 } 1266 unlock(&allpLock) 1267 1268 return next 1269 } 1270 1271 const timerHeapN = 4 1272 1273 // Heap maintenance algorithms. 1274 // These algorithms check for slice index errors manually. 1275 // Slice index error can happen if the program is using racy 1276 // access to timers. We don't want to panic here, because 1277 // it will cause the program to crash with a mysterious 1278 // "panic holding locks" message. Instead, we panic while not 1279 // holding a lock. 1280 1281 // siftUp puts the timer at position i in the right place 1282 // in the heap by moving it up toward the top of the heap. 1283 func (ts *timers) siftUp(i int) { 1284 heap := ts.heap 1285 if i >= len(heap) { 1286 badTimer() 1287 } 1288 tw := heap[i] 1289 when := tw.when 1290 if when <= 0 { 1291 badTimer() 1292 } 1293 for i > 0 { 1294 p := int(uint(i-1) / timerHeapN) // parent 1295 if when >= heap[p].when { 1296 break 1297 } 1298 heap[i] = heap[p] 1299 i = p 1300 } 1301 if heap[i].timer != tw.timer { 1302 heap[i] = tw 1303 } 1304 } 1305 1306 // siftDown puts the timer at position i in the right place 1307 // in the heap by moving it down toward the bottom of the heap. 1308 func (ts *timers) siftDown(i int) { 1309 heap := ts.heap 1310 n := len(heap) 1311 if i >= n { 1312 badTimer() 1313 } 1314 if i*timerHeapN+1 >= n { 1315 return 1316 } 1317 tw := heap[i] 1318 when := tw.when 1319 if when <= 0 { 1320 badTimer() 1321 } 1322 for { 1323 leftChild := i*timerHeapN + 1 1324 if leftChild >= n { 1325 break 1326 } 1327 w := when 1328 c := -1 1329 for j, tw := range heap[leftChild:min(leftChild+timerHeapN, n)] { 1330 if tw.when < w { 1331 w = tw.when 1332 c = leftChild + j 1333 } 1334 } 1335 if c < 0 { 1336 break 1337 } 1338 heap[i] = heap[c] 1339 i = c 1340 } 1341 if heap[i].timer != tw.timer { 1342 heap[i] = tw 1343 } 1344 } 1345 1346 // initHeap reestablishes the heap order in the slice ts.heap. 1347 // It takes O(n) time for n=len(ts.heap), not the O(n log n) of n repeated add operations. 1348 func (ts *timers) initHeap() { 1349 // Last possible element that needs sifting down is parent of last element; 1350 // last element is len(t)-1; parent of last element is (len(t)-1-1)/timerHeapN. 1351 if len(ts.heap) <= 1 { 1352 return 1353 } 1354 for i := int(uint(len(ts.heap)-1-1) / timerHeapN); i >= 0; i-- { 1355 ts.siftDown(i) 1356 } 1357 } 1358 1359 // badTimer is called if the timer data structures have been corrupted, 1360 // presumably due to racy use by the program. We panic here rather than 1361 // panicking due to invalid slice access while holding locks. 1362 // See issue #25686. 1363 func badTimer() { 1364 throw("timer data corruption") 1365 } 1366 1367 // Timer channels. 1368 1369 // maybeRunChan checks whether the timer needs to run 1370 // to send a value to its associated channel. If so, it does. 1371 // The timer must not be locked. 1372 func (t *timer) maybeRunChan() { 1373 if t.isFake { 1374 t.lock() 1375 var timerGroup *synctestGroup 1376 if t.ts != nil { 1377 timerGroup = t.ts.syncGroup 1378 } 1379 t.unlock() 1380 sg := getg().syncGroup 1381 if sg == nil { 1382 panic(plainError("synctest timer accessed from outside bubble")) 1383 } 1384 if timerGroup != nil && sg != timerGroup { 1385 panic(plainError("timer moved between synctest bubbles")) 1386 } 1387 // No need to do anything here. 1388 // synctest.Run will run the timer when it advances its fake clock. 1389 return 1390 } 1391 if t.astate.Load()&timerHeaped != 0 { 1392 // If the timer is in the heap, the ordinary timer code 1393 // is in charge of sending when appropriate. 1394 return 1395 } 1396 1397 t.lock() 1398 now := nanotime() 1399 if t.state&timerHeaped != 0 || t.when == 0 || t.when > now { 1400 t.trace("maybeRunChan-") 1401 // Timer in the heap, or not running at all, or not triggered. 1402 t.unlock() 1403 return 1404 } 1405 t.trace("maybeRunChan+") 1406 systemstack(func() { 1407 t.unlockAndRun(now) 1408 }) 1409 } 1410 1411 // blockTimerChan is called when a channel op has decided to block on c. 1412 // The caller holds the channel lock for c and possibly other channels. 1413 // blockTimerChan makes sure that c is in a timer heap, 1414 // adding it if needed. 1415 func blockTimerChan(c *hchan) { 1416 t := c.timer 1417 if t.isFake { 1418 return 1419 } 1420 t.lock() 1421 t.trace("blockTimerChan") 1422 if !t.isChan { 1423 badTimer() 1424 } 1425 1426 t.blocked++ 1427 1428 // If this is the first enqueue after a recent dequeue, 1429 // the timer may still be in the heap but marked as a zombie. 1430 // Unmark it in this case, if the timer is still pending. 1431 if t.state&timerHeaped != 0 && t.state&timerZombie != 0 && t.when > 0 { 1432 t.state &^= timerZombie 1433 t.ts.zombies.Add(-1) 1434 } 1435 1436 // t.maybeAdd must be called with t unlocked, 1437 // because it needs to lock t.ts before t. 1438 // Then it will do nothing if t.needsAdd(state) is false. 1439 // Check that now before the unlock, 1440 // avoiding the extra lock-lock-unlock-unlock 1441 // inside maybeAdd when t does not need to be added. 1442 add := t.needsAdd() 1443 t.unlock() 1444 if add { 1445 t.maybeAdd() 1446 } 1447 } 1448 1449 // unblockTimerChan is called when a channel op that was blocked on c 1450 // is no longer blocked. Every call to blockTimerChan must be paired with 1451 // a call to unblockTimerChan. 1452 // The caller holds the channel lock for c and possibly other channels. 1453 // unblockTimerChan removes c from the timer heap when nothing is 1454 // blocked on it anymore. 1455 func unblockTimerChan(c *hchan) { 1456 t := c.timer 1457 if t.isFake { 1458 return 1459 } 1460 t.lock() 1461 t.trace("unblockTimerChan") 1462 if !t.isChan || t.blocked == 0 { 1463 badTimer() 1464 } 1465 t.blocked-- 1466 if t.blocked == 0 && t.state&timerHeaped != 0 && t.state&timerZombie == 0 { 1467 // Last goroutine that was blocked on this timer. 1468 // Mark for removal from heap but do not clear t.when, 1469 // so that we know what time it is still meant to trigger. 1470 t.state |= timerZombie 1471 t.ts.zombies.Add(1) 1472 } 1473 t.unlock() 1474 } 1475