Source file src/runtime/proc.go
1 // Copyright 2014 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 package runtime 6 7 import ( 8 "internal/abi" 9 "internal/cpu" 10 "internal/goarch" 11 "internal/goexperiment" 12 "internal/goos" 13 "internal/runtime/atomic" 14 "internal/runtime/exithook" 15 "internal/runtime/maps" 16 "internal/runtime/sys" 17 "internal/strconv" 18 "internal/stringslite" 19 "unsafe" 20 ) 21 22 // set using cmd/go/internal/modload.ModInfoProg 23 var modinfo string 24 25 // Goroutine scheduler 26 // The scheduler's job is to distribute ready-to-run goroutines over worker threads. 27 // 28 // The main concepts are: 29 // G - goroutine. 30 // M - worker thread, or machine. 31 // P - processor, a resource that is required to execute Go code. 32 // M must have an associated P to execute Go code, however it can be 33 // blocked or in a syscall w/o an associated P. 34 // 35 // Design doc at https://golang.org/s/go11sched. 36 37 // Worker thread parking/unparking. 38 // We need to balance between keeping enough running worker threads to utilize 39 // available hardware parallelism and parking excessive running worker threads 40 // to conserve CPU resources and power. This is not simple for two reasons: 41 // (1) scheduler state is intentionally distributed (in particular, per-P work 42 // queues), so it is not possible to compute global predicates on fast paths; 43 // (2) for optimal thread management we would need to know the future (don't park 44 // a worker thread when a new goroutine will be readied in near future). 45 // 46 // Three rejected approaches that would work badly: 47 // 1. Centralize all scheduler state (would inhibit scalability). 48 // 2. Direct goroutine handoff. That is, when we ready a new goroutine and there 49 // is a spare P, unpark a thread and handoff it the thread and the goroutine. 50 // This would lead to thread state thrashing, as the thread that readied the 51 // goroutine can be out of work the very next moment, we will need to park it. 52 // Also, it would destroy locality of computation as we want to preserve 53 // dependent goroutines on the same thread; and introduce additional latency. 54 // 3. Unpark an additional thread whenever we ready a goroutine and there is an 55 // idle P, but don't do handoff. This would lead to excessive thread parking/ 56 // unparking as the additional threads will instantly park without discovering 57 // any work to do. 58 // 59 // The current approach: 60 // 61 // This approach applies to three primary sources of potential work: readying a 62 // goroutine, new/modified-earlier timers, and idle-priority GC. See below for 63 // additional details. 64 // 65 // We unpark an additional thread when we submit work if (this is wakep()): 66 // 1. There is an idle P, and 67 // 2. There are no "spinning" worker threads. 68 // 69 // A worker thread is considered spinning if it is out of local work and did 70 // not find work in the global run queue or netpoller; the spinning state is 71 // denoted in m.spinning and in sched.nmspinning. Threads unparked this way are 72 // also considered spinning; we don't do goroutine handoff so such threads are 73 // out of work initially. Spinning threads spin on looking for work in per-P 74 // run queues and timer heaps or from the GC before parking. If a spinning 75 // thread finds work it takes itself out of the spinning state and proceeds to 76 // execution. If it does not find work it takes itself out of the spinning 77 // state and then parks. 78 // 79 // If there is at least one spinning thread (sched.nmspinning>1), we don't 80 // unpark new threads when submitting work. To compensate for that, if the last 81 // spinning thread finds work and stops spinning, it must unpark a new spinning 82 // thread. This approach smooths out unjustified spikes of thread unparking, 83 // but at the same time guarantees eventual maximal CPU parallelism 84 // utilization. 85 // 86 // The main implementation complication is that we need to be very careful 87 // during spinning->non-spinning thread transition. This transition can race 88 // with submission of new work, and either one part or another needs to unpark 89 // another worker thread. If they both fail to do that, we can end up with 90 // semi-persistent CPU underutilization. 91 // 92 // The general pattern for submission is: 93 // 1. Submit work to the local or global run queue, timer heap, or GC state. 94 // 2. #StoreLoad-style memory barrier. 95 // 3. Check sched.nmspinning. 96 // 97 // The general pattern for spinning->non-spinning transition is: 98 // 1. Decrement nmspinning. 99 // 2. #StoreLoad-style memory barrier. 100 // 3. Check all per-P work queues and GC for new work. 101 // 102 // Note that all this complexity does not apply to global run queue as we are 103 // not sloppy about thread unparking when submitting to global queue. Also see 104 // comments for nmspinning manipulation. 105 // 106 // How these different sources of work behave varies, though it doesn't affect 107 // the synchronization approach: 108 // * Ready goroutine: this is an obvious source of work; the goroutine is 109 // immediately ready and must run on some thread eventually. 110 // * New/modified-earlier timer: The current timer implementation (see time.go) 111 // uses netpoll in a thread with no work available to wait for the soonest 112 // timer. If there is no thread waiting, we want a new spinning thread to go 113 // wait. 114 // * Idle-priority GC: The GC wakes a stopped idle thread to contribute to 115 // background GC work (note: currently disabled per golang.org/issue/19112). 116 // Also see golang.org/issue/44313, as this should be extended to all GC 117 // workers. 118 119 var ( 120 m0 m 121 g0 g 122 mcache0 *mcache 123 raceprocctx0 uintptr 124 raceFiniLock mutex 125 ) 126 127 // This slice records the initializing tasks that need to be 128 // done to start up the runtime. It is built by the linker. 129 var runtime_inittasks []*initTask 130 131 // mainInitDone is a signal used by cgocallbackg that initialization 132 // has been completed. If this is false, wait on mainInitDoneChan. 133 var mainInitDone atomic.Bool 134 135 // mainInitDoneChan is closed after initialization has been completed. 136 // It is made before _cgo_notify_runtime_init_done, so all cgo 137 // calls can rely on it existing. 138 var mainInitDoneChan chan bool 139 140 //go:linkname main_main main.main 141 func main_main() 142 143 // mainStarted indicates that the main M has started. 144 var mainStarted bool 145 146 // runtimeInitTime is the nanotime() at which the runtime started. 147 var runtimeInitTime int64 148 149 // Value to use for signal mask for newly created M's. 150 var initSigmask sigset 151 152 // The main goroutine. 153 func main() { 154 mp := getg().m 155 156 // Racectx of m0->g0 is used only as the parent of the main goroutine. 157 // It must not be used for anything else. 158 mp.g0.racectx = 0 159 160 // Max stack size is 1 GB on 64-bit, 250 MB on 32-bit. 161 // Using decimal instead of binary GB and MB because 162 // they look nicer in the stack overflow failure message. 163 if goarch.PtrSize == 8 { 164 maxstacksize = 1000000000 165 } else { 166 maxstacksize = 250000000 167 } 168 169 // An upper limit for max stack size. Used to avoid random crashes 170 // after calling SetMaxStack and trying to allocate a stack that is too big, 171 // since stackalloc works with 32-bit sizes. 172 maxstackceiling = 2 * maxstacksize 173 174 // Allow newproc to start new Ms. 175 mainStarted = true 176 177 if haveSysmon { 178 systemstack(func() { 179 newm(sysmon, nil, -1) 180 }) 181 } 182 183 // Lock the main goroutine onto this, the main OS thread, 184 // during initialization. Most programs won't care, but a few 185 // do require certain calls to be made by the main thread. 186 // Those can arrange for main.main to run in the main thread 187 // by calling runtime.LockOSThread during initialization 188 // to preserve the lock. 189 lockOSThread() 190 191 if mp != &m0 { 192 throw("runtime.main not on m0") 193 } 194 195 // Record when the world started. 196 // Must be before doInit for tracing init. 197 runtimeInitTime = nanotime() 198 if runtimeInitTime == 0 { 199 throw("nanotime returning zero") 200 } 201 202 if debug.inittrace != 0 { 203 inittrace.id = getg().goid 204 inittrace.active = true 205 } 206 207 doInit(runtime_inittasks) // Must be before defer. 208 209 // Defer unlock so that runtime.Goexit during init does the unlock too. 210 needUnlock := true 211 defer func() { 212 if needUnlock { 213 unlockOSThread() 214 } 215 }() 216 217 gcenable() 218 defaultGOMAXPROCSUpdateEnable() // don't STW before runtime initialized. 219 220 // If we encountered a removed GODEBUG during startup we can panic now. 221 if k := invalidGODEBUG.key; k != "" { 222 v := invalidGODEBUG.value 223 r := strconv.Itoa(invalidGODEBUG.removed) 224 fatal(`removed GODEBUG "` + k + `" set to old value "` + v + `" in environment (https://go.dev/doc/godebug#go-1` + r + `)`) 225 } 226 227 mainInitDoneChan = make(chan bool) 228 if iscgo { 229 if _cgo_pthread_key_created == nil { 230 throw("_cgo_pthread_key_created missing") 231 } 232 233 if GOOS != "windows" { 234 if _cgo_thread_start == nil { 235 throw("_cgo_thread_start missing") 236 } 237 if _cgo_setenv == nil { 238 throw("_cgo_setenv missing") 239 } 240 if _cgo_unsetenv == nil { 241 throw("_cgo_unsetenv missing") 242 } 243 } 244 if _cgo_notify_runtime_init_done == nil { 245 throw("_cgo_notify_runtime_init_done missing") 246 } 247 248 // Set the x_crosscall2_ptr C function pointer variable point to crosscall2. 249 if set_crosscall2 == nil { 250 throw("set_crosscall2 missing") 251 } 252 set_crosscall2() 253 254 // Start the template thread in case we enter Go from 255 // a C-created thread and need to create a new thread. 256 startTemplateThread() 257 cgocall(_cgo_notify_runtime_init_done, nil) 258 } 259 260 // Run the initializing tasks. Depending on build mode this 261 // list can arrive a few different ways, but it will always 262 // contain the init tasks computed by the linker for all the 263 // packages in the program (excluding those added at runtime 264 // by package plugin). Run through the modules in dependency 265 // order (the order they are initialized by the dynamic 266 // loader, i.e. they are added to the moduledata linked list). 267 last := lastmoduledatap // grab before loop starts. Any added modules after this point will do their own doInit calls. 268 for m := &firstmoduledata; true; m = m.next { 269 doInit(m.inittasks) 270 if m == last { 271 break 272 } 273 } 274 275 // Disable init tracing after main init done to avoid overhead 276 // of collecting statistics in malloc and newproc 277 inittrace.active = false 278 279 mainInitDone.Store(true) 280 close(mainInitDoneChan) 281 282 needUnlock = false 283 unlockOSThread() 284 285 if isarchive || islibrary { 286 // A program compiled with -buildmode=c-archive or c-shared 287 // has a main, but it is not executed. 288 if GOARCH == "wasm" { 289 // On Wasm, pause makes it return to the host. 290 // Unlike cgo callbacks where Ms are created on demand, 291 // on Wasm we have only one M. So we keep this M (and this 292 // G) for callbacks. 293 // Using the caller's SP unwinds this frame and backs to 294 // goexit. The -16 is: 8 for goexit's (fake) return PC, 295 // and pause's epilogue pops 8. 296 pause(sys.GetCallerSP() - 16) // should not return 297 panic("unreachable") 298 } 299 return 300 } 301 fn := main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime 302 fn() 303 304 // Check for C memory leaks if using ASAN and we've made cgo calls, 305 // or if we are running as a library in a C program. 306 // We always make one cgo call, above, to notify_runtime_init_done, 307 // so we ignore that one. 308 // No point in leak checking if no cgo calls, since leak checking 309 // just looks for objects allocated using malloc and friends. 310 // Just checking iscgo doesn't help because asan implies iscgo. 311 exitHooksRun := false 312 if asanenabled && (isarchive || islibrary || NumCgoCall() > 1) { 313 runExitHooks(0) // lsandoleakcheck may not return 314 exitHooksRun = true 315 lsandoleakcheck() 316 } 317 318 // Make racy client program work: if panicking on 319 // another goroutine at the same time as main returns, 320 // let the other goroutine finish printing the panic trace. 321 // Once it does, it will exit. See issues 3934 and 20018. 322 if runningPanicDefers.Load() != 0 { 323 // Running deferred functions should not take long. 324 for c := 0; c < 1000; c++ { 325 if runningPanicDefers.Load() == 0 { 326 break 327 } 328 Gosched() 329 } 330 } 331 if panicking.Load() != 0 { 332 gopark(nil, nil, waitReasonPanicWait, traceBlockForever, 1) 333 } 334 if !exitHooksRun { 335 runExitHooks(0) 336 } 337 if raceenabled { 338 racefini() // does not return 339 } 340 341 exit(0) 342 for { 343 var x *int32 344 *x = 0 345 } 346 } 347 348 // os_beforeExit is called from os.Exit(0). 349 // 350 //go:linkname os_beforeExit os.runtime_beforeExit 351 func os_beforeExit(exitCode int) { 352 runExitHooks(exitCode) 353 if exitCode == 0 && raceenabled { 354 racefini() 355 } 356 357 // See comment in main, above. 358 if exitCode == 0 && asanenabled && (isarchive || islibrary || NumCgoCall() > 1) { 359 lsandoleakcheck() 360 } 361 } 362 363 func init() { 364 exithook.Gosched = Gosched 365 exithook.Goid = func() uint64 { return getg().goid } 366 exithook.Throw = throw 367 } 368 369 func runExitHooks(code int) { 370 exithook.Run(code) 371 } 372 373 // start forcegc helper goroutine 374 func init() { 375 go forcegchelper() 376 } 377 378 func forcegchelper() { 379 forcegc.g = getg() 380 lockInit(&forcegc.lock, lockRankForcegc) 381 for { 382 lock(&forcegc.lock) 383 if forcegc.idle.Load() { 384 throw("forcegc: phase error") 385 } 386 forcegc.idle.Store(true) 387 goparkunlock(&forcegc.lock, waitReasonForceGCIdle, traceBlockSystemGoroutine, 1) 388 // this goroutine is explicitly resumed by sysmon 389 if debug.gctrace > 0 { 390 println("GC forced") 391 } 392 // Time-triggered, fully concurrent. 393 gcStart(gcTrigger{kind: gcTriggerTime, now: nanotime()}) 394 } 395 } 396 397 // Gosched yields the processor, allowing other goroutines to run. It does not 398 // suspend the current goroutine, so execution resumes automatically. 399 // 400 //go:nosplit 401 func Gosched() { 402 checkTimeouts() 403 mcall(gosched_m) 404 } 405 406 // goschedguarded yields the processor like gosched, but also checks 407 // for forbidden states and opts out of the yield in those cases. 408 // 409 //go:nosplit 410 func goschedguarded() { 411 mcall(goschedguarded_m) 412 } 413 414 // goschedIfBusy yields the processor like gosched, but only does so if 415 // there are no idle Ps or if we're on the only P and there's nothing in 416 // the run queue. In both cases, there is freely available idle time. 417 // 418 //go:nosplit 419 func goschedIfBusy() { 420 gp := getg() 421 // Call gosched if gp.preempt is set; we may be in a tight loop that 422 // doesn't otherwise yield. 423 if !gp.preempt && sched.npidle.Load() > 0 { 424 return 425 } 426 mcall(gosched_m) 427 } 428 429 // Puts the current goroutine into a waiting state and calls unlockf on the 430 // system stack. 431 // 432 // If unlockf returns false, the goroutine is resumed. 433 // 434 // unlockf must not access this G's stack, as it may be moved between 435 // the call to gopark and the call to unlockf. 436 // 437 // Note that because unlockf is called after putting the G into a waiting 438 // state, the G may have already been readied by the time unlockf is called 439 // unless there is external synchronization preventing the G from being 440 // readied. If unlockf returns false, it must guarantee that the G cannot be 441 // externally readied. 442 // 443 // Reason explains why the goroutine has been parked. It is displayed in stack 444 // traces and heap dumps. Reasons should be unique and descriptive. Do not 445 // re-use reasons, add new ones. 446 // 447 // gopark should be an internal detail, 448 // but widely used packages access it using linkname. 449 // Notable members of the hall of shame include: 450 // - gvisor.dev/gvisor 451 // - github.com/sagernet/gvisor 452 // 453 // Do not remove or change the type signature. 454 // See go.dev/issue/67401. 455 // 456 //go:linkname gopark 457 func gopark(unlockf func(*g, unsafe.Pointer) bool, lock unsafe.Pointer, reason waitReason, traceReason traceBlockReason, traceskip int) { 458 if reason != waitReasonSleep { 459 checkTimeouts() // timeouts may expire while two goroutines keep the scheduler busy 460 } 461 mp := acquirem() 462 gp := mp.curg 463 status := readgstatus(gp) 464 if status != _Grunning && status != _Gscanrunning { 465 throw("gopark: bad g status") 466 } 467 mp.waitlock = lock 468 mp.waitunlockf = unlockf 469 gp.waitreason = reason 470 mp.waitTraceBlockReason = traceReason 471 mp.waitTraceSkip = traceskip 472 releasem(mp) 473 // can't do anything that might move the G between Ms here. 474 mcall(park_m) 475 } 476 477 // Puts the current goroutine into a waiting state and unlocks the lock. 478 // The goroutine can be made runnable again by calling goready(gp). 479 func goparkunlock(lock *mutex, reason waitReason, traceReason traceBlockReason, traceskip int) { 480 gopark(parkunlock_c, unsafe.Pointer(lock), reason, traceReason, traceskip) 481 } 482 483 // goready should be an internal detail, 484 // but widely used packages access it using linkname. 485 // Notable members of the hall of shame include: 486 // - gvisor.dev/gvisor 487 // - github.com/sagernet/gvisor 488 // 489 // Do not remove or change the type signature. 490 // See go.dev/issue/67401. 491 // 492 //go:linkname goready 493 func goready(gp *g, traceskip int) { 494 systemstack(func() { 495 ready(gp, traceskip, true) 496 }) 497 } 498 499 //go:nosplit 500 func acquireSudog() *sudog { 501 // Delicate dance: the semaphore implementation calls 502 // acquireSudog, acquireSudog calls new(sudog), 503 // new calls malloc, malloc can call the garbage collector, 504 // and the garbage collector calls the semaphore implementation 505 // in stopTheWorld. 506 // Break the cycle by doing acquirem/releasem around new(sudog). 507 // The acquirem/releasem increments m.locks during new(sudog), 508 // which keeps the garbage collector from being invoked. 509 mp := acquirem() 510 pp := mp.p.ptr() 511 if len(pp.sudogcache) == 0 { 512 lock(&sched.sudoglock) 513 // First, try to grab a batch from central cache. 514 for len(pp.sudogcache) < cap(pp.sudogcache)/2 && sched.sudogcache != nil { 515 s := sched.sudogcache 516 sched.sudogcache = s.next 517 s.next = nil 518 pp.sudogcache = append(pp.sudogcache, s) 519 } 520 unlock(&sched.sudoglock) 521 // If the central cache is empty, allocate a new one. 522 if len(pp.sudogcache) == 0 { 523 pp.sudogcache = append(pp.sudogcache, new(sudog)) 524 } 525 } 526 n := len(pp.sudogcache) 527 s := pp.sudogcache[n-1] 528 pp.sudogcache[n-1] = nil 529 pp.sudogcache = pp.sudogcache[:n-1] 530 if s.elem.get() != nil { 531 throw("acquireSudog: found s.elem != nil in cache") 532 } 533 releasem(mp) 534 return s 535 } 536 537 //go:nosplit 538 func releaseSudog(s *sudog) { 539 if s.elem.get() != nil { 540 throw("runtime: sudog with non-nil elem") 541 } 542 if s.isSelect { 543 throw("runtime: sudog with non-false isSelect") 544 } 545 if s.next != nil { 546 throw("runtime: sudog with non-nil next") 547 } 548 if s.prev != nil { 549 throw("runtime: sudog with non-nil prev") 550 } 551 if s.waitlink != nil { 552 throw("runtime: sudog with non-nil waitlink") 553 } 554 if s.c.get() != nil { 555 throw("runtime: sudog with non-nil c") 556 } 557 gp := getg() 558 if gp.param != nil { 559 throw("runtime: releaseSudog with non-nil gp.param") 560 } 561 mp := acquirem() // avoid rescheduling to another P 562 pp := mp.p.ptr() 563 if len(pp.sudogcache) == cap(pp.sudogcache) { 564 // Transfer half of local cache to the central cache. 565 var first, last *sudog 566 for len(pp.sudogcache) > cap(pp.sudogcache)/2 { 567 n := len(pp.sudogcache) 568 p := pp.sudogcache[n-1] 569 pp.sudogcache[n-1] = nil 570 pp.sudogcache = pp.sudogcache[:n-1] 571 if first == nil { 572 first = p 573 } else { 574 last.next = p 575 } 576 last = p 577 } 578 lock(&sched.sudoglock) 579 last.next = sched.sudogcache 580 sched.sudogcache = first 581 unlock(&sched.sudoglock) 582 } 583 pp.sudogcache = append(pp.sudogcache, s) 584 releasem(mp) 585 } 586 587 // called from assembly. 588 func badmcall(fn func(*g)) { 589 throw("runtime: mcall called on m->g0 stack") 590 } 591 592 func badmcall2(fn func(*g)) { 593 throw("runtime: mcall function returned") 594 } 595 596 func badreflectcall() { 597 panic(plainError("arg size to reflect.call more than 1GB")) 598 } 599 600 //go:nosplit 601 //go:nowritebarrierrec 602 func badmorestackg0() { 603 if !crashStackImplemented { 604 writeErrStr("fatal: morestack on g0\n") 605 return 606 } 607 608 g := getg() 609 switchToCrashStack(func() { 610 print("runtime: morestack on g0, stack [", hex(g.stack.lo), " ", hex(g.stack.hi), "], sp=", hex(g.sched.sp), ", called from\n") 611 g.m.traceback = 2 // include pc and sp in stack trace 612 traceback1(g.sched.pc, g.sched.sp, g.sched.lr, g, 0) 613 print("\n") 614 615 throw("morestack on g0") 616 }) 617 } 618 619 //go:nosplit 620 //go:nowritebarrierrec 621 func badmorestackgsignal() { 622 writeErrStr("fatal: morestack on gsignal\n") 623 } 624 625 //go:nosplit 626 func badctxt() { 627 throw("ctxt != 0") 628 } 629 630 // gcrash is a fake g that can be used when crashing due to bad 631 // stack conditions. 632 var gcrash g 633 634 var crashingG atomic.Pointer[g] 635 636 // Switch to crashstack and call fn, with special handling of 637 // concurrent and recursive cases. 638 // 639 // Nosplit as it is called in a bad stack condition (we know 640 // morestack would fail). 641 // 642 //go:nosplit 643 //go:nowritebarrierrec 644 func switchToCrashStack(fn func()) { 645 me := getg() 646 if crashingG.CompareAndSwapNoWB(nil, me) { 647 switchToCrashStack0(fn) // should never return 648 abort() 649 } 650 if crashingG.Load() == me { 651 // recursive crashing. too bad. 652 writeErrStr("fatal: recursive switchToCrashStack\n") 653 abort() 654 } 655 // Another g is crashing. Give it some time, hopefully it will finish traceback. 656 usleep_no_g(100) 657 writeErrStr("fatal: concurrent switchToCrashStack\n") 658 abort() 659 } 660 661 // Disable crash stack on Windows for now. Apparently, throwing an exception 662 // on a non-system-allocated crash stack causes EXCEPTION_STACK_OVERFLOW and 663 // hangs the process (see issue 63938). 664 const crashStackImplemented = GOOS != "windows" 665 666 //go:noescape 667 func switchToCrashStack0(fn func()) // in assembly 668 669 func lockedOSThread() bool { 670 gp := getg() 671 return gp.lockedm != 0 && gp.m.lockedg != 0 672 } 673 674 var ( 675 // allgs contains all Gs ever created (including dead Gs), and thus 676 // never shrinks. 677 // 678 // Access via the slice is protected by allglock or stop-the-world. 679 // Readers that cannot take the lock may (carefully!) use the atomic 680 // variables below. 681 allglock mutex 682 allgs []*g 683 684 // allglen and allgptr are atomic variables that contain len(allgs) and 685 // &allgs[0] respectively. Proper ordering depends on totally-ordered 686 // loads and stores. Writes are protected by allglock. 687 // 688 // allgptr is updated before allglen. Readers should read allglen 689 // before allgptr to ensure that allglen is always <= len(allgptr). New 690 // Gs appended during the race can be missed. For a consistent view of 691 // all Gs, allglock must be held. 692 // 693 // allgptr copies should always be stored as a concrete type or 694 // unsafe.Pointer, not uintptr, to ensure that GC can still reach it 695 // even if it points to a stale array. 696 allglen uintptr 697 allgptr **g 698 ) 699 700 func allgadd(gp *g) { 701 if readgstatus(gp) == _Gidle { 702 throw("allgadd: bad status Gidle") 703 } 704 705 lock(&allglock) 706 allgs = append(allgs, gp) 707 if &allgs[0] != allgptr { 708 atomicstorep(unsafe.Pointer(&allgptr), unsafe.Pointer(&allgs[0])) 709 } 710 atomic.Storeuintptr(&allglen, uintptr(len(allgs))) 711 unlock(&allglock) 712 } 713 714 // allGsSnapshot returns a snapshot of the slice of all Gs. 715 // 716 // The world must be stopped or allglock must be held. 717 func allGsSnapshot() []*g { 718 assertWorldStoppedOrLockHeld(&allglock) 719 720 // Because the world is stopped or allglock is held, allgadd 721 // cannot happen concurrently with this. allgs grows 722 // monotonically and existing entries never change, so we can 723 // simply return a copy of the slice header. For added safety, 724 // we trim everything past len because that can still change. 725 return allgs[:len(allgs):len(allgs)] 726 } 727 728 // atomicAllG returns &allgs[0] and len(allgs) for use with atomicAllGIndex. 729 func atomicAllG() (**g, uintptr) { 730 length := atomic.Loaduintptr(&allglen) 731 ptr := (**g)(atomic.Loadp(unsafe.Pointer(&allgptr))) 732 return ptr, length 733 } 734 735 // atomicAllGIndex returns ptr[i] with the allgptr returned from atomicAllG. 736 func atomicAllGIndex(ptr **g, i uintptr) *g { 737 return *(**g)(add(unsafe.Pointer(ptr), i*goarch.PtrSize)) 738 } 739 740 // forEachG calls fn on every G from allgs. 741 // 742 // forEachG takes a lock to exclude concurrent addition of new Gs. 743 func forEachG(fn func(gp *g)) { 744 lock(&allglock) 745 for _, gp := range allgs { 746 fn(gp) 747 } 748 unlock(&allglock) 749 } 750 751 // forEachGRace calls fn on every G from allgs. 752 // 753 // forEachGRace avoids locking, but does not exclude addition of new Gs during 754 // execution, which may be missed. 755 func forEachGRace(fn func(gp *g)) { 756 ptr, length := atomicAllG() 757 for i := uintptr(0); i < length; i++ { 758 gp := atomicAllGIndex(ptr, i) 759 fn(gp) 760 } 761 return 762 } 763 764 const ( 765 // Number of goroutine ids to grab from sched.goidgen to local per-P cache at once. 766 // 16 seems to provide enough amortization, but other than that it's mostly arbitrary number. 767 _GoidCacheBatch = 16 768 ) 769 770 // cpuinit sets up CPU feature flags and calls internal/cpu.Initialize. env should be the complete 771 // value of the GODEBUG environment variable. 772 func cpuinit(env string) { 773 cpu.Initialize(env) 774 775 // Support cpu feature variables are used in code generated by the compiler 776 // to guard execution of instructions that can not be assumed to be always supported. 777 switch GOARCH { 778 case "386", "amd64": 779 x86HasAVX = cpu.X86.HasAVX 780 x86HasFMA = cpu.X86.HasFMA 781 x86HasPOPCNT = cpu.X86.HasPOPCNT 782 x86HasSSE41 = cpu.X86.HasSSE41 783 784 case "arm": 785 armHasVFPv4 = cpu.ARM.HasVFPv4 786 787 case "arm64": 788 arm64HasATOMICS = cpu.ARM64.HasATOMICS 789 790 case "loong64": 791 loong64HasLAMCAS = cpu.Loong64.HasLAMCAS 792 loong64HasLAM_BH = cpu.Loong64.HasLAM_BH 793 loong64HasDBAR_HINTS = cpu.Loong64.HasDBAR_HINTS 794 loong64HasLSX = cpu.Loong64.HasLSX 795 796 case "riscv64": 797 riscv64HasZbb = cpu.RISCV64.HasZbb 798 } 799 } 800 801 // getGodebugEarly extracts the environment variable GODEBUG from the environment on 802 // Unix-like operating systems and returns it. This function exists to extract GODEBUG 803 // early before much of the runtime is initialized. 804 // 805 // Returns nil, false if OS doesn't provide env vars early in the init sequence. 806 func getGodebugEarly() (string, bool) { 807 const prefix = "GODEBUG=" 808 var env string 809 switch GOOS { 810 case "aix", "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "illumos", "solaris", "linux": 811 // Similar to goenv_unix but extracts the environment value for 812 // GODEBUG directly. 813 // TODO(moehrmann): remove when general goenvs() can be called before cpuinit() 814 n := int32(0) 815 for argv_index(argv, argc+1+n) != nil { 816 n++ 817 } 818 819 for i := int32(0); i < n; i++ { 820 p := argv_index(argv, argc+1+i) 821 s := unsafe.String(p, findnull(p)) 822 823 if stringslite.HasPrefix(s, prefix) { 824 env = gostringnocopy(p)[len(prefix):] 825 break 826 } 827 } 828 break 829 830 default: 831 return "", false 832 } 833 return env, true 834 } 835 836 // The bootstrap sequence is: 837 // 838 // call osinit 839 // call schedinit 840 // make & queue new G 841 // call runtime·mstart 842 // 843 // The new G calls runtime·main. 844 func schedinit() { 845 lockInit(&sched.lock, lockRankSched) 846 lockInit(&sched.sysmonlock, lockRankSysmon) 847 lockInit(&sched.deferlock, lockRankDefer) 848 lockInit(&sched.sudoglock, lockRankSudog) 849 lockInit(&deadlock, lockRankDeadlock) 850 lockInit(&paniclk, lockRankPanic) 851 lockInit(&allglock, lockRankAllg) 852 lockInit(&allpLock, lockRankAllp) 853 lockInit(&reflectOffs.lock, lockRankReflectOffs) 854 lockInit(&finlock, lockRankFin) 855 lockInit(&cpuprof.lock, lockRankCpuprof) 856 lockInit(&computeMaxProcsLock, lockRankComputeMaxProcs) 857 allocmLock.init(lockRankAllocmR, lockRankAllocmRInternal, lockRankAllocmW) 858 execLock.init(lockRankExecR, lockRankExecRInternal, lockRankExecW) 859 traceLockInit() 860 // Enforce that this lock is always a leaf lock. 861 // All of this lock's critical sections should be 862 // extremely short. 863 lockInit(&memstats.heapStats.noPLock, lockRankLeafRank) 864 865 lockVerifyMSize() 866 867 sched.midle.init(unsafe.Offsetof(m{}.idleNode)) 868 869 // raceinit must be the first call to race detector. 870 // In particular, it must be done before mallocinit below calls racemapshadow. 871 gp := getg() 872 if raceenabled { 873 gp.racectx, raceprocctx0 = raceinit() 874 } 875 876 sched.maxmcount = 10000 877 crashFD.Store(^uintptr(0)) 878 879 // The world starts stopped. 880 worldStopped() 881 882 godebug, parsedGodebug := getGodebugEarly() 883 if parsedGodebug { 884 parseRuntimeDebugVars(godebug) 885 } 886 ticks.init() // run as early as possible 887 moduledataverify() 888 stackinit() 889 randinit() // must run before mallocinit, AlgInit, mcommoninit 890 mallocinit() 891 cpuinit(godebug) // must run before AlgInit 892 maps.AlgInit() // maps, hash, rand must not be used before this call 893 mcommoninit(gp.m, -1) 894 modulesinit() // provides activeModules 895 typelinksinit() // uses maps, activeModules 896 itabsinit() // uses activeModules 897 stkobjinit() // must run before GC starts 898 899 sigsave(&gp.m.sigmask) 900 initSigmask = gp.m.sigmask 901 902 goargs() 903 goenvs() 904 secure() 905 checkfds() 906 if !parsedGodebug { 907 // Some platforms, e.g., Windows, didn't make env vars available "early", 908 // so try again now. 909 parseRuntimeDebugVars(gogetenv("GODEBUG")) 910 } 911 finishDebugVarsSetup() 912 gcinit() 913 914 // Allocate stack space that can be used when crashing due to bad stack 915 // conditions, e.g. morestack on g0. 916 gcrash.stack = stackalloc(16384) 917 gcrash.stackguard0 = gcrash.stack.lo + 1000 918 gcrash.stackguard1 = gcrash.stack.lo + 1000 919 920 // if disableMemoryProfiling is set, update MemProfileRate to 0 to turn off memprofile. 921 // Note: parsedebugvars may update MemProfileRate, but when disableMemoryProfiling is 922 // set to true by the linker, it means that nothing is consuming the profile, it is 923 // safe to set MemProfileRate to 0. 924 if disableMemoryProfiling { 925 MemProfileRate = 0 926 } 927 928 // mcommoninit runs before parsedebugvars, so init profstacks again. 929 mProfStackInit(gp.m) 930 defaultGOMAXPROCSInit() 931 932 lock(&sched.lock) 933 sched.lastpoll.Store(nanotime()) 934 var procs int32 935 if n, err := strconv.ParseInt(gogetenv("GOMAXPROCS"), 10, 32); err == nil && n > 0 { 936 procs = int32(n) 937 sched.customGOMAXPROCS = true 938 } else { 939 // Use numCPUStartup for initial GOMAXPROCS for two reasons: 940 // 941 // 1. We just computed it in osinit, recomputing is (minorly) wasteful. 942 // 943 // 2. More importantly, if debug.containermaxprocs == 0 && 944 // debug.updatemaxprocs == 0, we want to guarantee that 945 // runtime.GOMAXPROCS(0) always equals runtime.NumCPU (which is 946 // just numCPUStartup). 947 procs = defaultGOMAXPROCS(numCPUStartup) 948 } 949 if procresize(procs) != nil { 950 throw("unknown runnable goroutine during bootstrap") 951 } 952 unlock(&sched.lock) 953 954 // World is effectively started now, as P's can run. 955 worldStarted() 956 957 if buildVersion == "" { 958 // Condition should never trigger. This code just serves 959 // to ensure runtime·buildVersion is kept in the resulting binary. 960 buildVersion = "unknown" 961 } 962 if len(modinfo) == 1 { 963 // Condition should never trigger. This code just serves 964 // to ensure runtime·modinfo is kept in the resulting binary. 965 modinfo = "" 966 } 967 } 968 969 func dumpgstatus(gp *g) { 970 thisg := getg() 971 print("runtime: gp: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n") 972 print("runtime: getg: g=", thisg, ", goid=", thisg.goid, ", g->atomicstatus=", readgstatus(thisg), "\n") 973 } 974 975 // sched.lock must be held. 976 func checkmcount() { 977 assertLockHeld(&sched.lock) 978 979 // Exclude extra M's, which are used for cgocallback from threads 980 // created in C. 981 // 982 // The purpose of the SetMaxThreads limit is to avoid accidental fork 983 // bomb from something like millions of goroutines blocking on system 984 // calls, causing the runtime to create millions of threads. By 985 // definition, this isn't a problem for threads created in C, so we 986 // exclude them from the limit. See https://go.dev/issue/60004. 987 count := mcount() - int32(extraMInUse.Load()) - int32(extraMLength.Load()) 988 if count > sched.maxmcount { 989 print("runtime: program exceeds ", sched.maxmcount, "-thread limit\n") 990 throw("thread exhaustion") 991 } 992 } 993 994 // mReserveID returns the next ID to use for a new m. This new m is immediately 995 // considered 'running' by checkdead. 996 // 997 // sched.lock must be held. 998 func mReserveID() int64 { 999 assertLockHeld(&sched.lock) 1000 1001 if sched.mnext+1 < sched.mnext { 1002 throw("runtime: thread ID overflow") 1003 } 1004 id := sched.mnext 1005 sched.mnext++ 1006 checkmcount() 1007 return id 1008 } 1009 1010 // Pre-allocated ID may be passed as 'id', or omitted by passing -1. 1011 func mcommoninit(mp *m, id int64) { 1012 gp := getg() 1013 1014 // g0 stack won't make sense for user (and is not necessary unwindable). 1015 if gp != gp.m.g0 { 1016 callers(1, mp.createstack[:]) 1017 } 1018 1019 lock(&sched.lock) 1020 1021 if id >= 0 { 1022 mp.id = id 1023 } else { 1024 mp.id = mReserveID() 1025 } 1026 1027 mp.self = newMWeakPointer(mp) 1028 1029 mrandinit(mp) 1030 1031 mpreinit(mp) 1032 if mp.gsignal != nil { 1033 mp.gsignal.stackguard1 = mp.gsignal.stack.lo + stackGuard 1034 } 1035 1036 // Add to allm so garbage collector doesn't free g->m 1037 // when it is just in a register or thread-local storage. 1038 mp.alllink = allm 1039 1040 // NumCgoCall and others iterate over allm w/o schedlock, 1041 // so we need to publish it safely. 1042 atomicstorep(unsafe.Pointer(&allm), unsafe.Pointer(mp)) 1043 unlock(&sched.lock) 1044 1045 // Allocate memory to hold a cgo traceback if the cgo call crashes. 1046 if iscgo || GOOS == "solaris" || GOOS == "illumos" || GOOS == "windows" { 1047 mp.cgoCallers = new(cgoCallers) 1048 } 1049 mProfStackInit(mp) 1050 } 1051 1052 // mProfStackInit is used to eagerly initialize stack trace buffers for 1053 // profiling. Lazy allocation would have to deal with reentrancy issues in 1054 // malloc and runtime locks for mLockProfile. 1055 // TODO(mknyszek): Implement lazy allocation if this becomes a problem. 1056 func mProfStackInit(mp *m) { 1057 if debug.profstackdepth == 0 { 1058 // debug.profstack is set to 0 by the user, or we're being called from 1059 // schedinit before parsedebugvars. 1060 return 1061 } 1062 mp.profStack = makeProfStackFP() 1063 mp.mLockProfile.stack = makeProfStackFP() 1064 } 1065 1066 // makeProfStackFP creates a buffer large enough to hold a maximum-sized stack 1067 // trace as well as any additional frames needed for frame pointer unwinding 1068 // with delayed inline expansion. 1069 func makeProfStackFP() []uintptr { 1070 // The "1" term is to account for the first stack entry being 1071 // taken up by a "skip" sentinel value for profilers which 1072 // defer inline frame expansion until the profile is reported. 1073 // The "maxSkip" term is for frame pointer unwinding, where we 1074 // want to end up with debug.profstackdebth frames but will discard 1075 // some "physical" frames to account for skipping. 1076 return make([]uintptr, 1+maxSkip+debug.profstackdepth) 1077 } 1078 1079 // makeProfStack returns a buffer large enough to hold a maximum-sized stack 1080 // trace. 1081 func makeProfStack() []uintptr { return make([]uintptr, debug.profstackdepth) } 1082 1083 //go:linkname pprof_makeProfStack 1084 func pprof_makeProfStack() []uintptr { return makeProfStack() } 1085 1086 func (mp *m) becomeSpinning() { 1087 mp.spinning = true 1088 sched.nmspinning.Add(1) 1089 sched.needspinning.Store(0) 1090 } 1091 1092 // Take a snapshot of allp, for use after dropping the P. 1093 // 1094 // Must be called with a P, but the returned slice may be used after dropping 1095 // the P. The M holds a reference on the snapshot to keep the backing array 1096 // alive. 1097 // 1098 //go:yeswritebarrierrec 1099 func (mp *m) snapshotAllp() []*p { 1100 mp.allpSnapshot = allp 1101 return mp.allpSnapshot 1102 } 1103 1104 // Clear the saved allp snapshot. Should be called as soon as the snapshot is 1105 // no longer required. 1106 // 1107 // Must be called after reacquiring a P, as it requires a write barrier. 1108 // 1109 //go:yeswritebarrierrec 1110 func (mp *m) clearAllpSnapshot() { 1111 mp.allpSnapshot = nil 1112 } 1113 1114 func (mp *m) hasCgoOnStack() bool { 1115 return mp.ncgo > 0 || mp.isextra 1116 } 1117 1118 const ( 1119 // osHasLowResTimer indicates that the platform's internal timer system has a low resolution, 1120 // typically on the order of 1 ms or more. 1121 osHasLowResTimer = GOOS == "windows" || GOOS == "openbsd" || GOOS == "netbsd" || GOOS == "plan9" 1122 1123 // osHasLowResClockInt is osHasLowResClock but in integer form, so it can be used to create 1124 // constants conditionally. 1125 osHasLowResClockInt = goos.IsWindows 1126 1127 // osHasLowResClock indicates that timestamps produced by nanotime on the platform have a 1128 // low resolution, typically on the order of 1 ms or more. 1129 osHasLowResClock = osHasLowResClockInt > 0 1130 ) 1131 1132 // Mark gp ready to run. 1133 func ready(gp *g, traceskip int, next bool) { 1134 status := readgstatus(gp) 1135 1136 // Mark runnable. 1137 mp := acquirem() // disable preemption because it can be holding p in a local var 1138 if status&^_Gscan != _Gwaiting { 1139 dumpgstatus(gp) 1140 throw("bad g->status in ready") 1141 } 1142 1143 // status is Gwaiting or Gscanwaiting, make Grunnable and put on runq 1144 trace := traceAcquire() 1145 casgstatus(gp, _Gwaiting, _Grunnable) 1146 if trace.ok() { 1147 trace.GoUnpark(gp, traceskip) 1148 traceRelease(trace) 1149 } 1150 runqput(mp.p.ptr(), gp, next) 1151 wakep() 1152 releasem(mp) 1153 } 1154 1155 // freezeStopWait is a large value that freezetheworld sets 1156 // sched.stopwait to in order to request that all Gs permanently stop. 1157 const freezeStopWait = 0x7fffffff 1158 1159 // freezing is set to non-zero if the runtime is trying to freeze the 1160 // world. 1161 var freezing atomic.Bool 1162 1163 // Similar to stopTheWorld but best-effort and can be called several times. 1164 // There is no reverse operation, used during crashing. 1165 // This function must not lock any mutexes. 1166 func freezetheworld() { 1167 freezing.Store(true) 1168 if debug.dontfreezetheworld > 0 { 1169 // Don't prempt Ps to stop goroutines. That will perturb 1170 // scheduler state, making debugging more difficult. Instead, 1171 // allow goroutines to continue execution. 1172 // 1173 // fatalpanic will tracebackothers to trace all goroutines. It 1174 // is unsafe to trace a running goroutine, so tracebackothers 1175 // will skip running goroutines. That is OK and expected, we 1176 // expect users of dontfreezetheworld to use core files anyway. 1177 // 1178 // However, allowing the scheduler to continue running free 1179 // introduces a race: a goroutine may be stopped when 1180 // tracebackothers checks its status, and then start running 1181 // later when we are in the middle of traceback, potentially 1182 // causing a crash. 1183 // 1184 // To mitigate this, when an M naturally enters the scheduler, 1185 // schedule checks if freezing is set and if so stops 1186 // execution. This guarantees that while Gs can transition from 1187 // running to stopped, they can never transition from stopped 1188 // to running. 1189 // 1190 // The sleep here allows racing Ms that missed freezing and are 1191 // about to run a G to complete the transition to running 1192 // before we start traceback. 1193 usleep(1000) 1194 return 1195 } 1196 1197 // stopwait and preemption requests can be lost 1198 // due to races with concurrently executing threads, 1199 // so try several times 1200 for i := 0; i < 5; i++ { 1201 // this should tell the scheduler to not start any new goroutines 1202 sched.stopwait = freezeStopWait 1203 sched.gcwaiting.Store(true) 1204 // this should stop running goroutines 1205 if !preemptall() { 1206 break // no running goroutines 1207 } 1208 usleep(1000) 1209 } 1210 // to be sure 1211 usleep(1000) 1212 preemptall() 1213 usleep(1000) 1214 } 1215 1216 // All reads and writes of g's status go through readgstatus, casgstatus 1217 // castogscanstatus, casfrom_Gscanstatus. 1218 // 1219 //go:nosplit 1220 func readgstatus(gp *g) uint32 { 1221 return gp.atomicstatus.Load() 1222 } 1223 1224 // The Gscanstatuses are acting like locks and this releases them. 1225 // If it proves to be a performance hit we should be able to make these 1226 // simple atomic stores but for now we are going to throw if 1227 // we see an inconsistent state. 1228 func casfrom_Gscanstatus(gp *g, oldval, newval uint32) { 1229 success := false 1230 1231 // Check that transition is valid. 1232 switch oldval { 1233 default: 1234 print("runtime: casfrom_Gscanstatus bad oldval gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n") 1235 dumpgstatus(gp) 1236 throw("casfrom_Gscanstatus:top gp->status is not in scan state") 1237 case _Gscanrunnable, 1238 _Gscanwaiting, 1239 _Gscanrunning, 1240 _Gscansyscall, 1241 _Gscanleaked, 1242 _Gscanpreempted, 1243 _Gscandeadextra: 1244 if newval == oldval&^_Gscan { 1245 success = gp.atomicstatus.CompareAndSwap(oldval, newval) 1246 } 1247 } 1248 if !success { 1249 print("runtime: casfrom_Gscanstatus failed gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n") 1250 dumpgstatus(gp) 1251 throw("casfrom_Gscanstatus: gp->status is not in scan state") 1252 } 1253 releaseLockRankAndM(lockRankGscan) 1254 } 1255 1256 // This will return false if the gp is not in the expected status and the cas fails. 1257 // This acts like a lock acquire while the casfromgstatus acts like a lock release. 1258 func castogscanstatus(gp *g, oldval, newval uint32) bool { 1259 switch oldval { 1260 case _Grunnable, 1261 _Grunning, 1262 _Gwaiting, 1263 _Gleaked, 1264 _Gsyscall, 1265 _Gdeadextra: 1266 if newval == oldval|_Gscan { 1267 r := gp.atomicstatus.CompareAndSwap(oldval, newval) 1268 if r { 1269 acquireLockRankAndM(lockRankGscan) 1270 } 1271 return r 1272 1273 } 1274 } 1275 print("runtime: castogscanstatus oldval=", hex(oldval), " newval=", hex(newval), "\n") 1276 throw("bad oldval passed to castogscanstatus") 1277 return false 1278 } 1279 1280 // casgstatusAlwaysTrack is a debug flag that causes casgstatus to always track 1281 // various latencies on every transition instead of sampling them. 1282 var casgstatusAlwaysTrack = false 1283 1284 // If asked to move to or from a Gscanstatus this will throw. Use the castogscanstatus 1285 // and casfrom_Gscanstatus instead. 1286 // casgstatus will loop if the g->atomicstatus is in a Gscan status until the routine that 1287 // put it in the Gscan state is finished. 1288 // 1289 //go:nosplit 1290 func casgstatus(gp *g, oldval, newval uint32) { 1291 if (oldval&_Gscan != 0) || (newval&_Gscan != 0) || oldval == newval { 1292 systemstack(func() { 1293 // Call on the systemstack to prevent print and throw from counting 1294 // against the nosplit stack reservation. 1295 print("runtime: casgstatus: oldval=", hex(oldval), " newval=", hex(newval), "\n") 1296 throw("casgstatus: bad incoming values") 1297 }) 1298 } 1299 1300 lockWithRankMayAcquire(nil, lockRankGscan) 1301 1302 // See https://golang.org/cl/21503 for justification of the yield delay. 1303 const yieldDelay = 5 * 1000 1304 var nextYield int64 1305 1306 // loop if gp->atomicstatus is in a scan state giving 1307 // GC time to finish and change the state to oldval. 1308 for i := 0; !gp.atomicstatus.CompareAndSwap(oldval, newval); i++ { 1309 if oldval == _Gwaiting && gp.atomicstatus.Load() == _Grunnable { 1310 systemstack(func() { 1311 // Call on the systemstack to prevent throw from counting 1312 // against the nosplit stack reservation. 1313 throw("casgstatus: waiting for Gwaiting but is Grunnable") 1314 }) 1315 } 1316 if i == 0 { 1317 nextYield = nanotime() + yieldDelay 1318 } 1319 if nanotime() < nextYield { 1320 for x := 0; x < 10 && gp.atomicstatus.Load() != oldval; x++ { 1321 procyield(1) 1322 } 1323 } else { 1324 osyield() 1325 nextYield = nanotime() + yieldDelay/2 1326 } 1327 } 1328 1329 if gp.bubble != nil { 1330 systemstack(func() { 1331 gp.bubble.changegstatus(gp, oldval, newval) 1332 }) 1333 } 1334 1335 if (oldval == _Grunning || oldval == _Gsyscall) && (newval != _Grunning && newval != _Gsyscall) { 1336 // Track every gTrackingPeriod time a goroutine transitions out of _Grunning or _Gsyscall. 1337 // Do not track _Grunning <-> _Gsyscall transitions, since they're two very similar states. 1338 if casgstatusAlwaysTrack || gp.trackingSeq%gTrackingPeriod == 0 { 1339 gp.tracking = true 1340 } 1341 gp.trackingSeq++ 1342 } 1343 if !gp.tracking { 1344 return 1345 } 1346 1347 // Handle various kinds of tracking. 1348 // 1349 // Currently: 1350 // - Time spent in runnable. 1351 // - Time spent blocked on a sync.Mutex or sync.RWMutex. 1352 switch oldval { 1353 case _Grunnable: 1354 // We transitioned out of runnable, so measure how much 1355 // time we spent in this state and add it to 1356 // runnableTime. 1357 now := nanotime() 1358 gp.runnableTime += now - gp.trackingStamp 1359 gp.trackingStamp = 0 1360 case _Gwaiting: 1361 if !gp.waitreason.isMutexWait() { 1362 // Not blocking on a lock. 1363 break 1364 } 1365 // Blocking on a lock, measure it. Note that because we're 1366 // sampling, we have to multiply by our sampling period to get 1367 // a more representative estimate of the absolute value. 1368 // gTrackingPeriod also represents an accurate sampling period 1369 // because we can only enter this state from _Grunning. 1370 now := nanotime() 1371 sched.totalMutexWaitTime.Add((now - gp.trackingStamp) * gTrackingPeriod) 1372 gp.trackingStamp = 0 1373 } 1374 switch newval { 1375 case _Gwaiting: 1376 if !gp.waitreason.isMutexWait() { 1377 // Not blocking on a lock. 1378 break 1379 } 1380 // Blocking on a lock. Write down the timestamp. 1381 now := nanotime() 1382 gp.trackingStamp = now 1383 case _Grunnable: 1384 // We just transitioned into runnable, so record what 1385 // time that happened. 1386 now := nanotime() 1387 gp.trackingStamp = now 1388 case _Grunning: 1389 // We're transitioning into running, so turn off 1390 // tracking and record how much time we spent in 1391 // runnable. 1392 gp.tracking = false 1393 sched.timeToRun.record(gp.runnableTime) 1394 gp.runnableTime = 0 1395 } 1396 } 1397 1398 // casGToWaiting transitions gp from old to _Gwaiting, and sets the wait reason. 1399 // 1400 // Use this over casgstatus when possible to ensure that a waitreason is set. 1401 func casGToWaiting(gp *g, old uint32, reason waitReason) { 1402 // Set the wait reason before calling casgstatus, because casgstatus will use it. 1403 gp.waitreason = reason 1404 casgstatus(gp, old, _Gwaiting) 1405 } 1406 1407 // casGToWaitingForSuspendG transitions gp from old to _Gwaiting, and sets the wait reason. 1408 // The wait reason must be a valid isWaitingForSuspendG wait reason. 1409 // 1410 // While a goroutine is in this state, it's stack is effectively pinned. 1411 // The garbage collector must not shrink or otherwise mutate the goroutine's stack. 1412 // 1413 // Use this over casgstatus when possible to ensure that a waitreason is set. 1414 func casGToWaitingForSuspendG(gp *g, old uint32, reason waitReason) { 1415 if !reason.isWaitingForSuspendG() { 1416 throw("casGToWaitingForSuspendG with non-isWaitingForSuspendG wait reason") 1417 } 1418 casGToWaiting(gp, old, reason) 1419 } 1420 1421 // casGToPreemptScan transitions gp from _Grunning to _Gscan|_Gpreempted. 1422 // 1423 // TODO(austin): This is the only status operation that both changes 1424 // the status and locks the _Gscan bit. Rethink this. 1425 func casGToPreemptScan(gp *g, old, new uint32) { 1426 if old != _Grunning || new != _Gscan|_Gpreempted { 1427 throw("bad g transition") 1428 } 1429 acquireLockRankAndM(lockRankGscan) 1430 for !gp.atomicstatus.CompareAndSwap(_Grunning, _Gscan|_Gpreempted) { 1431 } 1432 // We never notify gp.bubble that the goroutine state has moved 1433 // from _Grunning to _Gpreempted. We call bubble.changegstatus 1434 // after status changes happen, but doing so here would violate the 1435 // ordering between the gscan and synctest locks. The bubble doesn't 1436 // distinguish between _Grunning and _Gpreempted anyway, so not 1437 // notifying it is fine. 1438 } 1439 1440 // casGFromPreempted attempts to transition gp from _Gpreempted to 1441 // _Gwaiting. If successful, the caller is responsible for 1442 // re-scheduling gp. 1443 func casGFromPreempted(gp *g, old, new uint32) bool { 1444 if old != _Gpreempted || new != _Gwaiting { 1445 throw("bad g transition") 1446 } 1447 gp.waitreason = waitReasonPreempted 1448 if !gp.atomicstatus.CompareAndSwap(_Gpreempted, _Gwaiting) { 1449 return false 1450 } 1451 if bubble := gp.bubble; bubble != nil { 1452 bubble.changegstatus(gp, _Gpreempted, _Gwaiting) 1453 } 1454 return true 1455 } 1456 1457 // stwReason is an enumeration of reasons the world is stopping. 1458 type stwReason uint8 1459 1460 // Reasons to stop-the-world. 1461 // 1462 // Avoid reusing reasons and add new ones instead. 1463 const ( 1464 stwUnknown stwReason = iota // "unknown" 1465 stwGCMarkTerm // "GC mark termination" 1466 stwGCSweepTerm // "GC sweep termination" 1467 stwWriteHeapDump // "write heap dump" 1468 stwGoroutineProfile // "goroutine profile" 1469 stwGoroutineProfileCleanup // "goroutine profile cleanup" 1470 stwAllGoroutinesStack // "all goroutines stack trace" 1471 stwReadMemStats // "read mem stats" 1472 stwAllThreadsSyscall // "AllThreadsSyscall" 1473 stwGOMAXPROCS // "GOMAXPROCS" 1474 stwStartTrace // "start trace" 1475 stwStopTrace // "stop trace" 1476 stwForTestCountPagesInUse // "CountPagesInUse (test)" 1477 stwForTestReadMetricsSlow // "ReadMetricsSlow (test)" 1478 stwForTestReadMemStatsSlow // "ReadMemStatsSlow (test)" 1479 stwForTestPageCachePagesLeaked // "PageCachePagesLeaked (test)" 1480 stwForTestResetDebugLog // "ResetDebugLog (test)" 1481 ) 1482 1483 func (r stwReason) String() string { 1484 return stwReasonStrings[r] 1485 } 1486 1487 func (r stwReason) isGC() bool { 1488 return r == stwGCMarkTerm || r == stwGCSweepTerm 1489 } 1490 1491 // If you add to this list, also add it to src/internal/trace/parser.go. 1492 // If you change the values of any of the stw* constants, bump the trace 1493 // version number and make a copy of this. 1494 var stwReasonStrings = [...]string{ 1495 stwUnknown: "unknown", 1496 stwGCMarkTerm: "GC mark termination", 1497 stwGCSweepTerm: "GC sweep termination", 1498 stwWriteHeapDump: "write heap dump", 1499 stwGoroutineProfile: "goroutine profile", 1500 stwGoroutineProfileCleanup: "goroutine profile cleanup", 1501 stwAllGoroutinesStack: "all goroutines stack trace", 1502 stwReadMemStats: "read mem stats", 1503 stwAllThreadsSyscall: "AllThreadsSyscall", 1504 stwGOMAXPROCS: "GOMAXPROCS", 1505 stwStartTrace: "start trace", 1506 stwStopTrace: "stop trace", 1507 stwForTestCountPagesInUse: "CountPagesInUse (test)", 1508 stwForTestReadMetricsSlow: "ReadMetricsSlow (test)", 1509 stwForTestReadMemStatsSlow: "ReadMemStatsSlow (test)", 1510 stwForTestPageCachePagesLeaked: "PageCachePagesLeaked (test)", 1511 stwForTestResetDebugLog: "ResetDebugLog (test)", 1512 } 1513 1514 // worldStop provides context from the stop-the-world required by the 1515 // start-the-world. 1516 type worldStop struct { 1517 reason stwReason 1518 startedStopping int64 1519 finishedStopping int64 1520 stoppingCPUTime int64 1521 } 1522 1523 // Temporary variable for stopTheWorld, when it can't write to the stack. 1524 // 1525 // Protected by worldsema. 1526 var stopTheWorldContext worldStop 1527 1528 // stopTheWorld stops all P's from executing goroutines, interrupting 1529 // all goroutines at GC safe points and records reason as the reason 1530 // for the stop. On return, only the current goroutine's P is running. 1531 // stopTheWorld must not be called from a system stack and the caller 1532 // must not hold worldsema. The caller must call startTheWorld when 1533 // other P's should resume execution. 1534 // 1535 // stopTheWorld is safe for multiple goroutines to call at the 1536 // same time. Each will execute its own stop, and the stops will 1537 // be serialized. 1538 // 1539 // This is also used by routines that do stack dumps. If the system is 1540 // in panic or being exited, this may not reliably stop all 1541 // goroutines. 1542 // 1543 // Returns the STW context. When starting the world, this context must be 1544 // passed to startTheWorld. 1545 func stopTheWorld(reason stwReason) worldStop { 1546 semacquire(&worldsema) 1547 gp := getg() 1548 gp.m.preemptoff = reason.String() 1549 systemstack(func() { 1550 stopTheWorldContext = stopTheWorldWithSema(reason) // avoid write to stack 1551 }) 1552 return stopTheWorldContext 1553 } 1554 1555 // startTheWorld undoes the effects of stopTheWorld. 1556 // 1557 // w must be the worldStop returned by stopTheWorld. 1558 func startTheWorld(w worldStop) { 1559 systemstack(func() { startTheWorldWithSema(0, w) }) 1560 1561 // worldsema must be held over startTheWorldWithSema to ensure 1562 // gomaxprocs cannot change while worldsema is held. 1563 // 1564 // Release worldsema with direct handoff to the next waiter, but 1565 // acquirem so that semrelease1 doesn't try to yield our time. 1566 // 1567 // Otherwise if e.g. ReadMemStats is being called in a loop, 1568 // it might stomp on other attempts to stop the world, such as 1569 // for starting or ending GC. The operation this blocks is 1570 // so heavy-weight that we should just try to be as fair as 1571 // possible here. 1572 // 1573 // We don't want to just allow us to get preempted between now 1574 // and releasing the semaphore because then we keep everyone 1575 // (including, for example, GCs) waiting longer. 1576 mp := acquirem() 1577 mp.preemptoff = "" 1578 semrelease1(&worldsema, true, 0) 1579 releasem(mp) 1580 } 1581 1582 // stopTheWorldGC has the same effect as stopTheWorld, but blocks 1583 // until the GC is not running. It also blocks a GC from starting 1584 // until startTheWorldGC is called. 1585 func stopTheWorldGC(reason stwReason) worldStop { 1586 semacquire(&gcsema) 1587 return stopTheWorld(reason) 1588 } 1589 1590 // startTheWorldGC undoes the effects of stopTheWorldGC. 1591 // 1592 // w must be the worldStop returned by stopTheWorld. 1593 func startTheWorldGC(w worldStop) { 1594 startTheWorld(w) 1595 semrelease(&gcsema) 1596 } 1597 1598 // Holding worldsema grants an M the right to try to stop the world. 1599 var worldsema uint32 = 1 1600 1601 // Holding gcsema grants the M the right to block a GC, and blocks 1602 // until the current GC is done. In particular, it prevents gomaxprocs 1603 // from changing concurrently. 1604 // 1605 // TODO(mknyszek): Once gomaxprocs and the execution tracer can handle 1606 // being changed/enabled during a GC, remove this. 1607 var gcsema uint32 = 1 1608 1609 // stopTheWorldWithSema is the core implementation of stopTheWorld. 1610 // The caller is responsible for acquiring worldsema and disabling 1611 // preemption first and then should stopTheWorldWithSema on the system 1612 // stack: 1613 // 1614 // semacquire(&worldsema, 0) 1615 // m.preemptoff = "reason" 1616 // var stw worldStop 1617 // systemstack(func() { 1618 // stw = stopTheWorldWithSema(reason) 1619 // }) 1620 // 1621 // When finished, the caller must either call startTheWorld or undo 1622 // these three operations separately: 1623 // 1624 // m.preemptoff = "" 1625 // systemstack(func() { 1626 // now = startTheWorldWithSema(stw) 1627 // }) 1628 // semrelease(&worldsema) 1629 // 1630 // It is allowed to acquire worldsema once and then execute multiple 1631 // startTheWorldWithSema/stopTheWorldWithSema pairs. 1632 // Other P's are able to execute between successive calls to 1633 // startTheWorldWithSema and stopTheWorldWithSema. 1634 // Holding worldsema causes any other goroutines invoking 1635 // stopTheWorld to block. 1636 // 1637 // Returns the STW context. When starting the world, this context must be 1638 // passed to startTheWorldWithSema. 1639 // 1640 //go:systemstack 1641 func stopTheWorldWithSema(reason stwReason) worldStop { 1642 // Mark the goroutine which called stopTheWorld preemptible so its 1643 // stack may be scanned by the GC or observed by the execution tracer. 1644 // 1645 // This lets a mark worker scan us or the execution tracer take our 1646 // stack while we try to stop the world since otherwise we could get 1647 // in a mutual preemption deadlock. 1648 // 1649 // casGToWaitingForSuspendG marks the goroutine as ineligible for a 1650 // stack shrink, effectively pinning the stack in memory for the duration. 1651 // 1652 // N.B. The execution tracer is not aware of this status transition and 1653 // handles it specially based on the wait reason. 1654 casGToWaitingForSuspendG(getg().m.curg, _Grunning, waitReasonStoppingTheWorld) 1655 1656 trace := traceAcquire() 1657 if trace.ok() { 1658 trace.STWStart(reason) 1659 traceRelease(trace) 1660 } 1661 gp := getg() 1662 1663 // If we hold a lock, then we won't be able to stop another M 1664 // that is blocked trying to acquire the lock. 1665 if gp.m.locks > 0 { 1666 throw("stopTheWorld: holding locks") 1667 } 1668 1669 lock(&sched.lock) 1670 start := nanotime() // exclude time waiting for sched.lock from start and total time metrics. 1671 sched.stopwait = gomaxprocs 1672 sched.gcwaiting.Store(true) 1673 preemptall() 1674 1675 // Stop current P. 1676 gp.m.p.ptr().status = _Pgcstop // Pgcstop is only diagnostic. 1677 gp.m.p.ptr().gcStopTime = start 1678 sched.stopwait-- 1679 1680 // Try to retake all P's in syscalls. 1681 for _, pp := range allp { 1682 if thread, ok := setBlockOnExitSyscall(pp); ok { 1683 thread.gcstopP() 1684 thread.resume() 1685 } 1686 } 1687 1688 // Stop idle Ps. 1689 now := nanotime() 1690 for { 1691 pp, _ := pidleget(now) 1692 if pp == nil { 1693 break 1694 } 1695 pp.status = _Pgcstop 1696 pp.gcStopTime = nanotime() 1697 sched.stopwait-- 1698 } 1699 wait := sched.stopwait > 0 1700 unlock(&sched.lock) 1701 1702 // Wait for remaining Ps to stop voluntarily. 1703 if wait { 1704 for { 1705 // wait for 100us, then try to re-preempt in case of any races 1706 if notetsleep(&sched.stopnote, 100*1000) { 1707 noteclear(&sched.stopnote) 1708 break 1709 } 1710 preemptall() 1711 } 1712 } 1713 1714 finish := nanotime() 1715 startTime := finish - start 1716 if reason.isGC() { 1717 sched.stwStoppingTimeGC.record(startTime) 1718 } else { 1719 sched.stwStoppingTimeOther.record(startTime) 1720 } 1721 1722 // Double-check we actually stopped everything, and all the invariants hold. 1723 // Also accumulate all the time spent by each P in _Pgcstop up to the point 1724 // where everything was stopped. This will be accumulated into the total pause 1725 // CPU time by the caller. 1726 stoppingCPUTime := int64(0) 1727 bad := "" 1728 if sched.stopwait != 0 { 1729 bad = "stopTheWorld: not stopped (stopwait != 0)" 1730 } else { 1731 for _, pp := range allp { 1732 if pp.status != _Pgcstop { 1733 bad = "stopTheWorld: not stopped (status != _Pgcstop)" 1734 } 1735 if pp.gcStopTime == 0 && bad == "" { 1736 bad = "stopTheWorld: broken CPU time accounting" 1737 } 1738 stoppingCPUTime += finish - pp.gcStopTime 1739 pp.gcStopTime = 0 1740 } 1741 } 1742 if freezing.Load() { 1743 // Some other thread is panicking. This can cause the 1744 // sanity checks above to fail if the panic happens in 1745 // the signal handler on a stopped thread. Either way, 1746 // we should halt this thread. 1747 lock(&deadlock) 1748 lock(&deadlock) 1749 } 1750 if bad != "" { 1751 throw(bad) 1752 } 1753 1754 worldStopped() 1755 1756 // Switch back to _Grunning, now that the world is stopped. 1757 casgstatus(getg().m.curg, _Gwaiting, _Grunning) 1758 1759 return worldStop{ 1760 reason: reason, 1761 startedStopping: start, 1762 finishedStopping: finish, 1763 stoppingCPUTime: stoppingCPUTime, 1764 } 1765 } 1766 1767 // reason is the same STW reason passed to stopTheWorld. start is the start 1768 // time returned by stopTheWorld. 1769 // 1770 // now is the current time; prefer to pass 0 to capture a fresh timestamp. 1771 // 1772 // stattTheWorldWithSema returns now. 1773 func startTheWorldWithSema(now int64, w worldStop) int64 { 1774 assertWorldStopped() 1775 1776 mp := acquirem() // disable preemption because it can be holding p in a local var 1777 if netpollinited() { 1778 list, delta := netpoll(0) // non-blocking 1779 injectglist(&list) 1780 netpollAdjustWaiters(delta) 1781 } 1782 lock(&sched.lock) 1783 1784 procs := gomaxprocs 1785 if newprocs != 0 { 1786 procs = newprocs 1787 newprocs = 0 1788 } 1789 p1 := procresize(procs) 1790 sched.gcwaiting.Store(false) 1791 if sched.sysmonwait.Load() { 1792 sched.sysmonwait.Store(false) 1793 notewakeup(&sched.sysmonnote) 1794 } 1795 unlock(&sched.lock) 1796 1797 worldStarted() 1798 1799 for p1 != nil { 1800 p := p1 1801 p1 = p1.link.ptr() 1802 if p.m != 0 { 1803 mp := p.m.ptr() 1804 p.m = 0 1805 if mp.nextp != 0 { 1806 throw("startTheWorld: inconsistent mp->nextp") 1807 } 1808 mp.nextp.set(p) 1809 notewakeup(&mp.park) 1810 } else { 1811 // Start M to run P. Do not start another M below. 1812 newm(nil, p, -1) 1813 } 1814 } 1815 1816 // Capture start-the-world time before doing clean-up tasks. 1817 if now == 0 { 1818 now = nanotime() 1819 } 1820 totalTime := now - w.startedStopping 1821 if w.reason.isGC() { 1822 sched.stwTotalTimeGC.record(totalTime) 1823 } else { 1824 sched.stwTotalTimeOther.record(totalTime) 1825 } 1826 trace := traceAcquire() 1827 if trace.ok() { 1828 trace.STWDone() 1829 traceRelease(trace) 1830 } 1831 1832 // Wakeup an additional proc in case we have excessive runnable goroutines 1833 // in local queues or in the global queue. If we don't, the proc will park itself. 1834 // If we have lots of excessive work, resetspinning will unpark additional procs as necessary. 1835 wakep() 1836 1837 releasem(mp) 1838 1839 return now 1840 } 1841 1842 // usesLibcall indicates whether this runtime performs system calls 1843 // via libcall. 1844 func usesLibcall() bool { 1845 switch GOOS { 1846 case "aix", "darwin", "illumos", "ios", "openbsd", "solaris", "windows": 1847 return true 1848 } 1849 return false 1850 } 1851 1852 // mStackIsSystemAllocated indicates whether this runtime starts on a 1853 // system-allocated stack. 1854 func mStackIsSystemAllocated() bool { 1855 switch GOOS { 1856 case "aix", "darwin", "plan9", "illumos", "ios", "openbsd", "solaris", "windows": 1857 return true 1858 } 1859 return false 1860 } 1861 1862 // mstart is the entry-point for new Ms. 1863 // It is written in assembly, uses ABI0, is marked TOPFRAME, and calls mstart0. 1864 func mstart() 1865 1866 // mstart0 is the Go entry-point for new Ms. 1867 // This must not split the stack because we may not even have stack 1868 // bounds set up yet. 1869 // 1870 // May run during STW (because it doesn't have a P yet), so write 1871 // barriers are not allowed. 1872 // 1873 //go:nosplit 1874 //go:nowritebarrierrec 1875 func mstart0() { 1876 gp := getg() 1877 1878 osStack := gp.stack.lo == 0 1879 if osStack { 1880 // Initialize stack bounds from system stack. 1881 // Cgo may have left stack size in stack.hi. 1882 // minit may update the stack bounds. 1883 // 1884 // Note: these bounds may not be very accurate. 1885 // We set hi to &size, but there are things above 1886 // it. The 1024 is supposed to compensate this, 1887 // but is somewhat arbitrary. 1888 size := gp.stack.hi 1889 if size == 0 { 1890 size = 16384 * sys.StackGuardMultiplier 1891 } 1892 gp.stack.hi = uintptr(noescape(unsafe.Pointer(&size))) 1893 gp.stack.lo = gp.stack.hi - size + 1024 1894 } 1895 // Initialize stack guard so that we can start calling regular 1896 // Go code. 1897 gp.stackguard0 = gp.stack.lo + stackGuard 1898 // This is the g0, so we can also call go:systemstack 1899 // functions, which check stackguard1. 1900 gp.stackguard1 = gp.stackguard0 1901 mstart1() 1902 1903 // Exit this thread. 1904 if mStackIsSystemAllocated() { 1905 // Windows, Solaris, illumos, Darwin, AIX and Plan 9 always system-allocate 1906 // the stack, but put it in gp.stack before mstart, 1907 // so the logic above hasn't set osStack yet. 1908 osStack = true 1909 } 1910 mexit(osStack) 1911 } 1912 1913 // The go:noinline is to guarantee the sys.GetCallerPC/sys.GetCallerSP below are safe, 1914 // so that we can set up g0.sched to return to the call of mstart1 above. 1915 // 1916 //go:noinline 1917 func mstart1() { 1918 gp := getg() 1919 1920 if gp != gp.m.g0 { 1921 throw("bad runtime·mstart") 1922 } 1923 1924 // Set up m.g0.sched as a label returning to just 1925 // after the mstart1 call in mstart0 above, for use by goexit0 and mcall. 1926 // We're never coming back to mstart1 after we call schedule, 1927 // so other calls can reuse the current frame. 1928 // And goexit0 does a gogo that needs to return from mstart1 1929 // and let mstart0 exit the thread. 1930 gp.sched.g = guintptr(unsafe.Pointer(gp)) 1931 gp.sched.pc = sys.GetCallerPC() 1932 gp.sched.sp = sys.GetCallerSP() 1933 gp.sched.bp = getcallerfp() 1934 1935 asminit() 1936 minit() 1937 1938 // Install signal handlers; after minit so that minit can 1939 // prepare the thread to be able to handle the signals. 1940 if gp.m == &m0 { 1941 mstartm0() 1942 } 1943 1944 if debug.dataindependenttiming == 1 { 1945 sys.EnableDIT() 1946 } 1947 1948 if fn := gp.m.mstartfn; fn != nil { 1949 fn() 1950 } 1951 1952 if gp.m != &m0 { 1953 acquirep(gp.m.nextp.ptr()) 1954 gp.m.nextp = 0 1955 } 1956 schedule() 1957 } 1958 1959 // mstartm0 implements part of mstart1 that only runs on the m0. 1960 // 1961 // Write barriers are allowed here because we know the GC can't be 1962 // running yet, so they'll be no-ops. 1963 // 1964 //go:yeswritebarrierrec 1965 func mstartm0() { 1966 // Create an extra M for callbacks on threads not created by Go. 1967 // An extra M is also needed on Windows for callbacks created by 1968 // syscall.NewCallback. See issue #6751 for details. 1969 if (iscgo || GOOS == "windows") && !cgoHasExtraM { 1970 cgoHasExtraM = true 1971 newextram() 1972 } 1973 initsig(false) 1974 } 1975 1976 // mPark causes a thread to park itself, returning once woken. 1977 // 1978 //go:nosplit 1979 func mPark() { 1980 gp := getg() 1981 // This M might stay parked through an entire GC cycle. 1982 // Erase any leftovers on the signal stack. 1983 if goexperiment.RuntimeSecret { 1984 eraseSecretsSignalStk() 1985 } 1986 notesleep(&gp.m.park) 1987 noteclear(&gp.m.park) 1988 } 1989 1990 // mexit tears down and exits the current thread. 1991 // 1992 // Don't call this directly to exit the thread, since it must run at 1993 // the top of the thread stack. Instead, use gogo(&gp.m.g0.sched) to 1994 // unwind the stack to the point that exits the thread. 1995 // 1996 // It is entered with m.p != nil, so write barriers are allowed. It 1997 // will release the P before exiting. 1998 // 1999 //go:yeswritebarrierrec 2000 func mexit(osStack bool) { 2001 mp := getg().m 2002 2003 if mp == &m0 { 2004 // This is the main thread. Just wedge it. 2005 // 2006 // On Linux, exiting the main thread puts the process 2007 // into a non-waitable zombie state. On Plan 9, 2008 // exiting the main thread unblocks wait even though 2009 // other threads are still running. On Solaris we can 2010 // neither exitThread nor return from mstart. Other 2011 // bad things probably happen on other platforms. 2012 // 2013 // We could try to clean up this M more before wedging 2014 // it, but that complicates signal handling. 2015 handoffp(releasep()) 2016 lock(&sched.lock) 2017 sched.nmfreed++ 2018 checkdead() 2019 unlock(&sched.lock) 2020 mPark() 2021 throw("locked m0 woke up") 2022 } 2023 2024 sigblock(true) 2025 unminit() 2026 2027 // Free the gsignal stack. 2028 if mp.gsignal != nil { 2029 stackfree(mp.gsignal.stack) 2030 if valgrindenabled { 2031 valgrindDeregisterStack(mp.gsignal.valgrindStackID) 2032 mp.gsignal.valgrindStackID = 0 2033 } 2034 // On some platforms, when calling into VDSO (e.g. nanotime) 2035 // we store our g on the gsignal stack, if there is one. 2036 // Now the stack is freed, unlink it from the m, so we 2037 // won't write to it when calling VDSO code. 2038 mp.gsignal = nil 2039 } 2040 2041 // Free vgetrandom state. 2042 vgetrandomDestroy(mp) 2043 2044 // Clear the self pointer so Ps don't access this M after it is freed, 2045 // or keep it alive. 2046 mp.self.clear() 2047 2048 // Remove m from allm. 2049 lock(&sched.lock) 2050 for pprev := &allm; *pprev != nil; pprev = &(*pprev).alllink { 2051 if *pprev == mp { 2052 *pprev = mp.alllink 2053 goto found 2054 } 2055 } 2056 throw("m not found in allm") 2057 found: 2058 // Events must not be traced after this point. 2059 2060 // Delay reaping m until it's done with the stack. 2061 // 2062 // Put mp on the free list, though it will not be reaped while freeWait 2063 // is freeMWait. mp is no longer reachable via allm, so even if it is 2064 // on an OS stack, we must keep a reference to mp alive so that the GC 2065 // doesn't free mp while we are still using it. 2066 // 2067 // Note that the free list must not be linked through alllink because 2068 // some functions walk allm without locking, so may be using alllink. 2069 // 2070 // N.B. It's important that the M appears on the free list simultaneously 2071 // with it being removed so that the tracer can find it. 2072 mp.freeWait.Store(freeMWait) 2073 mp.freelink = sched.freem 2074 sched.freem = mp 2075 unlock(&sched.lock) 2076 2077 atomic.Xadd64(&ncgocall, int64(mp.ncgocall)) 2078 sched.totalRuntimeLockWaitTime.Add(mp.mLockProfile.waitTime.Load()) 2079 2080 // Release the P. 2081 handoffp(releasep()) 2082 // After this point we must not have write barriers. 2083 2084 // Invoke the deadlock detector. This must happen after 2085 // handoffp because it may have started a new M to take our 2086 // P's work. 2087 lock(&sched.lock) 2088 sched.nmfreed++ 2089 checkdead() 2090 unlock(&sched.lock) 2091 2092 if GOOS == "darwin" || GOOS == "ios" { 2093 // Make sure pendingPreemptSignals is correct when an M exits. 2094 // For #41702. 2095 if mp.signalPending.Load() != 0 { 2096 pendingPreemptSignals.Add(-1) 2097 } 2098 } 2099 2100 // Destroy all allocated resources. After this is called, we may no 2101 // longer take any locks. 2102 mdestroy(mp) 2103 2104 if osStack { 2105 // No more uses of mp, so it is safe to drop the reference. 2106 mp.freeWait.Store(freeMRef) 2107 2108 // Return from mstart and let the system thread 2109 // library free the g0 stack and terminate the thread. 2110 return 2111 } 2112 2113 // mstart is the thread's entry point, so there's nothing to 2114 // return to. Exit the thread directly. exitThread will clear 2115 // m.freeWait when it's done with the stack and the m can be 2116 // reaped. 2117 exitThread(&mp.freeWait) 2118 } 2119 2120 // forEachP calls fn(p) for every P p when p reaches a GC safe point. 2121 // If a P is currently executing code, this will bring the P to a GC 2122 // safe point and execute fn on that P. If the P is not executing code 2123 // (it is idle or in a syscall), this will call fn(p) directly while 2124 // preventing the P from exiting its state. This does not ensure that 2125 // fn will run on every CPU executing Go code, but it acts as a global 2126 // memory barrier. GC uses this as a "ragged barrier." 2127 // 2128 // The caller must hold worldsema. fn must not refer to any 2129 // part of the current goroutine's stack, since the GC may move it. 2130 func forEachP(reason waitReason, fn func(*p)) { 2131 systemstack(func() { 2132 gp := getg().m.curg 2133 // Mark the user stack as preemptible so that it may be scanned 2134 // by the GC or observed by the execution tracer. Otherwise, our 2135 // attempt to force all P's to a safepoint could result in a 2136 // deadlock as we attempt to preempt a goroutine that's trying 2137 // to preempt us (e.g. for a stack scan). 2138 // 2139 // casGToWaitingForSuspendG marks the goroutine as ineligible for a 2140 // stack shrink, effectively pinning the stack in memory for the duration. 2141 // 2142 // N.B. The execution tracer is not aware of this status transition and 2143 // handles it specially based on the wait reason. 2144 casGToWaitingForSuspendG(gp, _Grunning, reason) 2145 forEachPInternal(fn) 2146 casgstatus(gp, _Gwaiting, _Grunning) 2147 }) 2148 } 2149 2150 // forEachPInternal calls fn(p) for every P p when p reaches a GC safe point. 2151 // It is the internal implementation of forEachP. 2152 // 2153 // The caller must hold worldsema and either must ensure that a GC is not 2154 // running (otherwise this may deadlock with the GC trying to preempt this P) 2155 // or it must leave its goroutine in a preemptible state before it switches 2156 // to the systemstack. Due to these restrictions, prefer forEachP when possible. 2157 // 2158 //go:systemstack 2159 func forEachPInternal(fn func(*p)) { 2160 mp := acquirem() 2161 pp := getg().m.p.ptr() 2162 2163 lock(&sched.lock) 2164 if sched.safePointWait != 0 { 2165 throw("forEachP: sched.safePointWait != 0") 2166 } 2167 sched.safePointWait = gomaxprocs - 1 2168 sched.safePointFn = fn 2169 2170 // Ask all Ps to run the safe point function. 2171 for _, p2 := range allp { 2172 if p2 != pp { 2173 atomic.Store(&p2.runSafePointFn, 1) 2174 } 2175 } 2176 preemptall() 2177 2178 // Any P entering _Pidle or a system call from now on will observe 2179 // p.runSafePointFn == 1 and will call runSafePointFn when 2180 // changing its status to _Pidle. 2181 2182 // Run safe point function for all idle Ps. sched.pidle will 2183 // not change because we hold sched.lock. 2184 for p := sched.pidle.ptr(); p != nil; p = p.link.ptr() { 2185 if atomic.Cas(&p.runSafePointFn, 1, 0) { 2186 fn(p) 2187 sched.safePointWait-- 2188 } 2189 } 2190 2191 wait := sched.safePointWait > 0 2192 unlock(&sched.lock) 2193 2194 // Run fn for the current P. 2195 fn(pp) 2196 2197 // Force Ps currently in a system call into _Pidle and hand them 2198 // off to induce safe point function execution. 2199 for _, p2 := range allp { 2200 if atomic.Load(&p2.runSafePointFn) != 1 { 2201 // Already ran it. 2202 continue 2203 } 2204 if thread, ok := setBlockOnExitSyscall(p2); ok { 2205 thread.takeP() 2206 thread.resume() 2207 handoffp(p2) 2208 } 2209 } 2210 2211 // Wait for remaining Ps to run fn. 2212 if wait { 2213 for { 2214 // Wait for 100us, then try to re-preempt in 2215 // case of any races. 2216 // 2217 // Requires system stack. 2218 if notetsleep(&sched.safePointNote, 100*1000) { 2219 noteclear(&sched.safePointNote) 2220 break 2221 } 2222 preemptall() 2223 } 2224 } 2225 if sched.safePointWait != 0 { 2226 throw("forEachP: not done") 2227 } 2228 for _, p2 := range allp { 2229 if p2.runSafePointFn != 0 { 2230 throw("forEachP: P did not run fn") 2231 } 2232 } 2233 2234 lock(&sched.lock) 2235 sched.safePointFn = nil 2236 unlock(&sched.lock) 2237 releasem(mp) 2238 } 2239 2240 // runSafePointFn runs the safe point function, if any, for this P. 2241 // This should be called like 2242 // 2243 // if getg().m.p.runSafePointFn != 0 { 2244 // runSafePointFn() 2245 // } 2246 // 2247 // runSafePointFn must be checked on any transition in to _Pidle or 2248 // when entering a system call to avoid a race where forEachP sees 2249 // that the P is running just before the P goes into _Pidle/system call 2250 // and neither forEachP nor the P run the safe-point function. 2251 func runSafePointFn() { 2252 p := getg().m.p.ptr() 2253 // Resolve the race between forEachP running the safe-point 2254 // function on this P's behalf and this P running the 2255 // safe-point function directly. 2256 if !atomic.Cas(&p.runSafePointFn, 1, 0) { 2257 return 2258 } 2259 sched.safePointFn(p) 2260 lock(&sched.lock) 2261 sched.safePointWait-- 2262 if sched.safePointWait == 0 { 2263 notewakeup(&sched.safePointNote) 2264 } 2265 unlock(&sched.lock) 2266 } 2267 2268 // When running with cgo, we call _cgo_thread_start 2269 // to start threads for us so that we can play nicely with 2270 // foreign code. 2271 var cgoThreadStart unsafe.Pointer 2272 2273 type cgothreadstart struct { 2274 g guintptr 2275 tls *uint64 2276 fn unsafe.Pointer 2277 } 2278 2279 // Allocate a new m unassociated with any thread. 2280 // Can use p for allocation context if needed. 2281 // fn is recorded as the new m's m.mstartfn. 2282 // id is optional pre-allocated m ID. Omit by passing -1. 2283 // 2284 // This function is allowed to have write barriers even if the caller 2285 // isn't because it borrows pp. 2286 // 2287 //go:yeswritebarrierrec 2288 func allocm(pp *p, fn func(), id int64) *m { 2289 allocmLock.rlock() 2290 2291 // The caller owns pp, but we may borrow (i.e., acquirep) it. We must 2292 // disable preemption to ensure it is not stolen, which would make the 2293 // caller lose ownership. 2294 acquirem() 2295 2296 gp := getg() 2297 if gp.m.p == 0 { 2298 acquirep(pp) // temporarily borrow p for mallocs in this function 2299 } 2300 2301 // Release the free M list. We need to do this somewhere and 2302 // this may free up a stack we can use. 2303 if sched.freem != nil { 2304 lock(&sched.lock) 2305 var newList *m 2306 for freem := sched.freem; freem != nil; { 2307 // Wait for freeWait to indicate that freem's stack is unused. 2308 wait := freem.freeWait.Load() 2309 if wait == freeMWait { 2310 next := freem.freelink 2311 freem.freelink = newList 2312 newList = freem 2313 freem = next 2314 continue 2315 } 2316 // Drop any remaining trace resources. 2317 // Ms can continue to emit events all the way until wait != freeMWait, 2318 // so it's only safe to call traceThreadDestroy at this point. 2319 if traceEnabled() || traceShuttingDown() { 2320 traceThreadDestroy(freem) 2321 } 2322 // Free the stack if needed. For freeMRef, there is 2323 // nothing to do except drop freem from the sched.freem 2324 // list. 2325 if wait == freeMStack { 2326 // stackfree must be on the system stack, but allocm is 2327 // reachable off the system stack transitively from 2328 // startm. 2329 systemstack(func() { 2330 stackfree(freem.g0.stack) 2331 if valgrindenabled { 2332 valgrindDeregisterStack(freem.g0.valgrindStackID) 2333 freem.g0.valgrindStackID = 0 2334 } 2335 }) 2336 } 2337 freem = freem.freelink 2338 } 2339 sched.freem = newList 2340 unlock(&sched.lock) 2341 } 2342 2343 mp := &new(mPadded).m 2344 mp.mstartfn = fn 2345 mcommoninit(mp, id) 2346 2347 // In case of cgo or Solaris or illumos or Darwin, pthread_create will make us a stack. 2348 // Windows and Plan 9 will layout sched stack on OS stack. 2349 if iscgo || mStackIsSystemAllocated() { 2350 mp.g0 = malg(-1) 2351 } else { 2352 mp.g0 = malg(16384 * sys.StackGuardMultiplier) 2353 } 2354 mp.g0.m = mp 2355 2356 if pp == gp.m.p.ptr() { 2357 releasep() 2358 } 2359 2360 releasem(gp.m) 2361 allocmLock.runlock() 2362 return mp 2363 } 2364 2365 // needm is called when a cgo callback happens on a 2366 // thread without an m (a thread not created by Go). 2367 // In this case, needm is expected to find an m to use 2368 // and return with m, g initialized correctly. 2369 // Since m and g are not set now (likely nil, but see below) 2370 // needm is limited in what routines it can call. In particular 2371 // it can only call nosplit functions (textflag 7) and cannot 2372 // do any scheduling that requires an m. 2373 // 2374 // In order to avoid needing heavy lifting here, we adopt 2375 // the following strategy: there is a stack of available m's 2376 // that can be stolen. Using compare-and-swap 2377 // to pop from the stack has ABA races, so we simulate 2378 // a lock by doing an exchange (via Casuintptr) to steal the stack 2379 // head and replace the top pointer with MLOCKED (1). 2380 // This serves as a simple spin lock that we can use even 2381 // without an m. The thread that locks the stack in this way 2382 // unlocks the stack by storing a valid stack head pointer. 2383 // 2384 // In order to make sure that there is always an m structure 2385 // available to be stolen, we maintain the invariant that there 2386 // is always one more than needed. At the beginning of the 2387 // program (if cgo is in use) the list is seeded with a single m. 2388 // If needm finds that it has taken the last m off the list, its job 2389 // is - once it has installed its own m so that it can do things like 2390 // allocate memory - to create a spare m and put it on the list. 2391 // 2392 // Each of these extra m's also has a g0 and a curg that are 2393 // pressed into service as the scheduling stack and current 2394 // goroutine for the duration of the cgo callback. 2395 // 2396 // It calls dropm to put the m back on the list, 2397 // 1. when the callback is done with the m in non-pthread platforms, 2398 // 2. or when the C thread exiting on pthread platforms. 2399 // 2400 // The signal argument indicates whether we're called from a signal 2401 // handler. 2402 // 2403 //go:nosplit 2404 func needm(signal bool) { 2405 if (iscgo || GOOS == "windows") && !cgoHasExtraM { 2406 // Can happen if C/C++ code calls Go from a global ctor. 2407 // Can also happen on Windows if a global ctor uses a 2408 // callback created by syscall.NewCallback. See issue #6751 2409 // for details. 2410 // 2411 // Can not throw, because scheduler is not initialized yet. 2412 writeErrStr("fatal error: cgo callback before cgo call\n") 2413 exit(1) 2414 } 2415 2416 // Save and block signals before getting an M. 2417 // The signal handler may call needm itself, 2418 // and we must avoid a deadlock. Also, once g is installed, 2419 // any incoming signals will try to execute, 2420 // but we won't have the sigaltstack settings and other data 2421 // set up appropriately until the end of minit, which will 2422 // unblock the signals. This is the same dance as when 2423 // starting a new m to run Go code via newosproc. 2424 var sigmask sigset 2425 sigsave(&sigmask) 2426 sigblock(false) 2427 2428 // getExtraM is safe here because of the invariant above, 2429 // that the extra list always contains or will soon contain 2430 // at least one m. 2431 mp, last := getExtraM() 2432 2433 // Set needextram when we've just emptied the list, 2434 // so that the eventual call into cgocallbackg will 2435 // allocate a new m for the extra list. We delay the 2436 // allocation until then so that it can be done 2437 // after exitsyscall makes sure it is okay to be 2438 // running at all (that is, there's no garbage collection 2439 // running right now). 2440 mp.needextram = last 2441 2442 // Store the original signal mask for use by minit. 2443 mp.sigmask = sigmask 2444 2445 // Install TLS on some platforms (previously setg 2446 // would do this if necessary). 2447 osSetupTLS(mp) 2448 2449 // Install g (= m->g0) and set the stack bounds 2450 // to match the current stack. 2451 setg(mp.g0) 2452 sp := sys.GetCallerSP() 2453 callbackUpdateSystemStack(mp, sp, signal) 2454 2455 // We must mark that we are already in Go now. 2456 // Otherwise, we may call needm again when we get a signal, before cgocallbackg1, 2457 // which means the extram list may be empty, that will cause a deadlock. 2458 mp.isExtraInC = false 2459 2460 // Initialize this thread to use the m. 2461 asminit() 2462 minit() 2463 2464 // Emit a trace event for this dead -> syscall transition, 2465 // but only if we're not in a signal handler. 2466 // 2467 // N.B. the tracer can run on a bare M just fine, we just have 2468 // to make sure to do this before setg(nil) and unminit. 2469 var trace traceLocker 2470 if !signal { 2471 trace = traceAcquire() 2472 } 2473 2474 // mp.curg is now a real goroutine. 2475 casgstatus(mp.curg, _Gdeadextra, _Gsyscall) 2476 sched.ngsys.Add(-1) 2477 2478 // This is technically inaccurate, but we set isExtraInC to false above, 2479 // and so we need to update addGSyscallNoP to keep the two pieces of state 2480 // consistent (it's only updated when isExtraInC is false). More specifically, 2481 // When we get to cgocallbackg and exitsyscall, we'll be looking for a P, and 2482 // since isExtraInC is false, we will decrement this metric. 2483 // 2484 // The inaccuracy is thankfully transient: only until this thread can get a P. 2485 // We're going into Go anyway, so it's okay to pretend we're a real goroutine now. 2486 addGSyscallNoP(mp) 2487 2488 if !signal { 2489 if trace.ok() { 2490 trace.GoCreateSyscall(mp.curg) 2491 traceRelease(trace) 2492 } 2493 } 2494 mp.isExtraInSig = signal 2495 } 2496 2497 // Acquire an extra m and bind it to the C thread when a pthread key has been created. 2498 // 2499 //go:nosplit 2500 func needAndBindM() { 2501 needm(false) 2502 2503 if _cgo_pthread_key_created != nil && *(*uintptr)(_cgo_pthread_key_created) != 0 { 2504 cgoBindM() 2505 } 2506 } 2507 2508 // newextram allocates m's and puts them on the extra list. 2509 // It is called with a working local m, so that it can do things 2510 // like call schedlock and allocate. 2511 func newextram() { 2512 c := extraMWaiters.Swap(0) 2513 if c > 0 { 2514 for i := uint32(0); i < c; i++ { 2515 oneNewExtraM() 2516 } 2517 } else if extraMLength.Load() == 0 { 2518 // Make sure there is at least one extra M. 2519 oneNewExtraM() 2520 } 2521 } 2522 2523 // oneNewExtraM allocates an m and puts it on the extra list. 2524 func oneNewExtraM() { 2525 // Create extra goroutine locked to extra m. 2526 // The goroutine is the context in which the cgo callback will run. 2527 // The sched.pc will never be returned to, but setting it to 2528 // goexit makes clear to the traceback routines where 2529 // the goroutine stack ends. 2530 mp := allocm(nil, nil, -1) 2531 gp := malg(4096) 2532 gp.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum 2533 gp.sched.sp = gp.stack.hi 2534 gp.sched.sp -= 4 * goarch.PtrSize // extra space in case of reads slightly beyond frame 2535 gp.sched.lr = 0 2536 gp.sched.g = guintptr(unsafe.Pointer(gp)) 2537 gp.syscallpc = gp.sched.pc 2538 gp.syscallsp = gp.sched.sp 2539 gp.stktopsp = gp.sched.sp 2540 // malg returns status as _Gidle. Change to _Gdeadextra before 2541 // adding to allg where GC can see it. _Gdeadextra hides this 2542 // from traceback and stack scans. 2543 casgstatus(gp, _Gidle, _Gdeadextra) 2544 gp.m = mp 2545 mp.curg = gp 2546 mp.isextra = true 2547 // mark we are in C by default. 2548 mp.isExtraInC = true 2549 mp.lockedInt++ 2550 mp.lockedg.set(gp) 2551 gp.lockedm.set(mp) 2552 gp.goid = sched.goidgen.Add(1) 2553 if raceenabled { 2554 gp.racectx = racegostart(abi.FuncPCABIInternal(newextram) + sys.PCQuantum) 2555 } 2556 // put on allg for garbage collector 2557 allgadd(gp) 2558 2559 // gp is now on the allg list, but we don't want it to be 2560 // counted by gcount. It would be more "proper" to increment 2561 // sched.ngfree, but that requires locking. Incrementing ngsys 2562 // has the same effect. 2563 sched.ngsys.Add(1) 2564 2565 // Add m to the extra list. 2566 addExtraM(mp) 2567 } 2568 2569 // dropm puts the current m back onto the extra list. 2570 // 2571 // 1. On systems without pthreads, like Windows 2572 // dropm is called when a cgo callback has called needm but is now 2573 // done with the callback and returning back into the non-Go thread. 2574 // 2575 // The main expense here is the call to signalstack to release the 2576 // m's signal stack, and then the call to needm on the next callback 2577 // from this thread. It is tempting to try to save the m for next time, 2578 // which would eliminate both these costs, but there might not be 2579 // a next time: the current thread (which Go does not control) might exit. 2580 // If we saved the m for that thread, there would be an m leak each time 2581 // such a thread exited. Instead, we acquire and release an m on each 2582 // call. These should typically not be scheduling operations, just a few 2583 // atomics, so the cost should be small. 2584 // 2585 // 2. On systems with pthreads 2586 // dropm is called while a non-Go thread is exiting. 2587 // We allocate a pthread per-thread variable using pthread_key_create, 2588 // to register a thread-exit-time destructor. 2589 // And store the g into a thread-specific value associated with the pthread key, 2590 // when first return back to C. 2591 // So that the destructor would invoke dropm while the non-Go thread is exiting. 2592 // This is much faster since it avoids expensive signal-related syscalls. 2593 // 2594 // This may run without a P, so //go:nowritebarrierrec is required. 2595 // 2596 // This may run with a different stack than was recorded in g0 (there is no 2597 // call to callbackUpdateSystemStack prior to dropm), so this must be 2598 // //go:nosplit to avoid the stack bounds check. 2599 // 2600 //go:nowritebarrierrec 2601 //go:nosplit 2602 func dropm() { 2603 // Clear m and g, and return m to the extra list. 2604 // After the call to setg we can only call nosplit functions 2605 // with no pointer manipulation. 2606 mp := getg().m 2607 2608 // Emit a trace event for this syscall -> dead transition. 2609 // 2610 // N.B. the tracer can run on a bare M just fine, we just have 2611 // to make sure to do this before setg(nil) and unminit. 2612 var trace traceLocker 2613 if !mp.isExtraInSig { 2614 trace = traceAcquire() 2615 } 2616 2617 // Return mp.curg to _Gdeadextra state. 2618 casgstatus(mp.curg, _Gsyscall, _Gdeadextra) 2619 mp.curg.preemptStop = false 2620 sched.ngsys.Add(1) 2621 decGSyscallNoP(mp) 2622 2623 if !mp.isExtraInSig { 2624 if trace.ok() { 2625 trace.GoDestroySyscall() 2626 traceRelease(trace) 2627 } 2628 } 2629 2630 // Trash syscalltick so that it doesn't line up with mp.old.syscalltick anymore. 2631 // 2632 // In the new tracer, we model needm and dropm and a goroutine being created and 2633 // destroyed respectively. The m then might get reused with a different procid but 2634 // still with a reference to oldp, and still with the same syscalltick. The next 2635 // time a G is "created" in needm, it'll return and quietly reacquire its P from a 2636 // different m with a different procid, which will confuse the trace parser. By 2637 // trashing syscalltick, we ensure that it'll appear as if we lost the P to the 2638 // tracer parser and that we just reacquired it. 2639 // 2640 // Trash the value by decrementing because that gets us as far away from the value 2641 // the syscall exit code expects as possible. Setting to zero is risky because 2642 // syscalltick could already be zero (and in fact, is initialized to zero). 2643 mp.syscalltick-- 2644 2645 // Reset trace state unconditionally. This goroutine is being 'destroyed' 2646 // from the perspective of the tracer. 2647 mp.curg.trace.reset() 2648 2649 // Flush all the M's buffers. This is necessary because the M might 2650 // be used on a different thread with a different procid, so we have 2651 // to make sure we don't write into the same buffer. 2652 if traceEnabled() || traceShuttingDown() { 2653 // Acquire sched.lock across thread destruction. One of the invariants of the tracer 2654 // is that a thread cannot disappear from the tracer's view (allm or freem) without 2655 // it noticing, so it requires that sched.lock be held over traceThreadDestroy. 2656 // 2657 // This isn't strictly necessary in this case, because this thread never leaves allm, 2658 // but the critical section is short and dropm is rare on pthread platforms, so just 2659 // take the lock and play it safe. traceThreadDestroy also asserts that the lock is held. 2660 lock(&sched.lock) 2661 traceThreadDestroy(mp) 2662 unlock(&sched.lock) 2663 } 2664 mp.isExtraInSig = false 2665 2666 // Block signals before unminit. 2667 // Unminit unregisters the signal handling stack (but needs g on some systems). 2668 // Setg(nil) clears g, which is the signal handler's cue not to run Go handlers. 2669 // It's important not to try to handle a signal between those two steps. 2670 sigmask := mp.sigmask 2671 sigblock(false) 2672 unminit() 2673 2674 setg(nil) 2675 2676 // Clear g0 stack bounds to ensure that needm always refreshes the 2677 // bounds when reusing this M. 2678 g0 := mp.g0 2679 g0.stack.hi = 0 2680 g0.stack.lo = 0 2681 g0.stackguard0 = 0 2682 g0.stackguard1 = 0 2683 mp.g0StackAccurate = false 2684 2685 putExtraM(mp) 2686 2687 msigrestore(sigmask) 2688 } 2689 2690 // bindm store the g0 of the current m into a thread-specific value. 2691 // 2692 // We allocate a pthread per-thread variable using pthread_key_create, 2693 // to register a thread-exit-time destructor. 2694 // We are here setting the thread-specific value of the pthread key, to enable the destructor. 2695 // So that the pthread_key_destructor would dropm while the C thread is exiting. 2696 // 2697 // And the saved g will be used in pthread_key_destructor, 2698 // since the g stored in the TLS by Go might be cleared in some platforms, 2699 // before the destructor invoked, so, we restore g by the stored g, before dropm. 2700 // 2701 // We store g0 instead of m, to make the assembly code simpler, 2702 // since we need to restore g0 in runtime.cgocallback. 2703 // 2704 // On systems without pthreads, like Windows, bindm shouldn't be used. 2705 // 2706 // NOTE: this always runs without a P, so, nowritebarrierrec required. 2707 // 2708 //go:nosplit 2709 //go:nowritebarrierrec 2710 func cgoBindM() { 2711 if GOOS == "windows" || GOOS == "plan9" { 2712 fatal("bindm in unexpected GOOS") 2713 } 2714 g := getg() 2715 if g.m.g0 != g { 2716 fatal("the current g is not g0") 2717 } 2718 if _cgo_bindm != nil { 2719 asmcgocall(_cgo_bindm, unsafe.Pointer(g)) 2720 } 2721 } 2722 2723 // A helper function for EnsureDropM. 2724 // 2725 // getm should be an internal detail, 2726 // but widely used packages access it using linkname. 2727 // Notable members of the hall of shame include: 2728 // - fortio.org/log 2729 // 2730 // Do not remove or change the type signature. 2731 // See go.dev/issue/67401. 2732 // 2733 //go:linkname getm 2734 func getm() uintptr { 2735 return uintptr(unsafe.Pointer(getg().m)) 2736 } 2737 2738 var ( 2739 // Locking linked list of extra M's, via mp.schedlink. Must be accessed 2740 // only via lockextra/unlockextra. 2741 // 2742 // Can't be atomic.Pointer[m] because we use an invalid pointer as a 2743 // "locked" sentinel value. M's on this list remain visible to the GC 2744 // because their mp.curg is on allgs. 2745 extraM atomic.Uintptr 2746 // Number of M's in the extraM list. 2747 extraMLength atomic.Uint32 2748 // Number of waiters in lockextra. 2749 extraMWaiters atomic.Uint32 2750 2751 // Number of extra M's in use by threads. 2752 extraMInUse atomic.Uint32 2753 ) 2754 2755 // lockextra locks the extra list and returns the list head. 2756 // The caller must unlock the list by storing a new list head 2757 // to extram. If nilokay is true, then lockextra will 2758 // return a nil list head if that's what it finds. If nilokay is false, 2759 // lockextra will keep waiting until the list head is no longer nil. 2760 // 2761 //go:nosplit 2762 func lockextra(nilokay bool) *m { 2763 const locked = 1 2764 2765 incr := false 2766 for { 2767 old := extraM.Load() 2768 if old == locked { 2769 osyield_no_g() 2770 continue 2771 } 2772 if old == 0 && !nilokay { 2773 if !incr { 2774 // Add 1 to the number of threads 2775 // waiting for an M. 2776 // This is cleared by newextram. 2777 extraMWaiters.Add(1) 2778 incr = true 2779 } 2780 usleep_no_g(1) 2781 continue 2782 } 2783 if extraM.CompareAndSwap(old, locked) { 2784 return (*m)(unsafe.Pointer(old)) 2785 } 2786 osyield_no_g() 2787 continue 2788 } 2789 } 2790 2791 //go:nosplit 2792 func unlockextra(mp *m, delta int32) { 2793 extraMLength.Add(delta) 2794 extraM.Store(uintptr(unsafe.Pointer(mp))) 2795 } 2796 2797 // Return an M from the extra M list. Returns last == true if the list becomes 2798 // empty because of this call. 2799 // 2800 // Spins waiting for an extra M, so caller must ensure that the list always 2801 // contains or will soon contain at least one M. 2802 // 2803 //go:nosplit 2804 func getExtraM() (mp *m, last bool) { 2805 mp = lockextra(false) 2806 extraMInUse.Add(1) 2807 unlockextra(mp.schedlink.ptr(), -1) 2808 return mp, mp.schedlink.ptr() == nil 2809 } 2810 2811 // Returns an extra M back to the list. mp must be from getExtraM. Newly 2812 // allocated M's should use addExtraM. 2813 // 2814 //go:nosplit 2815 func putExtraM(mp *m) { 2816 extraMInUse.Add(-1) 2817 addExtraM(mp) 2818 } 2819 2820 // Adds a newly allocated M to the extra M list. 2821 // 2822 //go:nosplit 2823 func addExtraM(mp *m) { 2824 mnext := lockextra(true) 2825 mp.schedlink.set(mnext) 2826 unlockextra(mp, 1) 2827 } 2828 2829 var ( 2830 // allocmLock is locked for read when creating new Ms in allocm and their 2831 // addition to allm. Thus acquiring this lock for write blocks the 2832 // creation of new Ms. 2833 allocmLock rwmutex 2834 2835 // execLock serializes exec and clone to avoid bugs or unspecified 2836 // behaviour around exec'ing while creating/destroying threads. See 2837 // issue #19546. 2838 execLock rwmutex 2839 ) 2840 2841 // These errors are reported (via writeErrStr) by some OS-specific 2842 // versions of newosproc and newosproc0. 2843 const ( 2844 failthreadcreate = "runtime: failed to create new OS thread\n" 2845 failallocatestack = "runtime: failed to allocate stack for the new OS thread\n" 2846 ) 2847 2848 // newmHandoff contains a list of m structures that need new OS threads. 2849 // This is used by newm in situations where newm itself can't safely 2850 // start an OS thread. 2851 var newmHandoff struct { 2852 lock mutex 2853 2854 // newm points to a list of M structures that need new OS 2855 // threads. The list is linked through m.schedlink. 2856 newm muintptr 2857 2858 // waiting indicates that wake needs to be notified when an m 2859 // is put on the list. 2860 waiting bool 2861 wake note 2862 2863 // haveTemplateThread indicates that the templateThread has 2864 // been started. This is not protected by lock. Use cas to set 2865 // to 1. 2866 haveTemplateThread uint32 2867 } 2868 2869 // Create a new m. It will start off with a call to fn, or else the scheduler. 2870 // fn needs to be static and not a heap allocated closure. 2871 // May run with m.p==nil, so write barriers are not allowed. 2872 // 2873 // id is optional pre-allocated m ID. Omit by passing -1. 2874 // 2875 //go:nowritebarrierrec 2876 func newm(fn func(), pp *p, id int64) { 2877 // allocm adds a new M to allm, but they do not start until created by 2878 // the OS in newm1 or the template thread. 2879 // 2880 // doAllThreadsSyscall requires that every M in allm will eventually 2881 // start and be signal-able, even with a STW. 2882 // 2883 // Disable preemption here until we start the thread to ensure that 2884 // newm is not preempted between allocm and starting the new thread, 2885 // ensuring that anything added to allm is guaranteed to eventually 2886 // start. 2887 acquirem() 2888 2889 mp := allocm(pp, fn, id) 2890 mp.nextp.set(pp) 2891 mp.sigmask = initSigmask 2892 if gp := getg(); gp != nil && gp.m != nil && (gp.m.lockedExt != 0 || gp.m.incgo) && GOOS != "plan9" { 2893 // We're on a locked M or a thread that may have been 2894 // started by C. The kernel state of this thread may 2895 // be strange (the user may have locked it for that 2896 // purpose). We don't want to clone that into another 2897 // thread. Instead, ask a known-good thread to create 2898 // the thread for us. 2899 // 2900 // This is disabled on Plan 9. See golang.org/issue/22227. 2901 // 2902 // TODO: This may be unnecessary on Windows, which 2903 // doesn't model thread creation off fork. 2904 lock(&newmHandoff.lock) 2905 if newmHandoff.haveTemplateThread == 0 { 2906 throw("on a locked thread with no template thread") 2907 } 2908 mp.schedlink = newmHandoff.newm 2909 newmHandoff.newm.set(mp) 2910 if newmHandoff.waiting { 2911 newmHandoff.waiting = false 2912 notewakeup(&newmHandoff.wake) 2913 } 2914 unlock(&newmHandoff.lock) 2915 // The M has not started yet, but the template thread does not 2916 // participate in STW, so it will always process queued Ms and 2917 // it is safe to releasem. 2918 releasem(getg().m) 2919 return 2920 } 2921 newm1(mp) 2922 releasem(getg().m) 2923 } 2924 2925 func newm1(mp *m) { 2926 if iscgo && _cgo_thread_start != nil { 2927 var ts cgothreadstart 2928 ts.g.set(mp.g0) 2929 ts.tls = (*uint64)(unsafe.Pointer(&mp.tls[0])) 2930 ts.fn = unsafe.Pointer(abi.FuncPCABI0(mstart)) 2931 if msanenabled { 2932 msanwrite(unsafe.Pointer(&ts), unsafe.Sizeof(ts)) 2933 } 2934 if asanenabled { 2935 asanwrite(unsafe.Pointer(&ts), unsafe.Sizeof(ts)) 2936 } 2937 execLock.rlock() // Prevent process clone. 2938 asmcgocall(_cgo_thread_start, unsafe.Pointer(&ts)) 2939 execLock.runlock() 2940 return 2941 } 2942 execLock.rlock() // Prevent process clone. 2943 newosproc(mp) 2944 execLock.runlock() 2945 } 2946 2947 // startTemplateThread starts the template thread if it is not already 2948 // running. 2949 // 2950 // The calling thread must itself be in a known-good state. 2951 func startTemplateThread() { 2952 if GOARCH == "wasm" { // no threads on wasm yet 2953 return 2954 } 2955 2956 // Disable preemption to guarantee that the template thread will be 2957 // created before a park once haveTemplateThread is set. 2958 mp := acquirem() 2959 if !atomic.Cas(&newmHandoff.haveTemplateThread, 0, 1) { 2960 releasem(mp) 2961 return 2962 } 2963 newm(templateThread, nil, -1) 2964 releasem(mp) 2965 } 2966 2967 // templateThread is a thread in a known-good state that exists solely 2968 // to start new threads in known-good states when the calling thread 2969 // may not be in a good state. 2970 // 2971 // Many programs never need this, so templateThread is started lazily 2972 // when we first enter a state that might lead to running on a thread 2973 // in an unknown state. 2974 // 2975 // templateThread runs on an M without a P, so it must not have write 2976 // barriers. 2977 // 2978 //go:nowritebarrierrec 2979 func templateThread() { 2980 lock(&sched.lock) 2981 sched.nmsys++ 2982 checkdead() 2983 unlock(&sched.lock) 2984 2985 for { 2986 lock(&newmHandoff.lock) 2987 for newmHandoff.newm != 0 { 2988 newm := newmHandoff.newm.ptr() 2989 newmHandoff.newm = 0 2990 unlock(&newmHandoff.lock) 2991 for newm != nil { 2992 next := newm.schedlink.ptr() 2993 newm.schedlink = 0 2994 newm1(newm) 2995 newm = next 2996 } 2997 lock(&newmHandoff.lock) 2998 } 2999 newmHandoff.waiting = true 3000 noteclear(&newmHandoff.wake) 3001 unlock(&newmHandoff.lock) 3002 notesleep(&newmHandoff.wake) 3003 } 3004 } 3005 3006 // Stops execution of the current m until new work is available. 3007 // Returns with acquired P. 3008 func stopm() { 3009 gp := getg() 3010 3011 if gp.m.locks != 0 { 3012 throw("stopm holding locks") 3013 } 3014 if gp.m.p != 0 { 3015 throw("stopm holding p") 3016 } 3017 if gp.m.spinning { 3018 throw("stopm spinning") 3019 } 3020 3021 lock(&sched.lock) 3022 mput(gp.m) 3023 unlock(&sched.lock) 3024 mPark() 3025 acquirep(gp.m.nextp.ptr()) 3026 gp.m.nextp = 0 3027 } 3028 3029 func mspinning() { 3030 // startm's caller incremented nmspinning. Set the new M's spinning. 3031 getg().m.spinning = true 3032 } 3033 3034 // Schedules some M to run the p (creates an M if necessary). 3035 // If p==nil, tries to get an idle P, if no idle P's does nothing. 3036 // May run with m.p==nil, so write barriers are not allowed. 3037 // If spinning is set, the caller has incremented nmspinning and must provide a 3038 // P. startm will set m.spinning in the newly started M. 3039 // 3040 // Callers passing a non-nil P must call from a non-preemptible context. See 3041 // comment on acquirem below. 3042 // 3043 // Argument lockheld indicates whether the caller already acquired the 3044 // scheduler lock. Callers holding the lock when making the call must pass 3045 // true. The lock might be temporarily dropped, but will be reacquired before 3046 // returning. 3047 // 3048 // Must not have write barriers because this may be called without a P. 3049 // 3050 //go:nowritebarrierrec 3051 func startm(pp *p, spinning, lockheld bool) { 3052 // Disable preemption. 3053 // 3054 // Every owned P must have an owner that will eventually stop it in the 3055 // event of a GC stop request. startm takes transient ownership of a P 3056 // (either from argument or pidleget below) and transfers ownership to 3057 // a started M, which will be responsible for performing the stop. 3058 // 3059 // Preemption must be disabled during this transient ownership, 3060 // otherwise the P this is running on may enter GC stop while still 3061 // holding the transient P, leaving that P in limbo and deadlocking the 3062 // STW. 3063 // 3064 // Callers passing a non-nil P must already be in non-preemptible 3065 // context, otherwise such preemption could occur on function entry to 3066 // startm. Callers passing a nil P may be preemptible, so we must 3067 // disable preemption before acquiring a P from pidleget below. 3068 mp := acquirem() 3069 if !lockheld { 3070 lock(&sched.lock) 3071 } 3072 if pp == nil { 3073 if spinning { 3074 // TODO(prattmic): All remaining calls to this function 3075 // with _p_ == nil could be cleaned up to find a P 3076 // before calling startm. 3077 throw("startm: P required for spinning=true") 3078 } 3079 pp, _ = pidleget(0) 3080 if pp == nil { 3081 if !lockheld { 3082 unlock(&sched.lock) 3083 } 3084 releasem(mp) 3085 return 3086 } 3087 } 3088 nmp := mget() 3089 if nmp == nil { 3090 // No M is available, we must drop sched.lock and call newm. 3091 // However, we already own a P to assign to the M. 3092 // 3093 // Once sched.lock is released, another G (e.g., in a syscall), 3094 // could find no idle P while checkdead finds a runnable G but 3095 // no running M's because this new M hasn't started yet, thus 3096 // throwing in an apparent deadlock. 3097 // This apparent deadlock is possible when startm is called 3098 // from sysmon, which doesn't count as a running M. 3099 // 3100 // Avoid this situation by pre-allocating the ID for the new M, 3101 // thus marking it as 'running' before we drop sched.lock. This 3102 // new M will eventually run the scheduler to execute any 3103 // queued G's. 3104 id := mReserveID() 3105 unlock(&sched.lock) 3106 3107 var fn func() 3108 if spinning { 3109 // The caller incremented nmspinning, so set m.spinning in the new M. 3110 fn = mspinning 3111 } 3112 newm(fn, pp, id) 3113 3114 if lockheld { 3115 lock(&sched.lock) 3116 } 3117 // Ownership transfer of pp committed by start in newm. 3118 // Preemption is now safe. 3119 releasem(mp) 3120 return 3121 } 3122 if !lockheld { 3123 unlock(&sched.lock) 3124 } 3125 if nmp.spinning { 3126 throw("startm: m is spinning") 3127 } 3128 if nmp.nextp != 0 { 3129 throw("startm: m has p") 3130 } 3131 if spinning && !runqempty(pp) { 3132 throw("startm: p has runnable gs") 3133 } 3134 // The caller incremented nmspinning, so set m.spinning in the new M. 3135 nmp.spinning = spinning 3136 nmp.nextp.set(pp) 3137 notewakeup(&nmp.park) 3138 // Ownership transfer of pp committed by wakeup. Preemption is now 3139 // safe. 3140 releasem(mp) 3141 } 3142 3143 // Hands off P from syscall or locked M. 3144 // Always runs without a P, so write barriers are not allowed. 3145 // 3146 //go:nowritebarrierrec 3147 func handoffp(pp *p) { 3148 // handoffp must start an M in any situation where 3149 // findRunnable would return a G to run on pp. 3150 3151 // if it has local work, start it straight away 3152 if !runqempty(pp) || !sched.runq.empty() { 3153 startm(pp, false, false) 3154 return 3155 } 3156 // if there's trace work to do, start it straight away 3157 if (traceEnabled() || traceShuttingDown()) && traceReaderAvailable() != nil { 3158 startm(pp, false, false) 3159 return 3160 } 3161 // if it has GC work, start it straight away 3162 if gcBlackenEnabled != 0 && gcShouldScheduleWorker(pp) { 3163 startm(pp, false, false) 3164 return 3165 } 3166 // no local work, check that there are no spinning/idle M's, 3167 // otherwise our help is not required 3168 if sched.nmspinning.Load()+sched.npidle.Load() == 0 && sched.nmspinning.CompareAndSwap(0, 1) { // TODO: fast atomic 3169 sched.needspinning.Store(0) 3170 startm(pp, true, false) 3171 return 3172 } 3173 lock(&sched.lock) 3174 if sched.gcwaiting.Load() { 3175 pp.status = _Pgcstop 3176 pp.gcStopTime = nanotime() 3177 sched.stopwait-- 3178 if sched.stopwait == 0 { 3179 notewakeup(&sched.stopnote) 3180 } 3181 unlock(&sched.lock) 3182 return 3183 } 3184 if pp.runSafePointFn != 0 && atomic.Cas(&pp.runSafePointFn, 1, 0) { 3185 sched.safePointFn(pp) 3186 sched.safePointWait-- 3187 if sched.safePointWait == 0 { 3188 notewakeup(&sched.safePointNote) 3189 } 3190 } 3191 if !sched.runq.empty() { 3192 unlock(&sched.lock) 3193 startm(pp, false, false) 3194 return 3195 } 3196 // If this is the last running P and nobody is polling network, 3197 // need to wakeup another M to poll network. 3198 if sched.npidle.Load() == gomaxprocs-1 && sched.lastpoll.Load() != 0 { 3199 unlock(&sched.lock) 3200 startm(pp, false, false) 3201 return 3202 } 3203 3204 // The scheduler lock cannot be held when calling wakeNetPoller below 3205 // because wakeNetPoller may call wakep which may call startm. 3206 when := pp.timers.wakeTime() 3207 pidleput(pp, 0) 3208 unlock(&sched.lock) 3209 3210 if when != 0 { 3211 wakeNetPoller(when) 3212 } 3213 } 3214 3215 // Tries to add one more P to execute G's. 3216 // Called when a G is made runnable (newproc, ready). 3217 // Must be called with a P. 3218 // 3219 // wakep should be an internal detail, 3220 // but widely used packages access it using linkname. 3221 // Notable members of the hall of shame include: 3222 // - gvisor.dev/gvisor 3223 // 3224 // Do not remove or change the type signature. 3225 // See go.dev/issue/67401. 3226 // 3227 //go:linkname wakep 3228 func wakep() { 3229 // Be conservative about spinning threads, only start one if none exist 3230 // already. 3231 if sched.nmspinning.Load() != 0 || !sched.nmspinning.CompareAndSwap(0, 1) { 3232 return 3233 } 3234 3235 // Disable preemption until ownership of pp transfers to the next M in 3236 // startm. Otherwise preemption here would leave pp stuck waiting to 3237 // enter _Pgcstop. 3238 // 3239 // See preemption comment on acquirem in startm for more details. 3240 mp := acquirem() 3241 3242 var pp *p 3243 lock(&sched.lock) 3244 pp, _ = pidlegetSpinning(0) 3245 if pp == nil { 3246 if sched.nmspinning.Add(-1) < 0 { 3247 throw("wakep: negative nmspinning") 3248 } 3249 unlock(&sched.lock) 3250 releasem(mp) 3251 return 3252 } 3253 // Since we always have a P, the race in the "No M is available" 3254 // comment in startm doesn't apply during the small window between the 3255 // unlock here and lock in startm. A checkdead in between will always 3256 // see at least one running M (ours). 3257 unlock(&sched.lock) 3258 3259 startm(pp, true, false) 3260 3261 releasem(mp) 3262 } 3263 3264 // Stops execution of the current m that is locked to a g until the g is runnable again. 3265 // Returns with acquired P. 3266 func stoplockedm() { 3267 gp := getg() 3268 3269 if gp.m.lockedg == 0 || gp.m.lockedg.ptr().lockedm.ptr() != gp.m { 3270 throw("stoplockedm: inconsistent locking") 3271 } 3272 if gp.m.p != 0 { 3273 // Schedule another M to run this p. 3274 pp := releasep() 3275 handoffp(pp) 3276 } 3277 incidlelocked(1) 3278 // Wait until another thread schedules lockedg again. 3279 mPark() 3280 status := readgstatus(gp.m.lockedg.ptr()) 3281 if status&^_Gscan != _Grunnable { 3282 print("runtime:stoplockedm: lockedg (atomicstatus=", status, ") is not Grunnable or Gscanrunnable\n") 3283 dumpgstatus(gp.m.lockedg.ptr()) 3284 throw("stoplockedm: not runnable") 3285 } 3286 acquirep(gp.m.nextp.ptr()) 3287 gp.m.nextp = 0 3288 } 3289 3290 // Schedules the locked m to run the locked gp. 3291 // May run during STW, so write barriers are not allowed. 3292 // 3293 //go:nowritebarrierrec 3294 func startlockedm(gp *g) { 3295 mp := gp.lockedm.ptr() 3296 if mp == getg().m { 3297 throw("startlockedm: locked to me") 3298 } 3299 if mp.nextp != 0 { 3300 throw("startlockedm: m has p") 3301 } 3302 // directly handoff current P to the locked m 3303 incidlelocked(-1) 3304 pp := releasep() 3305 mp.nextp.set(pp) 3306 notewakeup(&mp.park) 3307 stopm() 3308 } 3309 3310 // Stops the current m for stopTheWorld. 3311 // Returns when the world is restarted. 3312 func gcstopm() { 3313 gp := getg() 3314 3315 if !sched.gcwaiting.Load() { 3316 throw("gcstopm: not waiting for gc") 3317 } 3318 if gp.m.spinning { 3319 gp.m.spinning = false 3320 // OK to just drop nmspinning here, 3321 // startTheWorld will unpark threads as necessary. 3322 if sched.nmspinning.Add(-1) < 0 { 3323 throw("gcstopm: negative nmspinning") 3324 } 3325 } 3326 pp := releasep() 3327 lock(&sched.lock) 3328 pp.status = _Pgcstop 3329 pp.gcStopTime = nanotime() 3330 sched.stopwait-- 3331 if sched.stopwait == 0 { 3332 notewakeup(&sched.stopnote) 3333 } 3334 unlock(&sched.lock) 3335 stopm() 3336 } 3337 3338 // Schedules gp to run on the current M. 3339 // If inheritTime is true, gp inherits the remaining time in the 3340 // current time slice. Otherwise, it starts a new time slice. 3341 // Never returns. 3342 // 3343 // Write barriers are allowed because this is called immediately after 3344 // acquiring a P in several places. 3345 // 3346 //go:yeswritebarrierrec 3347 func execute(gp *g, inheritTime bool) { 3348 mp := getg().m 3349 3350 if goroutineProfile.active { 3351 // Make sure that gp has had its stack written out to the goroutine 3352 // profile, exactly as it was when the goroutine profiler first stopped 3353 // the world. 3354 tryRecordGoroutineProfile(gp, nil, osyield) 3355 } 3356 3357 // Assign gp.m before entering _Grunning so running Gs have an M. 3358 mp.curg = gp 3359 gp.m = mp 3360 gp.syncSafePoint = false // Clear the flag, which may have been set by morestack. 3361 casgstatus(gp, _Grunnable, _Grunning) 3362 gp.waitsince = 0 3363 gp.preempt = false 3364 gp.stackguard0 = gp.stack.lo + stackGuard 3365 if !inheritTime { 3366 mp.p.ptr().schedtick++ 3367 } 3368 3369 if sys.DITSupported && debug.dataindependenttiming != 1 { 3370 if gp.ditWanted && !mp.ditEnabled { 3371 // The current M doesn't have DIT enabled, but the goroutine we're 3372 // executing does need it, so turn it on. 3373 sys.EnableDIT() 3374 mp.ditEnabled = true 3375 } else if !gp.ditWanted && mp.ditEnabled { 3376 // The current M has DIT enabled, but the goroutine we're executing does 3377 // not need it, so turn it off. 3378 // NOTE: turning off DIT here means that the scheduler will have DIT enabled 3379 // when it runs after this goroutine yields or is preempted. This may have 3380 // a minor performance impact on the scheduler. 3381 sys.DisableDIT() 3382 mp.ditEnabled = false 3383 } 3384 } 3385 3386 // Check whether the profiler needs to be turned on or off. 3387 hz := sched.profilehz 3388 if mp.profilehz != hz { 3389 setThreadCPUProfiler(hz) 3390 } 3391 3392 trace := traceAcquire() 3393 if trace.ok() { 3394 trace.GoStart() 3395 traceRelease(trace) 3396 } 3397 3398 gogo(&gp.sched) 3399 } 3400 3401 // Finds a runnable goroutine to execute. 3402 // Tries to steal from other P's, get g from local or global queue, poll network. 3403 // tryWakeP indicates that the returned goroutine is not normal (GC worker, trace 3404 // reader) so the caller should try to wake a P. 3405 func findRunnable() (gp *g, inheritTime, tryWakeP bool) { 3406 mp := getg().m 3407 3408 // The conditions here and in handoffp must agree: if 3409 // findRunnable would return a G to run, handoffp must start 3410 // an M. 3411 3412 top: 3413 // We may have collected an allp snapshot below. The snapshot is only 3414 // required in each loop iteration. Clear it to all GC to collect the 3415 // slice. 3416 mp.clearAllpSnapshot() 3417 3418 pp := mp.p.ptr() 3419 if sched.gcwaiting.Load() { 3420 gcstopm() 3421 goto top 3422 } 3423 if pp.runSafePointFn != 0 { 3424 runSafePointFn() 3425 } 3426 3427 // now and pollUntil are saved for work stealing later, 3428 // which may steal timers. It's important that between now 3429 // and then, nothing blocks, so these numbers remain mostly 3430 // relevant. 3431 now, pollUntil, _ := pp.timers.check(0, nil) 3432 3433 // Try to schedule the trace reader. 3434 if traceEnabled() || traceShuttingDown() { 3435 gp := traceReader() 3436 if gp != nil { 3437 trace := traceAcquire() 3438 casgstatus(gp, _Gwaiting, _Grunnable) 3439 if trace.ok() { 3440 trace.GoUnpark(gp, 0) 3441 traceRelease(trace) 3442 } 3443 return gp, false, true 3444 } 3445 } 3446 3447 // Try to schedule a GC worker. 3448 if gcBlackenEnabled != 0 { 3449 gp, tnow := gcController.findRunnableGCWorker(pp, now) 3450 if gp != nil { 3451 return gp, false, true 3452 } 3453 now = tnow 3454 } 3455 3456 // Check the global runnable queue once in a while to ensure fairness. 3457 // Otherwise two goroutines can completely occupy the local runqueue 3458 // by constantly respawning each other. 3459 if pp.schedtick%61 == 0 && !sched.runq.empty() { 3460 lock(&sched.lock) 3461 gp := globrunqget() 3462 unlock(&sched.lock) 3463 if gp != nil { 3464 return gp, false, false 3465 } 3466 } 3467 3468 // Wake up the finalizer G. 3469 if fingStatus.Load()&(fingWait|fingWake) == fingWait|fingWake { 3470 if gp := wakefing(); gp != nil { 3471 ready(gp, 0, true) 3472 } 3473 } 3474 3475 // Wake up one or more cleanup Gs. 3476 if gcCleanups.needsWake() { 3477 gcCleanups.wake() 3478 } 3479 3480 if *cgo_yield != nil { 3481 asmcgocall(*cgo_yield, nil) 3482 } 3483 3484 // local runq 3485 if gp, inheritTime := runqget(pp); gp != nil { 3486 return gp, inheritTime, false 3487 } 3488 3489 // global runq 3490 if !sched.runq.empty() { 3491 lock(&sched.lock) 3492 gp, q := globrunqgetbatch(int32(len(pp.runq)) / 2) 3493 unlock(&sched.lock) 3494 if gp != nil { 3495 if runqputbatch(pp, &q); !q.empty() { 3496 throw("Couldn't put Gs into empty local runq") 3497 } 3498 return gp, false, false 3499 } 3500 } 3501 3502 // Poll network. 3503 // This netpoll is only an optimization before we resort to stealing. 3504 // We can safely skip it if there are no waiters or a thread is blocked 3505 // in netpoll already. If there is any kind of logical race with that 3506 // blocked thread (e.g. it has already returned from netpoll, but does 3507 // not set lastpoll yet), this thread will do blocking netpoll below 3508 // anyway. 3509 // We only poll from one thread at a time to avoid kernel contention 3510 // on machines with many cores. 3511 if netpollinited() && netpollAnyWaiters() && sched.lastpoll.Load() != 0 && sched.pollingNet.Swap(1) == 0 { 3512 list, delta := netpoll(0) 3513 sched.pollingNet.Store(0) 3514 if !list.empty() { // non-blocking 3515 gp := list.pop() 3516 injectglist(&list) 3517 netpollAdjustWaiters(delta) 3518 trace := traceAcquire() 3519 casgstatus(gp, _Gwaiting, _Grunnable) 3520 if trace.ok() { 3521 trace.GoUnpark(gp, 0) 3522 traceRelease(trace) 3523 } 3524 return gp, false, false 3525 } 3526 } 3527 3528 // Spinning Ms: steal work from other Ps. 3529 // 3530 // Limit the number of spinning Ms to half the number of busy Ps. 3531 // This is necessary to prevent excessive CPU consumption when 3532 // GOMAXPROCS>>1 but the program parallelism is low. 3533 if mp.spinning || 2*sched.nmspinning.Load() < gomaxprocs-sched.npidle.Load() { 3534 if !mp.spinning { 3535 mp.becomeSpinning() 3536 } 3537 3538 gp, inheritTime, tnow, w, newWork := stealWork(now) 3539 if gp != nil { 3540 // Successfully stole. 3541 return gp, inheritTime, false 3542 } 3543 if newWork { 3544 // There may be new timer or GC work; restart to 3545 // discover. 3546 goto top 3547 } 3548 3549 now = tnow 3550 if w != 0 && (pollUntil == 0 || w < pollUntil) { 3551 // Earlier timer to wait for. 3552 pollUntil = w 3553 } 3554 } 3555 3556 // We have nothing to do. 3557 // 3558 // If we're in the GC mark phase, can safely scan and blacken objects, 3559 // and have work to do, run idle-time marking rather than give up the P. 3560 if gcBlackenEnabled != 0 && gcShouldScheduleWorker(pp) && gcController.addIdleMarkWorker() { 3561 node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop()) 3562 if node != nil { 3563 pp.gcMarkWorkerMode = gcMarkWorkerIdleMode 3564 gp := node.gp.ptr() 3565 3566 trace := traceAcquire() 3567 casgstatus(gp, _Gwaiting, _Grunnable) 3568 if trace.ok() { 3569 trace.GoUnpark(gp, 0) 3570 traceRelease(trace) 3571 } 3572 return gp, false, false 3573 } 3574 gcController.removeIdleMarkWorker() 3575 } 3576 3577 // wasm only: 3578 // If a callback returned and no other goroutine is awake, 3579 // then wake event handler goroutine which pauses execution 3580 // until a callback was triggered. 3581 gp, otherReady := beforeIdle(now, pollUntil) 3582 if gp != nil { 3583 trace := traceAcquire() 3584 casgstatus(gp, _Gwaiting, _Grunnable) 3585 if trace.ok() { 3586 trace.GoUnpark(gp, 0) 3587 traceRelease(trace) 3588 } 3589 return gp, false, false 3590 } 3591 if otherReady { 3592 goto top 3593 } 3594 3595 // Before we drop our P, make a snapshot of the allp slice, 3596 // which can change underfoot once we no longer block 3597 // safe-points. We don't need to snapshot the contents because 3598 // everything up to cap(allp) is immutable. 3599 // 3600 // We clear the snapshot from the M after return via 3601 // mp.clearAllpSnapshop (in schedule) and on each iteration of the top 3602 // loop. 3603 allpSnapshot := mp.snapshotAllp() 3604 // Also snapshot masks. Value changes are OK, but we can't allow 3605 // len to change out from under us. 3606 idlepMaskSnapshot := idlepMask 3607 timerpMaskSnapshot := timerpMask 3608 3609 // return P and block 3610 lock(&sched.lock) 3611 if sched.gcwaiting.Load() || pp.runSafePointFn != 0 { 3612 unlock(&sched.lock) 3613 goto top 3614 } 3615 if !sched.runq.empty() { 3616 gp, q := globrunqgetbatch(int32(len(pp.runq)) / 2) 3617 unlock(&sched.lock) 3618 if gp == nil { 3619 throw("global runq empty with non-zero runqsize") 3620 } 3621 if runqputbatch(pp, &q); !q.empty() { 3622 throw("Couldn't put Gs into empty local runq") 3623 } 3624 return gp, false, false 3625 } 3626 if !mp.spinning && sched.needspinning.Load() == 1 { 3627 // See "Delicate dance" comment below. 3628 mp.becomeSpinning() 3629 unlock(&sched.lock) 3630 goto top 3631 } 3632 if releasep() != pp { 3633 throw("findRunnable: wrong p") 3634 } 3635 now = pidleput(pp, now) 3636 unlock(&sched.lock) 3637 3638 // Delicate dance: thread transitions from spinning to non-spinning 3639 // state, potentially concurrently with submission of new work. We must 3640 // drop nmspinning first and then check all sources again (with 3641 // #StoreLoad memory barrier in between). If we do it the other way 3642 // around, another thread can submit work after we've checked all 3643 // sources but before we drop nmspinning; as a result nobody will 3644 // unpark a thread to run the work. 3645 // 3646 // This applies to the following sources of work: 3647 // 3648 // * Goroutines added to the global or a per-P run queue. 3649 // * New/modified-earlier timers on a per-P timer heap. 3650 // * Idle-priority GC work (barring golang.org/issue/19112). 3651 // 3652 // If we discover new work below, we need to restore m.spinning as a 3653 // signal for resetspinning to unpark a new worker thread (because 3654 // there can be more than one starving goroutine). 3655 // 3656 // However, if after discovering new work we also observe no idle Ps 3657 // (either here or in resetspinning), we have a problem. We may be 3658 // racing with a non-spinning M in the block above, having found no 3659 // work and preparing to release its P and park. Allowing that P to go 3660 // idle will result in loss of work conservation (idle P while there is 3661 // runnable work). This could result in complete deadlock in the 3662 // unlikely event that we discover new work (from netpoll) right as we 3663 // are racing with _all_ other Ps going idle. 3664 // 3665 // We use sched.needspinning to synchronize with non-spinning Ms going 3666 // idle. If needspinning is set when they are about to drop their P, 3667 // they abort the drop and instead become a new spinning M on our 3668 // behalf. If we are not racing and the system is truly fully loaded 3669 // then no spinning threads are required, and the next thread to 3670 // naturally become spinning will clear the flag. 3671 // 3672 // Also see "Worker thread parking/unparking" comment at the top of the 3673 // file. 3674 wasSpinning := mp.spinning 3675 if mp.spinning { 3676 mp.spinning = false 3677 if sched.nmspinning.Add(-1) < 0 { 3678 throw("findRunnable: negative nmspinning") 3679 } 3680 3681 // Note the for correctness, only the last M transitioning from 3682 // spinning to non-spinning must perform these rechecks to 3683 // ensure no missed work. However, the runtime has some cases 3684 // of transient increments of nmspinning that are decremented 3685 // without going through this path, so we must be conservative 3686 // and perform the check on all spinning Ms. 3687 // 3688 // See https://go.dev/issue/43997. 3689 3690 // Check global and P runqueues again. 3691 3692 lock(&sched.lock) 3693 if !sched.runq.empty() { 3694 pp, _ := pidlegetSpinning(0) 3695 if pp != nil { 3696 gp, q := globrunqgetbatch(int32(len(pp.runq)) / 2) 3697 unlock(&sched.lock) 3698 if gp == nil { 3699 throw("global runq empty with non-zero runqsize") 3700 } 3701 if runqputbatch(pp, &q); !q.empty() { 3702 throw("Couldn't put Gs into empty local runq") 3703 } 3704 acquirep(pp) 3705 mp.becomeSpinning() 3706 return gp, false, false 3707 } 3708 } 3709 unlock(&sched.lock) 3710 3711 pp := checkRunqsNoP(allpSnapshot, idlepMaskSnapshot) 3712 if pp != nil { 3713 acquirep(pp) 3714 mp.becomeSpinning() 3715 goto top 3716 } 3717 3718 // Check for idle-priority GC work again. 3719 pp, gp := checkIdleGCNoP() 3720 if pp != nil { 3721 acquirep(pp) 3722 mp.becomeSpinning() 3723 3724 // Run the idle worker. 3725 pp.gcMarkWorkerMode = gcMarkWorkerIdleMode 3726 trace := traceAcquire() 3727 casgstatus(gp, _Gwaiting, _Grunnable) 3728 if trace.ok() { 3729 trace.GoUnpark(gp, 0) 3730 traceRelease(trace) 3731 } 3732 return gp, false, false 3733 } 3734 3735 // Finally, check for timer creation or expiry concurrently with 3736 // transitioning from spinning to non-spinning. 3737 // 3738 // Note that we cannot use checkTimers here because it calls 3739 // adjusttimers which may need to allocate memory, and that isn't 3740 // allowed when we don't have an active P. 3741 pollUntil = checkTimersNoP(allpSnapshot, timerpMaskSnapshot, pollUntil) 3742 } 3743 3744 // We don't need allp anymore at this pointer, but can't clear the 3745 // snapshot without a P for the write barrier.. 3746 3747 // Poll network until next timer. 3748 if netpollinited() && (netpollAnyWaiters() || pollUntil != 0) && sched.lastpoll.Swap(0) != 0 { 3749 sched.pollUntil.Store(pollUntil) 3750 if mp.p != 0 { 3751 throw("findRunnable: netpoll with p") 3752 } 3753 if mp.spinning { 3754 throw("findRunnable: netpoll with spinning") 3755 } 3756 delay := int64(-1) 3757 if pollUntil != 0 { 3758 if now == 0 { 3759 now = nanotime() 3760 } 3761 delay = pollUntil - now 3762 if delay < 0 { 3763 delay = 0 3764 } 3765 } 3766 if faketime != 0 { 3767 // When using fake time, just poll. 3768 delay = 0 3769 } 3770 list, delta := netpoll(delay) // block until new work is available 3771 // Refresh now again, after potentially blocking. 3772 now = nanotime() 3773 sched.pollUntil.Store(0) 3774 sched.lastpoll.Store(now) 3775 if faketime != 0 && list.empty() { 3776 // Using fake time and nothing is ready; stop M. 3777 // When all M's stop, checkdead will call timejump. 3778 stopm() 3779 goto top 3780 } 3781 lock(&sched.lock) 3782 pp, _ := pidleget(now) 3783 unlock(&sched.lock) 3784 if pp == nil { 3785 injectglist(&list) 3786 netpollAdjustWaiters(delta) 3787 } else { 3788 acquirep(pp) 3789 if !list.empty() { 3790 gp := list.pop() 3791 injectglist(&list) 3792 netpollAdjustWaiters(delta) 3793 trace := traceAcquire() 3794 casgstatus(gp, _Gwaiting, _Grunnable) 3795 if trace.ok() { 3796 trace.GoUnpark(gp, 0) 3797 traceRelease(trace) 3798 } 3799 return gp, false, false 3800 } 3801 if wasSpinning { 3802 mp.becomeSpinning() 3803 } 3804 goto top 3805 } 3806 } else if pollUntil != 0 && netpollinited() { 3807 pollerPollUntil := sched.pollUntil.Load() 3808 if pollerPollUntil == 0 || pollerPollUntil > pollUntil { 3809 netpollBreak() 3810 } 3811 } 3812 stopm() 3813 goto top 3814 } 3815 3816 // pollWork reports whether there is non-background work this P could 3817 // be doing. This is a fairly lightweight check to be used for 3818 // background work loops, like idle GC. It checks a subset of the 3819 // conditions checked by the actual scheduler. 3820 func pollWork() bool { 3821 if !sched.runq.empty() { 3822 return true 3823 } 3824 p := getg().m.p.ptr() 3825 if !runqempty(p) { 3826 return true 3827 } 3828 if netpollinited() && netpollAnyWaiters() && sched.lastpoll.Load() != 0 { 3829 if list, delta := netpoll(0); !list.empty() { 3830 injectglist(&list) 3831 netpollAdjustWaiters(delta) 3832 return true 3833 } 3834 } 3835 return false 3836 } 3837 3838 // stealWork attempts to steal a runnable goroutine or timer from any P. 3839 // 3840 // If newWork is true, new work may have been readied. 3841 // 3842 // If now is not 0 it is the current time. stealWork returns the passed time or 3843 // the current time if now was passed as 0. 3844 func stealWork(now int64) (gp *g, inheritTime bool, rnow, pollUntil int64, newWork bool) { 3845 pp := getg().m.p.ptr() 3846 3847 ranTimer := false 3848 3849 const stealTries = 4 3850 for i := 0; i < stealTries; i++ { 3851 stealTimersOrRunNextG := i == stealTries-1 3852 3853 for enum := stealOrder.start(cheaprand()); !enum.done(); enum.next() { 3854 if sched.gcwaiting.Load() { 3855 // GC work may be available. 3856 return nil, false, now, pollUntil, true 3857 } 3858 p2 := allp[enum.position()] 3859 if pp == p2 { 3860 continue 3861 } 3862 3863 // Steal timers from p2. This call to checkTimers is the only place 3864 // where we might hold a lock on a different P's timers. We do this 3865 // once on the last pass before checking runnext because stealing 3866 // from the other P's runnext should be the last resort, so if there 3867 // are timers to steal do that first. 3868 // 3869 // We only check timers on one of the stealing iterations because 3870 // the time stored in now doesn't change in this loop and checking 3871 // the timers for each P more than once with the same value of now 3872 // is probably a waste of time. 3873 // 3874 // timerpMask tells us whether the P may have timers at all. If it 3875 // can't, no need to check at all. 3876 if stealTimersOrRunNextG && timerpMask.read(enum.position()) { 3877 tnow, w, ran := p2.timers.check(now, nil) 3878 now = tnow 3879 if w != 0 && (pollUntil == 0 || w < pollUntil) { 3880 pollUntil = w 3881 } 3882 if ran { 3883 // Running the timers may have 3884 // made an arbitrary number of G's 3885 // ready and added them to this P's 3886 // local run queue. That invalidates 3887 // the assumption of runqsteal 3888 // that it always has room to add 3889 // stolen G's. So check now if there 3890 // is a local G to run. 3891 if gp, inheritTime := runqget(pp); gp != nil { 3892 return gp, inheritTime, now, pollUntil, ranTimer 3893 } 3894 ranTimer = true 3895 } 3896 } 3897 3898 // Don't bother to attempt to steal if p2 is idle. 3899 if !idlepMask.read(enum.position()) { 3900 if gp := runqsteal(pp, p2, stealTimersOrRunNextG); gp != nil { 3901 return gp, false, now, pollUntil, ranTimer 3902 } 3903 } 3904 } 3905 } 3906 3907 // No goroutines found to steal. Regardless, running a timer may have 3908 // made some goroutine ready that we missed. Indicate the next timer to 3909 // wait for. 3910 return nil, false, now, pollUntil, ranTimer 3911 } 3912 3913 // Check all Ps for a runnable G to steal. 3914 // 3915 // On entry we have no P. If a G is available to steal and a P is available, 3916 // the P is returned which the caller should acquire and attempt to steal the 3917 // work to. 3918 func checkRunqsNoP(allpSnapshot []*p, idlepMaskSnapshot pMask) *p { 3919 for id, p2 := range allpSnapshot { 3920 if !idlepMaskSnapshot.read(uint32(id)) && !runqempty(p2) { 3921 lock(&sched.lock) 3922 pp, _ := pidlegetSpinning(0) 3923 if pp == nil { 3924 // Can't get a P, don't bother checking remaining Ps. 3925 unlock(&sched.lock) 3926 return nil 3927 } 3928 unlock(&sched.lock) 3929 return pp 3930 } 3931 } 3932 3933 // No work available. 3934 return nil 3935 } 3936 3937 // Check all Ps for a timer expiring sooner than pollUntil. 3938 // 3939 // Returns updated pollUntil value. 3940 func checkTimersNoP(allpSnapshot []*p, timerpMaskSnapshot pMask, pollUntil int64) int64 { 3941 for id, p2 := range allpSnapshot { 3942 if timerpMaskSnapshot.read(uint32(id)) { 3943 w := p2.timers.wakeTime() 3944 if w != 0 && (pollUntil == 0 || w < pollUntil) { 3945 pollUntil = w 3946 } 3947 } 3948 } 3949 3950 return pollUntil 3951 } 3952 3953 // Check for idle-priority GC, without a P on entry. 3954 // 3955 // If some GC work, a P, and a worker G are all available, the P and G will be 3956 // returned. The returned P has not been wired yet. 3957 func checkIdleGCNoP() (*p, *g) { 3958 // N.B. Since we have no P, gcBlackenEnabled may change at any time; we 3959 // must check again after acquiring a P. As an optimization, we also check 3960 // if an idle mark worker is needed at all. This is OK here, because if we 3961 // observe that one isn't needed, at least one is currently running. Even if 3962 // it stops running, its own journey into the scheduler should schedule it 3963 // again, if need be (at which point, this check will pass, if relevant). 3964 if atomic.Load(&gcBlackenEnabled) == 0 || !gcController.needIdleMarkWorker() { 3965 return nil, nil 3966 } 3967 if !gcShouldScheduleWorker(nil) { 3968 return nil, nil 3969 } 3970 3971 // Work is available; we can start an idle GC worker only if there is 3972 // an available P and available worker G. 3973 // 3974 // We can attempt to acquire these in either order, though both have 3975 // synchronization concerns (see below). Workers are almost always 3976 // available (see comment in findRunnableGCWorker for the one case 3977 // there may be none). Since we're slightly less likely to find a P, 3978 // check for that first. 3979 // 3980 // Synchronization: note that we must hold sched.lock until we are 3981 // committed to keeping it. Otherwise we cannot put the unnecessary P 3982 // back in sched.pidle without performing the full set of idle 3983 // transition checks. 3984 // 3985 // If we were to check gcBgMarkWorkerPool first, we must somehow handle 3986 // the assumption in gcControllerState.findRunnableGCWorker that an 3987 // empty gcBgMarkWorkerPool is only possible if gcMarkDone is running. 3988 lock(&sched.lock) 3989 pp, now := pidlegetSpinning(0) 3990 if pp == nil { 3991 unlock(&sched.lock) 3992 return nil, nil 3993 } 3994 3995 // Now that we own a P, gcBlackenEnabled can't change (as it requires STW). 3996 if gcBlackenEnabled == 0 || !gcController.addIdleMarkWorker() { 3997 pidleput(pp, now) 3998 unlock(&sched.lock) 3999 return nil, nil 4000 } 4001 4002 node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop()) 4003 if node == nil { 4004 pidleput(pp, now) 4005 unlock(&sched.lock) 4006 gcController.removeIdleMarkWorker() 4007 return nil, nil 4008 } 4009 4010 unlock(&sched.lock) 4011 4012 return pp, node.gp.ptr() 4013 } 4014 4015 // wakeNetPoller wakes up the thread sleeping in the network poller if it isn't 4016 // going to wake up before the when argument; or it wakes an idle P to service 4017 // timers and the network poller if there isn't one already. 4018 func wakeNetPoller(when int64) { 4019 if sched.lastpoll.Load() == 0 { 4020 // In findRunnable we ensure that when polling the pollUntil 4021 // field is either zero or the time to which the current 4022 // poll is expected to run. This can have a spurious wakeup 4023 // but should never miss a wakeup. 4024 pollerPollUntil := sched.pollUntil.Load() 4025 if pollerPollUntil == 0 || pollerPollUntil > when { 4026 netpollBreak() 4027 } 4028 } else { 4029 // There are no threads in the network poller, try to get 4030 // one there so it can handle new timers. 4031 if GOOS != "plan9" { // Temporary workaround - see issue #42303. 4032 wakep() 4033 } 4034 } 4035 } 4036 4037 func resetspinning() { 4038 gp := getg() 4039 if !gp.m.spinning { 4040 throw("resetspinning: not a spinning m") 4041 } 4042 gp.m.spinning = false 4043 nmspinning := sched.nmspinning.Add(-1) 4044 if nmspinning < 0 { 4045 throw("findRunnable: negative nmspinning") 4046 } 4047 // M wakeup policy is deliberately somewhat conservative, so check if we 4048 // need to wakeup another P here. See "Worker thread parking/unparking" 4049 // comment at the top of the file for details. 4050 wakep() 4051 } 4052 4053 // injectglist adds each runnable G on the list to some run queue, 4054 // and clears glist. If there is no current P, they are added to the 4055 // global queue, and up to npidle M's are started to run them. 4056 // Otherwise, for each idle P, this adds a G to the global queue 4057 // and starts an M. Any remaining G's are added to the current P's 4058 // local run queue. 4059 // This may temporarily acquire sched.lock. 4060 // Can run concurrently with GC. 4061 func injectglist(glist *gList) { 4062 if glist.empty() { 4063 return 4064 } 4065 4066 // Mark all the goroutines as runnable before we put them 4067 // on the run queues. 4068 var tail *g 4069 trace := traceAcquire() 4070 for gp := glist.head.ptr(); gp != nil; gp = gp.schedlink.ptr() { 4071 tail = gp 4072 casgstatus(gp, _Gwaiting, _Grunnable) 4073 if trace.ok() { 4074 trace.GoUnpark(gp, 0) 4075 } 4076 } 4077 if trace.ok() { 4078 traceRelease(trace) 4079 } 4080 4081 // Turn the gList into a gQueue. 4082 q := gQueue{glist.head, tail.guintptr(), glist.size} 4083 *glist = gList{} 4084 4085 startIdle := func(n int32) { 4086 for ; n > 0; n-- { 4087 mp := acquirem() // See comment in startm. 4088 lock(&sched.lock) 4089 4090 pp, _ := pidlegetSpinning(0) 4091 if pp == nil { 4092 unlock(&sched.lock) 4093 releasem(mp) 4094 break 4095 } 4096 4097 startm(pp, false, true) 4098 unlock(&sched.lock) 4099 releasem(mp) 4100 } 4101 } 4102 4103 pp := getg().m.p.ptr() 4104 if pp == nil { 4105 n := q.size 4106 lock(&sched.lock) 4107 globrunqputbatch(&q) 4108 unlock(&sched.lock) 4109 startIdle(n) 4110 return 4111 } 4112 4113 var globq gQueue 4114 npidle := sched.npidle.Load() 4115 for ; npidle > 0 && !q.empty(); npidle-- { 4116 g := q.pop() 4117 globq.pushBack(g) 4118 } 4119 if !globq.empty() { 4120 n := globq.size 4121 lock(&sched.lock) 4122 globrunqputbatch(&globq) 4123 unlock(&sched.lock) 4124 startIdle(n) 4125 } 4126 4127 if runqputbatch(pp, &q); !q.empty() { 4128 lock(&sched.lock) 4129 globrunqputbatch(&q) 4130 unlock(&sched.lock) 4131 } 4132 4133 // Some P's might have become idle after we loaded `sched.npidle` 4134 // but before any goroutines were added to the queue, which could 4135 // lead to idle P's when there is work available in the global queue. 4136 // That could potentially last until other goroutines become ready 4137 // to run. That said, we need to find a way to hedge 4138 // 4139 // Calling wakep() here is the best bet, it will do nothing in the 4140 // common case (no racing on `sched.npidle`), while it could wake one 4141 // more P to execute G's, which might end up with >1 P's: the first one 4142 // wakes another P and so forth until there is no more work, but this 4143 // ought to be an extremely rare case. 4144 // 4145 // Also see "Worker thread parking/unparking" comment at the top of the file for details. 4146 wakep() 4147 } 4148 4149 // One round of scheduler: find a runnable goroutine and execute it. 4150 // Never returns. 4151 func schedule() { 4152 mp := getg().m 4153 4154 if mp.locks != 0 { 4155 throw("schedule: holding locks") 4156 } 4157 4158 if mp.lockedg != 0 { 4159 stoplockedm() 4160 execute(mp.lockedg.ptr(), false) // Never returns. 4161 } 4162 4163 // We should not schedule away from a g that is executing a cgo call, 4164 // since the cgo call is using the m's g0 stack. 4165 if mp.incgo { 4166 throw("schedule: in cgo") 4167 } 4168 4169 top: 4170 pp := mp.p.ptr() 4171 pp.preempt = false 4172 4173 // Safety check: if we are spinning, the run queue should be empty. 4174 // Check this before calling checkTimers, as that might call 4175 // goready to put a ready goroutine on the local run queue. 4176 if mp.spinning && (pp.runnext != 0 || pp.runqhead != pp.runqtail) { 4177 throw("schedule: spinning with local work") 4178 } 4179 4180 gp, inheritTime, tryWakeP := findRunnable() // blocks until work is available 4181 4182 // May be on a new P. 4183 pp = mp.p.ptr() 4184 4185 // findRunnable may have collected an allp snapshot. The snapshot is 4186 // only required within findRunnable. Clear it to all GC to collect the 4187 // slice. 4188 mp.clearAllpSnapshot() 4189 4190 // If the P was assigned a next GC mark worker but findRunnable 4191 // selected anything else, release the worker so another P may run it. 4192 // 4193 // N.B. If this occurs because a higher-priority goroutine was selected 4194 // (trace reader), then tryWakeP is set, which will wake another P to 4195 // run the worker. If this occurs because the GC is no longer active, 4196 // there is no need to wakep. 4197 gcController.releaseNextGCMarkWorker(pp) 4198 4199 if debug.dontfreezetheworld > 0 && freezing.Load() { 4200 // See comment in freezetheworld. We don't want to perturb 4201 // scheduler state, so we didn't gcstopm in findRunnable, but 4202 // also don't want to allow new goroutines to run. 4203 // 4204 // Deadlock here rather than in the findRunnable loop so if 4205 // findRunnable is stuck in a loop we don't perturb that 4206 // either. 4207 lock(&deadlock) 4208 lock(&deadlock) 4209 } 4210 4211 // This thread is going to run a goroutine and is not spinning anymore, 4212 // so if it was marked as spinning we need to reset it now and potentially 4213 // start a new spinning M. 4214 if mp.spinning { 4215 resetspinning() 4216 } 4217 4218 if sched.disable.user && !schedEnabled(gp) { 4219 // Scheduling of this goroutine is disabled. Put it on 4220 // the list of pending runnable goroutines for when we 4221 // re-enable user scheduling and look again. 4222 lock(&sched.lock) 4223 if schedEnabled(gp) { 4224 // Something re-enabled scheduling while we 4225 // were acquiring the lock. 4226 unlock(&sched.lock) 4227 } else { 4228 sched.disable.runnable.pushBack(gp) 4229 unlock(&sched.lock) 4230 goto top 4231 } 4232 } 4233 4234 // If about to schedule a not-normal goroutine (a GCworker or tracereader), 4235 // wake a P if there is one. 4236 if tryWakeP { 4237 wakep() 4238 } 4239 if gp.lockedm != 0 { 4240 // Hands off own p to the locked m, 4241 // then blocks waiting for a new p. 4242 startlockedm(gp) 4243 goto top 4244 } 4245 4246 execute(gp, inheritTime) 4247 } 4248 4249 // dropg removes the association between m and the current goroutine m->curg (gp for short). 4250 // Typically a caller sets gp's status away from Grunning and then 4251 // immediately calls dropg to finish the job. The caller is also responsible 4252 // for arranging that gp will be restarted using ready at an 4253 // appropriate time. After calling dropg and arranging for gp to be 4254 // readied later, the caller can do other work but eventually should 4255 // call schedule to restart the scheduling of goroutines on this m. 4256 func dropg() { 4257 gp := getg() 4258 4259 setMNoWB(&gp.m.curg.m, nil) 4260 setGNoWB(&gp.m.curg, nil) 4261 } 4262 4263 func parkunlock_c(gp *g, lock unsafe.Pointer) bool { 4264 unlock((*mutex)(lock)) 4265 return true 4266 } 4267 4268 // park continuation on g0. 4269 func park_m(gp *g) { 4270 mp := getg().m 4271 4272 trace := traceAcquire() 4273 4274 // If g is in a synctest group, we don't want to let the group 4275 // become idle until after the waitunlockf (if any) has confirmed 4276 // that the park is happening. 4277 // We need to record gp.bubble here, since waitunlockf can change it. 4278 bubble := gp.bubble 4279 if bubble != nil { 4280 bubble.incActive() 4281 } 4282 4283 if trace.ok() { 4284 // Trace the event before the transition. It may take a 4285 // stack trace, but we won't own the stack after the 4286 // transition anymore. 4287 trace.GoPark(mp.waitTraceBlockReason, mp.waitTraceSkip) 4288 } 4289 // N.B. Not using casGToWaiting here because the waitreason is 4290 // set by park_m's caller. 4291 casgstatus(gp, _Grunning, _Gwaiting) 4292 if trace.ok() { 4293 traceRelease(trace) 4294 } 4295 4296 dropg() 4297 4298 if fn := mp.waitunlockf; fn != nil { 4299 ok := fn(gp, mp.waitlock) 4300 mp.waitunlockf = nil 4301 mp.waitlock = nil 4302 if !ok { 4303 trace := traceAcquire() 4304 casgstatus(gp, _Gwaiting, _Grunnable) 4305 if bubble != nil { 4306 bubble.decActive() 4307 } 4308 if trace.ok() { 4309 trace.GoUnpark(gp, 2) 4310 traceRelease(trace) 4311 } 4312 execute(gp, true) // Schedule it back, never returns. 4313 } 4314 } 4315 4316 if bubble != nil { 4317 bubble.decActive() 4318 } 4319 4320 schedule() 4321 } 4322 4323 func goschedImpl(gp *g, preempted bool) { 4324 pp := gp.m.p.ptr() 4325 trace := traceAcquire() 4326 status := readgstatus(gp) 4327 if status&^_Gscan != _Grunning { 4328 dumpgstatus(gp) 4329 throw("bad g status") 4330 } 4331 if trace.ok() { 4332 // Trace the event before the transition. It may take a 4333 // stack trace, but we won't own the stack after the 4334 // transition anymore. 4335 if preempted { 4336 trace.GoPreempt() 4337 } else { 4338 trace.GoSched() 4339 } 4340 } 4341 casgstatus(gp, _Grunning, _Grunnable) 4342 if trace.ok() { 4343 traceRelease(trace) 4344 } 4345 4346 dropg() 4347 if preempted && sched.gcwaiting.Load() { 4348 // If preempted for STW, keep the G on the local P in runnext 4349 // so it can keep running immediately after the STW. 4350 runqput(pp, gp, true) 4351 } else { 4352 lock(&sched.lock) 4353 globrunqput(gp) 4354 unlock(&sched.lock) 4355 } 4356 4357 if mainStarted { 4358 wakep() 4359 } 4360 4361 schedule() 4362 } 4363 4364 // Gosched continuation on g0. 4365 func gosched_m(gp *g) { 4366 goschedImpl(gp, false) 4367 } 4368 4369 // goschedguarded is a forbidden-states-avoided version of gosched_m. 4370 func goschedguarded_m(gp *g) { 4371 if !canPreemptM(gp.m) { 4372 gogo(&gp.sched) // never return 4373 } 4374 goschedImpl(gp, false) 4375 } 4376 4377 func gopreempt_m(gp *g) { 4378 goschedImpl(gp, true) 4379 } 4380 4381 // preemptPark parks gp and puts it in _Gpreempted. 4382 // 4383 //go:systemstack 4384 func preemptPark(gp *g) { 4385 status := readgstatus(gp) 4386 if status&^_Gscan != _Grunning { 4387 dumpgstatus(gp) 4388 throw("bad g status") 4389 } 4390 4391 if gp.asyncSafePoint { 4392 // Double-check that async preemption does not 4393 // happen in SPWRITE assembly functions. 4394 // isAsyncSafePoint must exclude this case. 4395 f := findfunc(gp.sched.pc) 4396 if !f.valid() { 4397 throw("preempt at unknown pc") 4398 } 4399 if f.flag&abi.FuncFlagSPWrite != 0 { 4400 println("runtime: unexpected SPWRITE function", funcname(f), "in async preempt") 4401 throw("preempt SPWRITE") 4402 } 4403 } 4404 4405 // Transition from _Grunning to _Gscan|_Gpreempted. We can't 4406 // be in _Grunning when we dropg because then we'd be running 4407 // without an M, but the moment we're in _Gpreempted, 4408 // something could claim this G before we've fully cleaned it 4409 // up. Hence, we set the scan bit to lock down further 4410 // transitions until we can dropg. 4411 casGToPreemptScan(gp, _Grunning, _Gscan|_Gpreempted) 4412 4413 // Be careful about ownership as we trace this next event. 4414 // 4415 // According to the tracer invariants (trace.go) it's unsafe 4416 // for us to emit an event for a goroutine we do not own. 4417 // The moment we CAS into _Gpreempted, suspendG could CAS the 4418 // goroutine to _Gwaiting, effectively taking ownership. All of 4419 // this could happen before we even get the chance to emit 4420 // an event. The end result is that the events could appear 4421 // out of order, and the tracer generally assumes the scheduler 4422 // takes care of the ordering between GoPark and GoUnpark. 4423 // 4424 // The answer here is simple: emit the event while we still hold 4425 // the _Gscan bit on the goroutine, since the _Gscan bit means 4426 // ownership over transitions. 4427 // 4428 // We still need to traceAcquire and traceRelease across the CAS 4429 // because the tracer could be what's calling suspendG in the first 4430 // place. This also upholds the tracer invariant that we must hold 4431 // traceAcquire/traceRelease across the transition. However, we 4432 // specifically *only* emit the event while we still have ownership. 4433 trace := traceAcquire() 4434 if trace.ok() { 4435 trace.GoPark(traceBlockPreempted, 0) 4436 } 4437 4438 // Drop the goroutine from the M. Only do this after the tracer has 4439 // emitted an event, because it needs the association for GoPark to 4440 // work correctly. 4441 dropg() 4442 4443 // Drop the scan bit and release the trace locker if necessary. 4444 casfrom_Gscanstatus(gp, _Gscan|_Gpreempted, _Gpreempted) 4445 if trace.ok() { 4446 traceRelease(trace) 4447 } 4448 4449 // All done. 4450 schedule() 4451 } 4452 4453 // goyield is like Gosched, but it: 4454 // - emits a GoPreempt trace event instead of a GoSched trace event 4455 // - puts the current G on the runq of the current P instead of the globrunq 4456 // 4457 // goyield should be an internal detail, 4458 // but widely used packages access it using linkname. 4459 // Notable members of the hall of shame include: 4460 // - gvisor.dev/gvisor 4461 // - github.com/sagernet/gvisor 4462 // 4463 // Do not remove or change the type signature. 4464 // See go.dev/issue/67401. 4465 // 4466 //go:linkname goyield 4467 func goyield() { 4468 checkTimeouts() 4469 mcall(goyield_m) 4470 } 4471 4472 func goyield_m(gp *g) { 4473 trace := traceAcquire() 4474 pp := gp.m.p.ptr() 4475 if trace.ok() { 4476 // Trace the event before the transition. It may take a 4477 // stack trace, but we won't own the stack after the 4478 // transition anymore. 4479 trace.GoPreempt() 4480 } 4481 casgstatus(gp, _Grunning, _Grunnable) 4482 if trace.ok() { 4483 traceRelease(trace) 4484 } 4485 dropg() 4486 runqput(pp, gp, false) 4487 schedule() 4488 } 4489 4490 // Finishes execution of the current goroutine. 4491 func goexit1() { 4492 if raceenabled { 4493 if gp := getg(); gp.bubble != nil { 4494 racereleasemergeg(gp, gp.bubble.raceaddr()) 4495 } 4496 racegoend() 4497 } 4498 trace := traceAcquire() 4499 if trace.ok() { 4500 trace.GoEnd() 4501 traceRelease(trace) 4502 } 4503 mcall(goexit0) 4504 } 4505 4506 // goexit continuation on g0. 4507 func goexit0(gp *g) { 4508 if goexperiment.RuntimeSecret && gp.secret > 0 { 4509 // Erase the whole stack. This path only occurs when 4510 // runtime.Goexit is called from within a runtime/secret.Do call. 4511 memclrNoHeapPointers(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo) 4512 // Since this is running on g0, our registers are already zeroed from going through 4513 // mcall in secret mode. 4514 } 4515 gdestroy(gp) 4516 schedule() 4517 } 4518 4519 func gdestroy(gp *g) { 4520 mp := getg().m 4521 pp := mp.p.ptr() 4522 4523 casgstatus(gp, _Grunning, _Gdead) 4524 gcController.addScannableStack(pp, -int64(gp.stack.hi-gp.stack.lo)) 4525 if isSystemGoroutine(gp, false) { 4526 sched.ngsys.Add(-1) 4527 } 4528 gp.m = nil 4529 locked := gp.lockedm != 0 4530 gp.lockedm = 0 4531 mp.lockedg = 0 4532 gp.preemptStop = false 4533 gp.paniconfault = false 4534 gp._defer = nil // should be true already but just in case. 4535 gp._panic = nil // non-nil for Goexit during panic. points at stack-allocated data. 4536 gp.writebuf = nil 4537 gp.waitreason = waitReasonZero 4538 gp.param = nil 4539 gp.labels = nil 4540 gp.timer = nil 4541 gp.bubble = nil 4542 gp.fipsOnlyBypass = false 4543 gp.secret = 0 4544 4545 if gcBlackenEnabled != 0 && gp.gcAssistBytes > 0 { 4546 // Flush assist credit to the global pool. This gives 4547 // better information to pacing if the application is 4548 // rapidly creating an exiting goroutines. 4549 assistWorkPerByte := gcController.assistWorkPerByte.Load() 4550 scanCredit := int64(assistWorkPerByte * float64(gp.gcAssistBytes)) 4551 gcController.bgScanCredit.Add(scanCredit) 4552 gp.gcAssistBytes = 0 4553 } 4554 4555 dropg() 4556 4557 if GOARCH == "wasm" { // no threads yet on wasm 4558 gfput(pp, gp) 4559 return 4560 } 4561 4562 if locked && mp.lockedInt != 0 { 4563 print("runtime: mp.lockedInt = ", mp.lockedInt, "\n") 4564 if mp.isextra { 4565 throw("runtime.Goexit called in a thread that was not created by the Go runtime") 4566 } 4567 throw("exited a goroutine internally locked to the OS thread") 4568 } 4569 gfput(pp, gp) 4570 if locked { 4571 // The goroutine may have locked this thread because 4572 // it put it in an unusual kernel state. Kill it 4573 // rather than returning it to the thread pool. 4574 4575 // Return to mstart, which will release the P and exit 4576 // the thread. 4577 if GOOS != "plan9" { // See golang.org/issue/22227. 4578 gogo(&mp.g0.sched) 4579 } else { 4580 // Clear lockedExt on plan9 since we may end up re-using 4581 // this thread. 4582 mp.lockedExt = 0 4583 } 4584 } 4585 } 4586 4587 // save updates getg().sched to refer to pc and sp so that a following 4588 // gogo will restore pc and sp. 4589 // 4590 // save must not have write barriers because invoking a write barrier 4591 // can clobber getg().sched. 4592 // 4593 //go:nosplit 4594 //go:nowritebarrierrec 4595 func save(pc, sp, bp uintptr) { 4596 gp := getg() 4597 4598 if gp == gp.m.g0 || gp == gp.m.gsignal { 4599 // m.g0.sched is special and must describe the context 4600 // for exiting the thread. mstart1 writes to it directly. 4601 // m.gsignal.sched should not be used at all. 4602 // This check makes sure save calls do not accidentally 4603 // run in contexts where they'd write to system g's. 4604 throw("save on system g not allowed") 4605 } 4606 4607 gp.sched.pc = pc 4608 gp.sched.sp = sp 4609 gp.sched.lr = 0 4610 gp.sched.bp = bp 4611 // We need to ensure ctxt is zero, but can't have a write 4612 // barrier here. However, it should always already be zero. 4613 // Assert that. 4614 if gp.sched.ctxt != nil { 4615 badctxt() 4616 } 4617 } 4618 4619 // The goroutine g is about to enter a system call. 4620 // Record that it's not using the cpu anymore. 4621 // This is called only from the go syscall library and cgocall, 4622 // not from the low-level system calls used by the runtime. 4623 // 4624 // Entersyscall cannot split the stack: the save must 4625 // make g->sched refer to the caller's stack segment, because 4626 // entersyscall is going to return immediately after. 4627 // 4628 // Nothing entersyscall calls can split the stack either. 4629 // We cannot safely move the stack during an active call to syscall, 4630 // because we do not know which of the uintptr arguments are 4631 // really pointers (back into the stack). 4632 // In practice, this means that we make the fast path run through 4633 // entersyscall doing no-split things, and the slow path has to use systemstack 4634 // to run bigger things on the system stack. 4635 // 4636 // reentersyscall is the entry point used by cgo callbacks, where explicitly 4637 // saved SP and PC are restored. This is needed when exitsyscall will be called 4638 // from a function further up in the call stack than the parent, as g->syscallsp 4639 // must always point to a valid stack frame. entersyscall below is the normal 4640 // entry point for syscalls, which obtains the SP and PC from the caller. 4641 // 4642 //go:nosplit 4643 func reentersyscall(pc, sp, bp uintptr) { 4644 gp := getg() 4645 4646 // Disable preemption because during this function g is in Gsyscall status, 4647 // but can have inconsistent g->sched, do not let GC observe it. 4648 gp.m.locks++ 4649 4650 // This M may have a signal stack that is dirtied with secret information 4651 // (see package "runtime/secret"). Since it's about to go into a syscall for 4652 // an arbitrary amount of time and the G that put the secret info there 4653 // might have returned from secret.Do, we have to zero it out now, lest we 4654 // break the guarantee that secrets are purged by the next GC after a return 4655 // to secret.Do. 4656 // 4657 // It might be tempting to think that we only need to zero out this if we're 4658 // not running in secret mode anymore, but that leaves an ABA problem. The G 4659 // that put the secrets onto our signal stack may not be the one that is 4660 // currently executing. 4661 // 4662 // Logically, we should erase this when we lose our P, not when we enter the 4663 // syscall. This would avoid a zeroing in the case where the call returns 4664 // almost immediately. Since we use this path for cgo calls as well, these 4665 // fast "syscalls" are quite common. However, since we only erase the signal 4666 // stack if we were delivered a signal in secret mode and considering the 4667 // cross-thread synchronization cost for the P, it hardly seems worth it. 4668 // 4669 // TODO(dmo): can we encode the goid into mp.signalSecret and avoid the ABA problem? 4670 if goexperiment.RuntimeSecret { 4671 eraseSecretsSignalStk() 4672 } 4673 4674 // Entersyscall must not call any function that might split/grow the stack. 4675 // (See details in comment above.) 4676 // Catch calls that might, by replacing the stack guard with something that 4677 // will trip any stack check and leaving a flag to tell newstack to die. 4678 gp.stackguard0 = stackPreempt 4679 gp.throwsplit = true 4680 4681 // Copy the syscalltick over so we can identify if the P got stolen later. 4682 gp.m.syscalltick = gp.m.p.ptr().syscalltick 4683 4684 pp := gp.m.p.ptr() 4685 if pp.runSafePointFn != 0 { 4686 // runSafePointFn may stack split if run on this stack 4687 systemstack(runSafePointFn) 4688 } 4689 gp.m.oldp.set(pp) 4690 4691 // Leave SP around for GC and traceback. 4692 save(pc, sp, bp) 4693 gp.syscallsp = sp 4694 gp.syscallpc = pc 4695 gp.syscallbp = bp 4696 4697 // Double-check sp and bp. 4698 if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp { 4699 systemstack(func() { 4700 print("entersyscall inconsistent sp ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n") 4701 throw("entersyscall") 4702 }) 4703 } 4704 if gp.syscallbp != 0 && gp.syscallbp < gp.stack.lo || gp.stack.hi < gp.syscallbp { 4705 systemstack(func() { 4706 print("entersyscall inconsistent bp ", hex(gp.syscallbp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n") 4707 throw("entersyscall") 4708 }) 4709 } 4710 trace := traceAcquire() 4711 if trace.ok() { 4712 // Emit a trace event. Notably, actually emitting the event must happen before 4713 // the casgstatus because it mutates the P, but the traceLocker must be held 4714 // across the casgstatus since we're transitioning out of _Grunning 4715 // (see trace.go invariants). 4716 systemstack(func() { 4717 trace.GoSysCall() 4718 }) 4719 // systemstack clobbered gp.sched, so restore it. 4720 save(pc, sp, bp) 4721 } 4722 if sched.gcwaiting.Load() { 4723 // Optimization: If there's a pending STW, do the equivalent of 4724 // entersyscallblock here at the last minute and immediately give 4725 // away our P. 4726 systemstack(func() { 4727 entersyscallHandleGCWait(trace) 4728 }) 4729 // systemstack clobbered gp.sched, so restore it. 4730 save(pc, sp, bp) 4731 } 4732 // As soon as we switch to _Gsyscall, we are in danger of losing our P. 4733 // We must not touch it after this point. 4734 // 4735 // Try to do a quick CAS to avoid calling into casgstatus in the common case. 4736 // If we have a bubble, we need to fall into casgstatus. 4737 if gp.bubble != nil || !gp.atomicstatus.CompareAndSwap(_Grunning, _Gsyscall) { 4738 casgstatus(gp, _Grunning, _Gsyscall) 4739 } 4740 if staticLockRanking { 4741 // casgstatus clobbers gp.sched via systemstack under staticLockRanking. Restore it. 4742 save(pc, sp, bp) 4743 } 4744 if trace.ok() { 4745 // N.B. We don't need to go on the systemstack because traceRelease is very 4746 // carefully recursively nosplit. This also means we don't need to worry 4747 // about clobbering gp.sched. 4748 traceRelease(trace) 4749 } 4750 if sched.sysmonwait.Load() { 4751 systemstack(entersyscallWakeSysmon) 4752 // systemstack clobbered gp.sched, so restore it. 4753 save(pc, sp, bp) 4754 } 4755 gp.m.locks-- 4756 } 4757 4758 // debugExtendGrunningNoP is a debug mode that extends the windows in which 4759 // we're _Grunning without a P in order to try to shake out bugs with code 4760 // assuming this state is impossible. 4761 const debugExtendGrunningNoP = false 4762 4763 // Standard syscall entry used by the go syscall library and normal cgo calls. 4764 // 4765 // This is exported via linkname to assembly in the syscall package and x/sys. 4766 // 4767 // Other packages should not be accessing entersyscall directly, 4768 // but widely used packages access it using linkname. 4769 // Notable members of the hall of shame include: 4770 // - gvisor.dev/gvisor 4771 // 4772 // Do not remove or change the type signature. 4773 // See go.dev/issue/67401. 4774 // 4775 //go:nosplit 4776 //go:linkname entersyscall 4777 func entersyscall() { 4778 // N.B. getcallerfp cannot be written directly as argument in the call 4779 // to reentersyscall because it forces spilling the other arguments to 4780 // the stack. This results in exceeding the nosplit stack requirements 4781 // on some platforms. 4782 fp := getcallerfp() 4783 reentersyscall(sys.GetCallerPC(), sys.GetCallerSP(), fp) 4784 } 4785 4786 func entersyscallWakeSysmon() { 4787 lock(&sched.lock) 4788 if sched.sysmonwait.Load() { 4789 sched.sysmonwait.Store(false) 4790 notewakeup(&sched.sysmonnote) 4791 } 4792 unlock(&sched.lock) 4793 } 4794 4795 func entersyscallHandleGCWait(trace traceLocker) { 4796 gp := getg() 4797 4798 lock(&sched.lock) 4799 if sched.stopwait > 0 { 4800 // Set our P to _Pgcstop so the STW can take it. 4801 pp := gp.m.p.ptr() 4802 pp.m = 0 4803 gp.m.p = 0 4804 atomic.Store(&pp.status, _Pgcstop) 4805 4806 if trace.ok() { 4807 trace.ProcStop(pp) 4808 } 4809 addGSyscallNoP(gp.m) // We gave up our P voluntarily. 4810 pp.gcStopTime = nanotime() 4811 pp.syscalltick++ 4812 if sched.stopwait--; sched.stopwait == 0 { 4813 notewakeup(&sched.stopnote) 4814 } 4815 } 4816 unlock(&sched.lock) 4817 } 4818 4819 // The same as entersyscall(), but with a hint that the syscall is blocking. 4820 4821 // entersyscallblock should be an internal detail, 4822 // but widely used packages access it using linkname. 4823 // Notable members of the hall of shame include: 4824 // - gvisor.dev/gvisor 4825 // 4826 // Do not remove or change the type signature. 4827 // See go.dev/issue/67401. 4828 // 4829 //go:linkname entersyscallblock 4830 //go:nosplit 4831 func entersyscallblock() { 4832 gp := getg() 4833 4834 gp.m.locks++ // see comment in entersyscall 4835 gp.throwsplit = true 4836 gp.stackguard0 = stackPreempt // see comment in entersyscall 4837 gp.m.syscalltick = gp.m.p.ptr().syscalltick 4838 gp.m.p.ptr().syscalltick++ 4839 4840 addGSyscallNoP(gp.m) // We're going to give up our P. 4841 4842 // Leave SP around for GC and traceback. 4843 pc := sys.GetCallerPC() 4844 sp := sys.GetCallerSP() 4845 bp := getcallerfp() 4846 save(pc, sp, bp) 4847 gp.syscallsp = gp.sched.sp 4848 gp.syscallpc = gp.sched.pc 4849 gp.syscallbp = gp.sched.bp 4850 if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp { 4851 sp1 := sp 4852 sp2 := gp.sched.sp 4853 sp3 := gp.syscallsp 4854 systemstack(func() { 4855 print("entersyscallblock inconsistent sp ", hex(sp1), " ", hex(sp2), " ", hex(sp3), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n") 4856 throw("entersyscallblock") 4857 }) 4858 } 4859 4860 // Once we switch to _Gsyscall, we can't safely touch 4861 // our P anymore, so we need to hand it off beforehand. 4862 // The tracer also needs to see the syscall before the P 4863 // handoff, so the order here must be (1) trace, 4864 // (2) handoff, (3) _Gsyscall switch. 4865 trace := traceAcquire() 4866 systemstack(func() { 4867 if trace.ok() { 4868 trace.GoSysCall() 4869 } 4870 handoffp(releasep()) 4871 }) 4872 // <-- 4873 // Caution: we're in a small window where we are in _Grunning without a P. 4874 // --> 4875 if debugExtendGrunningNoP { 4876 usleep(10) 4877 } 4878 casgstatus(gp, _Grunning, _Gsyscall) 4879 if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp { 4880 systemstack(func() { 4881 print("entersyscallblock inconsistent sp ", hex(sp), " ", hex(gp.sched.sp), " ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n") 4882 throw("entersyscallblock") 4883 }) 4884 } 4885 if gp.syscallbp != 0 && gp.syscallbp < gp.stack.lo || gp.stack.hi < gp.syscallbp { 4886 systemstack(func() { 4887 print("entersyscallblock inconsistent bp ", hex(bp), " ", hex(gp.sched.bp), " ", hex(gp.syscallbp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n") 4888 throw("entersyscallblock") 4889 }) 4890 } 4891 if trace.ok() { 4892 systemstack(func() { 4893 traceRelease(trace) 4894 }) 4895 } 4896 4897 // Resave for traceback during blocked call. 4898 save(sys.GetCallerPC(), sys.GetCallerSP(), getcallerfp()) 4899 4900 gp.m.locks-- 4901 } 4902 4903 // The goroutine g exited its system call. 4904 // Arrange for it to run on a cpu again. 4905 // This is called only from the go syscall library, not 4906 // from the low-level system calls used by the runtime. 4907 // 4908 // Write barriers are not allowed because our P may have been stolen. 4909 // 4910 // This is exported via linkname to assembly in the syscall package. 4911 // 4912 // exitsyscall should be an internal detail, 4913 // but widely used packages access it using linkname. 4914 // Notable members of the hall of shame include: 4915 // - gvisor.dev/gvisor 4916 // 4917 // Do not remove or change the type signature. 4918 // See go.dev/issue/67401. 4919 // 4920 //go:nosplit 4921 //go:nowritebarrierrec 4922 //go:linkname exitsyscall 4923 func exitsyscall() { 4924 gp := getg() 4925 4926 gp.m.locks++ // see comment in entersyscall 4927 if sys.GetCallerSP() > gp.syscallsp { 4928 throw("exitsyscall: syscall frame is no longer valid") 4929 } 4930 gp.waitsince = 0 4931 4932 if sched.stopwait == freezeStopWait { 4933 // Wedge ourselves if there's an outstanding freezetheworld. 4934 // If we transition to running, we might end up with our traceback 4935 // being taken twice. 4936 systemstack(func() { 4937 lock(&deadlock) 4938 lock(&deadlock) 4939 }) 4940 } 4941 4942 // Optimistically assume we're going to keep running, and switch to running. 4943 // Before this point, our P wiring is not ours. Once we get past this point, 4944 // we can access our P if we have it, otherwise we lost it. 4945 // 4946 // N.B. Because we're transitioning to _Grunning here, traceAcquire doesn't 4947 // need to be held ahead of time. We're effectively atomic with respect to 4948 // the tracer because we're non-preemptible and in the runtime. It can't stop 4949 // us to read a bad status. 4950 // 4951 // Try to do a quick CAS to avoid calling into casgstatus in the common case. 4952 // If we have a bubble, we need to fall into casgstatus. 4953 if gp.bubble != nil || !gp.atomicstatus.CompareAndSwap(_Gsyscall, _Grunning) { 4954 casgstatus(gp, _Gsyscall, _Grunning) 4955 } 4956 4957 // Caution: we're in a window where we may be in _Grunning without a P. 4958 // Either we will grab a P or call exitsyscall0, where we'll switch to 4959 // _Grunnable. 4960 if debugExtendGrunningNoP { 4961 usleep(10) 4962 } 4963 4964 // Grab and clear our old P. 4965 oldp := gp.m.oldp.ptr() 4966 gp.m.oldp.set(nil) 4967 4968 // Check if we still have a P, and if not, try to acquire an idle P. 4969 pp := gp.m.p.ptr() 4970 if pp != nil { 4971 // Fast path: we still have our P. Just emit a syscall exit event. 4972 if trace := traceAcquire(); trace.ok() { 4973 systemstack(func() { 4974 // The truth is we truly never lost the P, but syscalltick 4975 // is used to indicate whether the P should be treated as 4976 // lost anyway. For example, when syscalltick is trashed by 4977 // dropm. 4978 // 4979 // TODO(mknyszek): Consider a more explicit mechanism for this. 4980 // Then syscalltick doesn't need to be trashed, and can be used 4981 // exclusively by sysmon for deciding when it's time to retake. 4982 if pp.syscalltick == gp.m.syscalltick { 4983 trace.GoSysExit(false) 4984 } else { 4985 // Since we need to pretend we lost the P, but nobody ever 4986 // took it, we need a ProcSteal event to model the loss. 4987 // Then, continue with everything else we'd do if we lost 4988 // the P. 4989 trace.ProcSteal(pp) 4990 trace.ProcStart() 4991 trace.GoSysExit(true) 4992 trace.GoStart() 4993 } 4994 traceRelease(trace) 4995 }) 4996 } 4997 } else { 4998 // Slow path: we lost our P. Try to get another one. 4999 systemstack(func() { 5000 // Try to get some other P. 5001 if pp := exitsyscallTryGetP(oldp); pp != nil { 5002 // Install the P. 5003 acquirepNoTrace(pp) 5004 5005 // We're going to start running again, so emit all the relevant events. 5006 if trace := traceAcquire(); trace.ok() { 5007 trace.ProcStart() 5008 trace.GoSysExit(true) 5009 trace.GoStart() 5010 traceRelease(trace) 5011 } 5012 } 5013 }) 5014 pp = gp.m.p.ptr() 5015 } 5016 5017 // If we have a P, clean up and exit. 5018 if pp != nil { 5019 if goroutineProfile.active { 5020 // Make sure that gp has had its stack written out to the goroutine 5021 // profile, exactly as it was when the goroutine profiler first 5022 // stopped the world. 5023 systemstack(func() { 5024 tryRecordGoroutineProfileWB(gp) 5025 }) 5026 } 5027 5028 // Increment the syscalltick for P, since we're exiting a syscall. 5029 pp.syscalltick++ 5030 5031 // Garbage collector isn't running (since we are), 5032 // so okay to clear syscallsp. 5033 gp.syscallsp = 0 5034 gp.m.locks-- 5035 if gp.preempt { 5036 // Restore the preemption request in case we cleared it in newstack. 5037 gp.stackguard0 = stackPreempt 5038 } else { 5039 // Otherwise restore the real stackGuard, we clobbered it in entersyscall/entersyscallblock. 5040 gp.stackguard0 = gp.stack.lo + stackGuard 5041 } 5042 gp.throwsplit = false 5043 5044 if sched.disable.user && !schedEnabled(gp) { 5045 // Scheduling of this goroutine is disabled. 5046 Gosched() 5047 } 5048 return 5049 } 5050 // Slowest path: We couldn't get a P, so call into the scheduler. 5051 gp.m.locks-- 5052 5053 // Call the scheduler. 5054 mcall(exitsyscallNoP) 5055 5056 // Scheduler returned, so we're allowed to run now. 5057 // Delete the syscallsp information that we left for 5058 // the garbage collector during the system call. 5059 // Must wait until now because until gosched returns 5060 // we don't know for sure that the garbage collector 5061 // is not running. 5062 gp.syscallsp = 0 5063 gp.m.p.ptr().syscalltick++ 5064 gp.throwsplit = false 5065 } 5066 5067 // exitsyscall's attempt to try to get any P, if it's missing one. 5068 // Returns true on success. 5069 // 5070 // Must execute on the systemstack because exitsyscall is nosplit. 5071 // 5072 //go:systemstack 5073 func exitsyscallTryGetP(oldp *p) *p { 5074 // Try to steal our old P back. 5075 if oldp != nil { 5076 if thread, ok := setBlockOnExitSyscall(oldp); ok { 5077 thread.takeP() 5078 decGSyscallNoP(getg().m) // We got a P for ourselves. 5079 thread.resume() 5080 return oldp 5081 } 5082 } 5083 5084 // Try to get an idle P. 5085 if sched.pidle != 0 { 5086 lock(&sched.lock) 5087 pp, _ := pidleget(0) 5088 if pp != nil && sched.sysmonwait.Load() { 5089 sched.sysmonwait.Store(false) 5090 notewakeup(&sched.sysmonnote) 5091 } 5092 unlock(&sched.lock) 5093 if pp != nil { 5094 decGSyscallNoP(getg().m) // We got a P for ourselves. 5095 return pp 5096 } 5097 } 5098 return nil 5099 } 5100 5101 // exitsyscall slow path on g0. 5102 // Failed to acquire P, enqueue gp as runnable. 5103 // 5104 // Called via mcall, so gp is the calling g from this M. 5105 // 5106 //go:nowritebarrierrec 5107 func exitsyscallNoP(gp *g) { 5108 traceExitingSyscall() 5109 trace := traceAcquire() 5110 casgstatus(gp, _Grunning, _Grunnable) 5111 traceExitedSyscall() 5112 if trace.ok() { 5113 // Write out syscall exit eagerly. 5114 // 5115 // It's important that we write this *after* we know whether we 5116 // lost our P or not (determined by exitsyscallfast). 5117 trace.GoSysExit(true) 5118 traceRelease(trace) 5119 } 5120 decGSyscallNoP(getg().m) 5121 dropg() 5122 lock(&sched.lock) 5123 var pp *p 5124 if schedEnabled(gp) { 5125 pp, _ = pidleget(0) 5126 } 5127 var locked bool 5128 if pp == nil { 5129 globrunqput(gp) 5130 5131 // Below, we stoplockedm if gp is locked. globrunqput releases 5132 // ownership of gp, so we must check if gp is locked prior to 5133 // committing the release by unlocking sched.lock, otherwise we 5134 // could race with another M transitioning gp from unlocked to 5135 // locked. 5136 locked = gp.lockedm != 0 5137 } else if sched.sysmonwait.Load() { 5138 sched.sysmonwait.Store(false) 5139 notewakeup(&sched.sysmonnote) 5140 } 5141 unlock(&sched.lock) 5142 if pp != nil { 5143 acquirep(pp) 5144 execute(gp, false) // Never returns. 5145 } 5146 if locked { 5147 // Wait until another thread schedules gp and so m again. 5148 // 5149 // N.B. lockedm must be this M, as this g was running on this M 5150 // before entersyscall. 5151 stoplockedm() 5152 execute(gp, false) // Never returns. 5153 } 5154 stopm() 5155 schedule() // Never returns. 5156 } 5157 5158 // addGSyscallNoP must be called when a goroutine in a syscall loses its P. 5159 // This function updates all relevant accounting. 5160 // 5161 // nosplit because it's called on the syscall paths. 5162 // 5163 //go:nosplit 5164 func addGSyscallNoP(mp *m) { 5165 // It's safe to read isExtraInC here because it's only mutated 5166 // outside of _Gsyscall, and we know this thread is attached 5167 // to a goroutine in _Gsyscall and blocked from exiting. 5168 if !mp.isExtraInC { 5169 // Increment nGsyscallNoP since we're taking away a P 5170 // from a _Gsyscall goroutine, but only if isExtraInC 5171 // is not set on the M. If it is, then this thread is 5172 // back to being a full C thread, and will just inflate 5173 // the count of not-in-go goroutines. See go.dev/issue/76435. 5174 sched.nGsyscallNoP.Add(1) 5175 } 5176 } 5177 5178 // decGSsyscallNoP must be called whenever a goroutine in a syscall without 5179 // a P exits the system call. This function updates all relevant accounting. 5180 // 5181 // nosplit because it's called from dropm. 5182 // 5183 //go:nosplit 5184 func decGSyscallNoP(mp *m) { 5185 // Update nGsyscallNoP, but only if this is not a thread coming 5186 // out of C. See the comment in addGSyscallNoP. This logic must match, 5187 // to avoid unmatched increments and decrements. 5188 if !mp.isExtraInC { 5189 sched.nGsyscallNoP.Add(-1) 5190 } 5191 } 5192 5193 // Called from syscall package before fork. 5194 // 5195 // syscall_runtime_BeforeFork is for package syscall, 5196 // but widely used packages access it using linkname. 5197 // Notable members of the hall of shame include: 5198 // - gvisor.dev/gvisor 5199 // 5200 // Do not remove or change the type signature. 5201 // See go.dev/issue/67401. 5202 // 5203 //go:linkname syscall_runtime_BeforeFork syscall.runtime_BeforeFork 5204 //go:nosplit 5205 func syscall_runtime_BeforeFork() { 5206 gp := getg().m.curg 5207 5208 // Block signals during a fork, so that the child does not run 5209 // a signal handler before exec if a signal is sent to the process 5210 // group. See issue #18600. 5211 gp.m.locks++ 5212 sigsave(&gp.m.sigmask) 5213 sigblock(false) 5214 5215 // This function is called before fork in syscall package. 5216 // Code between fork and exec must not allocate memory nor even try to grow stack. 5217 // Here we spoil g.stackguard0 to reliably detect any attempts to grow stack. 5218 // runtime_AfterFork will undo this in parent process, but not in child. 5219 gp.stackguard0 = stackFork 5220 } 5221 5222 // Called from syscall package after fork in parent. 5223 // 5224 // syscall_runtime_AfterFork is for package syscall, 5225 // but widely used packages access it using linkname. 5226 // Notable members of the hall of shame include: 5227 // - gvisor.dev/gvisor 5228 // 5229 // Do not remove or change the type signature. 5230 // See go.dev/issue/67401. 5231 // 5232 //go:linkname syscall_runtime_AfterFork syscall.runtime_AfterFork 5233 //go:nosplit 5234 func syscall_runtime_AfterFork() { 5235 gp := getg().m.curg 5236 5237 // See the comments in beforefork. 5238 gp.stackguard0 = gp.stack.lo + stackGuard 5239 5240 msigrestore(gp.m.sigmask) 5241 5242 gp.m.locks-- 5243 } 5244 5245 // inForkedChild is true while manipulating signals in the child process. 5246 // This is used to avoid calling libc functions in case we are using vfork. 5247 var inForkedChild bool 5248 5249 // Called from syscall package after fork in child. 5250 // It resets non-sigignored signals to the default handler, and 5251 // restores the signal mask in preparation for the exec. 5252 // 5253 // Because this might be called during a vfork, and therefore may be 5254 // temporarily sharing address space with the parent process, this must 5255 // not change any global variables or calling into C code that may do so. 5256 // 5257 // syscall_runtime_AfterForkInChild is for package syscall, 5258 // but widely used packages access it using linkname. 5259 // Notable members of the hall of shame include: 5260 // - gvisor.dev/gvisor 5261 // 5262 // Do not remove or change the type signature. 5263 // See go.dev/issue/67401. 5264 // 5265 //go:linkname syscall_runtime_AfterForkInChild syscall.runtime_AfterForkInChild 5266 //go:nosplit 5267 //go:nowritebarrierrec 5268 func syscall_runtime_AfterForkInChild() { 5269 // It's OK to change the global variable inForkedChild here 5270 // because we are going to change it back. There is no race here, 5271 // because if we are sharing address space with the parent process, 5272 // then the parent process can not be running concurrently. 5273 inForkedChild = true 5274 5275 clearSignalHandlers() 5276 5277 // When we are the child we are the only thread running, 5278 // so we know that nothing else has changed gp.m.sigmask. 5279 msigrestore(getg().m.sigmask) 5280 5281 inForkedChild = false 5282 } 5283 5284 // pendingPreemptSignals is the number of preemption signals 5285 // that have been sent but not received. This is only used on Darwin. 5286 // For #41702. 5287 var pendingPreemptSignals atomic.Int32 5288 5289 // Called from syscall package before Exec. 5290 // 5291 //go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec 5292 func syscall_runtime_BeforeExec() { 5293 // Prevent thread creation during exec. 5294 execLock.lock() 5295 5296 // On Darwin, wait for all pending preemption signals to 5297 // be received. See issue #41702. 5298 if GOOS == "darwin" || GOOS == "ios" { 5299 for pendingPreemptSignals.Load() > 0 { 5300 osyield() 5301 } 5302 } 5303 } 5304 5305 // Called from syscall package after Exec. 5306 // 5307 //go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec 5308 func syscall_runtime_AfterExec() { 5309 execLock.unlock() 5310 } 5311 5312 // Allocate a new g, with a stack big enough for stacksize bytes. 5313 func malg(stacksize int32) *g { 5314 newg := new(g) 5315 if stacksize >= 0 { 5316 stacksize = round2(stackSystem + stacksize) 5317 systemstack(func() { 5318 newg.stack = stackalloc(uint32(stacksize)) 5319 if valgrindenabled { 5320 newg.valgrindStackID = valgrindRegisterStack(unsafe.Pointer(newg.stack.lo), unsafe.Pointer(newg.stack.hi)) 5321 } 5322 }) 5323 newg.stackguard0 = newg.stack.lo + stackGuard 5324 newg.stackguard1 = ^uintptr(0) 5325 // Clear the bottom word of the stack. We record g 5326 // there on gsignal stack during VDSO on ARM and ARM64. 5327 *(*uintptr)(unsafe.Pointer(newg.stack.lo)) = 0 5328 } 5329 return newg 5330 } 5331 5332 // Create a new g running fn. 5333 // Put it on the queue of g's waiting to run. 5334 // The compiler turns a go statement into a call to this. 5335 func newproc(fn *funcval) { 5336 gp := getg() 5337 pc := sys.GetCallerPC() 5338 systemstack(func() { 5339 newg := newproc1(fn, gp, pc, false, waitReasonZero) 5340 5341 pp := getg().m.p.ptr() 5342 runqput(pp, newg, true) 5343 5344 if mainStarted { 5345 wakep() 5346 } 5347 }) 5348 } 5349 5350 // Create a new g in state _Grunnable (or _Gwaiting if parked is true), starting at fn. 5351 // callerpc is the address of the go statement that created this. The caller is responsible 5352 // for adding the new g to the scheduler. If parked is true, waitreason must be non-zero. 5353 func newproc1(fn *funcval, callergp *g, callerpc uintptr, parked bool, waitreason waitReason) *g { 5354 if fn == nil { 5355 fatal("go of nil func value") 5356 } 5357 5358 mp := acquirem() // disable preemption because we hold M and P in local vars. 5359 pp := mp.p.ptr() 5360 newg := gfget(pp) 5361 if newg == nil { 5362 newg = malg(stackMin) 5363 casgstatus(newg, _Gidle, _Gdead) 5364 allgadd(newg) // publishes with a g->status of Gdead so GC scanner doesn't look at uninitialized stack. 5365 } 5366 if newg.stack.hi == 0 { 5367 throw("newproc1: newg missing stack") 5368 } 5369 5370 if readgstatus(newg) != _Gdead { 5371 throw("newproc1: new g is not Gdead") 5372 } 5373 5374 totalSize := uintptr(4*goarch.PtrSize + sys.MinFrameSize) // extra space in case of reads slightly beyond frame 5375 totalSize = alignUp(totalSize, sys.StackAlign) 5376 sp := newg.stack.hi - totalSize 5377 if usesLR { 5378 // caller's LR 5379 *(*uintptr)(unsafe.Pointer(sp)) = 0 5380 prepGoExitFrame(sp) 5381 } 5382 if GOARCH == "arm64" { 5383 // caller's FP 5384 *(*uintptr)(unsafe.Pointer(sp - goarch.PtrSize)) = 0 5385 } 5386 5387 memclrNoHeapPointers(unsafe.Pointer(&newg.sched), unsafe.Sizeof(newg.sched)) 5388 newg.sched.sp = sp 5389 newg.stktopsp = sp 5390 newg.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum // +PCQuantum so that previous instruction is in same function 5391 newg.sched.g = guintptr(unsafe.Pointer(newg)) 5392 gostartcallfn(&newg.sched, fn) 5393 newg.parentGoid = callergp.goid 5394 newg.gopc = callerpc 5395 newg.ancestors = saveAncestors(callergp) 5396 newg.startpc = fn.fn 5397 newg.runningCleanups.Store(false) 5398 if isSystemGoroutine(newg, false) { 5399 sched.ngsys.Add(1) 5400 } else { 5401 // Only user goroutines inherit synctest groups and pprof labels. 5402 newg.bubble = callergp.bubble 5403 if mp.curg != nil { 5404 newg.labels = mp.curg.labels 5405 } 5406 if goroutineProfile.active { 5407 // A concurrent goroutine profile is running. It should include 5408 // exactly the set of goroutines that were alive when the goroutine 5409 // profiler first stopped the world. That does not include newg, so 5410 // mark it as not needing a profile before transitioning it from 5411 // _Gdead. 5412 newg.goroutineProfiled.Store(goroutineProfileSatisfied) 5413 } 5414 } 5415 // Track initial transition? 5416 newg.trackingSeq = uint8(cheaprand()) 5417 if newg.trackingSeq%gTrackingPeriod == 0 { 5418 newg.tracking = true 5419 } 5420 gcController.addScannableStack(pp, int64(newg.stack.hi-newg.stack.lo)) 5421 5422 // Get a goid and switch to runnable. This needs to happen under traceAcquire 5423 // since it's a goroutine transition. See tracer invariants in trace.go. 5424 trace := traceAcquire() 5425 var status uint32 = _Grunnable 5426 if parked { 5427 status = _Gwaiting 5428 newg.waitreason = waitreason 5429 } 5430 if pp.goidcache == pp.goidcacheend { 5431 // Sched.goidgen is the last allocated id, 5432 // this batch must be [sched.goidgen+1, sched.goidgen+GoidCacheBatch]. 5433 // At startup sched.goidgen=0, so main goroutine receives goid=1. 5434 pp.goidcache = sched.goidgen.Add(_GoidCacheBatch) 5435 pp.goidcache -= _GoidCacheBatch - 1 5436 pp.goidcacheend = pp.goidcache + _GoidCacheBatch 5437 } 5438 newg.goid = pp.goidcache 5439 casgstatus(newg, _Gdead, status) 5440 pp.goidcache++ 5441 newg.trace.reset() 5442 if trace.ok() { 5443 trace.GoCreate(newg, newg.startpc, parked) 5444 traceRelease(trace) 5445 } 5446 5447 // fips140 bubble 5448 newg.fipsOnlyBypass = callergp.fipsOnlyBypass 5449 5450 // dit bubble 5451 newg.ditWanted = callergp.ditWanted 5452 5453 if goexperiment.RuntimeSecret && callergp.secret > 0 { 5454 // while it might seem weird to have a non-zero gp.secret value 5455 // with no calls to secret.Do on the stack, this case is handled 5456 // just fine by the cleanup logic in goexit0 5457 // TODO: secret mode is invisible to the user if they don't ask about it via secret.Enabled 5458 // and can have severe performance penalties (at time of writing, wrapping the entire 5459 // tls handshake resulted in a 30% slowdown of the benchmarks). 5460 // Whether a goroutine is running in secret mode should be more visible, 5461 // maybe with a stack frame or some sort of bubble inspecting mechanism 5462 newg.secret = 1 5463 } 5464 5465 // Set up race context. 5466 if raceenabled { 5467 newg.racectx = racegostart(callerpc) 5468 newg.raceignore = 0 5469 if newg.labels != nil { 5470 // See note in proflabel.go on labelSync's role in synchronizing 5471 // with the reads in the signal handler. 5472 racereleasemergeg(newg, unsafe.Pointer(&labelSync)) 5473 } 5474 } 5475 pp.goroutinesCreated++ 5476 releasem(mp) 5477 5478 return newg 5479 } 5480 5481 // saveAncestors copies previous ancestors of the given caller g and 5482 // includes info for the current caller into a new set of tracebacks for 5483 // a g being created. 5484 func saveAncestors(callergp *g) *[]ancestorInfo { 5485 // Copy all prior info, except for the root goroutine (goid 0). 5486 if debug.tracebackancestors <= 0 || callergp.goid == 0 { 5487 return nil 5488 } 5489 var callerAncestors []ancestorInfo 5490 if callergp.ancestors != nil { 5491 callerAncestors = *callergp.ancestors 5492 } 5493 n := int32(len(callerAncestors)) + 1 5494 if n > debug.tracebackancestors { 5495 n = debug.tracebackancestors 5496 } 5497 ancestors := make([]ancestorInfo, n) 5498 copy(ancestors[1:], callerAncestors) 5499 5500 var pcs [tracebackInnerFrames]uintptr 5501 npcs := gcallers(callergp, 0, pcs[:]) 5502 ipcs := make([]uintptr, npcs) 5503 copy(ipcs, pcs[:]) 5504 ancestors[0] = ancestorInfo{ 5505 pcs: ipcs, 5506 goid: callergp.goid, 5507 gopc: callergp.gopc, 5508 } 5509 5510 ancestorsp := new([]ancestorInfo) 5511 *ancestorsp = ancestors 5512 return ancestorsp 5513 } 5514 5515 // Put on gfree list. 5516 // If local list is too long, transfer a batch to the global list. 5517 func gfput(pp *p, gp *g) { 5518 if readgstatus(gp) != _Gdead { 5519 throw("gfput: bad status (not Gdead)") 5520 } 5521 5522 stksize := gp.stack.hi - gp.stack.lo 5523 5524 if stksize != uintptr(startingStackSize) { 5525 // non-standard stack size - free it. 5526 stackfree(gp.stack) 5527 gp.stack.lo = 0 5528 gp.stack.hi = 0 5529 gp.stackguard0 = 0 5530 if valgrindenabled { 5531 valgrindDeregisterStack(gp.valgrindStackID) 5532 gp.valgrindStackID = 0 5533 } 5534 } 5535 5536 pp.gFree.push(gp) 5537 if pp.gFree.size >= 64 { 5538 var ( 5539 stackQ gQueue 5540 noStackQ gQueue 5541 ) 5542 for pp.gFree.size >= 32 { 5543 gp := pp.gFree.pop() 5544 if gp.stack.lo == 0 { 5545 noStackQ.push(gp) 5546 } else { 5547 stackQ.push(gp) 5548 } 5549 } 5550 lock(&sched.gFree.lock) 5551 sched.gFree.noStack.pushAll(noStackQ) 5552 sched.gFree.stack.pushAll(stackQ) 5553 unlock(&sched.gFree.lock) 5554 } 5555 } 5556 5557 // Get from gfree list. 5558 // If local list is empty, grab a batch from global list. 5559 func gfget(pp *p) *g { 5560 retry: 5561 if pp.gFree.empty() && (!sched.gFree.stack.empty() || !sched.gFree.noStack.empty()) { 5562 lock(&sched.gFree.lock) 5563 // Move a batch of free Gs to the P. 5564 for pp.gFree.size < 32 { 5565 // Prefer Gs with stacks. 5566 gp := sched.gFree.stack.pop() 5567 if gp == nil { 5568 gp = sched.gFree.noStack.pop() 5569 if gp == nil { 5570 break 5571 } 5572 } 5573 pp.gFree.push(gp) 5574 } 5575 unlock(&sched.gFree.lock) 5576 goto retry 5577 } 5578 gp := pp.gFree.pop() 5579 if gp == nil { 5580 return nil 5581 } 5582 if gp.stack.lo != 0 && gp.stack.hi-gp.stack.lo != uintptr(startingStackSize) { 5583 // Deallocate old stack. We kept it in gfput because it was the 5584 // right size when the goroutine was put on the free list, but 5585 // the right size has changed since then. 5586 systemstack(func() { 5587 stackfree(gp.stack) 5588 gp.stack.lo = 0 5589 gp.stack.hi = 0 5590 gp.stackguard0 = 0 5591 if valgrindenabled { 5592 valgrindDeregisterStack(gp.valgrindStackID) 5593 gp.valgrindStackID = 0 5594 } 5595 }) 5596 } 5597 if gp.stack.lo == 0 { 5598 // Stack was deallocated in gfput or just above. Allocate a new one. 5599 systemstack(func() { 5600 gp.stack = stackalloc(startingStackSize) 5601 if valgrindenabled { 5602 gp.valgrindStackID = valgrindRegisterStack(unsafe.Pointer(gp.stack.lo), unsafe.Pointer(gp.stack.hi)) 5603 } 5604 }) 5605 gp.stackguard0 = gp.stack.lo + stackGuard 5606 } else { 5607 if raceenabled { 5608 racemalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo) 5609 } 5610 if msanenabled { 5611 msanmalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo) 5612 } 5613 if asanenabled { 5614 asanunpoison(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo) 5615 } 5616 } 5617 return gp 5618 } 5619 5620 // Purge all cached G's from gfree list to the global list. 5621 func gfpurge(pp *p) { 5622 var ( 5623 stackQ gQueue 5624 noStackQ gQueue 5625 ) 5626 for !pp.gFree.empty() { 5627 gp := pp.gFree.pop() 5628 if gp.stack.lo == 0 { 5629 noStackQ.push(gp) 5630 } else { 5631 stackQ.push(gp) 5632 } 5633 } 5634 lock(&sched.gFree.lock) 5635 sched.gFree.noStack.pushAll(noStackQ) 5636 sched.gFree.stack.pushAll(stackQ) 5637 unlock(&sched.gFree.lock) 5638 } 5639 5640 // Breakpoint executes a breakpoint trap. 5641 func Breakpoint() { 5642 breakpoint() 5643 } 5644 5645 // dolockOSThread is called by LockOSThread and lockOSThread below 5646 // after they modify m.locked. Do not allow preemption during this call, 5647 // or else the m might be different in this function than in the caller. 5648 // 5649 //go:nosplit 5650 func dolockOSThread() { 5651 if GOARCH == "wasm" { 5652 return // no threads on wasm yet 5653 } 5654 gp := getg() 5655 gp.m.lockedg.set(gp) 5656 gp.lockedm.set(gp.m) 5657 } 5658 5659 // LockOSThread wires the calling goroutine to its current operating system thread. 5660 // The calling goroutine will always execute in that thread, 5661 // and no other goroutine will execute in it, 5662 // until the calling goroutine has made as many calls to 5663 // [UnlockOSThread] as to LockOSThread. 5664 // If the calling goroutine exits without unlocking the thread, 5665 // the thread will be terminated. 5666 // 5667 // All init functions are run on the startup thread. Calling LockOSThread 5668 // from an init function will cause the main function to be invoked on 5669 // that thread. 5670 // 5671 // A goroutine should call LockOSThread before calling OS services or 5672 // non-Go library functions that depend on per-thread state. 5673 // 5674 //go:nosplit 5675 func LockOSThread() { 5676 if atomic.Load(&newmHandoff.haveTemplateThread) == 0 && GOOS != "plan9" { 5677 // If we need to start a new thread from the locked 5678 // thread, we need the template thread. Start it now 5679 // while we're in a known-good state. 5680 startTemplateThread() 5681 } 5682 gp := getg() 5683 gp.m.lockedExt++ 5684 if gp.m.lockedExt == 0 { 5685 gp.m.lockedExt-- 5686 panic("LockOSThread nesting overflow") 5687 } 5688 dolockOSThread() 5689 } 5690 5691 //go:nosplit 5692 func lockOSThread() { 5693 getg().m.lockedInt++ 5694 dolockOSThread() 5695 } 5696 5697 // dounlockOSThread is called by UnlockOSThread and unlockOSThread below 5698 // after they update m->locked. Do not allow preemption during this call, 5699 // or else the m might be in different in this function than in the caller. 5700 // 5701 //go:nosplit 5702 func dounlockOSThread() { 5703 if GOARCH == "wasm" { 5704 return // no threads on wasm yet 5705 } 5706 gp := getg() 5707 if gp.m.lockedInt != 0 || gp.m.lockedExt != 0 { 5708 return 5709 } 5710 gp.m.lockedg = 0 5711 gp.lockedm = 0 5712 } 5713 5714 // UnlockOSThread undoes an earlier call to LockOSThread. 5715 // If this drops the number of active LockOSThread calls on the 5716 // calling goroutine to zero, it unwires the calling goroutine from 5717 // its fixed operating system thread. 5718 // If there are no active LockOSThread calls, this is a no-op. 5719 // 5720 // Before calling UnlockOSThread, the caller must ensure that the OS 5721 // thread is suitable for running other goroutines. If the caller made 5722 // any permanent changes to the state of the thread that would affect 5723 // other goroutines, it should not call this function and thus leave 5724 // the goroutine locked to the OS thread until the goroutine (and 5725 // hence the thread) exits. 5726 // 5727 //go:nosplit 5728 func UnlockOSThread() { 5729 gp := getg() 5730 if gp.m.lockedExt == 0 { 5731 return 5732 } 5733 gp.m.lockedExt-- 5734 dounlockOSThread() 5735 } 5736 5737 //go:nosplit 5738 func unlockOSThread() { 5739 gp := getg() 5740 if gp.m.lockedInt == 0 { 5741 systemstack(badunlockosthread) 5742 } 5743 gp.m.lockedInt-- 5744 dounlockOSThread() 5745 } 5746 5747 func badunlockosthread() { 5748 throw("runtime: internal error: misuse of lockOSThread/unlockOSThread") 5749 } 5750 5751 func gcount(includeSys bool) int32 { 5752 n := int32(atomic.Loaduintptr(&allglen)) - sched.gFree.stack.size - sched.gFree.noStack.size 5753 if !includeSys { 5754 n -= sched.ngsys.Load() 5755 } 5756 for _, pp := range allp { 5757 n -= pp.gFree.size 5758 } 5759 5760 // All these variables can be changed concurrently, so the result can be inconsistent. 5761 // But at least the current goroutine is running. 5762 if n < 1 { 5763 n = 1 5764 } 5765 return n 5766 } 5767 5768 // goroutineleakcount returns the number of leaked goroutines last reported by 5769 // the runtime. 5770 // 5771 //go:linkname goroutineleakcount runtime/pprof.runtime_goroutineleakcount 5772 func goroutineleakcount() int { 5773 return work.goroutineLeak.count 5774 } 5775 5776 func mcount() int32 { 5777 return int32(sched.mnext - sched.nmfreed) 5778 } 5779 5780 var prof struct { 5781 signalLock atomic.Uint32 5782 5783 // Must hold signalLock to write. Reads may be lock-free, but 5784 // signalLock should be taken to synchronize with changes. 5785 hz atomic.Int32 5786 } 5787 5788 func _System() { _System() } 5789 func _ExternalCode() { _ExternalCode() } 5790 func _LostExternalCode() { _LostExternalCode() } 5791 func _GC() { _GC() } 5792 func _LostSIGPROFDuringAtomic64() { _LostSIGPROFDuringAtomic64() } 5793 func _LostContendedRuntimeLock() { _LostContendedRuntimeLock() } 5794 func _VDSO() { _VDSO() } 5795 5796 // Called if we receive a SIGPROF signal. 5797 // Called by the signal handler, may run during STW. 5798 // 5799 //go:nowritebarrierrec 5800 func sigprof(pc, sp, lr uintptr, gp *g, mp *m) { 5801 if prof.hz.Load() == 0 { 5802 return 5803 } 5804 5805 // If mp.profilehz is 0, then profiling is not enabled for this thread. 5806 // We must check this to avoid a deadlock between setcpuprofilerate 5807 // and the call to cpuprof.add, below. 5808 if mp != nil && mp.profilehz == 0 { 5809 return 5810 } 5811 5812 // On mips{,le}/arm, 64bit atomics are emulated with spinlocks, in 5813 // internal/runtime/atomic. If SIGPROF arrives while the program is inside 5814 // the critical section, it creates a deadlock (when writing the sample). 5815 // As a workaround, create a counter of SIGPROFs while in critical section 5816 // to store the count, and pass it to sigprof.add() later when SIGPROF is 5817 // received from somewhere else (with _LostSIGPROFDuringAtomic64 as pc). 5818 if GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "arm" { 5819 if f := findfunc(pc); f.valid() { 5820 if stringslite.HasPrefix(funcname(f), "internal/runtime/atomic") { 5821 cpuprof.lostAtomic++ 5822 return 5823 } 5824 } 5825 if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && pc&0xffff0000 == 0xffff0000 { 5826 // internal/runtime/atomic functions call into kernel 5827 // helpers on arm < 7. See 5828 // internal/runtime/atomic/sys_linux_arm.s. 5829 cpuprof.lostAtomic++ 5830 return 5831 } 5832 } 5833 5834 // Profiling runs concurrently with GC, so it must not allocate. 5835 // Set a trap in case the code does allocate. 5836 // Note that on windows, one thread takes profiles of all the 5837 // other threads, so mp is usually not getg().m. 5838 // In fact mp may not even be stopped. 5839 // See golang.org/issue/17165. 5840 getg().m.mallocing++ 5841 5842 var u unwinder 5843 var stk [maxCPUProfStack]uintptr 5844 n := 0 5845 if mp.ncgo > 0 && mp.curg != nil && mp.curg.syscallpc != 0 && mp.curg.syscallsp != 0 { 5846 cgoOff := 0 5847 // Check cgoCallersUse to make sure that we are not 5848 // interrupting other code that is fiddling with 5849 // cgoCallers. We are running in a signal handler 5850 // with all signals blocked, so we don't have to worry 5851 // about any other code interrupting us. 5852 if mp.cgoCallersUse.Load() == 0 && mp.cgoCallers != nil && mp.cgoCallers[0] != 0 { 5853 for cgoOff < len(mp.cgoCallers) && mp.cgoCallers[cgoOff] != 0 { 5854 cgoOff++ 5855 } 5856 n += copy(stk[:], mp.cgoCallers[:cgoOff]) 5857 mp.cgoCallers[0] = 0 5858 } 5859 5860 // Collect Go stack that leads to the cgo call. 5861 u.initAt(mp.curg.syscallpc, mp.curg.syscallsp, 0, mp.curg, unwindSilentErrors) 5862 } else if usesLibcall() && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 { 5863 // Libcall, i.e. runtime syscall on windows. 5864 // Collect Go stack that leads to the call. 5865 u.initAt(mp.libcallpc, mp.libcallsp, 0, mp.libcallg.ptr(), unwindSilentErrors) 5866 } else if mp != nil && mp.vdsoSP != 0 { 5867 // VDSO call, e.g. nanotime1 on Linux. 5868 // Collect Go stack that leads to the call. 5869 u.initAt(mp.vdsoPC, mp.vdsoSP, 0, gp, unwindSilentErrors|unwindJumpStack) 5870 } else { 5871 u.initAt(pc, sp, lr, gp, unwindSilentErrors|unwindTrap|unwindJumpStack) 5872 } 5873 n += tracebackPCs(&u, 0, stk[n:]) 5874 5875 if n <= 0 { 5876 // Normal traceback is impossible or has failed. 5877 // Account it against abstract "System" or "GC". 5878 n = 2 5879 if inVDSOPage(pc) { 5880 pc = abi.FuncPCABIInternal(_VDSO) + sys.PCQuantum 5881 } else if pc > firstmoduledata.etext { 5882 // "ExternalCode" is better than "etext". 5883 pc = abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum 5884 } 5885 stk[0] = pc 5886 if mp.preemptoff != "" { 5887 stk[1] = abi.FuncPCABIInternal(_GC) + sys.PCQuantum 5888 } else { 5889 stk[1] = abi.FuncPCABIInternal(_System) + sys.PCQuantum 5890 } 5891 } 5892 5893 if prof.hz.Load() != 0 { 5894 // Note: it can happen on Windows that we interrupted a system thread 5895 // with no g, so gp could nil. The other nil checks are done out of 5896 // caution, but not expected to be nil in practice. 5897 var tagPtr *unsafe.Pointer 5898 if gp != nil && gp.m != nil && gp.m.curg != nil { 5899 tagPtr = &gp.m.curg.labels 5900 } 5901 cpuprof.add(tagPtr, stk[:n]) 5902 5903 gprof := gp 5904 var mp *m 5905 var pp *p 5906 if gp != nil && gp.m != nil { 5907 if gp.m.curg != nil { 5908 gprof = gp.m.curg 5909 } 5910 mp = gp.m 5911 pp = gp.m.p.ptr() 5912 } 5913 traceCPUSample(gprof, mp, pp, stk[:n]) 5914 } 5915 getg().m.mallocing-- 5916 } 5917 5918 // setcpuprofilerate sets the CPU profiling rate to hz times per second. 5919 // If hz <= 0, setcpuprofilerate turns off CPU profiling. 5920 func setcpuprofilerate(hz int32) { 5921 // Force sane arguments. 5922 if hz < 0 { 5923 hz = 0 5924 } 5925 5926 // Disable preemption, otherwise we can be rescheduled to another thread 5927 // that has profiling enabled. 5928 gp := getg() 5929 gp.m.locks++ 5930 5931 // Stop profiler on this thread so that it is safe to lock prof. 5932 // if a profiling signal came in while we had prof locked, 5933 // it would deadlock. 5934 setThreadCPUProfiler(0) 5935 5936 for !prof.signalLock.CompareAndSwap(0, 1) { 5937 osyield() 5938 } 5939 if prof.hz.Load() != hz { 5940 setProcessCPUProfiler(hz) 5941 prof.hz.Store(hz) 5942 } 5943 prof.signalLock.Store(0) 5944 5945 lock(&sched.lock) 5946 sched.profilehz = hz 5947 unlock(&sched.lock) 5948 5949 if hz != 0 { 5950 setThreadCPUProfiler(hz) 5951 } 5952 5953 gp.m.locks-- 5954 } 5955 5956 // init initializes pp, which may be a freshly allocated p or a 5957 // previously destroyed p, and transitions it to status _Pgcstop. 5958 func (pp *p) init(id int32) { 5959 pp.id = id 5960 pp.gcw.id = id 5961 pp.status = _Pgcstop 5962 pp.sudogcache = pp.sudogbuf[:0] 5963 pp.deferpool = pp.deferpoolbuf[:0] 5964 pp.wbBuf.reset() 5965 if pp.mcache == nil { 5966 if id == 0 { 5967 if mcache0 == nil { 5968 throw("missing mcache?") 5969 } 5970 // Use the bootstrap mcache0. Only one P will get 5971 // mcache0: the one with ID 0. 5972 pp.mcache = mcache0 5973 } else { 5974 pp.mcache = allocmcache() 5975 } 5976 } 5977 if raceenabled && pp.raceprocctx == 0 { 5978 if id == 0 { 5979 pp.raceprocctx = raceprocctx0 5980 raceprocctx0 = 0 // bootstrap 5981 } else { 5982 pp.raceprocctx = raceproccreate() 5983 } 5984 } 5985 lockInit(&pp.timers.mu, lockRankTimers) 5986 5987 // This P may get timers when it starts running. Set the mask here 5988 // since the P may not go through pidleget (notably P 0 on startup). 5989 timerpMask.set(id) 5990 // Similarly, we may not go through pidleget before this P starts 5991 // running if it is P 0 on startup. 5992 idlepMask.clear(id) 5993 } 5994 5995 // destroy releases all of the resources associated with pp and 5996 // transitions it to status _Pdead. 5997 // 5998 // sched.lock must be held and the world must be stopped. 5999 func (pp *p) destroy() { 6000 assertLockHeld(&sched.lock) 6001 assertWorldStopped() 6002 6003 // Move all runnable goroutines to the global queue 6004 for pp.runqhead != pp.runqtail { 6005 // Pop from tail of local queue 6006 pp.runqtail-- 6007 gp := pp.runq[pp.runqtail%uint32(len(pp.runq))].ptr() 6008 // Push onto head of global queue 6009 globrunqputhead(gp) 6010 } 6011 if pp.runnext != 0 { 6012 globrunqputhead(pp.runnext.ptr()) 6013 pp.runnext = 0 6014 } 6015 6016 // Move all timers to the local P. 6017 getg().m.p.ptr().timers.take(&pp.timers) 6018 6019 // No need to flush p's write barrier buffer or span queue, as Ps 6020 // cannot be destroyed during the mark phase. 6021 if phase := gcphase; phase != _GCoff { 6022 println("runtime: p id", pp.id, "destroyed during GC phase", phase) 6023 throw("P destroyed while GC is running") 6024 } 6025 // We should free the queues though. 6026 pp.gcw.spanq.destroy() 6027 6028 clear(pp.sudogbuf[:]) 6029 pp.sudogcache = pp.sudogbuf[:0] 6030 pp.pinnerCache = nil 6031 clear(pp.deferpoolbuf[:]) 6032 pp.deferpool = pp.deferpoolbuf[:0] 6033 systemstack(func() { 6034 for i := 0; i < pp.mspancache.len; i++ { 6035 // Safe to call since the world is stopped. 6036 mheap_.spanalloc.free(unsafe.Pointer(pp.mspancache.buf[i])) 6037 } 6038 pp.mspancache.len = 0 6039 lock(&mheap_.lock) 6040 pp.pcache.flush(&mheap_.pages) 6041 unlock(&mheap_.lock) 6042 }) 6043 freemcache(pp.mcache) 6044 pp.mcache = nil 6045 gfpurge(pp) 6046 if raceenabled { 6047 if pp.timers.raceCtx != 0 { 6048 // The race detector code uses a callback to fetch 6049 // the proc context, so arrange for that callback 6050 // to see the right thing. 6051 // This hack only works because we are the only 6052 // thread running. 6053 mp := getg().m 6054 phold := mp.p.ptr() 6055 mp.p.set(pp) 6056 6057 racectxend(pp.timers.raceCtx) 6058 pp.timers.raceCtx = 0 6059 6060 mp.p.set(phold) 6061 } 6062 raceprocdestroy(pp.raceprocctx) 6063 pp.raceprocctx = 0 6064 } 6065 pp.gcAssistTime = 0 6066 gcCleanups.queued += pp.cleanupsQueued 6067 pp.cleanupsQueued = 0 6068 sched.goroutinesCreated.Add(int64(pp.goroutinesCreated)) 6069 pp.goroutinesCreated = 0 6070 pp.xRegs.free() 6071 pp.status = _Pdead 6072 } 6073 6074 // Change number of processors. 6075 // 6076 // sched.lock must be held, and the world must be stopped. 6077 // 6078 // gcworkbufs must not be being modified by either the GC or the write barrier 6079 // code, so the GC must not be running if the number of Ps actually changes. 6080 // 6081 // Returns list of Ps with local work, they need to be scheduled by the caller. 6082 func procresize(nprocs int32) *p { 6083 assertLockHeld(&sched.lock) 6084 assertWorldStopped() 6085 6086 old := gomaxprocs 6087 if old < 0 || nprocs <= 0 { 6088 throw("procresize: invalid arg") 6089 } 6090 trace := traceAcquire() 6091 if trace.ok() { 6092 trace.Gomaxprocs(nprocs) 6093 traceRelease(trace) 6094 } 6095 6096 // update statistics 6097 now := nanotime() 6098 if sched.procresizetime != 0 { 6099 sched.totaltime += int64(old) * (now - sched.procresizetime) 6100 } 6101 sched.procresizetime = now 6102 6103 // Grow allp if necessary. 6104 if nprocs > int32(len(allp)) { 6105 // Synchronize with retake, which could be running 6106 // concurrently since it doesn't run on a P. 6107 lock(&allpLock) 6108 if nprocs <= int32(cap(allp)) { 6109 allp = allp[:nprocs] 6110 } else { 6111 nallp := make([]*p, nprocs) 6112 // Copy everything up to allp's cap so we 6113 // never lose old allocated Ps. 6114 copy(nallp, allp[:cap(allp)]) 6115 allp = nallp 6116 } 6117 6118 idlepMask = idlepMask.resize(nprocs) 6119 timerpMask = timerpMask.resize(nprocs) 6120 work.spanqMask = work.spanqMask.resize(nprocs) 6121 unlock(&allpLock) 6122 } 6123 6124 // initialize new P's 6125 for i := old; i < nprocs; i++ { 6126 pp := allp[i] 6127 if pp == nil { 6128 pp = new(p) 6129 } 6130 pp.init(i) 6131 atomicstorep(unsafe.Pointer(&allp[i]), unsafe.Pointer(pp)) 6132 } 6133 6134 gp := getg() 6135 if gp.m.p != 0 && gp.m.p.ptr().id < nprocs { 6136 // continue to use the current P 6137 gp.m.p.ptr().status = _Prunning 6138 gp.m.p.ptr().mcache.prepareForSweep() 6139 } else { 6140 // release the current P and acquire allp[0]. 6141 // 6142 // We must do this before destroying our current P 6143 // because p.destroy itself has write barriers, so we 6144 // need to do that from a valid P. 6145 if gp.m.p != 0 { 6146 trace := traceAcquire() 6147 if trace.ok() { 6148 // Pretend that we were descheduled 6149 // and then scheduled again to keep 6150 // the trace consistent. 6151 trace.GoSched() 6152 trace.ProcStop(gp.m.p.ptr()) 6153 traceRelease(trace) 6154 } 6155 gp.m.p.ptr().m = 0 6156 } 6157 gp.m.p = 0 6158 pp := allp[0] 6159 pp.m = 0 6160 pp.status = _Pidle 6161 acquirep(pp) 6162 trace := traceAcquire() 6163 if trace.ok() { 6164 trace.GoStart() 6165 traceRelease(trace) 6166 } 6167 } 6168 6169 // g.m.p is now set, so we no longer need mcache0 for bootstrapping. 6170 mcache0 = nil 6171 6172 // release resources from unused P's 6173 for i := nprocs; i < old; i++ { 6174 pp := allp[i] 6175 pp.destroy() 6176 // can't free P itself because it can be referenced by an M in syscall 6177 } 6178 6179 // Trim allp. 6180 if int32(len(allp)) != nprocs { 6181 lock(&allpLock) 6182 allp = allp[:nprocs] 6183 idlepMask = idlepMask.resize(nprocs) 6184 timerpMask = timerpMask.resize(nprocs) 6185 work.spanqMask = work.spanqMask.resize(nprocs) 6186 unlock(&allpLock) 6187 } 6188 6189 // Assign Ms to Ps with runnable goroutines. 6190 var runnablePs *p 6191 var runnablePsNeedM *p 6192 var idlePs *p 6193 for i := nprocs - 1; i >= 0; i-- { 6194 pp := allp[i] 6195 if gp.m.p.ptr() == pp { 6196 continue 6197 } 6198 pp.status = _Pidle 6199 if runqempty(pp) { 6200 pp.link.set(idlePs) 6201 idlePs = pp 6202 continue 6203 } 6204 6205 // Prefer to run on the most recent M if it is 6206 // available. 6207 // 6208 // Ps with no oldm (or for which oldm is already taken 6209 // by an earlier P), we delay until all oldm Ps are 6210 // handled. Otherwise, mget may return an M that a 6211 // later P has in oldm. 6212 var mp *m 6213 if oldm := pp.oldm.get(); oldm != nil { 6214 // Returns nil if oldm is not idle. 6215 mp = mgetSpecific(oldm) 6216 } 6217 if mp == nil { 6218 // Call mget later. 6219 pp.link.set(runnablePsNeedM) 6220 runnablePsNeedM = pp 6221 continue 6222 } 6223 pp.m.set(mp) 6224 pp.link.set(runnablePs) 6225 runnablePs = pp 6226 } 6227 // Assign Ms to remaining runnable Ps without usable oldm. See comment 6228 // above. 6229 for runnablePsNeedM != nil { 6230 pp := runnablePsNeedM 6231 runnablePsNeedM = pp.link.ptr() 6232 6233 mp := mget() 6234 pp.m.set(mp) 6235 pp.link.set(runnablePs) 6236 runnablePs = pp 6237 } 6238 6239 // Now that we've assigned Ms to Ps with runnable goroutines, assign GC 6240 // mark workers to remaining idle Ps, if needed. 6241 // 6242 // By assigning GC workers to Ps here, we slightly speed up starting 6243 // the world, as we will start enough Ps to run all of the user 6244 // goroutines and GC mark workers all at once, rather than using a 6245 // sequence of wakep calls as each P's findRunnable realizes it needs 6246 // to run a mark worker instead of a user goroutine. 6247 // 6248 // By assigning GC workers to Ps only _after_ previously-running Ps are 6249 // assigned Ms, we ensure that goroutines previously running on a P 6250 // continue to run on the same P, with GC mark workers preferring 6251 // previously-idle Ps. This helps prevent goroutines from shuffling 6252 // around too much across STW. 6253 // 6254 // N.B., if there aren't enough Ps left in idlePs for all of the GC 6255 // mark workers, then findRunnable will still choose to run mark 6256 // workers on Ps assigned above. 6257 // 6258 // N.B., we do this during any STW in the mark phase, not just the 6259 // sweep termination STW that starts the mark phase. gcBgMarkWorker 6260 // always preempts by removing itself from the P, so even unrelated 6261 // STWs during the mark require that Ps reselect mark workers upon 6262 // restart. 6263 if gcBlackenEnabled != 0 { 6264 for idlePs != nil { 6265 pp := idlePs 6266 6267 ok, _ := gcController.assignWaitingGCWorker(pp, now) 6268 if !ok { 6269 // No more mark workers needed. 6270 break 6271 } 6272 6273 // Got a worker, P is now runnable. 6274 // 6275 // mget may return nil if there aren't enough Ms, in 6276 // which case startTheWorldWithSema will start one. 6277 // 6278 // N.B. findRunnableGCWorker will make the worker G 6279 // itself runnable. 6280 idlePs = pp.link.ptr() 6281 mp := mget() 6282 pp.m.set(mp) 6283 pp.link.set(runnablePs) 6284 runnablePs = pp 6285 } 6286 } 6287 6288 // Finally, any remaining Ps are truly idle. 6289 for idlePs != nil { 6290 pp := idlePs 6291 idlePs = pp.link.ptr() 6292 pidleput(pp, now) 6293 } 6294 6295 stealOrder.reset(uint32(nprocs)) 6296 var int32p *int32 = &gomaxprocs // make compiler check that gomaxprocs is an int32 6297 atomic.Store((*uint32)(unsafe.Pointer(int32p)), uint32(nprocs)) 6298 if old != nprocs { 6299 // Notify the limiter that the amount of procs has changed. 6300 gcCPULimiter.resetCapacity(now, nprocs) 6301 } 6302 return runnablePs 6303 } 6304 6305 // Associate p and the current m. 6306 // 6307 // This function is allowed to have write barriers even if the caller 6308 // isn't because it immediately acquires pp. 6309 // 6310 //go:yeswritebarrierrec 6311 func acquirep(pp *p) { 6312 // Do the work. 6313 acquirepNoTrace(pp) 6314 6315 // Emit the event. 6316 trace := traceAcquire() 6317 if trace.ok() { 6318 trace.ProcStart() 6319 traceRelease(trace) 6320 } 6321 } 6322 6323 // Internals of acquirep, just skipping the trace events. 6324 // 6325 //go:yeswritebarrierrec 6326 func acquirepNoTrace(pp *p) { 6327 // Do the part that isn't allowed to have write barriers. 6328 wirep(pp) 6329 6330 // Have p; write barriers now allowed. 6331 6332 // The M we're associating with will be the old M after the next 6333 // releasep. We must set this here because write barriers are not 6334 // allowed in releasep. 6335 pp.oldm = pp.m.ptr().self 6336 6337 // Perform deferred mcache flush before this P can allocate 6338 // from a potentially stale mcache. 6339 pp.mcache.prepareForSweep() 6340 } 6341 6342 // wirep is the first step of acquirep, which actually associates the 6343 // current M to pp. This is broken out so we can disallow write 6344 // barriers for this part, since we don't yet have a P. 6345 // 6346 //go:nowritebarrierrec 6347 //go:nosplit 6348 func wirep(pp *p) { 6349 gp := getg() 6350 6351 if gp.m.p != 0 { 6352 // Call on the systemstack to avoid a nosplit overflow build failure 6353 // on some platforms when built with -N -l. See #64113. 6354 systemstack(func() { 6355 throw("wirep: already in go") 6356 }) 6357 } 6358 if pp.m != 0 || pp.status != _Pidle { 6359 // Call on the systemstack to avoid a nosplit overflow build failure 6360 // on some platforms when built with -N -l. See #64113. 6361 systemstack(func() { 6362 id := int64(0) 6363 if pp.m != 0 { 6364 id = pp.m.ptr().id 6365 } 6366 print("wirep: p->m=", pp.m, "(", id, ") p->status=", pp.status, "\n") 6367 throw("wirep: invalid p state") 6368 }) 6369 } 6370 gp.m.p.set(pp) 6371 pp.m.set(gp.m) 6372 pp.status = _Prunning 6373 } 6374 6375 // Disassociate p and the current m. 6376 func releasep() *p { 6377 trace := traceAcquire() 6378 if trace.ok() { 6379 trace.ProcStop(getg().m.p.ptr()) 6380 traceRelease(trace) 6381 } 6382 return releasepNoTrace() 6383 } 6384 6385 // Disassociate p and the current m without tracing an event. 6386 func releasepNoTrace() *p { 6387 gp := getg() 6388 6389 if gp.m.p == 0 { 6390 throw("releasep: invalid arg") 6391 } 6392 pp := gp.m.p.ptr() 6393 if pp.m.ptr() != gp.m || pp.status != _Prunning { 6394 print("releasep: m=", gp.m, " m->p=", gp.m.p.ptr(), " p->m=", hex(pp.m), " p->status=", pp.status, "\n") 6395 throw("releasep: invalid p state") 6396 } 6397 6398 // P must clear if nextGCMarkWorker if it stops. 6399 gcController.releaseNextGCMarkWorker(pp) 6400 6401 gp.m.p = 0 6402 pp.m = 0 6403 pp.status = _Pidle 6404 return pp 6405 } 6406 6407 func incidlelocked(v int32) { 6408 lock(&sched.lock) 6409 sched.nmidlelocked += v 6410 if v > 0 { 6411 checkdead() 6412 } 6413 unlock(&sched.lock) 6414 } 6415 6416 // Check for deadlock situation. 6417 // The check is based on number of running M's, if 0 -> deadlock. 6418 // sched.lock must be held. 6419 func checkdead() { 6420 assertLockHeld(&sched.lock) 6421 6422 // For -buildmode=c-shared or -buildmode=c-archive it's OK if 6423 // there are no running goroutines. The calling program is 6424 // assumed to be running. 6425 // One exception is Wasm, which is single-threaded. If we are 6426 // in Go and all goroutines are blocked, it deadlocks. 6427 if (islibrary || isarchive) && GOARCH != "wasm" { 6428 return 6429 } 6430 6431 // If we are dying because of a signal caught on an already idle thread, 6432 // freezetheworld will cause all running threads to block. 6433 // And runtime will essentially enter into deadlock state, 6434 // except that there is a thread that will call exit soon. 6435 if panicking.Load() > 0 { 6436 return 6437 } 6438 6439 // If we are not running under cgo, but we have an extra M then account 6440 // for it. (It is possible to have an extra M on Windows without cgo to 6441 // accommodate callbacks created by syscall.NewCallback. See issue #6751 6442 // for details.) 6443 var run0 int32 6444 if !iscgo && cgoHasExtraM && extraMLength.Load() > 0 { 6445 run0 = 1 6446 } 6447 6448 run := mcount() - sched.nmidle - sched.nmidlelocked - sched.nmsys 6449 if run > run0 { 6450 return 6451 } 6452 if run < 0 { 6453 print("runtime: checkdead: nmidle=", sched.nmidle, " nmidlelocked=", sched.nmidlelocked, " mcount=", mcount(), " nmsys=", sched.nmsys, "\n") 6454 unlock(&sched.lock) 6455 throw("checkdead: inconsistent counts") 6456 } 6457 6458 grunning := 0 6459 forEachG(func(gp *g) { 6460 if isSystemGoroutine(gp, false) { 6461 return 6462 } 6463 s := readgstatus(gp) 6464 switch s &^ _Gscan { 6465 case _Gwaiting, 6466 _Gpreempted: 6467 grunning++ 6468 case _Grunnable, 6469 _Grunning, 6470 _Gsyscall: 6471 print("runtime: checkdead: find g ", gp.goid, " in status ", s, "\n") 6472 unlock(&sched.lock) 6473 throw("checkdead: runnable g") 6474 } 6475 }) 6476 if grunning == 0 { // possible if main goroutine calls runtime·Goexit() 6477 unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang 6478 fatal("no goroutines (main called runtime.Goexit) - deadlock!") 6479 } 6480 6481 // Maybe jump time forward for playground. 6482 if faketime != 0 { 6483 if when := timeSleepUntil(); when < maxWhen { 6484 faketime = when 6485 6486 // Start an M to steal the timer. 6487 pp, _ := pidleget(faketime) 6488 if pp == nil { 6489 // There should always be a free P since 6490 // nothing is running. 6491 unlock(&sched.lock) 6492 throw("checkdead: no p for timer") 6493 } 6494 mp := mget() 6495 if mp == nil { 6496 // There should always be a free M since 6497 // nothing is running. 6498 unlock(&sched.lock) 6499 throw("checkdead: no m for timer") 6500 } 6501 // M must be spinning to steal. We set this to be 6502 // explicit, but since this is the only M it would 6503 // become spinning on its own anyways. 6504 sched.nmspinning.Add(1) 6505 mp.spinning = true 6506 mp.nextp.set(pp) 6507 notewakeup(&mp.park) 6508 return 6509 } 6510 } 6511 6512 // There are no goroutines running, so we can look at the P's. 6513 for _, pp := range allp { 6514 if len(pp.timers.heap) > 0 { 6515 return 6516 } 6517 } 6518 6519 unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang 6520 fatal("all goroutines are asleep - deadlock!") 6521 } 6522 6523 // forcegcperiod is the maximum time in nanoseconds between garbage 6524 // collections. If we go this long without a garbage collection, one 6525 // is forced to run. 6526 // 6527 // This is a variable for testing purposes. It normally doesn't change. 6528 var forcegcperiod int64 = 2 * 60 * 1e9 6529 6530 // haveSysmon indicates whether there is sysmon thread support. 6531 // 6532 // No threads on wasm yet, so no sysmon. 6533 const haveSysmon = GOARCH != "wasm" 6534 6535 // Always runs without a P, so write barriers are not allowed. 6536 // 6537 //go:nowritebarrierrec 6538 func sysmon() { 6539 lock(&sched.lock) 6540 sched.nmsys++ 6541 checkdead() 6542 unlock(&sched.lock) 6543 6544 lastgomaxprocs := int64(0) 6545 lasttrace := int64(0) 6546 idle := 0 // how many cycles in succession we had not wokeup somebody 6547 delay := uint32(0) 6548 6549 for { 6550 if idle == 0 { // start with 20us sleep... 6551 delay = 20 6552 } else if idle > 50 { // start doubling the sleep after 1ms... 6553 delay *= 2 6554 } 6555 if delay > 10*1000 { // up to 10ms 6556 delay = 10 * 1000 6557 } 6558 usleep(delay) 6559 6560 // sysmon should not enter deep sleep if schedtrace is enabled so that 6561 // it can print that information at the right time. 6562 // 6563 // It should also not enter deep sleep if there are any active P's so 6564 // that it can retake P's from syscalls, preempt long running G's, and 6565 // poll the network if all P's are busy for long stretches. 6566 // 6567 // It should wakeup from deep sleep if any P's become active either due 6568 // to exiting a syscall or waking up due to a timer expiring so that it 6569 // can resume performing those duties. If it wakes from a syscall it 6570 // resets idle and delay as a bet that since it had retaken a P from a 6571 // syscall before, it may need to do it again shortly after the 6572 // application starts work again. It does not reset idle when waking 6573 // from a timer to avoid adding system load to applications that spend 6574 // most of their time sleeping. 6575 now := nanotime() 6576 if debug.schedtrace <= 0 && (sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs) { 6577 lock(&sched.lock) 6578 if sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs { 6579 syscallWake := false 6580 next := timeSleepUntil() 6581 if next > now { 6582 sched.sysmonwait.Store(true) 6583 unlock(&sched.lock) 6584 // Make wake-up period small enough 6585 // for the sampling to be correct. 6586 sleep := forcegcperiod / 2 6587 if next-now < sleep { 6588 sleep = next - now 6589 } 6590 shouldRelax := sleep >= osRelaxMinNS 6591 if shouldRelax { 6592 osRelax(true) 6593 } 6594 syscallWake = notetsleep(&sched.sysmonnote, sleep) 6595 if shouldRelax { 6596 osRelax(false) 6597 } 6598 lock(&sched.lock) 6599 sched.sysmonwait.Store(false) 6600 noteclear(&sched.sysmonnote) 6601 } 6602 if syscallWake { 6603 idle = 0 6604 delay = 20 6605 } 6606 } 6607 unlock(&sched.lock) 6608 } 6609 6610 lock(&sched.sysmonlock) 6611 // Update now in case we blocked on sysmonnote or spent a long time 6612 // blocked on schedlock or sysmonlock above. 6613 now = nanotime() 6614 6615 // trigger libc interceptors if needed 6616 if *cgo_yield != nil { 6617 asmcgocall(*cgo_yield, nil) 6618 } 6619 // poll network if not polled for more than 10ms 6620 lastpoll := sched.lastpoll.Load() 6621 if netpollinited() && lastpoll != 0 && lastpoll+10*1000*1000 < now { 6622 sched.lastpoll.CompareAndSwap(lastpoll, now) 6623 list, delta := netpoll(0) // non-blocking - returns list of goroutines 6624 if !list.empty() { 6625 // Need to decrement number of idle locked M's 6626 // (pretending that one more is running) before injectglist. 6627 // Otherwise it can lead to the following situation: 6628 // injectglist grabs all P's but before it starts M's to run the P's, 6629 // another M returns from syscall, finishes running its G, 6630 // observes that there is no work to do and no other running M's 6631 // and reports deadlock. 6632 incidlelocked(-1) 6633 injectglist(&list) 6634 incidlelocked(1) 6635 netpollAdjustWaiters(delta) 6636 } 6637 } 6638 // Check if we need to update GOMAXPROCS at most once per second. 6639 if debug.updatemaxprocs != 0 && lastgomaxprocs+1e9 <= now { 6640 sysmonUpdateGOMAXPROCS() 6641 lastgomaxprocs = now 6642 } 6643 if scavenger.sysmonWake.Load() != 0 { 6644 // Kick the scavenger awake if someone requested it. 6645 scavenger.wake() 6646 } 6647 // retake P's blocked in syscalls 6648 // and preempt long running G's 6649 if retake(now) != 0 { 6650 idle = 0 6651 } else { 6652 idle++ 6653 } 6654 // check if we need to force a GC 6655 if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && forcegc.idle.Load() { 6656 lock(&forcegc.lock) 6657 forcegc.idle.Store(false) 6658 var list gList 6659 list.push(forcegc.g) 6660 injectglist(&list) 6661 unlock(&forcegc.lock) 6662 } 6663 if debug.schedtrace > 0 && lasttrace+int64(debug.schedtrace)*1000000 <= now { 6664 lasttrace = now 6665 schedtrace(debug.scheddetail > 0) 6666 } 6667 unlock(&sched.sysmonlock) 6668 } 6669 } 6670 6671 type sysmontick struct { 6672 schedtick uint32 6673 syscalltick uint32 6674 schedwhen int64 6675 syscallwhen int64 6676 } 6677 6678 // forcePreemptNS is the time slice given to a G before it is 6679 // preempted. 6680 const forcePreemptNS = 10 * 1000 * 1000 // 10ms 6681 6682 func retake(now int64) uint32 { 6683 n := 0 6684 // Prevent allp slice changes. This lock will be completely 6685 // uncontended unless we're already stopping the world. 6686 lock(&allpLock) 6687 // We can't use a range loop over allp because we may 6688 // temporarily drop the allpLock. Hence, we need to re-fetch 6689 // allp each time around the loop. 6690 for i := 0; i < len(allp); i++ { 6691 // Quickly filter out non-running Ps. Running Ps are either 6692 // in a syscall or are actually executing. Idle Ps don't 6693 // need to be retaken. 6694 // 6695 // This is best-effort, so it's OK that it's racy. Our target 6696 // is to retake Ps that have been running or in a syscall for 6697 // a long time (milliseconds), so the state has plenty of time 6698 // to stabilize. 6699 pp := allp[i] 6700 if pp == nil || atomic.Load(&pp.status) != _Prunning { 6701 // pp can be nil if procresize has grown 6702 // allp but not yet created new Ps. 6703 continue 6704 } 6705 pd := &pp.sysmontick 6706 sysretake := false 6707 6708 // Preempt G if it's running on the same schedtick for 6709 // too long. This could be from a single long-running 6710 // goroutine or a sequence of goroutines run via 6711 // runnext, which share a single schedtick time slice. 6712 schedt := int64(pp.schedtick) 6713 if int64(pd.schedtick) != schedt { 6714 pd.schedtick = uint32(schedt) 6715 pd.schedwhen = now 6716 } else if pd.schedwhen+forcePreemptNS <= now { 6717 preemptone(pp) 6718 // If pp is in a syscall, preemptone doesn't work. 6719 // The goroutine nor the thread can respond to a 6720 // preemption request because they're not in Go code, 6721 // so we need to take the P ourselves. 6722 sysretake = true 6723 } 6724 6725 // Drop allpLock so we can take sched.lock. 6726 unlock(&allpLock) 6727 6728 // Need to decrement number of idle locked M's (pretending that 6729 // one more is running) before we take the P and resume. 6730 // Otherwise the M from which we retake can exit the syscall, 6731 // increment nmidle and report deadlock. 6732 // 6733 // Can't call incidlelocked once we setBlockOnExitSyscall, due 6734 // to a lock ordering violation between sched.lock and _Gscan. 6735 incidlelocked(-1) 6736 6737 // Try to prevent the P from continuing in the syscall, if it's in one at all. 6738 thread, ok := setBlockOnExitSyscall(pp) 6739 if !ok { 6740 // Not in a syscall, or something changed out from under us. 6741 goto done 6742 } 6743 6744 // Retake the P if it's there for more than 1 sysmon tick (at least 20us). 6745 if syst := int64(pp.syscalltick); !sysretake && int64(pd.syscalltick) != syst { 6746 pd.syscalltick = uint32(syst) 6747 pd.syscallwhen = now 6748 thread.resume() 6749 goto done 6750 } 6751 6752 // On the one hand we don't want to retake Ps if there is no other work to do, 6753 // but on the other hand we want to retake them eventually 6754 // because they can prevent the sysmon thread from deep sleep. 6755 if runqempty(pp) && sched.nmspinning.Load()+sched.npidle.Load() > 0 && pd.syscallwhen+10*1000*1000 > now { 6756 thread.resume() 6757 goto done 6758 } 6759 6760 // Take the P. Note: because we have the scan bit, the goroutine 6761 // is at worst stuck spinning in exitsyscall. 6762 thread.takeP() 6763 thread.resume() 6764 n++ 6765 6766 // Handoff the P for some other thread to run it. 6767 handoffp(pp) 6768 6769 // The P has been handed off to another thread, so risk of a false 6770 // deadlock report while we hold onto it is gone. 6771 done: 6772 incidlelocked(1) 6773 lock(&allpLock) 6774 } 6775 unlock(&allpLock) 6776 return uint32(n) 6777 } 6778 6779 // syscallingThread represents a thread in a system call that temporarily 6780 // cannot advance out of the system call. 6781 type syscallingThread struct { 6782 gp *g 6783 mp *m 6784 pp *p 6785 status uint32 6786 } 6787 6788 // setBlockOnExitSyscall prevents pp's thread from advancing out of 6789 // exitsyscall. On success, returns the g/m/p state of the thread 6790 // and true. At that point, the caller owns the g/m/p links referenced, 6791 // the goroutine is in _Gsyscall, and prevented from transitioning out 6792 // of it. On failure, it returns false, and none of these guarantees are 6793 // made. 6794 // 6795 // Callers must call resume on the resulting thread state once 6796 // they're done with thread, otherwise it will remain blocked forever. 6797 // 6798 // This function races with state changes on pp, and thus may fail 6799 // if pp is not in a system call, or exits a system call concurrently 6800 // with this function. However, this function is safe to call without 6801 // any additional synchronization. 6802 func setBlockOnExitSyscall(pp *p) (syscallingThread, bool) { 6803 if pp.status != _Prunning { 6804 return syscallingThread{}, false 6805 } 6806 // Be very careful here, these reads are intentionally racy. 6807 // Once we notice the G is in _Gsyscall, acquire its scan bit, 6808 // and validate that it's still connected to the *same* M and P, 6809 // we can actually get to work. Holding the scan bit will prevent 6810 // the G from exiting the syscall. 6811 // 6812 // Our goal here is to interrupt long syscalls. If it turns out 6813 // that we're wrong and the G switched to another syscall while 6814 // we were trying to do this, that's completely fine. It's 6815 // probably making more frequent syscalls and the typical 6816 // preemption paths should be effective. 6817 mp := pp.m.ptr() 6818 if mp == nil { 6819 // Nothing to do. 6820 return syscallingThread{}, false 6821 } 6822 gp := mp.curg 6823 if gp == nil { 6824 // Nothing to do. 6825 return syscallingThread{}, false 6826 } 6827 status := readgstatus(gp) &^ _Gscan 6828 6829 // A goroutine is considered in a syscall, and may have a corresponding 6830 // P, if it's in _Gsyscall *or* _Gdeadextra. In the latter case, it's an 6831 // extra M goroutine. 6832 if status != _Gsyscall && status != _Gdeadextra { 6833 // Not in a syscall, nothing to do. 6834 return syscallingThread{}, false 6835 } 6836 if !castogscanstatus(gp, status, status|_Gscan) { 6837 // Not in _Gsyscall or _Gdeadextra anymore. Nothing to do. 6838 return syscallingThread{}, false 6839 } 6840 if gp.m != mp || gp.m.p.ptr() != pp { 6841 // This is not what we originally observed. Nothing to do. 6842 casfrom_Gscanstatus(gp, status|_Gscan, status) 6843 return syscallingThread{}, false 6844 } 6845 return syscallingThread{gp, mp, pp, status}, true 6846 } 6847 6848 // gcstopP unwires the P attached to the syscalling thread 6849 // and moves it into the _Pgcstop state. 6850 // 6851 // The caller must be stopping the world. 6852 func (s syscallingThread) gcstopP() { 6853 assertLockHeld(&sched.lock) 6854 6855 s.releaseP(_Pgcstop) 6856 s.pp.gcStopTime = nanotime() 6857 sched.stopwait-- 6858 } 6859 6860 // takeP unwires the P attached to the syscalling thread 6861 // and moves it into the _Pidle state. 6862 func (s syscallingThread) takeP() { 6863 s.releaseP(_Pidle) 6864 } 6865 6866 // releaseP unwires the P from the syscalling thread, moving 6867 // it to the provided state. Callers should prefer to use 6868 // takeP and gcstopP. 6869 func (s syscallingThread) releaseP(state uint32) { 6870 if state != _Pidle && state != _Pgcstop { 6871 throw("attempted to release P into a bad state") 6872 } 6873 trace := traceAcquire() 6874 s.pp.m = 0 6875 s.mp.p = 0 6876 atomic.Store(&s.pp.status, state) 6877 if trace.ok() { 6878 trace.ProcSteal(s.pp) 6879 traceRelease(trace) 6880 } 6881 addGSyscallNoP(s.mp) 6882 s.pp.syscalltick++ 6883 } 6884 6885 // resume allows a syscalling thread to advance beyond exitsyscall. 6886 func (s syscallingThread) resume() { 6887 casfrom_Gscanstatus(s.gp, s.status|_Gscan, s.status) 6888 } 6889 6890 // Tell all goroutines that they have been preempted and they should stop. 6891 // This function is purely best-effort. It can fail to inform a goroutine if a 6892 // processor just started running it. 6893 // No locks need to be held. 6894 // Returns true if preemption request was issued to at least one goroutine. 6895 func preemptall() bool { 6896 res := false 6897 for _, pp := range allp { 6898 if pp.status != _Prunning { 6899 continue 6900 } 6901 if preemptone(pp) { 6902 res = true 6903 } 6904 } 6905 return res 6906 } 6907 6908 // Tell the goroutine running on processor P to stop. 6909 // This function is purely best-effort. It can incorrectly fail to inform the 6910 // goroutine. It can inform the wrong goroutine. Even if it informs the 6911 // correct goroutine, that goroutine might ignore the request if it is 6912 // simultaneously executing newstack. 6913 // No lock needs to be held. 6914 // Returns true if preemption request was issued. 6915 // The actual preemption will happen at some point in the future 6916 // and will be indicated by the gp->status no longer being 6917 // Grunning 6918 func preemptone(pp *p) bool { 6919 mp := pp.m.ptr() 6920 if mp == nil || mp == getg().m { 6921 return false 6922 } 6923 gp := mp.curg 6924 if gp == nil || gp == mp.g0 { 6925 return false 6926 } 6927 if readgstatus(gp)&^_Gscan == _Gsyscall { 6928 // Don't bother trying to preempt a goroutine in a syscall. 6929 return false 6930 } 6931 6932 gp.preempt = true 6933 6934 // Every call in a goroutine checks for stack overflow by 6935 // comparing the current stack pointer to gp->stackguard0. 6936 // Setting gp->stackguard0 to StackPreempt folds 6937 // preemption into the normal stack overflow check. 6938 gp.stackguard0 = stackPreempt 6939 6940 // Request an async preemption of this P. 6941 if preemptMSupported && debug.asyncpreemptoff == 0 { 6942 pp.preempt = true 6943 preemptM(mp) 6944 } 6945 6946 return true 6947 } 6948 6949 var starttime int64 6950 6951 func schedtrace(detailed bool) { 6952 now := nanotime() 6953 if starttime == 0 { 6954 starttime = now 6955 } 6956 6957 lock(&sched.lock) 6958 print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle.Load(), " threads=", mcount(), " spinningthreads=", sched.nmspinning.Load(), " needspinning=", sched.needspinning.Load(), " idlethreads=", sched.nmidle, " runqueue=", sched.runq.size) 6959 if detailed { 6960 print(" gcwaiting=", sched.gcwaiting.Load(), " nmidlelocked=", sched.nmidlelocked, " stopwait=", sched.stopwait, " sysmonwait=", sched.sysmonwait.Load(), "\n") 6961 } 6962 // We must be careful while reading data from P's, M's and G's. 6963 // Even if we hold schedlock, most data can be changed concurrently. 6964 // E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil. 6965 for i, pp := range allp { 6966 h := atomic.Load(&pp.runqhead) 6967 t := atomic.Load(&pp.runqtail) 6968 if detailed { 6969 print(" P", i, ": status=", pp.status, " schedtick=", pp.schedtick, " syscalltick=", pp.syscalltick, " m=") 6970 mp := pp.m.ptr() 6971 if mp != nil { 6972 print(mp.id) 6973 } else { 6974 print("nil") 6975 } 6976 print(" runqsize=", t-h, " gfreecnt=", pp.gFree.size, " timerslen=", len(pp.timers.heap), "\n") 6977 } else { 6978 // In non-detailed mode format lengths of per-P run queues as: 6979 // [ len1 len2 len3 len4 ] 6980 print(" ") 6981 if i == 0 { 6982 print("[ ") 6983 } 6984 print(t - h) 6985 if i == len(allp)-1 { 6986 print(" ]") 6987 } 6988 } 6989 } 6990 6991 if !detailed { 6992 // Format per-P schedticks as: schedticks=[ tick1 tick2 tick3 tick4 ]. 6993 print(" schedticks=[ ") 6994 for _, pp := range allp { 6995 print(pp.schedtick) 6996 print(" ") 6997 } 6998 print("]\n") 6999 } 7000 7001 if !detailed { 7002 unlock(&sched.lock) 7003 return 7004 } 7005 7006 for mp := allm; mp != nil; mp = mp.alllink { 7007 pp := mp.p.ptr() 7008 print(" M", mp.id, ": p=") 7009 if pp != nil { 7010 print(pp.id) 7011 } else { 7012 print("nil") 7013 } 7014 print(" curg=") 7015 if mp.curg != nil { 7016 print(mp.curg.goid) 7017 } else { 7018 print("nil") 7019 } 7020 print(" mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, " locks=", mp.locks, " dying=", mp.dying, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=") 7021 if lockedg := mp.lockedg.ptr(); lockedg != nil { 7022 print(lockedg.goid) 7023 } else { 7024 print("nil") 7025 } 7026 print("\n") 7027 } 7028 7029 forEachG(func(gp *g) { 7030 print(" G", gp.goid, ": status=", readgstatus(gp), "(", gp.waitreason.String(), ") m=") 7031 if gp.m != nil { 7032 print(gp.m.id) 7033 } else { 7034 print("nil") 7035 } 7036 print(" lockedm=") 7037 if lockedm := gp.lockedm.ptr(); lockedm != nil { 7038 print(lockedm.id) 7039 } else { 7040 print("nil") 7041 } 7042 print("\n") 7043 }) 7044 unlock(&sched.lock) 7045 } 7046 7047 type updateMaxProcsGState struct { 7048 lock mutex 7049 g *g 7050 idle atomic.Bool 7051 7052 // Readable when idle == false, writable when idle == true. 7053 procs int32 // new GOMAXPROCS value 7054 } 7055 7056 var ( 7057 // GOMAXPROCS update godebug metric. Incremented if automatic 7058 // GOMAXPROCS updates actually change the value of GOMAXPROCS. 7059 updatemaxprocs = &godebugInc{name: "updatemaxprocs"} 7060 7061 // Synchronization and state between updateMaxProcsGoroutine and 7062 // sysmon. 7063 updateMaxProcsG updateMaxProcsGState 7064 7065 // Synchronization between GOMAXPROCS and sysmon. 7066 // 7067 // Setting GOMAXPROCS via a call to GOMAXPROCS disables automatic 7068 // GOMAXPROCS updates. 7069 // 7070 // We want to make two guarantees to callers of GOMAXPROCS. After 7071 // GOMAXPROCS returns: 7072 // 7073 // 1. The runtime will not make any automatic changes to GOMAXPROCS. 7074 // 7075 // 2. The runtime will not perform any of the system calls used to 7076 // determine the appropriate value of GOMAXPROCS (i.e., it won't 7077 // call defaultGOMAXPROCS). 7078 // 7079 // (1) is the baseline guarantee that everyone needs. The GOMAXPROCS 7080 // API isn't useful to anyone if automatic updates may occur after it 7081 // returns. This is easily achieved by double-checking the state under 7082 // STW before committing an automatic GOMAXPROCS update. 7083 // 7084 // (2) doesn't matter to most users, as it is isn't observable as long 7085 // as (1) holds. However, it can be important to users sandboxing Go. 7086 // They want disable these system calls and need some way to know when 7087 // they are guaranteed the calls will stop. 7088 // 7089 // This would be simple to achieve if we simply called 7090 // defaultGOMAXPROCS under STW in updateMaxProcsGoroutine below. 7091 // However, we would like to avoid scheduling this goroutine every 7092 // second when it will almost never do anything. Instead, sysmon calls 7093 // defaultGOMAXPROCS to decide whether to schedule 7094 // updateMaxProcsGoroutine. Thus we need to synchronize between sysmon 7095 // and GOMAXPROCS calls. 7096 // 7097 // GOMAXPROCS can't hold a runtime mutex across STW. It could hold a 7098 // semaphore, but sysmon cannot take semaphores. Instead, we have a 7099 // more complex scheme: 7100 // 7101 // * sysmon holds computeMaxProcsLock while calling defaultGOMAXPROCS. 7102 // * sysmon skips the current update if sched.customGOMAXPROCS is 7103 // set. 7104 // * GOMAXPROCS sets sched.customGOMAXPROCS once it is committed to 7105 // changing GOMAXPROCS. 7106 // * GOMAXPROCS takes computeMaxProcsLock to wait for outstanding 7107 // defaultGOMAXPROCS calls to complete. 7108 // 7109 // N.B. computeMaxProcsLock could simply be sched.lock, but we want to 7110 // avoid holding that lock during the potentially slow 7111 // defaultGOMAXPROCS. 7112 computeMaxProcsLock mutex 7113 ) 7114 7115 // Start GOMAXPROCS update helper goroutine. 7116 // 7117 // This is based on forcegchelper. 7118 func defaultGOMAXPROCSUpdateEnable() { 7119 if debug.updatemaxprocs == 0 { 7120 // Unconditionally increment the metric when updates are disabled. 7121 // 7122 // It would be more descriptive if we did a dry run of the 7123 // complete update, determining the appropriate value of 7124 // GOMAXPROCS and the bailing out and just incrementing the 7125 // metric if a change would occur. 7126 // 7127 // Not only is that a lot of ongoing work for a disabled 7128 // feature, but some users need to be able to completely 7129 // disable the update system calls (such as sandboxes). 7130 // Currently, updatemaxprocs=0 serves that purpose. 7131 updatemaxprocs.IncNonDefault() 7132 return 7133 } 7134 7135 go updateMaxProcsGoroutine() 7136 } 7137 7138 func updateMaxProcsGoroutine() { 7139 updateMaxProcsG.g = getg() 7140 lockInit(&updateMaxProcsG.lock, lockRankUpdateMaxProcsG) 7141 for { 7142 lock(&updateMaxProcsG.lock) 7143 if updateMaxProcsG.idle.Load() { 7144 throw("updateMaxProcsGoroutine: phase error") 7145 } 7146 updateMaxProcsG.idle.Store(true) 7147 goparkunlock(&updateMaxProcsG.lock, waitReasonUpdateGOMAXPROCSIdle, traceBlockSystemGoroutine, 1) 7148 // This goroutine is explicitly resumed by sysmon. 7149 7150 stw := stopTheWorldGC(stwGOMAXPROCS) 7151 7152 // Still OK to update? 7153 lock(&sched.lock) 7154 custom := sched.customGOMAXPROCS 7155 unlock(&sched.lock) 7156 if custom { 7157 startTheWorldGC(stw) 7158 return 7159 } 7160 7161 // newprocs will be processed by startTheWorld 7162 // 7163 // TODO(prattmic): this could use a nicer API. Perhaps add it to the 7164 // stw parameter? 7165 newprocs = updateMaxProcsG.procs 7166 lock(&sched.lock) 7167 sched.customGOMAXPROCS = false 7168 unlock(&sched.lock) 7169 7170 startTheWorldGC(stw) 7171 } 7172 } 7173 7174 func sysmonUpdateGOMAXPROCS() { 7175 // Synchronize with GOMAXPROCS. See comment on computeMaxProcsLock. 7176 lock(&computeMaxProcsLock) 7177 7178 // No update if GOMAXPROCS was set manually. 7179 lock(&sched.lock) 7180 custom := sched.customGOMAXPROCS 7181 curr := gomaxprocs 7182 unlock(&sched.lock) 7183 if custom { 7184 unlock(&computeMaxProcsLock) 7185 return 7186 } 7187 7188 // Don't hold sched.lock while we read the filesystem. 7189 procs := defaultGOMAXPROCS(0) 7190 unlock(&computeMaxProcsLock) 7191 if procs == curr { 7192 // Nothing to do. 7193 return 7194 } 7195 7196 // Sysmon can't directly stop the world. Run the helper to do so on our 7197 // behalf. If updateGOMAXPROCS.idle is false, then a previous update is 7198 // still pending. 7199 if updateMaxProcsG.idle.Load() { 7200 lock(&updateMaxProcsG.lock) 7201 updateMaxProcsG.procs = procs 7202 updateMaxProcsG.idle.Store(false) 7203 var list gList 7204 list.push(updateMaxProcsG.g) 7205 injectglist(&list) 7206 unlock(&updateMaxProcsG.lock) 7207 } 7208 } 7209 7210 // schedEnableUser enables or disables the scheduling of user 7211 // goroutines. 7212 // 7213 // This does not stop already running user goroutines, so the caller 7214 // should first stop the world when disabling user goroutines. 7215 func schedEnableUser(enable bool) { 7216 lock(&sched.lock) 7217 if sched.disable.user == !enable { 7218 unlock(&sched.lock) 7219 return 7220 } 7221 sched.disable.user = !enable 7222 if enable { 7223 n := sched.disable.runnable.size 7224 globrunqputbatch(&sched.disable.runnable) 7225 unlock(&sched.lock) 7226 for ; n != 0 && sched.npidle.Load() != 0; n-- { 7227 startm(nil, false, false) 7228 } 7229 } else { 7230 unlock(&sched.lock) 7231 } 7232 } 7233 7234 // schedEnabled reports whether gp should be scheduled. It returns 7235 // false is scheduling of gp is disabled. 7236 // 7237 // sched.lock must be held. 7238 func schedEnabled(gp *g) bool { 7239 assertLockHeld(&sched.lock) 7240 7241 if sched.disable.user { 7242 return isSystemGoroutine(gp, true) 7243 } 7244 return true 7245 } 7246 7247 // Put mp on midle list. 7248 // sched.lock must be held. 7249 // May run during STW, so write barriers are not allowed. 7250 // 7251 //go:nowritebarrierrec 7252 func mput(mp *m) { 7253 assertLockHeld(&sched.lock) 7254 7255 sched.midle.push(unsafe.Pointer(mp)) 7256 sched.nmidle++ 7257 checkdead() 7258 } 7259 7260 // Try to get an m from midle list. 7261 // sched.lock must be held. 7262 // May run during STW, so write barriers are not allowed. 7263 // 7264 //go:nowritebarrierrec 7265 func mget() *m { 7266 assertLockHeld(&sched.lock) 7267 7268 mp := (*m)(sched.midle.pop()) 7269 if mp != nil { 7270 sched.nmidle-- 7271 } 7272 return mp 7273 } 7274 7275 // Try to get a specific m from midle list. Returns nil if it isn't on the 7276 // midle list. 7277 // 7278 // sched.lock must be held. 7279 // May run during STW, so write barriers are not allowed. 7280 // 7281 //go:nowritebarrierrec 7282 func mgetSpecific(mp *m) *m { 7283 assertLockHeld(&sched.lock) 7284 7285 if mp.idleNode.prev == 0 && mp.idleNode.next == 0 { 7286 // Not on the list. 7287 return nil 7288 } 7289 7290 sched.midle.remove(unsafe.Pointer(mp)) 7291 sched.nmidle-- 7292 7293 return mp 7294 } 7295 7296 // Put gp on the global runnable queue. 7297 // sched.lock must be held. 7298 // May run during STW, so write barriers are not allowed. 7299 // 7300 //go:nowritebarrierrec 7301 func globrunqput(gp *g) { 7302 assertLockHeld(&sched.lock) 7303 7304 sched.runq.pushBack(gp) 7305 } 7306 7307 // Put gp at the head of the global runnable queue. 7308 // sched.lock must be held. 7309 // May run during STW, so write barriers are not allowed. 7310 // 7311 //go:nowritebarrierrec 7312 func globrunqputhead(gp *g) { 7313 assertLockHeld(&sched.lock) 7314 7315 sched.runq.push(gp) 7316 } 7317 7318 // Put a batch of runnable goroutines on the global runnable queue. 7319 // This clears *batch. 7320 // sched.lock must be held. 7321 // May run during STW, so write barriers are not allowed. 7322 // 7323 //go:nowritebarrierrec 7324 func globrunqputbatch(batch *gQueue) { 7325 assertLockHeld(&sched.lock) 7326 7327 sched.runq.pushBackAll(*batch) 7328 *batch = gQueue{} 7329 } 7330 7331 // Try get a single G from the global runnable queue. 7332 // sched.lock must be held. 7333 func globrunqget() *g { 7334 assertLockHeld(&sched.lock) 7335 7336 if sched.runq.size == 0 { 7337 return nil 7338 } 7339 7340 return sched.runq.pop() 7341 } 7342 7343 // Try get a batch of G's from the global runnable queue. 7344 // sched.lock must be held. 7345 func globrunqgetbatch(n int32) (gp *g, q gQueue) { 7346 assertLockHeld(&sched.lock) 7347 7348 if sched.runq.size == 0 { 7349 return 7350 } 7351 7352 n = min(n, sched.runq.size, sched.runq.size/gomaxprocs+1) 7353 7354 gp = sched.runq.pop() 7355 n-- 7356 7357 for ; n > 0; n-- { 7358 gp1 := sched.runq.pop() 7359 q.pushBack(gp1) 7360 } 7361 return 7362 } 7363 7364 // pMask is an atomic bitstring with one bit per P. 7365 type pMask []uint32 7366 7367 // read returns true if P id's bit is set. 7368 func (p pMask) read(id uint32) bool { 7369 word := id / 32 7370 mask := uint32(1) << (id % 32) 7371 return (atomic.Load(&p[word]) & mask) != 0 7372 } 7373 7374 // set sets P id's bit. 7375 func (p pMask) set(id int32) { 7376 word := id / 32 7377 mask := uint32(1) << (id % 32) 7378 atomic.Or(&p[word], mask) 7379 } 7380 7381 // clear clears P id's bit. 7382 func (p pMask) clear(id int32) { 7383 word := id / 32 7384 mask := uint32(1) << (id % 32) 7385 atomic.And(&p[word], ^mask) 7386 } 7387 7388 // any returns true if any bit in p is set. 7389 func (p pMask) any() bool { 7390 for i := range p { 7391 if atomic.Load(&p[i]) != 0 { 7392 return true 7393 } 7394 } 7395 return false 7396 } 7397 7398 // resize resizes the pMask and returns a new one. 7399 // 7400 // The result may alias p, so callers are encouraged to 7401 // discard p. Not safe for concurrent use. 7402 func (p pMask) resize(nprocs int32) pMask { 7403 maskWords := (nprocs + 31) / 32 7404 7405 if maskWords <= int32(cap(p)) { 7406 return p[:maskWords] 7407 } 7408 newMask := make([]uint32, maskWords) 7409 // No need to copy beyond len, old Ps are irrelevant. 7410 copy(newMask, p) 7411 return newMask 7412 } 7413 7414 // pidleput puts p on the _Pidle list. now must be a relatively recent call 7415 // to nanotime or zero. Returns now or the current time if now was zero. 7416 // 7417 // This releases ownership of p. Once sched.lock is released it is no longer 7418 // safe to use p. 7419 // 7420 // sched.lock must be held. 7421 // 7422 // May run during STW, so write barriers are not allowed. 7423 // 7424 //go:nowritebarrierrec 7425 func pidleput(pp *p, now int64) int64 { 7426 assertLockHeld(&sched.lock) 7427 7428 if !runqempty(pp) { 7429 throw("pidleput: P has non-empty run queue") 7430 } 7431 if now == 0 { 7432 now = nanotime() 7433 } 7434 if pp.timers.len.Load() == 0 { 7435 timerpMask.clear(pp.id) 7436 } 7437 idlepMask.set(pp.id) 7438 pp.link = sched.pidle 7439 sched.pidle.set(pp) 7440 sched.npidle.Add(1) 7441 if !pp.limiterEvent.start(limiterEventIdle, now) { 7442 throw("must be able to track idle limiter event") 7443 } 7444 return now 7445 } 7446 7447 // pidleget tries to get a p from the _Pidle list, acquiring ownership. 7448 // 7449 // sched.lock must be held. 7450 // 7451 // May run during STW, so write barriers are not allowed. 7452 // 7453 //go:nowritebarrierrec 7454 func pidleget(now int64) (*p, int64) { 7455 assertLockHeld(&sched.lock) 7456 7457 pp := sched.pidle.ptr() 7458 if pp != nil { 7459 // Timer may get added at any time now. 7460 if now == 0 { 7461 now = nanotime() 7462 } 7463 timerpMask.set(pp.id) 7464 idlepMask.clear(pp.id) 7465 sched.pidle = pp.link 7466 sched.npidle.Add(-1) 7467 pp.limiterEvent.stop(limiterEventIdle, now) 7468 } 7469 return pp, now 7470 } 7471 7472 // pidlegetSpinning tries to get a p from the _Pidle list, acquiring ownership. 7473 // This is called by spinning Ms (or callers than need a spinning M) that have 7474 // found work. If no P is available, this must synchronized with non-spinning 7475 // Ms that may be preparing to drop their P without discovering this work. 7476 // 7477 // sched.lock must be held. 7478 // 7479 // May run during STW, so write barriers are not allowed. 7480 // 7481 //go:nowritebarrierrec 7482 func pidlegetSpinning(now int64) (*p, int64) { 7483 assertLockHeld(&sched.lock) 7484 7485 pp, now := pidleget(now) 7486 if pp == nil { 7487 // See "Delicate dance" comment in findRunnable. We found work 7488 // that we cannot take, we must synchronize with non-spinning 7489 // Ms that may be preparing to drop their P. 7490 sched.needspinning.Store(1) 7491 return nil, now 7492 } 7493 7494 return pp, now 7495 } 7496 7497 // runqempty reports whether pp has no Gs on its local run queue. 7498 // It never returns true spuriously. 7499 func runqempty(pp *p) bool { 7500 // Defend against a race where 1) pp has G1 in runqnext but runqhead == runqtail, 7501 // 2) runqput on pp kicks G1 to the runq, 3) runqget on pp empties runqnext. 7502 // Simply observing that runqhead == runqtail and then observing that runqnext == nil 7503 // does not mean the queue is empty. 7504 for { 7505 head := atomic.Load(&pp.runqhead) 7506 tail := atomic.Load(&pp.runqtail) 7507 runnext := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&pp.runnext))) 7508 if tail == atomic.Load(&pp.runqtail) { 7509 return head == tail && runnext == 0 7510 } 7511 } 7512 } 7513 7514 // To shake out latent assumptions about scheduling order, 7515 // we introduce some randomness into scheduling decisions 7516 // when running with the race detector. 7517 // The need for this was made obvious by changing the 7518 // (deterministic) scheduling order in Go 1.5 and breaking 7519 // many poorly-written tests. 7520 // With the randomness here, as long as the tests pass 7521 // consistently with -race, they shouldn't have latent scheduling 7522 // assumptions. 7523 const randomizeScheduler = raceenabled 7524 7525 // runqput tries to put g on the local runnable queue. 7526 // If next is false, runqput adds g to the tail of the runnable queue. 7527 // If next is true, runqput puts g in the pp.runnext slot. 7528 // If the run queue is full, runnext puts g on the global queue. 7529 // Executed only by the owner P. 7530 func runqput(pp *p, gp *g, next bool) { 7531 if !haveSysmon && next { 7532 // A runnext goroutine shares the same time slice as the 7533 // current goroutine (inheritTime from runqget). To prevent a 7534 // ping-pong pair of goroutines from starving all others, we 7535 // depend on sysmon to preempt "long-running goroutines". That 7536 // is, any set of goroutines sharing the same time slice. 7537 // 7538 // If there is no sysmon, we must avoid runnext entirely or 7539 // risk starvation. 7540 next = false 7541 } 7542 if randomizeScheduler && next && randn(2) == 0 { 7543 next = false 7544 } 7545 7546 if next { 7547 retryNext: 7548 oldnext := pp.runnext 7549 if !pp.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) { 7550 goto retryNext 7551 } 7552 if oldnext == 0 { 7553 return 7554 } 7555 // Kick the old runnext out to the regular run queue. 7556 gp = oldnext.ptr() 7557 } 7558 7559 retry: 7560 h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers 7561 t := pp.runqtail 7562 if t-h < uint32(len(pp.runq)) { 7563 pp.runq[t%uint32(len(pp.runq))].set(gp) 7564 atomic.StoreRel(&pp.runqtail, t+1) // store-release, makes the item available for consumption 7565 return 7566 } 7567 if runqputslow(pp, gp, h, t) { 7568 return 7569 } 7570 // the queue is not full, now the put above must succeed 7571 goto retry 7572 } 7573 7574 // Put g and a batch of work from local runnable queue on global queue. 7575 // Executed only by the owner P. 7576 func runqputslow(pp *p, gp *g, h, t uint32) bool { 7577 var batch [len(pp.runq)/2 + 1]*g 7578 7579 // First, grab a batch from local queue. 7580 n := t - h 7581 n = n / 2 7582 if n != uint32(len(pp.runq)/2) { 7583 throw("runqputslow: queue is not full") 7584 } 7585 for i := uint32(0); i < n; i++ { 7586 batch[i] = pp.runq[(h+i)%uint32(len(pp.runq))].ptr() 7587 } 7588 if !atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume 7589 return false 7590 } 7591 batch[n] = gp 7592 7593 if randomizeScheduler { 7594 for i := uint32(1); i <= n; i++ { 7595 j := cheaprandn(i + 1) 7596 batch[i], batch[j] = batch[j], batch[i] 7597 } 7598 } 7599 7600 // Link the goroutines. 7601 for i := uint32(0); i < n; i++ { 7602 batch[i].schedlink.set(batch[i+1]) 7603 } 7604 7605 q := gQueue{batch[0].guintptr(), batch[n].guintptr(), int32(n + 1)} 7606 7607 // Now put the batch on global queue. 7608 lock(&sched.lock) 7609 globrunqputbatch(&q) 7610 unlock(&sched.lock) 7611 return true 7612 } 7613 7614 // runqputbatch tries to put all the G's on q on the local runnable queue. 7615 // If the local runq is full the input queue still contains unqueued Gs. 7616 // Executed only by the owner P. 7617 func runqputbatch(pp *p, q *gQueue) { 7618 if q.empty() { 7619 return 7620 } 7621 h := atomic.LoadAcq(&pp.runqhead) 7622 t := pp.runqtail 7623 n := uint32(0) 7624 for !q.empty() && t-h < uint32(len(pp.runq)) { 7625 gp := q.pop() 7626 pp.runq[t%uint32(len(pp.runq))].set(gp) 7627 t++ 7628 n++ 7629 } 7630 7631 if randomizeScheduler { 7632 off := func(o uint32) uint32 { 7633 return (pp.runqtail + o) % uint32(len(pp.runq)) 7634 } 7635 for i := uint32(1); i < n; i++ { 7636 j := cheaprandn(i + 1) 7637 pp.runq[off(i)], pp.runq[off(j)] = pp.runq[off(j)], pp.runq[off(i)] 7638 } 7639 } 7640 7641 atomic.StoreRel(&pp.runqtail, t) 7642 7643 return 7644 } 7645 7646 // Get g from local runnable queue. 7647 // If inheritTime is true, gp should inherit the remaining time in the 7648 // current time slice. Otherwise, it should start a new time slice. 7649 // Executed only by the owner P. 7650 func runqget(pp *p) (gp *g, inheritTime bool) { 7651 // If there's a runnext, it's the next G to run. 7652 next := pp.runnext 7653 // If the runnext is non-0 and the CAS fails, it could only have been stolen by another P, 7654 // because other Ps can race to set runnext to 0, but only the current P can set it to non-0. 7655 // Hence, there's no need to retry this CAS if it fails. 7656 if next != 0 && pp.runnext.cas(next, 0) { 7657 return next.ptr(), true 7658 } 7659 7660 for { 7661 h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers 7662 t := pp.runqtail 7663 if t == h { 7664 return nil, false 7665 } 7666 gp := pp.runq[h%uint32(len(pp.runq))].ptr() 7667 if atomic.CasRel(&pp.runqhead, h, h+1) { // cas-release, commits consume 7668 return gp, false 7669 } 7670 } 7671 } 7672 7673 // runqdrain drains the local runnable queue of pp and returns all goroutines in it. 7674 // Executed only by the owner P. 7675 func runqdrain(pp *p) (drainQ gQueue) { 7676 oldNext := pp.runnext 7677 if oldNext != 0 && pp.runnext.cas(oldNext, 0) { 7678 drainQ.pushBack(oldNext.ptr()) 7679 } 7680 7681 retry: 7682 h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers 7683 t := pp.runqtail 7684 qn := t - h 7685 if qn == 0 { 7686 return 7687 } 7688 if qn > uint32(len(pp.runq)) { // read inconsistent h and t 7689 goto retry 7690 } 7691 7692 if !atomic.CasRel(&pp.runqhead, h, h+qn) { // cas-release, commits consume 7693 goto retry 7694 } 7695 7696 // We've inverted the order in which it gets G's from the local P's runnable queue 7697 // and then advances the head pointer because we don't want to mess up the statuses of G's 7698 // while runqdrain() and runqsteal() are running in parallel. 7699 // Thus we should advance the head pointer before draining the local P into a gQueue, 7700 // so that we can update any gp.schedlink only after we take the full ownership of G, 7701 // meanwhile, other P's can't access to all G's in local P's runnable queue and steal them. 7702 // See https://groups.google.com/g/golang-dev/c/0pTKxEKhHSc/m/6Q85QjdVBQAJ for more details. 7703 for i := uint32(0); i < qn; i++ { 7704 gp := pp.runq[(h+i)%uint32(len(pp.runq))].ptr() 7705 drainQ.pushBack(gp) 7706 } 7707 return 7708 } 7709 7710 // Grabs a batch of goroutines from pp's runnable queue into batch. 7711 // Batch is a ring buffer starting at batchHead. 7712 // Returns number of grabbed goroutines. 7713 // Can be executed by any P. 7714 func runqgrab(pp *p, batch *[256]guintptr, batchHead uint32, stealRunNextG bool) uint32 { 7715 for { 7716 h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers 7717 t := atomic.LoadAcq(&pp.runqtail) // load-acquire, synchronize with the producer 7718 n := t - h 7719 n = n - n/2 7720 if n == 0 { 7721 if stealRunNextG { 7722 // Try to steal from pp.runnext. 7723 if next := pp.runnext; next != 0 { 7724 if pp.status == _Prunning { 7725 if mp := pp.m.ptr(); mp != nil { 7726 if gp := mp.curg; gp == nil || readgstatus(gp)&^_Gscan != _Gsyscall { 7727 // Sleep to ensure that pp isn't about to run the g 7728 // we are about to steal. 7729 // The important use case here is when the g running 7730 // on pp ready()s another g and then almost 7731 // immediately blocks. Instead of stealing runnext 7732 // in this window, back off to give pp a chance to 7733 // schedule runnext. This will avoid thrashing gs 7734 // between different Ps. 7735 // A sync chan send/recv takes ~50ns as of time of 7736 // writing, so 3us gives ~50x overshoot. 7737 // If curg is nil, we assume that the P is likely 7738 // to be in the scheduler. If curg isn't nil and isn't 7739 // in a syscall, then it's either running, waiting, or 7740 // runnable. In this case we want to sleep because the 7741 // P might either call into the scheduler soon (running), 7742 // or already is (since we found a waiting or runnable 7743 // goroutine hanging off of a running P, suggesting it 7744 // either recently transitioned out of running, or will 7745 // transition to running shortly). 7746 if !osHasLowResTimer { 7747 usleep(3) 7748 } else { 7749 // On some platforms system timer granularity is 7750 // 1-15ms, which is way too much for this 7751 // optimization. So just yield. 7752 osyield() 7753 } 7754 } 7755 } 7756 } 7757 if !pp.runnext.cas(next, 0) { 7758 continue 7759 } 7760 batch[batchHead%uint32(len(batch))] = next 7761 return 1 7762 } 7763 } 7764 return 0 7765 } 7766 if n > uint32(len(pp.runq)/2) { // read inconsistent h and t 7767 continue 7768 } 7769 for i := uint32(0); i < n; i++ { 7770 g := pp.runq[(h+i)%uint32(len(pp.runq))] 7771 batch[(batchHead+i)%uint32(len(batch))] = g 7772 } 7773 if atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume 7774 return n 7775 } 7776 } 7777 } 7778 7779 // Steal half of elements from local runnable queue of p2 7780 // and put onto local runnable queue of p. 7781 // Returns one of the stolen elements (or nil if failed). 7782 func runqsteal(pp, p2 *p, stealRunNextG bool) *g { 7783 t := pp.runqtail 7784 n := runqgrab(p2, &pp.runq, t, stealRunNextG) 7785 if n == 0 { 7786 return nil 7787 } 7788 n-- 7789 gp := pp.runq[(t+n)%uint32(len(pp.runq))].ptr() 7790 if n == 0 { 7791 return gp 7792 } 7793 h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers 7794 if t-h+n >= uint32(len(pp.runq)) { 7795 throw("runqsteal: runq overflow") 7796 } 7797 atomic.StoreRel(&pp.runqtail, t+n) // store-release, makes the item available for consumption 7798 return gp 7799 } 7800 7801 // A gQueue is a dequeue of Gs linked through g.schedlink. A G can only 7802 // be on one gQueue or gList at a time. 7803 type gQueue struct { 7804 head guintptr 7805 tail guintptr 7806 size int32 7807 } 7808 7809 // empty reports whether q is empty. 7810 func (q *gQueue) empty() bool { 7811 return q.head == 0 7812 } 7813 7814 // push adds gp to the head of q. 7815 func (q *gQueue) push(gp *g) { 7816 gp.schedlink = q.head 7817 q.head.set(gp) 7818 if q.tail == 0 { 7819 q.tail.set(gp) 7820 } 7821 q.size++ 7822 } 7823 7824 // pushBack adds gp to the tail of q. 7825 func (q *gQueue) pushBack(gp *g) { 7826 gp.schedlink = 0 7827 if q.tail != 0 { 7828 q.tail.ptr().schedlink.set(gp) 7829 } else { 7830 q.head.set(gp) 7831 } 7832 q.tail.set(gp) 7833 q.size++ 7834 } 7835 7836 // pushBackAll adds all Gs in q2 to the tail of q. After this q2 must 7837 // not be used. 7838 func (q *gQueue) pushBackAll(q2 gQueue) { 7839 if q2.tail == 0 { 7840 return 7841 } 7842 q2.tail.ptr().schedlink = 0 7843 if q.tail != 0 { 7844 q.tail.ptr().schedlink = q2.head 7845 } else { 7846 q.head = q2.head 7847 } 7848 q.tail = q2.tail 7849 q.size += q2.size 7850 } 7851 7852 // pop removes and returns the head of queue q. It returns nil if 7853 // q is empty. 7854 func (q *gQueue) pop() *g { 7855 gp := q.head.ptr() 7856 if gp != nil { 7857 q.head = gp.schedlink 7858 if q.head == 0 { 7859 q.tail = 0 7860 } 7861 q.size-- 7862 } 7863 return gp 7864 } 7865 7866 // popList takes all Gs in q and returns them as a gList. 7867 func (q *gQueue) popList() gList { 7868 stack := gList{q.head, q.size} 7869 *q = gQueue{} 7870 return stack 7871 } 7872 7873 // A gList is a list of Gs linked through g.schedlink. A G can only be 7874 // on one gQueue or gList at a time. 7875 type gList struct { 7876 head guintptr 7877 size int32 7878 } 7879 7880 // empty reports whether l is empty. 7881 func (l *gList) empty() bool { 7882 return l.head == 0 7883 } 7884 7885 // push adds gp to the head of l. 7886 func (l *gList) push(gp *g) { 7887 gp.schedlink = l.head 7888 l.head.set(gp) 7889 l.size++ 7890 } 7891 7892 // pushAll prepends all Gs in q to l. After this q must not be used. 7893 func (l *gList) pushAll(q gQueue) { 7894 if !q.empty() { 7895 q.tail.ptr().schedlink = l.head 7896 l.head = q.head 7897 l.size += q.size 7898 } 7899 } 7900 7901 // pop removes and returns the head of l. If l is empty, it returns nil. 7902 func (l *gList) pop() *g { 7903 gp := l.head.ptr() 7904 if gp != nil { 7905 l.head = gp.schedlink 7906 l.size-- 7907 } 7908 return gp 7909 } 7910 7911 //go:linkname setMaxThreads runtime/debug.setMaxThreads 7912 func setMaxThreads(in int) (out int) { 7913 lock(&sched.lock) 7914 out = int(sched.maxmcount) 7915 if in > 0x7fffffff { // MaxInt32 7916 sched.maxmcount = 0x7fffffff 7917 } else { 7918 sched.maxmcount = int32(in) 7919 } 7920 checkmcount() 7921 unlock(&sched.lock) 7922 return 7923 } 7924 7925 // procPin should be an internal detail, 7926 // but widely used packages access it using linkname. 7927 // Notable members of the hall of shame include: 7928 // - github.com/bytedance/gopkg 7929 // - github.com/choleraehyq/pid 7930 // - github.com/songzhibin97/gkit 7931 // 7932 // Do not remove or change the type signature. 7933 // See go.dev/issue/67401. 7934 // 7935 //go:linkname procPin 7936 //go:nosplit 7937 func procPin() int { 7938 gp := getg() 7939 mp := gp.m 7940 7941 mp.locks++ 7942 return int(mp.p.ptr().id) 7943 } 7944 7945 // procUnpin should be an internal detail, 7946 // but widely used packages access it using linkname. 7947 // Notable members of the hall of shame include: 7948 // - github.com/bytedance/gopkg 7949 // - github.com/choleraehyq/pid 7950 // - github.com/songzhibin97/gkit 7951 // 7952 // Do not remove or change the type signature. 7953 // See go.dev/issue/67401. 7954 // 7955 //go:linkname procUnpin 7956 //go:nosplit 7957 func procUnpin() { 7958 gp := getg() 7959 gp.m.locks-- 7960 } 7961 7962 //go:linkname sync_runtime_procPin sync.runtime_procPin 7963 //go:nosplit 7964 func sync_runtime_procPin() int { 7965 return procPin() 7966 } 7967 7968 //go:linkname sync_runtime_procUnpin sync.runtime_procUnpin 7969 //go:nosplit 7970 func sync_runtime_procUnpin() { 7971 procUnpin() 7972 } 7973 7974 //go:linkname sync_atomic_runtime_procPin sync/atomic.runtime_procPin 7975 //go:nosplit 7976 func sync_atomic_runtime_procPin() int { 7977 return procPin() 7978 } 7979 7980 //go:linkname sync_atomic_runtime_procUnpin sync/atomic.runtime_procUnpin 7981 //go:nosplit 7982 func sync_atomic_runtime_procUnpin() { 7983 procUnpin() 7984 } 7985 7986 // Active spinning for sync.Mutex. 7987 // 7988 //go:linkname internal_sync_runtime_canSpin internal/sync.runtime_canSpin 7989 //go:nosplit 7990 func internal_sync_runtime_canSpin(i int) bool { 7991 // sync.Mutex is cooperative, so we are conservative with spinning. 7992 // Spin only few times and only if running on a multicore machine and 7993 // GOMAXPROCS>1 and there is at least one other running P and local runq is empty. 7994 // As opposed to runtime mutex we don't do passive spinning here, 7995 // because there can be work on global runq or on other Ps. 7996 if i >= active_spin || numCPUStartup <= 1 || gomaxprocs <= sched.npidle.Load()+sched.nmspinning.Load()+1 { 7997 return false 7998 } 7999 if p := getg().m.p.ptr(); !runqempty(p) { 8000 return false 8001 } 8002 return true 8003 } 8004 8005 //go:linkname internal_sync_runtime_doSpin internal/sync.runtime_doSpin 8006 //go:nosplit 8007 func internal_sync_runtime_doSpin() { 8008 procyield(active_spin_cnt) 8009 } 8010 8011 // Active spinning for sync.Mutex. 8012 // 8013 // sync_runtime_canSpin should be an internal detail, 8014 // but widely used packages access it using linkname. 8015 // Notable members of the hall of shame include: 8016 // - github.com/livekit/protocol 8017 // - github.com/sagernet/gvisor 8018 // - gvisor.dev/gvisor 8019 // 8020 // Do not remove or change the type signature. 8021 // See go.dev/issue/67401. 8022 // 8023 //go:linkname sync_runtime_canSpin sync.runtime_canSpin 8024 //go:nosplit 8025 func sync_runtime_canSpin(i int) bool { 8026 return internal_sync_runtime_canSpin(i) 8027 } 8028 8029 // sync_runtime_doSpin should be an internal detail, 8030 // but widely used packages access it using linkname. 8031 // Notable members of the hall of shame include: 8032 // - github.com/livekit/protocol 8033 // - github.com/sagernet/gvisor 8034 // - gvisor.dev/gvisor 8035 // 8036 // Do not remove or change the type signature. 8037 // See go.dev/issue/67401. 8038 // 8039 //go:linkname sync_runtime_doSpin sync.runtime_doSpin 8040 //go:nosplit 8041 func sync_runtime_doSpin() { 8042 internal_sync_runtime_doSpin() 8043 } 8044 8045 var stealOrder randomOrder 8046 8047 // randomOrder/randomEnum are helper types for randomized work stealing. 8048 // They allow to enumerate all Ps in different pseudo-random orders without repetitions. 8049 // The algorithm is based on the fact that if we have X such that X and GOMAXPROCS 8050 // are coprime, then a sequences of (i + X) % GOMAXPROCS gives the required enumeration. 8051 type randomOrder struct { 8052 count uint32 8053 coprimes []uint32 8054 } 8055 8056 type randomEnum struct { 8057 i uint32 8058 count uint32 8059 pos uint32 8060 inc uint32 8061 } 8062 8063 func (ord *randomOrder) reset(count uint32) { 8064 ord.count = count 8065 ord.coprimes = ord.coprimes[:0] 8066 for i := uint32(1); i <= count; i++ { 8067 if gcd(i, count) == 1 { 8068 ord.coprimes = append(ord.coprimes, i) 8069 } 8070 } 8071 } 8072 8073 func (ord *randomOrder) start(i uint32) randomEnum { 8074 return randomEnum{ 8075 count: ord.count, 8076 pos: i % ord.count, 8077 inc: ord.coprimes[i/ord.count%uint32(len(ord.coprimes))], 8078 } 8079 } 8080 8081 func (enum *randomEnum) done() bool { 8082 return enum.i == enum.count 8083 } 8084 8085 func (enum *randomEnum) next() { 8086 enum.i++ 8087 enum.pos = (enum.pos + enum.inc) % enum.count 8088 } 8089 8090 func (enum *randomEnum) position() uint32 { 8091 return enum.pos 8092 } 8093 8094 func gcd(a, b uint32) uint32 { 8095 for b != 0 { 8096 a, b = b, a%b 8097 } 8098 return a 8099 } 8100 8101 // An initTask represents the set of initializations that need to be done for a package. 8102 // Keep in sync with ../../test/noinit.go:initTask 8103 type initTask struct { 8104 state uint32 // 0 = uninitialized, 1 = in progress, 2 = done 8105 nfns uint32 8106 // followed by nfns pcs, uintptr sized, one per init function to run 8107 } 8108 8109 // inittrace stores statistics for init functions which are 8110 // updated by malloc and newproc when active is true. 8111 var inittrace tracestat 8112 8113 type tracestat struct { 8114 active bool // init tracing activation status 8115 id uint64 // init goroutine id 8116 allocs uint64 // heap allocations 8117 bytes uint64 // heap allocated bytes 8118 } 8119 8120 func doInit(ts []*initTask) { 8121 for _, t := range ts { 8122 doInit1(t) 8123 } 8124 } 8125 8126 func doInit1(t *initTask) { 8127 switch t.state { 8128 case 2: // fully initialized 8129 return 8130 case 1: // initialization in progress 8131 throw("recursive call during initialization - linker skew") 8132 default: // not initialized yet 8133 t.state = 1 // initialization in progress 8134 8135 var ( 8136 start int64 8137 before tracestat 8138 ) 8139 8140 if inittrace.active { 8141 start = nanotime() 8142 // Load stats non-atomically since tracinit is updated only by this init goroutine. 8143 before = inittrace 8144 } 8145 8146 if t.nfns == 0 { 8147 // We should have pruned all of these in the linker. 8148 throw("inittask with no functions") 8149 } 8150 8151 firstFunc := add(unsafe.Pointer(t), 8) 8152 for i := uint32(0); i < t.nfns; i++ { 8153 p := add(firstFunc, uintptr(i)*goarch.PtrSize) 8154 f := *(*func())(unsafe.Pointer(&p)) 8155 f() 8156 } 8157 8158 if inittrace.active { 8159 end := nanotime() 8160 // Load stats non-atomically since tracinit is updated only by this init goroutine. 8161 after := inittrace 8162 8163 f := *(*func())(unsafe.Pointer(&firstFunc)) 8164 pkg := funcpkgpath(findfunc(abi.FuncPCABIInternal(f))) 8165 8166 var sbuf [24]byte 8167 print("init ", pkg, " @") 8168 print(string(fmtNSAsMS(sbuf[:], uint64(start-runtimeInitTime))), " ms, ") 8169 print(string(fmtNSAsMS(sbuf[:], uint64(end-start))), " ms clock, ") 8170 print(string(itoa(sbuf[:], after.bytes-before.bytes)), " bytes, ") 8171 print(string(itoa(sbuf[:], after.allocs-before.allocs)), " allocs") 8172 print("\n") 8173 } 8174 8175 t.state = 2 // initialization done 8176 } 8177 } 8178