github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/runtime/proc.go (about) 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 "runtime/internal/atomic" 9 "runtime/internal/sys" 10 "unsafe" 11 ) 12 13 var buildVersion = sys.TheVersion 14 15 // Goroutine scheduler 16 // The scheduler's job is to distribute ready-to-run goroutines over worker threads. 17 // 18 // The main concepts are: 19 // G - goroutine. 20 // M - worker thread, or machine. 21 // P - processor, a resource that is required to execute Go code. 22 // M must have an associated P to execute Go code, however it can be 23 // blocked or in a syscall w/o an associated P. 24 // 25 // Design doc at https://golang.org/s/go11sched. 26 27 // Worker thread parking/unparking. 28 // We need to balance between keeping enough running worker threads to utilize 29 // available hardware parallelism and parking excessive running worker threads 30 // to conserve CPU resources and power. This is not simple for two reasons: 31 // (1) scheduler state is intentionally distributed (in particular, per-P work 32 // queues), so it is not possible to compute global predicates on fast paths; 33 // (2) for optimal thread management we would need to know the future (don't park 34 // a worker thread when a new goroutine will be readied in near future). 35 // 36 // Three rejected approaches that would work badly: 37 // 1. Centralize all scheduler state (would inhibit scalability). 38 // 2. Direct goroutine handoff. That is, when we ready a new goroutine and there 39 // is a spare P, unpark a thread and handoff it the thread and the goroutine. 40 // This would lead to thread state thrashing, as the thread that readied the 41 // goroutine can be out of work the very next moment, we will need to park it. 42 // Also, it would destroy locality of computation as we want to preserve 43 // dependent goroutines on the same thread; and introduce additional latency. 44 // 3. Unpark an additional thread whenever we ready a goroutine and there is an 45 // idle P, but don't do handoff. This would lead to excessive thread parking/ 46 // unparking as the additional threads will instantly park without discovering 47 // any work to do. 48 // 49 // The current approach: 50 // We unpark an additional thread when we ready a goroutine if (1) there is an 51 // idle P and there are no "spinning" worker threads. A worker thread is considered 52 // spinning if it is out of local work and did not find work in global run queue/ 53 // netpoller; the spinning state is denoted in m.spinning and in sched.nmspinning. 54 // Threads unparked this way are also considered spinning; we don't do goroutine 55 // handoff so such threads are out of work initially. Spinning threads do some 56 // spinning looking for work in per-P run queues before parking. If a spinning 57 // thread finds work it takes itself out of the spinning state and proceeds to 58 // execution. If it does not find work it takes itself out of the spinning state 59 // and then parks. 60 // If there is at least one spinning thread (sched.nmspinning>1), we don't unpark 61 // new threads when readying goroutines. To compensate for that, if the last spinning 62 // thread finds work and stops spinning, it must unpark a new spinning thread. 63 // This approach smooths out unjustified spikes of thread unparking, 64 // but at the same time guarantees eventual maximal CPU parallelism utilization. 65 // 66 // The main implementation complication is that we need to be very careful during 67 // spinning->non-spinning thread transition. This transition can race with submission 68 // of a new goroutine, and either one part or another needs to unpark another worker 69 // thread. If they both fail to do that, we can end up with semi-persistent CPU 70 // underutilization. The general pattern for goroutine readying is: submit a goroutine 71 // to local work queue, #StoreLoad-style memory barrier, check sched.nmspinning. 72 // The general pattern for spinning->non-spinning transition is: decrement nmspinning, 73 // #StoreLoad-style memory barrier, check all per-P work queues for new work. 74 // Note that all this complexity does not apply to global run queue as we are not 75 // sloppy about thread unparking when submitting to global queue. Also see comments 76 // for nmspinning manipulation. 77 78 var ( 79 m0 m 80 g0 g 81 raceprocctx0 uintptr 82 ) 83 84 //go:linkname runtime_init runtime.init 85 func runtime_init() 86 87 //go:linkname main_init main.init 88 func main_init() 89 90 // main_init_done is a signal used by cgocallbackg that initialization 91 // has been completed. It is made before _cgo_notify_runtime_init_done, 92 // so all cgo calls can rely on it existing. When main_init is complete, 93 // it is closed, meaning cgocallbackg can reliably receive from it. 94 var main_init_done chan bool 95 96 //go:linkname main_main main.main 97 func main_main() 98 99 // mainStarted indicates that the main M has started. 100 var mainStarted bool 101 102 // runtimeInitTime is the nanotime() at which the runtime started. 103 var runtimeInitTime int64 104 105 // Value to use for signal mask for newly created M's. 106 var initSigmask sigset 107 108 // The main goroutine. 109 func main() { 110 g := getg() 111 112 // Racectx of m0->g0 is used only as the parent of the main goroutine. 113 // It must not be used for anything else. 114 g.m.g0.racectx = 0 115 116 // Max stack size is 1 GB on 64-bit, 250 MB on 32-bit. 117 // Using decimal instead of binary GB and MB because 118 // they look nicer in the stack overflow failure message. 119 if sys.PtrSize == 8 { 120 maxstacksize = 1000000000 121 } else { 122 maxstacksize = 250000000 123 } 124 125 // Allow newproc to start new Ms. 126 mainStarted = true 127 128 systemstack(func() { 129 newm(sysmon, nil) 130 }) 131 132 // Lock the main goroutine onto this, the main OS thread, 133 // during initialization. Most programs won't care, but a few 134 // do require certain calls to be made by the main thread. 135 // Those can arrange for main.main to run in the main thread 136 // by calling runtime.LockOSThread during initialization 137 // to preserve the lock. 138 lockOSThread() 139 140 if g.m != &m0 { 141 throw("runtime.main not on m0") 142 } 143 144 runtime_init() // must be before defer 145 if nanotime() == 0 { 146 throw("nanotime returning zero") 147 } 148 149 // Defer unlock so that runtime.Goexit during init does the unlock too. 150 needUnlock := true 151 defer func() { 152 if needUnlock { 153 unlockOSThread() 154 } 155 }() 156 157 // Record when the world started. Must be after runtime_init 158 // because nanotime on some platforms depends on startNano. 159 runtimeInitTime = nanotime() 160 161 gcenable() 162 163 main_init_done = make(chan bool) 164 if iscgo { 165 if _cgo_thread_start == nil { 166 throw("_cgo_thread_start missing") 167 } 168 if GOOS != "windows" { 169 if _cgo_setenv == nil { 170 throw("_cgo_setenv missing") 171 } 172 if _cgo_unsetenv == nil { 173 throw("_cgo_unsetenv missing") 174 } 175 } 176 if _cgo_notify_runtime_init_done == nil { 177 throw("_cgo_notify_runtime_init_done missing") 178 } 179 // Start the template thread in case we enter Go from 180 // a C-created thread and need to create a new thread. 181 startTemplateThread() 182 cgocall(_cgo_notify_runtime_init_done, nil) 183 } 184 185 fn := main_init // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime 186 fn() 187 close(main_init_done) 188 189 needUnlock = false 190 unlockOSThread() 191 192 if isarchive || islibrary { 193 // A program compiled with -buildmode=c-archive or c-shared 194 // has a main, but it is not executed. 195 return 196 } 197 fn = main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime 198 fn() 199 if raceenabled { 200 racefini() 201 } 202 203 // Make racy client program work: if panicking on 204 // another goroutine at the same time as main returns, 205 // let the other goroutine finish printing the panic trace. 206 // Once it does, it will exit. See issues 3934 and 20018. 207 if atomic.Load(&runningPanicDefers) != 0 { 208 // Running deferred functions should not take long. 209 for c := 0; c < 1000; c++ { 210 if atomic.Load(&runningPanicDefers) == 0 { 211 break 212 } 213 Gosched() 214 } 215 } 216 if atomic.Load(&panicking) != 0 { 217 gopark(nil, nil, "panicwait", traceEvGoStop, 1) 218 } 219 220 exit(0) 221 for { 222 var x *int32 223 *x = 0 224 } 225 } 226 227 // os_beforeExit is called from os.Exit(0). 228 //go:linkname os_beforeExit os.runtime_beforeExit 229 func os_beforeExit() { 230 if raceenabled { 231 racefini() 232 } 233 } 234 235 // start forcegc helper goroutine 236 func init() { 237 go forcegchelper() 238 } 239 240 func forcegchelper() { 241 forcegc.g = getg() 242 for { 243 lock(&forcegc.lock) 244 if forcegc.idle != 0 { 245 throw("forcegc: phase error") 246 } 247 atomic.Store(&forcegc.idle, 1) 248 goparkunlock(&forcegc.lock, "force gc (idle)", traceEvGoBlock, 1) 249 // this goroutine is explicitly resumed by sysmon 250 if debug.gctrace > 0 { 251 println("GC forced") 252 } 253 // Time-triggered, fully concurrent. 254 gcStart(gcBackgroundMode, gcTrigger{kind: gcTriggerTime, now: nanotime()}) 255 } 256 } 257 258 //go:nosplit 259 260 // Gosched yields the processor, allowing other goroutines to run. It does not 261 // suspend the current goroutine, so execution resumes automatically. 262 func Gosched() { 263 mcall(gosched_m) 264 } 265 266 // goschedguarded yields the processor like gosched, but also checks 267 // for forbidden states and opts out of the yield in those cases. 268 //go:nosplit 269 func goschedguarded() { 270 mcall(goschedguarded_m) 271 } 272 273 // Puts the current goroutine into a waiting state and calls unlockf. 274 // If unlockf returns false, the goroutine is resumed. 275 // unlockf must not access this G's stack, as it may be moved between 276 // the call to gopark and the call to unlockf. 277 func gopark(unlockf func(*g, unsafe.Pointer) bool, lock unsafe.Pointer, reason string, traceEv byte, traceskip int) { 278 mp := acquirem() 279 gp := mp.curg 280 status := readgstatus(gp) 281 if status != _Grunning && status != _Gscanrunning { 282 throw("gopark: bad g status") 283 } 284 mp.waitlock = lock 285 mp.waitunlockf = *(*unsafe.Pointer)(unsafe.Pointer(&unlockf)) 286 gp.waitreason = reason 287 mp.waittraceev = traceEv 288 mp.waittraceskip = traceskip 289 releasem(mp) 290 // can't do anything that might move the G between Ms here. 291 mcall(park_m) 292 } 293 294 // Puts the current goroutine into a waiting state and unlocks the lock. 295 // The goroutine can be made runnable again by calling goready(gp). 296 func goparkunlock(lock *mutex, reason string, traceEv byte, traceskip int) { 297 gopark(parkunlock_c, unsafe.Pointer(lock), reason, traceEv, traceskip) 298 } 299 300 func goready(gp *g, traceskip int) { 301 systemstack(func() { 302 ready(gp, traceskip, true) 303 }) 304 } 305 306 //go:nosplit 307 func acquireSudog() *sudog { 308 // Delicate dance: the semaphore implementation calls 309 // acquireSudog, acquireSudog calls new(sudog), 310 // new calls malloc, malloc can call the garbage collector, 311 // and the garbage collector calls the semaphore implementation 312 // in stopTheWorld. 313 // Break the cycle by doing acquirem/releasem around new(sudog). 314 // The acquirem/releasem increments m.locks during new(sudog), 315 // which keeps the garbage collector from being invoked. 316 mp := acquirem() 317 pp := mp.p.ptr() 318 if len(pp.sudogcache) == 0 { 319 lock(&sched.sudoglock) 320 // First, try to grab a batch from central cache. 321 for len(pp.sudogcache) < cap(pp.sudogcache)/2 && sched.sudogcache != nil { 322 s := sched.sudogcache 323 sched.sudogcache = s.next 324 s.next = nil 325 pp.sudogcache = append(pp.sudogcache, s) 326 } 327 unlock(&sched.sudoglock) 328 // If the central cache is empty, allocate a new one. 329 if len(pp.sudogcache) == 0 { 330 pp.sudogcache = append(pp.sudogcache, new(sudog)) 331 } 332 } 333 n := len(pp.sudogcache) 334 s := pp.sudogcache[n-1] 335 pp.sudogcache[n-1] = nil 336 pp.sudogcache = pp.sudogcache[:n-1] 337 if s.elem != nil { 338 throw("acquireSudog: found s.elem != nil in cache") 339 } 340 releasem(mp) 341 return s 342 } 343 344 //go:nosplit 345 func releaseSudog(s *sudog) { 346 if s.elem != nil { 347 throw("runtime: sudog with non-nil elem") 348 } 349 if s.isSelect { 350 throw("runtime: sudog with non-false isSelect") 351 } 352 if s.next != nil { 353 throw("runtime: sudog with non-nil next") 354 } 355 if s.prev != nil { 356 throw("runtime: sudog with non-nil prev") 357 } 358 if s.waitlink != nil { 359 throw("runtime: sudog with non-nil waitlink") 360 } 361 if s.c != nil { 362 throw("runtime: sudog with non-nil c") 363 } 364 gp := getg() 365 if gp.param != nil { 366 throw("runtime: releaseSudog with non-nil gp.param") 367 } 368 mp := acquirem() // avoid rescheduling to another P 369 pp := mp.p.ptr() 370 if len(pp.sudogcache) == cap(pp.sudogcache) { 371 // Transfer half of local cache to the central cache. 372 var first, last *sudog 373 for len(pp.sudogcache) > cap(pp.sudogcache)/2 { 374 n := len(pp.sudogcache) 375 p := pp.sudogcache[n-1] 376 pp.sudogcache[n-1] = nil 377 pp.sudogcache = pp.sudogcache[:n-1] 378 if first == nil { 379 first = p 380 } else { 381 last.next = p 382 } 383 last = p 384 } 385 lock(&sched.sudoglock) 386 last.next = sched.sudogcache 387 sched.sudogcache = first 388 unlock(&sched.sudoglock) 389 } 390 pp.sudogcache = append(pp.sudogcache, s) 391 releasem(mp) 392 } 393 394 // funcPC returns the entry PC of the function f. 395 // It assumes that f is a func value. Otherwise the behavior is undefined. 396 //go:nosplit 397 func funcPC(f interface{}) uintptr { 398 return **(**uintptr)(add(unsafe.Pointer(&f), sys.PtrSize)) 399 } 400 401 // called from assembly 402 func badmcall(fn func(*g)) { 403 throw("runtime: mcall called on m->g0 stack") 404 } 405 406 func badmcall2(fn func(*g)) { 407 throw("runtime: mcall function returned") 408 } 409 410 func badreflectcall() { 411 panic(plainError("arg size to reflect.call more than 1GB")) 412 } 413 414 var badmorestackg0Msg = "fatal: morestack on g0\n" 415 416 //go:nosplit 417 //go:nowritebarrierrec 418 func badmorestackg0() { 419 sp := stringStructOf(&badmorestackg0Msg) 420 write(2, sp.str, int32(sp.len)) 421 } 422 423 var badmorestackgsignalMsg = "fatal: morestack on gsignal\n" 424 425 //go:nosplit 426 //go:nowritebarrierrec 427 func badmorestackgsignal() { 428 sp := stringStructOf(&badmorestackgsignalMsg) 429 write(2, sp.str, int32(sp.len)) 430 } 431 432 //go:nosplit 433 func badctxt() { 434 throw("ctxt != 0") 435 } 436 437 func lockedOSThread() bool { 438 gp := getg() 439 return gp.lockedm != 0 && gp.m.lockedg != 0 440 } 441 442 var ( 443 allgs []*g 444 allglock mutex 445 ) 446 447 func allgadd(gp *g) { 448 if readgstatus(gp) == _Gidle { 449 throw("allgadd: bad status Gidle") 450 } 451 452 lock(&allglock) 453 allgs = append(allgs, gp) 454 allglen = uintptr(len(allgs)) 455 unlock(&allglock) 456 } 457 458 const ( 459 // Number of goroutine ids to grab from sched.goidgen to local per-P cache at once. 460 // 16 seems to provide enough amortization, but other than that it's mostly arbitrary number. 461 _GoidCacheBatch = 16 462 ) 463 464 // The bootstrap sequence is: 465 // 466 // call osinit 467 // call schedinit 468 // make & queue new G 469 // call runtime·mstart 470 // 471 // The new G calls runtime·main. 472 func schedinit() { 473 // raceinit must be the first call to race detector. 474 // In particular, it must be done before mallocinit below calls racemapshadow. 475 _g_ := getg() 476 if raceenabled { 477 _g_.racectx, raceprocctx0 = raceinit() 478 } 479 480 sched.maxmcount = 10000 481 482 tracebackinit() 483 moduledataverify() 484 stackinit() 485 mallocinit() 486 mcommoninit(_g_.m) 487 alginit() // maps must not be used before this call 488 modulesinit() // provides activeModules 489 typelinksinit() // uses maps, activeModules 490 itabsinit() // uses activeModules 491 492 msigsave(_g_.m) 493 initSigmask = _g_.m.sigmask 494 495 goargs() 496 goenvs() 497 parsedebugvars() 498 gcinit() 499 500 sched.lastpoll = uint64(nanotime()) 501 procs := ncpu 502 if n, ok := atoi32(gogetenv("GOMAXPROCS")); ok && n > 0 { 503 procs = n 504 } 505 if procresize(procs) != nil { 506 throw("unknown runnable goroutine during bootstrap") 507 } 508 509 // For cgocheck > 1, we turn on the write barrier at all times 510 // and check all pointer writes. We can't do this until after 511 // procresize because the write barrier needs a P. 512 if debug.cgocheck > 1 { 513 writeBarrier.cgo = true 514 writeBarrier.enabled = true 515 for _, p := range allp { 516 p.wbBuf.reset() 517 } 518 } 519 520 if buildVersion == "" { 521 // Condition should never trigger. This code just serves 522 // to ensure runtime·buildVersion is kept in the resulting binary. 523 buildVersion = "unknown" 524 } 525 } 526 527 func dumpgstatus(gp *g) { 528 _g_ := getg() 529 print("runtime: gp: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n") 530 print("runtime: g: g=", _g_, ", goid=", _g_.goid, ", g->atomicstatus=", readgstatus(_g_), "\n") 531 } 532 533 func checkmcount() { 534 // sched lock is held 535 if mcount() > sched.maxmcount { 536 print("runtime: program exceeds ", sched.maxmcount, "-thread limit\n") 537 throw("thread exhaustion") 538 } 539 } 540 541 func mcommoninit(mp *m) { 542 _g_ := getg() 543 544 // g0 stack won't make sense for user (and is not necessary unwindable). 545 if _g_ != _g_.m.g0 { 546 callers(1, mp.createstack[:]) 547 } 548 549 lock(&sched.lock) 550 if sched.mnext+1 < sched.mnext { 551 throw("runtime: thread ID overflow") 552 } 553 mp.id = sched.mnext 554 sched.mnext++ 555 checkmcount() 556 557 mp.fastrand[0] = 1597334677 * uint32(mp.id) 558 mp.fastrand[1] = uint32(cputicks()) 559 if mp.fastrand[0]|mp.fastrand[1] == 0 { 560 mp.fastrand[1] = 1 561 } 562 563 mpreinit(mp) 564 if mp.gsignal != nil { 565 mp.gsignal.stackguard1 = mp.gsignal.stack.lo + _StackGuard 566 } 567 568 // Add to allm so garbage collector doesn't free g->m 569 // when it is just in a register or thread-local storage. 570 mp.alllink = allm 571 572 // NumCgoCall() iterates over allm w/o schedlock, 573 // so we need to publish it safely. 574 atomicstorep(unsafe.Pointer(&allm), unsafe.Pointer(mp)) 575 unlock(&sched.lock) 576 577 // Allocate memory to hold a cgo traceback if the cgo call crashes. 578 if iscgo || GOOS == "solaris" || GOOS == "windows" { 579 mp.cgoCallers = new(cgoCallers) 580 } 581 } 582 583 // Mark gp ready to run. 584 func ready(gp *g, traceskip int, next bool) { 585 if trace.enabled { 586 traceGoUnpark(gp, traceskip) 587 } 588 589 status := readgstatus(gp) 590 591 // Mark runnable. 592 _g_ := getg() 593 _g_.m.locks++ // disable preemption because it can be holding p in a local var 594 if status&^_Gscan != _Gwaiting { 595 dumpgstatus(gp) 596 throw("bad g->status in ready") 597 } 598 599 // status is Gwaiting or Gscanwaiting, make Grunnable and put on runq 600 casgstatus(gp, _Gwaiting, _Grunnable) 601 runqput(_g_.m.p.ptr(), gp, next) 602 if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 { 603 wakep() 604 } 605 _g_.m.locks-- 606 if _g_.m.locks == 0 && _g_.preempt { // restore the preemption request in Case we've cleared it in newstack 607 _g_.stackguard0 = stackPreempt 608 } 609 } 610 611 func gcprocs() int32 { 612 // Figure out how many CPUs to use during GC. 613 // Limited by gomaxprocs, number of actual CPUs, and MaxGcproc. 614 lock(&sched.lock) 615 n := gomaxprocs 616 if n > ncpu { 617 n = ncpu 618 } 619 if n > _MaxGcproc { 620 n = _MaxGcproc 621 } 622 if n > sched.nmidle+1 { // one M is currently running 623 n = sched.nmidle + 1 624 } 625 unlock(&sched.lock) 626 return n 627 } 628 629 func needaddgcproc() bool { 630 lock(&sched.lock) 631 n := gomaxprocs 632 if n > ncpu { 633 n = ncpu 634 } 635 if n > _MaxGcproc { 636 n = _MaxGcproc 637 } 638 n -= sched.nmidle + 1 // one M is currently running 639 unlock(&sched.lock) 640 return n > 0 641 } 642 643 func helpgc(nproc int32) { 644 _g_ := getg() 645 lock(&sched.lock) 646 pos := 0 647 for n := int32(1); n < nproc; n++ { // one M is currently running 648 if allp[pos].mcache == _g_.m.mcache { 649 pos++ 650 } 651 mp := mget() 652 if mp == nil { 653 throw("gcprocs inconsistency") 654 } 655 mp.helpgc = n 656 mp.p.set(allp[pos]) 657 mp.mcache = allp[pos].mcache 658 pos++ 659 notewakeup(&mp.park) 660 } 661 unlock(&sched.lock) 662 } 663 664 // freezeStopWait is a large value that freezetheworld sets 665 // sched.stopwait to in order to request that all Gs permanently stop. 666 const freezeStopWait = 0x7fffffff 667 668 // freezing is set to non-zero if the runtime is trying to freeze the 669 // world. 670 var freezing uint32 671 672 // Similar to stopTheWorld but best-effort and can be called several times. 673 // There is no reverse operation, used during crashing. 674 // This function must not lock any mutexes. 675 func freezetheworld() { 676 atomic.Store(&freezing, 1) 677 // stopwait and preemption requests can be lost 678 // due to races with concurrently executing threads, 679 // so try several times 680 for i := 0; i < 5; i++ { 681 // this should tell the scheduler to not start any new goroutines 682 sched.stopwait = freezeStopWait 683 atomic.Store(&sched.gcwaiting, 1) 684 // this should stop running goroutines 685 if !preemptall() { 686 break // no running goroutines 687 } 688 usleep(1000) 689 } 690 // to be sure 691 usleep(1000) 692 preemptall() 693 usleep(1000) 694 } 695 696 func isscanstatus(status uint32) bool { 697 if status == _Gscan { 698 throw("isscanstatus: Bad status Gscan") 699 } 700 return status&_Gscan == _Gscan 701 } 702 703 // All reads and writes of g's status go through readgstatus, casgstatus 704 // castogscanstatus, casfrom_Gscanstatus. 705 //go:nosplit 706 func readgstatus(gp *g) uint32 { 707 return atomic.Load(&gp.atomicstatus) 708 } 709 710 // Ownership of gcscanvalid: 711 // 712 // If gp is running (meaning status == _Grunning or _Grunning|_Gscan), 713 // then gp owns gp.gcscanvalid, and other goroutines must not modify it. 714 // 715 // Otherwise, a second goroutine can lock the scan state by setting _Gscan 716 // in the status bit and then modify gcscanvalid, and then unlock the scan state. 717 // 718 // Note that the first condition implies an exception to the second: 719 // if a second goroutine changes gp's status to _Grunning|_Gscan, 720 // that second goroutine still does not have the right to modify gcscanvalid. 721 722 // The Gscanstatuses are acting like locks and this releases them. 723 // If it proves to be a performance hit we should be able to make these 724 // simple atomic stores but for now we are going to throw if 725 // we see an inconsistent state. 726 func casfrom_Gscanstatus(gp *g, oldval, newval uint32) { 727 success := false 728 729 // Check that transition is valid. 730 switch oldval { 731 default: 732 print("runtime: casfrom_Gscanstatus bad oldval gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n") 733 dumpgstatus(gp) 734 throw("casfrom_Gscanstatus:top gp->status is not in scan state") 735 case _Gscanrunnable, 736 _Gscanwaiting, 737 _Gscanrunning, 738 _Gscansyscall: 739 if newval == oldval&^_Gscan { 740 success = atomic.Cas(&gp.atomicstatus, oldval, newval) 741 } 742 } 743 if !success { 744 print("runtime: casfrom_Gscanstatus failed gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n") 745 dumpgstatus(gp) 746 throw("casfrom_Gscanstatus: gp->status is not in scan state") 747 } 748 } 749 750 // This will return false if the gp is not in the expected status and the cas fails. 751 // This acts like a lock acquire while the casfromgstatus acts like a lock release. 752 func castogscanstatus(gp *g, oldval, newval uint32) bool { 753 switch oldval { 754 case _Grunnable, 755 _Grunning, 756 _Gwaiting, 757 _Gsyscall: 758 if newval == oldval|_Gscan { 759 return atomic.Cas(&gp.atomicstatus, oldval, newval) 760 } 761 } 762 print("runtime: castogscanstatus oldval=", hex(oldval), " newval=", hex(newval), "\n") 763 throw("castogscanstatus") 764 panic("not reached") 765 } 766 767 // If asked to move to or from a Gscanstatus this will throw. Use the castogscanstatus 768 // and casfrom_Gscanstatus instead. 769 // casgstatus will loop if the g->atomicstatus is in a Gscan status until the routine that 770 // put it in the Gscan state is finished. 771 //go:nosplit 772 func casgstatus(gp *g, oldval, newval uint32) { 773 if (oldval&_Gscan != 0) || (newval&_Gscan != 0) || oldval == newval { 774 systemstack(func() { 775 print("runtime: casgstatus: oldval=", hex(oldval), " newval=", hex(newval), "\n") 776 throw("casgstatus: bad incoming values") 777 }) 778 } 779 780 if oldval == _Grunning && gp.gcscanvalid { 781 // If oldvall == _Grunning, then the actual status must be 782 // _Grunning or _Grunning|_Gscan; either way, 783 // we own gp.gcscanvalid, so it's safe to read. 784 // gp.gcscanvalid must not be true when we are running. 785 print("runtime: casgstatus ", hex(oldval), "->", hex(newval), " gp.status=", hex(gp.atomicstatus), " gp.gcscanvalid=true\n") 786 throw("casgstatus") 787 } 788 789 // See http://golang.org/cl/21503 for justification of the yield delay. 790 const yieldDelay = 5 * 1000 791 var nextYield int64 792 793 // loop if gp->atomicstatus is in a scan state giving 794 // GC time to finish and change the state to oldval. 795 for i := 0; !atomic.Cas(&gp.atomicstatus, oldval, newval); i++ { 796 if oldval == _Gwaiting && gp.atomicstatus == _Grunnable { 797 systemstack(func() { 798 throw("casgstatus: waiting for Gwaiting but is Grunnable") 799 }) 800 } 801 // Help GC if needed. 802 // if gp.preemptscan && !gp.gcworkdone && (oldval == _Grunning || oldval == _Gsyscall) { 803 // gp.preemptscan = false 804 // systemstack(func() { 805 // gcphasework(gp) 806 // }) 807 // } 808 // But meanwhile just yield. 809 if i == 0 { 810 nextYield = nanotime() + yieldDelay 811 } 812 if nanotime() < nextYield { 813 for x := 0; x < 10 && gp.atomicstatus != oldval; x++ { 814 procyield(1) 815 } 816 } else { 817 osyield() 818 nextYield = nanotime() + yieldDelay/2 819 } 820 } 821 if newval == _Grunning { 822 gp.gcscanvalid = false 823 } 824 } 825 826 // casgstatus(gp, oldstatus, Gcopystack), assuming oldstatus is Gwaiting or Grunnable. 827 // Returns old status. Cannot call casgstatus directly, because we are racing with an 828 // async wakeup that might come in from netpoll. If we see Gwaiting from the readgstatus, 829 // it might have become Grunnable by the time we get to the cas. If we called casgstatus, 830 // it would loop waiting for the status to go back to Gwaiting, which it never will. 831 //go:nosplit 832 func casgcopystack(gp *g) uint32 { 833 for { 834 oldstatus := readgstatus(gp) &^ _Gscan 835 if oldstatus != _Gwaiting && oldstatus != _Grunnable { 836 throw("copystack: bad status, not Gwaiting or Grunnable") 837 } 838 if atomic.Cas(&gp.atomicstatus, oldstatus, _Gcopystack) { 839 return oldstatus 840 } 841 } 842 } 843 844 // scang blocks until gp's stack has been scanned. 845 // It might be scanned by scang or it might be scanned by the goroutine itself. 846 // Either way, the stack scan has completed when scang returns. 847 func scang(gp *g, gcw *gcWork) { 848 // Invariant; we (the caller, markroot for a specific goroutine) own gp.gcscandone. 849 // Nothing is racing with us now, but gcscandone might be set to true left over 850 // from an earlier round of stack scanning (we scan twice per GC). 851 // We use gcscandone to record whether the scan has been done during this round. 852 853 gp.gcscandone = false 854 855 // See http://golang.org/cl/21503 for justification of the yield delay. 856 const yieldDelay = 10 * 1000 857 var nextYield int64 858 859 // Endeavor to get gcscandone set to true, 860 // either by doing the stack scan ourselves or by coercing gp to scan itself. 861 // gp.gcscandone can transition from false to true when we're not looking 862 // (if we asked for preemption), so any time we lock the status using 863 // castogscanstatus we have to double-check that the scan is still not done. 864 loop: 865 for i := 0; !gp.gcscandone; i++ { 866 switch s := readgstatus(gp); s { 867 default: 868 dumpgstatus(gp) 869 throw("stopg: invalid status") 870 871 case _Gdead: 872 // No stack. 873 gp.gcscandone = true 874 break loop 875 876 case _Gcopystack: 877 // Stack being switched. Go around again. 878 879 case _Grunnable, _Gsyscall, _Gwaiting: 880 // Claim goroutine by setting scan bit. 881 // Racing with execution or readying of gp. 882 // The scan bit keeps them from running 883 // the goroutine until we're done. 884 if castogscanstatus(gp, s, s|_Gscan) { 885 if !gp.gcscandone { 886 scanstack(gp, gcw) 887 gp.gcscandone = true 888 } 889 restartg(gp) 890 break loop 891 } 892 893 case _Gscanwaiting: 894 // newstack is doing a scan for us right now. Wait. 895 896 case _Grunning: 897 // Goroutine running. Try to preempt execution so it can scan itself. 898 // The preemption handler (in newstack) does the actual scan. 899 900 // Optimization: if there is already a pending preemption request 901 // (from the previous loop iteration), don't bother with the atomics. 902 if gp.preemptscan && gp.preempt && gp.stackguard0 == stackPreempt { 903 break 904 } 905 906 // Ask for preemption and self scan. 907 if castogscanstatus(gp, _Grunning, _Gscanrunning) { 908 if !gp.gcscandone { 909 gp.preemptscan = true 910 gp.preempt = true 911 gp.stackguard0 = stackPreempt 912 } 913 casfrom_Gscanstatus(gp, _Gscanrunning, _Grunning) 914 } 915 } 916 917 if i == 0 { 918 nextYield = nanotime() + yieldDelay 919 } 920 if nanotime() < nextYield { 921 procyield(10) 922 } else { 923 osyield() 924 nextYield = nanotime() + yieldDelay/2 925 } 926 } 927 928 gp.preemptscan = false // cancel scan request if no longer needed 929 } 930 931 // The GC requests that this routine be moved from a scanmumble state to a mumble state. 932 func restartg(gp *g) { 933 s := readgstatus(gp) 934 switch s { 935 default: 936 dumpgstatus(gp) 937 throw("restartg: unexpected status") 938 939 case _Gdead: 940 // ok 941 942 case _Gscanrunnable, 943 _Gscanwaiting, 944 _Gscansyscall: 945 casfrom_Gscanstatus(gp, s, s&^_Gscan) 946 } 947 } 948 949 // stopTheWorld stops all P's from executing goroutines, interrupting 950 // all goroutines at GC safe points and records reason as the reason 951 // for the stop. On return, only the current goroutine's P is running. 952 // stopTheWorld must not be called from a system stack and the caller 953 // must not hold worldsema. The caller must call startTheWorld when 954 // other P's should resume execution. 955 // 956 // stopTheWorld is safe for multiple goroutines to call at the 957 // same time. Each will execute its own stop, and the stops will 958 // be serialized. 959 // 960 // This is also used by routines that do stack dumps. If the system is 961 // in panic or being exited, this may not reliably stop all 962 // goroutines. 963 func stopTheWorld(reason string) { 964 semacquire(&worldsema) 965 getg().m.preemptoff = reason 966 systemstack(stopTheWorldWithSema) 967 } 968 969 // startTheWorld undoes the effects of stopTheWorld. 970 func startTheWorld() { 971 systemstack(func() { startTheWorldWithSema(false) }) 972 // worldsema must be held over startTheWorldWithSema to ensure 973 // gomaxprocs cannot change while worldsema is held. 974 semrelease(&worldsema) 975 getg().m.preemptoff = "" 976 } 977 978 // Holding worldsema grants an M the right to try to stop the world 979 // and prevents gomaxprocs from changing concurrently. 980 var worldsema uint32 = 1 981 982 // stopTheWorldWithSema is the core implementation of stopTheWorld. 983 // The caller is responsible for acquiring worldsema and disabling 984 // preemption first and then should stopTheWorldWithSema on the system 985 // stack: 986 // 987 // semacquire(&worldsema, 0) 988 // m.preemptoff = "reason" 989 // systemstack(stopTheWorldWithSema) 990 // 991 // When finished, the caller must either call startTheWorld or undo 992 // these three operations separately: 993 // 994 // m.preemptoff = "" 995 // systemstack(startTheWorldWithSema) 996 // semrelease(&worldsema) 997 // 998 // It is allowed to acquire worldsema once and then execute multiple 999 // startTheWorldWithSema/stopTheWorldWithSema pairs. 1000 // Other P's are able to execute between successive calls to 1001 // startTheWorldWithSema and stopTheWorldWithSema. 1002 // Holding worldsema causes any other goroutines invoking 1003 // stopTheWorld to block. 1004 func stopTheWorldWithSema() { 1005 _g_ := getg() 1006 1007 // If we hold a lock, then we won't be able to stop another M 1008 // that is blocked trying to acquire the lock. 1009 if _g_.m.locks > 0 { 1010 throw("stopTheWorld: holding locks") 1011 } 1012 1013 lock(&sched.lock) 1014 sched.stopwait = gomaxprocs 1015 atomic.Store(&sched.gcwaiting, 1) 1016 preemptall() 1017 // stop current P 1018 _g_.m.p.ptr().status = _Pgcstop // Pgcstop is only diagnostic. 1019 sched.stopwait-- 1020 // try to retake all P's in Psyscall status 1021 for _, p := range allp { 1022 s := p.status 1023 if s == _Psyscall && atomic.Cas(&p.status, s, _Pgcstop) { 1024 if trace.enabled { 1025 traceGoSysBlock(p) 1026 traceProcStop(p) 1027 } 1028 p.syscalltick++ 1029 sched.stopwait-- 1030 } 1031 } 1032 // stop idle P's 1033 for { 1034 p := pidleget() 1035 if p == nil { 1036 break 1037 } 1038 p.status = _Pgcstop 1039 sched.stopwait-- 1040 } 1041 wait := sched.stopwait > 0 1042 unlock(&sched.lock) 1043 1044 // wait for remaining P's to stop voluntarily 1045 if wait { 1046 for { 1047 // wait for 100us, then try to re-preempt in case of any races 1048 if notetsleep(&sched.stopnote, 100*1000) { 1049 noteclear(&sched.stopnote) 1050 break 1051 } 1052 preemptall() 1053 } 1054 } 1055 1056 // sanity checks 1057 bad := "" 1058 if sched.stopwait != 0 { 1059 bad = "stopTheWorld: not stopped (stopwait != 0)" 1060 } else { 1061 for _, p := range allp { 1062 if p.status != _Pgcstop { 1063 bad = "stopTheWorld: not stopped (status != _Pgcstop)" 1064 } 1065 } 1066 } 1067 if atomic.Load(&freezing) != 0 { 1068 // Some other thread is panicking. This can cause the 1069 // sanity checks above to fail if the panic happens in 1070 // the signal handler on a stopped thread. Either way, 1071 // we should halt this thread. 1072 lock(&deadlock) 1073 lock(&deadlock) 1074 } 1075 if bad != "" { 1076 throw(bad) 1077 } 1078 } 1079 1080 func mhelpgc() { 1081 _g_ := getg() 1082 _g_.m.helpgc = -1 1083 } 1084 1085 func startTheWorldWithSema(emitTraceEvent bool) int64 { 1086 _g_ := getg() 1087 1088 _g_.m.locks++ // disable preemption because it can be holding p in a local var 1089 if netpollinited() { 1090 gp := netpoll(false) // non-blocking 1091 injectglist(gp) 1092 } 1093 add := needaddgcproc() 1094 lock(&sched.lock) 1095 1096 procs := gomaxprocs 1097 if newprocs != 0 { 1098 procs = newprocs 1099 newprocs = 0 1100 } 1101 p1 := procresize(procs) 1102 sched.gcwaiting = 0 1103 if sched.sysmonwait != 0 { 1104 sched.sysmonwait = 0 1105 notewakeup(&sched.sysmonnote) 1106 } 1107 unlock(&sched.lock) 1108 1109 for p1 != nil { 1110 p := p1 1111 p1 = p1.link.ptr() 1112 if p.m != 0 { 1113 mp := p.m.ptr() 1114 p.m = 0 1115 if mp.nextp != 0 { 1116 throw("startTheWorld: inconsistent mp->nextp") 1117 } 1118 mp.nextp.set(p) 1119 notewakeup(&mp.park) 1120 } else { 1121 // Start M to run P. Do not start another M below. 1122 newm(nil, p) 1123 add = false 1124 } 1125 } 1126 1127 // Capture start-the-world time before doing clean-up tasks. 1128 startTime := nanotime() 1129 if emitTraceEvent { 1130 traceGCSTWDone() 1131 } 1132 1133 // Wakeup an additional proc in case we have excessive runnable goroutines 1134 // in local queues or in the global queue. If we don't, the proc will park itself. 1135 // If we have lots of excessive work, resetspinning will unpark additional procs as necessary. 1136 if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 { 1137 wakep() 1138 } 1139 1140 if add { 1141 // If GC could have used another helper proc, start one now, 1142 // in the hope that it will be available next time. 1143 // It would have been even better to start it before the collection, 1144 // but doing so requires allocating memory, so it's tricky to 1145 // coordinate. This lazy approach works out in practice: 1146 // we don't mind if the first couple gc rounds don't have quite 1147 // the maximum number of procs. 1148 newm(mhelpgc, nil) 1149 } 1150 _g_.m.locks-- 1151 if _g_.m.locks == 0 && _g_.preempt { // restore the preemption request in case we've cleared it in newstack 1152 _g_.stackguard0 = stackPreempt 1153 } 1154 1155 return startTime 1156 } 1157 1158 // Called to start an M. 1159 // 1160 // This must not split the stack because we may not even have stack 1161 // bounds set up yet. 1162 // 1163 // May run during STW (because it doesn't have a P yet), so write 1164 // barriers are not allowed. 1165 // 1166 //go:nosplit 1167 //go:nowritebarrierrec 1168 func mstart() { 1169 _g_ := getg() 1170 1171 osStack := _g_.stack.lo == 0 1172 if osStack { 1173 // Initialize stack bounds from system stack. 1174 // Cgo may have left stack size in stack.hi. 1175 size := _g_.stack.hi 1176 if size == 0 { 1177 size = 8192 * sys.StackGuardMultiplier 1178 } 1179 _g_.stack.hi = uintptr(noescape(unsafe.Pointer(&size))) 1180 _g_.stack.lo = _g_.stack.hi - size + 1024 1181 } 1182 // Initialize stack guards so that we can start calling 1183 // both Go and C functions with stack growth prologues. 1184 _g_.stackguard0 = _g_.stack.lo + _StackGuard 1185 _g_.stackguard1 = _g_.stackguard0 1186 mstart1(0) 1187 1188 // Exit this thread. 1189 if GOOS == "windows" || GOOS == "solaris" || GOOS == "plan9" { 1190 // Window, Solaris and Plan 9 always system-allocate 1191 // the stack, but put it in _g_.stack before mstart, 1192 // so the logic above hasn't set osStack yet. 1193 osStack = true 1194 } 1195 mexit(osStack) 1196 } 1197 1198 func mstart1(dummy int32) { 1199 _g_ := getg() 1200 1201 if _g_ != _g_.m.g0 { 1202 throw("bad runtime·mstart") 1203 } 1204 1205 // Record the caller for use as the top of stack in mcall and 1206 // for terminating the thread. 1207 // We're never coming back to mstart1 after we call schedule, 1208 // so other calls can reuse the current frame. 1209 save(getcallerpc(), getcallersp(unsafe.Pointer(&dummy))) 1210 asminit() 1211 minit() 1212 1213 // Install signal handlers; after minit so that minit can 1214 // prepare the thread to be able to handle the signals. 1215 if _g_.m == &m0 { 1216 mstartm0() 1217 } 1218 1219 if fn := _g_.m.mstartfn; fn != nil { 1220 fn() 1221 } 1222 1223 if _g_.m.helpgc != 0 { 1224 _g_.m.helpgc = 0 1225 stopm() 1226 } else if _g_.m != &m0 { 1227 acquirep(_g_.m.nextp.ptr()) 1228 _g_.m.nextp = 0 1229 } 1230 schedule() 1231 } 1232 1233 // mstartm0 implements part of mstart1 that only runs on the m0. 1234 // 1235 // Write barriers are allowed here because we know the GC can't be 1236 // running yet, so they'll be no-ops. 1237 // 1238 //go:yeswritebarrierrec 1239 func mstartm0() { 1240 // Create an extra M for callbacks on threads not created by Go. 1241 if iscgo && !cgoHasExtraM { 1242 cgoHasExtraM = true 1243 newextram() 1244 } 1245 initsig(false) 1246 } 1247 1248 // mexit tears down and exits the current thread. 1249 // 1250 // Don't call this directly to exit the thread, since it must run at 1251 // the top of the thread stack. Instead, use gogo(&_g_.m.g0.sched) to 1252 // unwind the stack to the point that exits the thread. 1253 // 1254 // It is entered with m.p != nil, so write barriers are allowed. It 1255 // will release the P before exiting. 1256 // 1257 //go:yeswritebarrierrec 1258 func mexit(osStack bool) { 1259 g := getg() 1260 m := g.m 1261 1262 if m == &m0 { 1263 // This is the main thread. Just wedge it. 1264 // 1265 // On Linux, exiting the main thread puts the process 1266 // into a non-waitable zombie state. On Plan 9, 1267 // exiting the main thread unblocks wait even though 1268 // other threads are still running. On Solaris we can 1269 // neither exitThread nor return from mstart. Other 1270 // bad things probably happen on other platforms. 1271 // 1272 // We could try to clean up this M more before wedging 1273 // it, but that complicates signal handling. 1274 handoffp(releasep()) 1275 lock(&sched.lock) 1276 sched.nmfreed++ 1277 checkdead() 1278 unlock(&sched.lock) 1279 notesleep(&m.park) 1280 throw("locked m0 woke up") 1281 } 1282 1283 sigblock() 1284 unminit() 1285 1286 // Free the gsignal stack. 1287 // 1288 // If the signal stack was created outside Go, then gsignal 1289 // will be non-nil, but unminitSignals set stack.lo to 0 1290 // (e.g., Android's libc creates all threads with a signal 1291 // stack, so it's possible for Go to exit them but not control 1292 // the signal stack). 1293 if m.gsignal != nil && m.gsignal.stack.lo != 0 { 1294 stackfree(m.gsignal.stack) 1295 } 1296 1297 // Remove m from allm. 1298 lock(&sched.lock) 1299 for pprev := &allm; *pprev != nil; pprev = &(*pprev).alllink { 1300 if *pprev == m { 1301 *pprev = m.alllink 1302 goto found 1303 } 1304 } 1305 throw("m not found in allm") 1306 found: 1307 if !osStack { 1308 // Delay reaping m until it's done with the stack. 1309 // 1310 // If this is using an OS stack, the OS will free it 1311 // so there's no need for reaping. 1312 atomic.Store(&m.freeWait, 1) 1313 // Put m on the free list, though it will not be reaped until 1314 // freeWait is 0. Note that the free list must not be linked 1315 // through alllink because some functions walk allm without 1316 // locking, so may be using alllink. 1317 m.freelink = sched.freem 1318 sched.freem = m 1319 } 1320 unlock(&sched.lock) 1321 1322 // Release the P. 1323 handoffp(releasep()) 1324 // After this point we must not have write barriers. 1325 1326 // Invoke the deadlock detector. This must happen after 1327 // handoffp because it may have started a new M to take our 1328 // P's work. 1329 lock(&sched.lock) 1330 sched.nmfreed++ 1331 checkdead() 1332 unlock(&sched.lock) 1333 1334 if osStack { 1335 // Return from mstart and let the system thread 1336 // library free the g0 stack and terminate the thread. 1337 return 1338 } 1339 1340 // mstart is the thread's entry point, so there's nothing to 1341 // return to. Exit the thread directly. exitThread will clear 1342 // m.freeWait when it's done with the stack and the m can be 1343 // reaped. 1344 exitThread(&m.freeWait) 1345 } 1346 1347 // forEachP calls fn(p) for every P p when p reaches a GC safe point. 1348 // If a P is currently executing code, this will bring the P to a GC 1349 // safe point and execute fn on that P. If the P is not executing code 1350 // (it is idle or in a syscall), this will call fn(p) directly while 1351 // preventing the P from exiting its state. This does not ensure that 1352 // fn will run on every CPU executing Go code, but it acts as a global 1353 // memory barrier. GC uses this as a "ragged barrier." 1354 // 1355 // The caller must hold worldsema. 1356 // 1357 //go:systemstack 1358 func forEachP(fn func(*p)) { 1359 mp := acquirem() 1360 _p_ := getg().m.p.ptr() 1361 1362 lock(&sched.lock) 1363 if sched.safePointWait != 0 { 1364 throw("forEachP: sched.safePointWait != 0") 1365 } 1366 sched.safePointWait = gomaxprocs - 1 1367 sched.safePointFn = fn 1368 1369 // Ask all Ps to run the safe point function. 1370 for _, p := range allp { 1371 if p != _p_ { 1372 atomic.Store(&p.runSafePointFn, 1) 1373 } 1374 } 1375 preemptall() 1376 1377 // Any P entering _Pidle or _Psyscall from now on will observe 1378 // p.runSafePointFn == 1 and will call runSafePointFn when 1379 // changing its status to _Pidle/_Psyscall. 1380 1381 // Run safe point function for all idle Ps. sched.pidle will 1382 // not change because we hold sched.lock. 1383 for p := sched.pidle.ptr(); p != nil; p = p.link.ptr() { 1384 if atomic.Cas(&p.runSafePointFn, 1, 0) { 1385 fn(p) 1386 sched.safePointWait-- 1387 } 1388 } 1389 1390 wait := sched.safePointWait > 0 1391 unlock(&sched.lock) 1392 1393 // Run fn for the current P. 1394 fn(_p_) 1395 1396 // Force Ps currently in _Psyscall into _Pidle and hand them 1397 // off to induce safe point function execution. 1398 for _, p := range allp { 1399 s := p.status 1400 if s == _Psyscall && p.runSafePointFn == 1 && atomic.Cas(&p.status, s, _Pidle) { 1401 if trace.enabled { 1402 traceGoSysBlock(p) 1403 traceProcStop(p) 1404 } 1405 p.syscalltick++ 1406 handoffp(p) 1407 } 1408 } 1409 1410 // Wait for remaining Ps to run fn. 1411 if wait { 1412 for { 1413 // Wait for 100us, then try to re-preempt in 1414 // case of any races. 1415 // 1416 // Requires system stack. 1417 if notetsleep(&sched.safePointNote, 100*1000) { 1418 noteclear(&sched.safePointNote) 1419 break 1420 } 1421 preemptall() 1422 } 1423 } 1424 if sched.safePointWait != 0 { 1425 throw("forEachP: not done") 1426 } 1427 for _, p := range allp { 1428 if p.runSafePointFn != 0 { 1429 throw("forEachP: P did not run fn") 1430 } 1431 } 1432 1433 lock(&sched.lock) 1434 sched.safePointFn = nil 1435 unlock(&sched.lock) 1436 releasem(mp) 1437 } 1438 1439 // runSafePointFn runs the safe point function, if any, for this P. 1440 // This should be called like 1441 // 1442 // if getg().m.p.runSafePointFn != 0 { 1443 // runSafePointFn() 1444 // } 1445 // 1446 // runSafePointFn must be checked on any transition in to _Pidle or 1447 // _Psyscall to avoid a race where forEachP sees that the P is running 1448 // just before the P goes into _Pidle/_Psyscall and neither forEachP 1449 // nor the P run the safe-point function. 1450 func runSafePointFn() { 1451 p := getg().m.p.ptr() 1452 // Resolve the race between forEachP running the safe-point 1453 // function on this P's behalf and this P running the 1454 // safe-point function directly. 1455 if !atomic.Cas(&p.runSafePointFn, 1, 0) { 1456 return 1457 } 1458 sched.safePointFn(p) 1459 lock(&sched.lock) 1460 sched.safePointWait-- 1461 if sched.safePointWait == 0 { 1462 notewakeup(&sched.safePointNote) 1463 } 1464 unlock(&sched.lock) 1465 } 1466 1467 // When running with cgo, we call _cgo_thread_start 1468 // to start threads for us so that we can play nicely with 1469 // foreign code. 1470 var cgoThreadStart unsafe.Pointer 1471 1472 type cgothreadstart struct { 1473 g guintptr 1474 tls *uint64 1475 fn unsafe.Pointer 1476 } 1477 1478 // Allocate a new m unassociated with any thread. 1479 // Can use p for allocation context if needed. 1480 // fn is recorded as the new m's m.mstartfn. 1481 // 1482 // This function is allowed to have write barriers even if the caller 1483 // isn't because it borrows _p_. 1484 // 1485 //go:yeswritebarrierrec 1486 func allocm(_p_ *p, fn func()) *m { 1487 _g_ := getg() 1488 _g_.m.locks++ // disable GC because it can be called from sysmon 1489 if _g_.m.p == 0 { 1490 acquirep(_p_) // temporarily borrow p for mallocs in this function 1491 } 1492 1493 // Release the free M list. We need to do this somewhere and 1494 // this may free up a stack we can use. 1495 if sched.freem != nil { 1496 lock(&sched.lock) 1497 var newList *m 1498 for freem := sched.freem; freem != nil; { 1499 if freem.freeWait != 0 { 1500 next := freem.freelink 1501 freem.freelink = newList 1502 newList = freem 1503 freem = next 1504 continue 1505 } 1506 stackfree(freem.g0.stack) 1507 freem = freem.freelink 1508 } 1509 sched.freem = newList 1510 unlock(&sched.lock) 1511 } 1512 1513 mp := new(m) 1514 mp.mstartfn = fn 1515 mcommoninit(mp) 1516 1517 // In case of cgo or Solaris, pthread_create will make us a stack. 1518 // Windows and Plan 9 will layout sched stack on OS stack. 1519 if iscgo || GOOS == "solaris" || GOOS == "windows" || GOOS == "plan9" { 1520 mp.g0 = malg(-1) 1521 } else { 1522 mp.g0 = malg(8192 * sys.StackGuardMultiplier) 1523 } 1524 mp.g0.m = mp 1525 1526 if _p_ == _g_.m.p.ptr() { 1527 releasep() 1528 } 1529 _g_.m.locks-- 1530 if _g_.m.locks == 0 && _g_.preempt { // restore the preemption request in case we've cleared it in newstack 1531 _g_.stackguard0 = stackPreempt 1532 } 1533 1534 return mp 1535 } 1536 1537 // needm is called when a cgo callback happens on a 1538 // thread without an m (a thread not created by Go). 1539 // In this case, needm is expected to find an m to use 1540 // and return with m, g initialized correctly. 1541 // Since m and g are not set now (likely nil, but see below) 1542 // needm is limited in what routines it can call. In particular 1543 // it can only call nosplit functions (textflag 7) and cannot 1544 // do any scheduling that requires an m. 1545 // 1546 // In order to avoid needing heavy lifting here, we adopt 1547 // the following strategy: there is a stack of available m's 1548 // that can be stolen. Using compare-and-swap 1549 // to pop from the stack has ABA races, so we simulate 1550 // a lock by doing an exchange (via casp) to steal the stack 1551 // head and replace the top pointer with MLOCKED (1). 1552 // This serves as a simple spin lock that we can use even 1553 // without an m. The thread that locks the stack in this way 1554 // unlocks the stack by storing a valid stack head pointer. 1555 // 1556 // In order to make sure that there is always an m structure 1557 // available to be stolen, we maintain the invariant that there 1558 // is always one more than needed. At the beginning of the 1559 // program (if cgo is in use) the list is seeded with a single m. 1560 // If needm finds that it has taken the last m off the list, its job 1561 // is - once it has installed its own m so that it can do things like 1562 // allocate memory - to create a spare m and put it on the list. 1563 // 1564 // Each of these extra m's also has a g0 and a curg that are 1565 // pressed into service as the scheduling stack and current 1566 // goroutine for the duration of the cgo callback. 1567 // 1568 // When the callback is done with the m, it calls dropm to 1569 // put the m back on the list. 1570 //go:nosplit 1571 func needm(x byte) { 1572 if iscgo && !cgoHasExtraM { 1573 // Can happen if C/C++ code calls Go from a global ctor. 1574 // Can not throw, because scheduler is not initialized yet. 1575 write(2, unsafe.Pointer(&earlycgocallback[0]), int32(len(earlycgocallback))) 1576 exit(1) 1577 } 1578 1579 // Lock extra list, take head, unlock popped list. 1580 // nilokay=false is safe here because of the invariant above, 1581 // that the extra list always contains or will soon contain 1582 // at least one m. 1583 mp := lockextra(false) 1584 1585 // Set needextram when we've just emptied the list, 1586 // so that the eventual call into cgocallbackg will 1587 // allocate a new m for the extra list. We delay the 1588 // allocation until then so that it can be done 1589 // after exitsyscall makes sure it is okay to be 1590 // running at all (that is, there's no garbage collection 1591 // running right now). 1592 mp.needextram = mp.schedlink == 0 1593 extraMCount-- 1594 unlockextra(mp.schedlink.ptr()) 1595 1596 // Save and block signals before installing g. 1597 // Once g is installed, any incoming signals will try to execute, 1598 // but we won't have the sigaltstack settings and other data 1599 // set up appropriately until the end of minit, which will 1600 // unblock the signals. This is the same dance as when 1601 // starting a new m to run Go code via newosproc. 1602 msigsave(mp) 1603 sigblock() 1604 1605 // Install g (= m->g0) and set the stack bounds 1606 // to match the current stack. We don't actually know 1607 // how big the stack is, like we don't know how big any 1608 // scheduling stack is, but we assume there's at least 32 kB, 1609 // which is more than enough for us. 1610 setg(mp.g0) 1611 _g_ := getg() 1612 _g_.stack.hi = uintptr(noescape(unsafe.Pointer(&x))) + 1024 1613 _g_.stack.lo = uintptr(noescape(unsafe.Pointer(&x))) - 32*1024 1614 _g_.stackguard0 = _g_.stack.lo + _StackGuard 1615 1616 // Initialize this thread to use the m. 1617 asminit() 1618 minit() 1619 1620 // mp.curg is now a real goroutine. 1621 casgstatus(mp.curg, _Gdead, _Gsyscall) 1622 atomic.Xadd(&sched.ngsys, -1) 1623 } 1624 1625 var earlycgocallback = []byte("fatal error: cgo callback before cgo call\n") 1626 1627 // newextram allocates m's and puts them on the extra list. 1628 // It is called with a working local m, so that it can do things 1629 // like call schedlock and allocate. 1630 func newextram() { 1631 c := atomic.Xchg(&extraMWaiters, 0) 1632 if c > 0 { 1633 for i := uint32(0); i < c; i++ { 1634 oneNewExtraM() 1635 } 1636 } else { 1637 // Make sure there is at least one extra M. 1638 mp := lockextra(true) 1639 unlockextra(mp) 1640 if mp == nil { 1641 oneNewExtraM() 1642 } 1643 } 1644 } 1645 1646 // oneNewExtraM allocates an m and puts it on the extra list. 1647 func oneNewExtraM() { 1648 // Create extra goroutine locked to extra m. 1649 // The goroutine is the context in which the cgo callback will run. 1650 // The sched.pc will never be returned to, but setting it to 1651 // goexit makes clear to the traceback routines where 1652 // the goroutine stack ends. 1653 mp := allocm(nil, nil) 1654 gp := malg(4096) 1655 gp.sched.pc = funcPC(goexit) + sys.PCQuantum 1656 gp.sched.sp = gp.stack.hi 1657 gp.sched.sp -= 4 * sys.RegSize // extra space in case of reads slightly beyond frame 1658 gp.sched.lr = 0 1659 gp.sched.g = guintptr(unsafe.Pointer(gp)) 1660 gp.syscallpc = gp.sched.pc 1661 gp.syscallsp = gp.sched.sp 1662 gp.stktopsp = gp.sched.sp 1663 gp.gcscanvalid = true 1664 gp.gcscandone = true 1665 // malg returns status as _Gidle. Change to _Gdead before 1666 // adding to allg where GC can see it. We use _Gdead to hide 1667 // this from tracebacks and stack scans since it isn't a 1668 // "real" goroutine until needm grabs it. 1669 casgstatus(gp, _Gidle, _Gdead) 1670 gp.m = mp 1671 mp.curg = gp 1672 mp.lockedInt++ 1673 mp.lockedg.set(gp) 1674 gp.lockedm.set(mp) 1675 gp.goid = int64(atomic.Xadd64(&sched.goidgen, 1)) 1676 if raceenabled { 1677 gp.racectx = racegostart(funcPC(newextram) + sys.PCQuantum) 1678 } 1679 // put on allg for garbage collector 1680 allgadd(gp) 1681 1682 // gp is now on the allg list, but we don't want it to be 1683 // counted by gcount. It would be more "proper" to increment 1684 // sched.ngfree, but that requires locking. Incrementing ngsys 1685 // has the same effect. 1686 atomic.Xadd(&sched.ngsys, +1) 1687 1688 // Add m to the extra list. 1689 mnext := lockextra(true) 1690 mp.schedlink.set(mnext) 1691 extraMCount++ 1692 unlockextra(mp) 1693 } 1694 1695 // dropm is called when a cgo callback has called needm but is now 1696 // done with the callback and returning back into the non-Go thread. 1697 // It puts the current m back onto the extra list. 1698 // 1699 // The main expense here is the call to signalstack to release the 1700 // m's signal stack, and then the call to needm on the next callback 1701 // from this thread. It is tempting to try to save the m for next time, 1702 // which would eliminate both these costs, but there might not be 1703 // a next time: the current thread (which Go does not control) might exit. 1704 // If we saved the m for that thread, there would be an m leak each time 1705 // such a thread exited. Instead, we acquire and release an m on each 1706 // call. These should typically not be scheduling operations, just a few 1707 // atomics, so the cost should be small. 1708 // 1709 // TODO(rsc): An alternative would be to allocate a dummy pthread per-thread 1710 // variable using pthread_key_create. Unlike the pthread keys we already use 1711 // on OS X, this dummy key would never be read by Go code. It would exist 1712 // only so that we could register at thread-exit-time destructor. 1713 // That destructor would put the m back onto the extra list. 1714 // This is purely a performance optimization. The current version, 1715 // in which dropm happens on each cgo call, is still correct too. 1716 // We may have to keep the current version on systems with cgo 1717 // but without pthreads, like Windows. 1718 func dropm() { 1719 // Clear m and g, and return m to the extra list. 1720 // After the call to setg we can only call nosplit functions 1721 // with no pointer manipulation. 1722 mp := getg().m 1723 1724 // Return mp.curg to dead state. 1725 casgstatus(mp.curg, _Gsyscall, _Gdead) 1726 atomic.Xadd(&sched.ngsys, +1) 1727 1728 // Block signals before unminit. 1729 // Unminit unregisters the signal handling stack (but needs g on some systems). 1730 // Setg(nil) clears g, which is the signal handler's cue not to run Go handlers. 1731 // It's important not to try to handle a signal between those two steps. 1732 sigmask := mp.sigmask 1733 sigblock() 1734 unminit() 1735 1736 mnext := lockextra(true) 1737 extraMCount++ 1738 mp.schedlink.set(mnext) 1739 1740 setg(nil) 1741 1742 // Commit the release of mp. 1743 unlockextra(mp) 1744 1745 msigrestore(sigmask) 1746 } 1747 1748 // A helper function for EnsureDropM. 1749 func getm() uintptr { 1750 return uintptr(unsafe.Pointer(getg().m)) 1751 } 1752 1753 var extram uintptr 1754 var extraMCount uint32 // Protected by lockextra 1755 var extraMWaiters uint32 1756 1757 // lockextra locks the extra list and returns the list head. 1758 // The caller must unlock the list by storing a new list head 1759 // to extram. If nilokay is true, then lockextra will 1760 // return a nil list head if that's what it finds. If nilokay is false, 1761 // lockextra will keep waiting until the list head is no longer nil. 1762 //go:nosplit 1763 func lockextra(nilokay bool) *m { 1764 const locked = 1 1765 1766 incr := false 1767 for { 1768 old := atomic.Loaduintptr(&extram) 1769 if old == locked { 1770 yield := osyield 1771 yield() 1772 continue 1773 } 1774 if old == 0 && !nilokay { 1775 if !incr { 1776 // Add 1 to the number of threads 1777 // waiting for an M. 1778 // This is cleared by newextram. 1779 atomic.Xadd(&extraMWaiters, 1) 1780 incr = true 1781 } 1782 usleep(1) 1783 continue 1784 } 1785 if atomic.Casuintptr(&extram, old, locked) { 1786 return (*m)(unsafe.Pointer(old)) 1787 } 1788 yield := osyield 1789 yield() 1790 continue 1791 } 1792 } 1793 1794 //go:nosplit 1795 func unlockextra(mp *m) { 1796 atomic.Storeuintptr(&extram, uintptr(unsafe.Pointer(mp))) 1797 } 1798 1799 // execLock serializes exec and clone to avoid bugs or unspecified behaviour 1800 // around exec'ing while creating/destroying threads. See issue #19546. 1801 var execLock rwmutex 1802 1803 // newmHandoff contains a list of m structures that need new OS threads. 1804 // This is used by newm in situations where newm itself can't safely 1805 // start an OS thread. 1806 var newmHandoff struct { 1807 lock mutex 1808 1809 // newm points to a list of M structures that need new OS 1810 // threads. The list is linked through m.schedlink. 1811 newm muintptr 1812 1813 // waiting indicates that wake needs to be notified when an m 1814 // is put on the list. 1815 waiting bool 1816 wake note 1817 1818 // haveTemplateThread indicates that the templateThread has 1819 // been started. This is not protected by lock. Use cas to set 1820 // to 1. 1821 haveTemplateThread uint32 1822 } 1823 1824 // Create a new m. It will start off with a call to fn, or else the scheduler. 1825 // fn needs to be static and not a heap allocated closure. 1826 // May run with m.p==nil, so write barriers are not allowed. 1827 //go:nowritebarrierrec 1828 func newm(fn func(), _p_ *p) { 1829 mp := allocm(_p_, fn) 1830 mp.nextp.set(_p_) 1831 mp.sigmask = initSigmask 1832 if gp := getg(); gp != nil && gp.m != nil && (gp.m.lockedExt != 0 || gp.m.incgo) && GOOS != "plan9" { 1833 // We're on a locked M or a thread that may have been 1834 // started by C. The kernel state of this thread may 1835 // be strange (the user may have locked it for that 1836 // purpose). We don't want to clone that into another 1837 // thread. Instead, ask a known-good thread to create 1838 // the thread for us. 1839 // 1840 // This is disabled on Plan 9. See golang.org/issue/22227. 1841 // 1842 // TODO: This may be unnecessary on Windows, which 1843 // doesn't model thread creation off fork. 1844 lock(&newmHandoff.lock) 1845 if newmHandoff.haveTemplateThread == 0 { 1846 throw("on a locked thread with no template thread") 1847 } 1848 mp.schedlink = newmHandoff.newm 1849 newmHandoff.newm.set(mp) 1850 if newmHandoff.waiting { 1851 newmHandoff.waiting = false 1852 notewakeup(&newmHandoff.wake) 1853 } 1854 unlock(&newmHandoff.lock) 1855 return 1856 } 1857 newm1(mp) 1858 } 1859 1860 func newm1(mp *m) { 1861 if iscgo { 1862 var ts cgothreadstart 1863 if _cgo_thread_start == nil { 1864 throw("_cgo_thread_start missing") 1865 } 1866 ts.g.set(mp.g0) 1867 ts.tls = (*uint64)(unsafe.Pointer(&mp.tls[0])) 1868 ts.fn = unsafe.Pointer(funcPC(mstart)) 1869 if msanenabled { 1870 msanwrite(unsafe.Pointer(&ts), unsafe.Sizeof(ts)) 1871 } 1872 execLock.rlock() // Prevent process clone. 1873 asmcgocall(_cgo_thread_start, unsafe.Pointer(&ts)) 1874 execLock.runlock() 1875 return 1876 } 1877 execLock.rlock() // Prevent process clone. 1878 newosproc(mp, unsafe.Pointer(mp.g0.stack.hi)) 1879 execLock.runlock() 1880 } 1881 1882 // startTemplateThread starts the template thread if it is not already 1883 // running. 1884 // 1885 // The calling thread must itself be in a known-good state. 1886 func startTemplateThread() { 1887 if !atomic.Cas(&newmHandoff.haveTemplateThread, 0, 1) { 1888 return 1889 } 1890 newm(templateThread, nil) 1891 } 1892 1893 // tmeplateThread is a thread in a known-good state that exists solely 1894 // to start new threads in known-good states when the calling thread 1895 // may not be a a good state. 1896 // 1897 // Many programs never need this, so templateThread is started lazily 1898 // when we first enter a state that might lead to running on a thread 1899 // in an unknown state. 1900 // 1901 // templateThread runs on an M without a P, so it must not have write 1902 // barriers. 1903 // 1904 //go:nowritebarrierrec 1905 func templateThread() { 1906 lock(&sched.lock) 1907 sched.nmsys++ 1908 checkdead() 1909 unlock(&sched.lock) 1910 1911 for { 1912 lock(&newmHandoff.lock) 1913 for newmHandoff.newm != 0 { 1914 newm := newmHandoff.newm.ptr() 1915 newmHandoff.newm = 0 1916 unlock(&newmHandoff.lock) 1917 for newm != nil { 1918 next := newm.schedlink.ptr() 1919 newm.schedlink = 0 1920 newm1(newm) 1921 newm = next 1922 } 1923 lock(&newmHandoff.lock) 1924 } 1925 newmHandoff.waiting = true 1926 noteclear(&newmHandoff.wake) 1927 unlock(&newmHandoff.lock) 1928 notesleep(&newmHandoff.wake) 1929 } 1930 } 1931 1932 // Stops execution of the current m until new work is available. 1933 // Returns with acquired P. 1934 func stopm() { 1935 _g_ := getg() 1936 1937 if _g_.m.locks != 0 { 1938 throw("stopm holding locks") 1939 } 1940 if _g_.m.p != 0 { 1941 throw("stopm holding p") 1942 } 1943 if _g_.m.spinning { 1944 throw("stopm spinning") 1945 } 1946 1947 retry: 1948 lock(&sched.lock) 1949 mput(_g_.m) 1950 unlock(&sched.lock) 1951 notesleep(&_g_.m.park) 1952 noteclear(&_g_.m.park) 1953 if _g_.m.helpgc != 0 { 1954 // helpgc() set _g_.m.p and _g_.m.mcache, so we have a P. 1955 gchelper() 1956 // Undo the effects of helpgc(). 1957 _g_.m.helpgc = 0 1958 _g_.m.mcache = nil 1959 _g_.m.p = 0 1960 goto retry 1961 } 1962 acquirep(_g_.m.nextp.ptr()) 1963 _g_.m.nextp = 0 1964 } 1965 1966 func mspinning() { 1967 // startm's caller incremented nmspinning. Set the new M's spinning. 1968 getg().m.spinning = true 1969 } 1970 1971 // Schedules some M to run the p (creates an M if necessary). 1972 // If p==nil, tries to get an idle P, if no idle P's does nothing. 1973 // May run with m.p==nil, so write barriers are not allowed. 1974 // If spinning is set, the caller has incremented nmspinning and startm will 1975 // either decrement nmspinning or set m.spinning in the newly started M. 1976 //go:nowritebarrierrec 1977 func startm(_p_ *p, spinning bool) { 1978 lock(&sched.lock) 1979 if _p_ == nil { 1980 _p_ = pidleget() 1981 if _p_ == nil { 1982 unlock(&sched.lock) 1983 if spinning { 1984 // The caller incremented nmspinning, but there are no idle Ps, 1985 // so it's okay to just undo the increment and give up. 1986 if int32(atomic.Xadd(&sched.nmspinning, -1)) < 0 { 1987 throw("startm: negative nmspinning") 1988 } 1989 } 1990 return 1991 } 1992 } 1993 mp := mget() 1994 unlock(&sched.lock) 1995 if mp == nil { 1996 var fn func() 1997 if spinning { 1998 // The caller incremented nmspinning, so set m.spinning in the new M. 1999 fn = mspinning 2000 } 2001 newm(fn, _p_) 2002 return 2003 } 2004 if mp.spinning { 2005 throw("startm: m is spinning") 2006 } 2007 if mp.nextp != 0 { 2008 throw("startm: m has p") 2009 } 2010 if spinning && !runqempty(_p_) { 2011 throw("startm: p has runnable gs") 2012 } 2013 // The caller incremented nmspinning, so set m.spinning in the new M. 2014 mp.spinning = spinning 2015 mp.nextp.set(_p_) 2016 notewakeup(&mp.park) 2017 } 2018 2019 // Hands off P from syscall or locked M. 2020 // Always runs without a P, so write barriers are not allowed. 2021 //go:nowritebarrierrec 2022 func handoffp(_p_ *p) { 2023 // handoffp must start an M in any situation where 2024 // findrunnable would return a G to run on _p_. 2025 2026 // if it has local work, start it straight away 2027 if !runqempty(_p_) || sched.runqsize != 0 { 2028 startm(_p_, false) 2029 return 2030 } 2031 // if it has GC work, start it straight away 2032 if gcBlackenEnabled != 0 && gcMarkWorkAvailable(_p_) { 2033 startm(_p_, false) 2034 return 2035 } 2036 // no local work, check that there are no spinning/idle M's, 2037 // otherwise our help is not required 2038 if atomic.Load(&sched.nmspinning)+atomic.Load(&sched.npidle) == 0 && atomic.Cas(&sched.nmspinning, 0, 1) { // TODO: fast atomic 2039 startm(_p_, true) 2040 return 2041 } 2042 lock(&sched.lock) 2043 if sched.gcwaiting != 0 { 2044 _p_.status = _Pgcstop 2045 sched.stopwait-- 2046 if sched.stopwait == 0 { 2047 notewakeup(&sched.stopnote) 2048 } 2049 unlock(&sched.lock) 2050 return 2051 } 2052 if _p_.runSafePointFn != 0 && atomic.Cas(&_p_.runSafePointFn, 1, 0) { 2053 sched.safePointFn(_p_) 2054 sched.safePointWait-- 2055 if sched.safePointWait == 0 { 2056 notewakeup(&sched.safePointNote) 2057 } 2058 } 2059 if sched.runqsize != 0 { 2060 unlock(&sched.lock) 2061 startm(_p_, false) 2062 return 2063 } 2064 // If this is the last running P and nobody is polling network, 2065 // need to wakeup another M to poll network. 2066 if sched.npidle == uint32(gomaxprocs-1) && atomic.Load64(&sched.lastpoll) != 0 { 2067 unlock(&sched.lock) 2068 startm(_p_, false) 2069 return 2070 } 2071 pidleput(_p_) 2072 unlock(&sched.lock) 2073 } 2074 2075 // Tries to add one more P to execute G's. 2076 // Called when a G is made runnable (newproc, ready). 2077 func wakep() { 2078 // be conservative about spinning threads 2079 if !atomic.Cas(&sched.nmspinning, 0, 1) { 2080 return 2081 } 2082 startm(nil, true) 2083 } 2084 2085 // Stops execution of the current m that is locked to a g until the g is runnable again. 2086 // Returns with acquired P. 2087 func stoplockedm() { 2088 _g_ := getg() 2089 2090 if _g_.m.lockedg == 0 || _g_.m.lockedg.ptr().lockedm.ptr() != _g_.m { 2091 throw("stoplockedm: inconsistent locking") 2092 } 2093 if _g_.m.p != 0 { 2094 // Schedule another M to run this p. 2095 _p_ := releasep() 2096 handoffp(_p_) 2097 } 2098 incidlelocked(1) 2099 // Wait until another thread schedules lockedg again. 2100 notesleep(&_g_.m.park) 2101 noteclear(&_g_.m.park) 2102 status := readgstatus(_g_.m.lockedg.ptr()) 2103 if status&^_Gscan != _Grunnable { 2104 print("runtime:stoplockedm: g is not Grunnable or Gscanrunnable\n") 2105 dumpgstatus(_g_) 2106 throw("stoplockedm: not runnable") 2107 } 2108 acquirep(_g_.m.nextp.ptr()) 2109 _g_.m.nextp = 0 2110 } 2111 2112 // Schedules the locked m to run the locked gp. 2113 // May run during STW, so write barriers are not allowed. 2114 //go:nowritebarrierrec 2115 func startlockedm(gp *g) { 2116 _g_ := getg() 2117 2118 mp := gp.lockedm.ptr() 2119 if mp == _g_.m { 2120 throw("startlockedm: locked to me") 2121 } 2122 if mp.nextp != 0 { 2123 throw("startlockedm: m has p") 2124 } 2125 // directly handoff current P to the locked m 2126 incidlelocked(-1) 2127 _p_ := releasep() 2128 mp.nextp.set(_p_) 2129 notewakeup(&mp.park) 2130 stopm() 2131 } 2132 2133 // Stops the current m for stopTheWorld. 2134 // Returns when the world is restarted. 2135 func gcstopm() { 2136 _g_ := getg() 2137 2138 if sched.gcwaiting == 0 { 2139 throw("gcstopm: not waiting for gc") 2140 } 2141 if _g_.m.spinning { 2142 _g_.m.spinning = false 2143 // OK to just drop nmspinning here, 2144 // startTheWorld will unpark threads as necessary. 2145 if int32(atomic.Xadd(&sched.nmspinning, -1)) < 0 { 2146 throw("gcstopm: negative nmspinning") 2147 } 2148 } 2149 _p_ := releasep() 2150 lock(&sched.lock) 2151 _p_.status = _Pgcstop 2152 sched.stopwait-- 2153 if sched.stopwait == 0 { 2154 notewakeup(&sched.stopnote) 2155 } 2156 unlock(&sched.lock) 2157 stopm() 2158 } 2159 2160 // Schedules gp to run on the current M. 2161 // If inheritTime is true, gp inherits the remaining time in the 2162 // current time slice. Otherwise, it starts a new time slice. 2163 // Never returns. 2164 // 2165 // Write barriers are allowed because this is called immediately after 2166 // acquiring a P in several places. 2167 // 2168 //go:yeswritebarrierrec 2169 func execute(gp *g, inheritTime bool) { 2170 _g_ := getg() 2171 2172 casgstatus(gp, _Grunnable, _Grunning) 2173 gp.waitsince = 0 2174 gp.preempt = false 2175 gp.stackguard0 = gp.stack.lo + _StackGuard 2176 if !inheritTime { 2177 _g_.m.p.ptr().schedtick++ 2178 } 2179 _g_.m.curg = gp 2180 gp.m = _g_.m 2181 2182 // Check whether the profiler needs to be turned on or off. 2183 hz := sched.profilehz 2184 if _g_.m.profilehz != hz { 2185 setThreadCPUProfiler(hz) 2186 } 2187 2188 if trace.enabled { 2189 // GoSysExit has to happen when we have a P, but before GoStart. 2190 // So we emit it here. 2191 if gp.syscallsp != 0 && gp.sysblocktraced { 2192 traceGoSysExit(gp.sysexitticks) 2193 } 2194 traceGoStart() 2195 } 2196 2197 gogo(&gp.sched) 2198 } 2199 2200 // Finds a runnable goroutine to execute. 2201 // Tries to steal from other P's, get g from global queue, poll network. 2202 func findrunnable() (gp *g, inheritTime bool) { 2203 _g_ := getg() 2204 2205 // The conditions here and in handoffp must agree: if 2206 // findrunnable would return a G to run, handoffp must start 2207 // an M. 2208 2209 top: 2210 _p_ := _g_.m.p.ptr() 2211 if sched.gcwaiting != 0 { 2212 gcstopm() 2213 goto top 2214 } 2215 if _p_.runSafePointFn != 0 { 2216 runSafePointFn() 2217 } 2218 if fingwait && fingwake { 2219 if gp := wakefing(); gp != nil { 2220 ready(gp, 0, true) 2221 } 2222 } 2223 if *cgo_yield != nil { 2224 asmcgocall(*cgo_yield, nil) 2225 } 2226 2227 // local runq 2228 if gp, inheritTime := runqget(_p_); gp != nil { 2229 return gp, inheritTime 2230 } 2231 2232 // global runq 2233 if sched.runqsize != 0 { 2234 lock(&sched.lock) 2235 gp := globrunqget(_p_, 0) 2236 unlock(&sched.lock) 2237 if gp != nil { 2238 return gp, false 2239 } 2240 } 2241 2242 // Poll network. 2243 // This netpoll is only an optimization before we resort to stealing. 2244 // We can safely skip it if there a thread blocked in netpoll already. 2245 // If there is any kind of logical race with that blocked thread 2246 // (e.g. it has already returned from netpoll, but does not set lastpoll yet), 2247 // this thread will do blocking netpoll below anyway. 2248 if netpollinited() && sched.lastpoll != 0 { 2249 if gp := netpoll(false); gp != nil { // non-blocking 2250 // netpoll returns list of goroutines linked by schedlink. 2251 injectglist(gp.schedlink.ptr()) 2252 casgstatus(gp, _Gwaiting, _Grunnable) 2253 if trace.enabled { 2254 traceGoUnpark(gp, 0) 2255 } 2256 return gp, false 2257 } 2258 } 2259 2260 // Steal work from other P's. 2261 procs := uint32(gomaxprocs) 2262 if atomic.Load(&sched.npidle) == procs-1 { 2263 // Either GOMAXPROCS=1 or everybody, except for us, is idle already. 2264 // New work can appear from returning syscall/cgocall, network or timers. 2265 // Neither of that submits to local run queues, so no point in stealing. 2266 goto stop 2267 } 2268 // If number of spinning M's >= number of busy P's, block. 2269 // This is necessary to prevent excessive CPU consumption 2270 // when GOMAXPROCS>>1 but the program parallelism is low. 2271 if !_g_.m.spinning && 2*atomic.Load(&sched.nmspinning) >= procs-atomic.Load(&sched.npidle) { 2272 goto stop 2273 } 2274 if !_g_.m.spinning { 2275 _g_.m.spinning = true 2276 atomic.Xadd(&sched.nmspinning, 1) 2277 } 2278 for i := 0; i < 4; i++ { 2279 for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() { 2280 if sched.gcwaiting != 0 { 2281 goto top 2282 } 2283 stealRunNextG := i > 2 // first look for ready queues with more than 1 g 2284 if gp := runqsteal(_p_, allp[enum.position()], stealRunNextG); gp != nil { 2285 return gp, false 2286 } 2287 } 2288 } 2289 2290 stop: 2291 2292 // We have nothing to do. If we're in the GC mark phase, can 2293 // safely scan and blacken objects, and have work to do, run 2294 // idle-time marking rather than give up the P. 2295 if gcBlackenEnabled != 0 && _p_.gcBgMarkWorker != 0 && gcMarkWorkAvailable(_p_) { 2296 _p_.gcMarkWorkerMode = gcMarkWorkerIdleMode 2297 gp := _p_.gcBgMarkWorker.ptr() 2298 casgstatus(gp, _Gwaiting, _Grunnable) 2299 if trace.enabled { 2300 traceGoUnpark(gp, 0) 2301 } 2302 return gp, false 2303 } 2304 2305 // return P and block 2306 lock(&sched.lock) 2307 if sched.gcwaiting != 0 || _p_.runSafePointFn != 0 { 2308 unlock(&sched.lock) 2309 goto top 2310 } 2311 if sched.runqsize != 0 { 2312 gp := globrunqget(_p_, 0) 2313 unlock(&sched.lock) 2314 return gp, false 2315 } 2316 if releasep() != _p_ { 2317 throw("findrunnable: wrong p") 2318 } 2319 pidleput(_p_) 2320 unlock(&sched.lock) 2321 2322 // Delicate dance: thread transitions from spinning to non-spinning state, 2323 // potentially concurrently with submission of new goroutines. We must 2324 // drop nmspinning first and then check all per-P queues again (with 2325 // #StoreLoad memory barrier in between). If we do it the other way around, 2326 // another thread can submit a goroutine after we've checked all run queues 2327 // but before we drop nmspinning; as the result nobody will unpark a thread 2328 // to run the goroutine. 2329 // If we discover new work below, we need to restore m.spinning as a signal 2330 // for resetspinning to unpark a new worker thread (because there can be more 2331 // than one starving goroutine). However, if after discovering new work 2332 // we also observe no idle Ps, it is OK to just park the current thread: 2333 // the system is fully loaded so no spinning threads are required. 2334 // Also see "Worker thread parking/unparking" comment at the top of the file. 2335 wasSpinning := _g_.m.spinning 2336 if _g_.m.spinning { 2337 _g_.m.spinning = false 2338 if int32(atomic.Xadd(&sched.nmspinning, -1)) < 0 { 2339 throw("findrunnable: negative nmspinning") 2340 } 2341 } 2342 2343 // check all runqueues once again 2344 for _, _p_ := range allp { 2345 if !runqempty(_p_) { 2346 lock(&sched.lock) 2347 _p_ = pidleget() 2348 unlock(&sched.lock) 2349 if _p_ != nil { 2350 acquirep(_p_) 2351 if wasSpinning { 2352 _g_.m.spinning = true 2353 atomic.Xadd(&sched.nmspinning, 1) 2354 } 2355 goto top 2356 } 2357 break 2358 } 2359 } 2360 2361 // Check for idle-priority GC work again. 2362 if gcBlackenEnabled != 0 && gcMarkWorkAvailable(nil) { 2363 lock(&sched.lock) 2364 _p_ = pidleget() 2365 if _p_ != nil && _p_.gcBgMarkWorker == 0 { 2366 pidleput(_p_) 2367 _p_ = nil 2368 } 2369 unlock(&sched.lock) 2370 if _p_ != nil { 2371 acquirep(_p_) 2372 if wasSpinning { 2373 _g_.m.spinning = true 2374 atomic.Xadd(&sched.nmspinning, 1) 2375 } 2376 // Go back to idle GC check. 2377 goto stop 2378 } 2379 } 2380 2381 // poll network 2382 if netpollinited() && atomic.Load(&netpollWaiters) > 0 && atomic.Xchg64(&sched.lastpoll, 0) != 0 { 2383 if _g_.m.p != 0 { 2384 throw("findrunnable: netpoll with p") 2385 } 2386 if _g_.m.spinning { 2387 throw("findrunnable: netpoll with spinning") 2388 } 2389 gp := netpoll(true) // block until new work is available 2390 atomic.Store64(&sched.lastpoll, uint64(nanotime())) 2391 if gp != nil { 2392 lock(&sched.lock) 2393 _p_ = pidleget() 2394 unlock(&sched.lock) 2395 if _p_ != nil { 2396 acquirep(_p_) 2397 injectglist(gp.schedlink.ptr()) 2398 casgstatus(gp, _Gwaiting, _Grunnable) 2399 if trace.enabled { 2400 traceGoUnpark(gp, 0) 2401 } 2402 return gp, false 2403 } 2404 injectglist(gp) 2405 } 2406 } 2407 stopm() 2408 goto top 2409 } 2410 2411 // pollWork returns true if there is non-background work this P could 2412 // be doing. This is a fairly lightweight check to be used for 2413 // background work loops, like idle GC. It checks a subset of the 2414 // conditions checked by the actual scheduler. 2415 func pollWork() bool { 2416 if sched.runqsize != 0 { 2417 return true 2418 } 2419 p := getg().m.p.ptr() 2420 if !runqempty(p) { 2421 return true 2422 } 2423 if netpollinited() && atomic.Load(&netpollWaiters) > 0 && sched.lastpoll != 0 { 2424 if gp := netpoll(false); gp != nil { 2425 injectglist(gp) 2426 return true 2427 } 2428 } 2429 return false 2430 } 2431 2432 func resetspinning() { 2433 _g_ := getg() 2434 if !_g_.m.spinning { 2435 throw("resetspinning: not a spinning m") 2436 } 2437 _g_.m.spinning = false 2438 nmspinning := atomic.Xadd(&sched.nmspinning, -1) 2439 if int32(nmspinning) < 0 { 2440 throw("findrunnable: negative nmspinning") 2441 } 2442 // M wakeup policy is deliberately somewhat conservative, so check if we 2443 // need to wakeup another P here. See "Worker thread parking/unparking" 2444 // comment at the top of the file for details. 2445 if nmspinning == 0 && atomic.Load(&sched.npidle) > 0 { 2446 wakep() 2447 } 2448 } 2449 2450 // Injects the list of runnable G's into the scheduler. 2451 // Can run concurrently with GC. 2452 func injectglist(glist *g) { 2453 if glist == nil { 2454 return 2455 } 2456 if trace.enabled { 2457 for gp := glist; gp != nil; gp = gp.schedlink.ptr() { 2458 traceGoUnpark(gp, 0) 2459 } 2460 } 2461 lock(&sched.lock) 2462 var n int 2463 for n = 0; glist != nil; n++ { 2464 gp := glist 2465 glist = gp.schedlink.ptr() 2466 casgstatus(gp, _Gwaiting, _Grunnable) 2467 globrunqput(gp) 2468 } 2469 unlock(&sched.lock) 2470 for ; n != 0 && sched.npidle != 0; n-- { 2471 startm(nil, false) 2472 } 2473 } 2474 2475 // One round of scheduler: find a runnable goroutine and execute it. 2476 // Never returns. 2477 func schedule() { 2478 _g_ := getg() 2479 2480 if _g_.m.locks != 0 { 2481 throw("schedule: holding locks") 2482 } 2483 2484 if _g_.m.lockedg != 0 { 2485 stoplockedm() 2486 execute(_g_.m.lockedg.ptr(), false) // Never returns. 2487 } 2488 2489 // We should not schedule away from a g that is executing a cgo call, 2490 // since the cgo call is using the m's g0 stack. 2491 if _g_.m.incgo { 2492 throw("schedule: in cgo") 2493 } 2494 2495 top: 2496 if sched.gcwaiting != 0 { 2497 gcstopm() 2498 goto top 2499 } 2500 if _g_.m.p.ptr().runSafePointFn != 0 { 2501 runSafePointFn() 2502 } 2503 2504 var gp *g 2505 var inheritTime bool 2506 if trace.enabled || trace.shutdown { 2507 gp = traceReader() 2508 if gp != nil { 2509 casgstatus(gp, _Gwaiting, _Grunnable) 2510 traceGoUnpark(gp, 0) 2511 } 2512 } 2513 if gp == nil && gcBlackenEnabled != 0 { 2514 gp = gcController.findRunnableGCWorker(_g_.m.p.ptr()) 2515 } 2516 if gp == nil { 2517 // Check the global runnable queue once in a while to ensure fairness. 2518 // Otherwise two goroutines can completely occupy the local runqueue 2519 // by constantly respawning each other. 2520 if _g_.m.p.ptr().schedtick%61 == 0 && sched.runqsize > 0 { 2521 lock(&sched.lock) 2522 gp = globrunqget(_g_.m.p.ptr(), 1) 2523 unlock(&sched.lock) 2524 } 2525 } 2526 if gp == nil { 2527 gp, inheritTime = runqget(_g_.m.p.ptr()) 2528 if gp != nil && _g_.m.spinning { 2529 throw("schedule: spinning with local work") 2530 } 2531 } 2532 if gp == nil { 2533 gp, inheritTime = findrunnable() // blocks until work is available 2534 } 2535 2536 // This thread is going to run a goroutine and is not spinning anymore, 2537 // so if it was marked as spinning we need to reset it now and potentially 2538 // start a new spinning M. 2539 if _g_.m.spinning { 2540 resetspinning() 2541 } 2542 2543 if gp.lockedm != 0 { 2544 // Hands off own p to the locked m, 2545 // then blocks waiting for a new p. 2546 startlockedm(gp) 2547 goto top 2548 } 2549 2550 execute(gp, inheritTime) 2551 } 2552 2553 // dropg removes the association between m and the current goroutine m->curg (gp for short). 2554 // Typically a caller sets gp's status away from Grunning and then 2555 // immediately calls dropg to finish the job. The caller is also responsible 2556 // for arranging that gp will be restarted using ready at an 2557 // appropriate time. After calling dropg and arranging for gp to be 2558 // readied later, the caller can do other work but eventually should 2559 // call schedule to restart the scheduling of goroutines on this m. 2560 func dropg() { 2561 _g_ := getg() 2562 2563 setMNoWB(&_g_.m.curg.m, nil) 2564 setGNoWB(&_g_.m.curg, nil) 2565 } 2566 2567 func parkunlock_c(gp *g, lock unsafe.Pointer) bool { 2568 unlock((*mutex)(lock)) 2569 return true 2570 } 2571 2572 // park continuation on g0. 2573 func park_m(gp *g) { 2574 _g_ := getg() 2575 2576 if trace.enabled { 2577 traceGoPark(_g_.m.waittraceev, _g_.m.waittraceskip) 2578 } 2579 2580 casgstatus(gp, _Grunning, _Gwaiting) 2581 dropg() 2582 2583 if _g_.m.waitunlockf != nil { 2584 fn := *(*func(*g, unsafe.Pointer) bool)(unsafe.Pointer(&_g_.m.waitunlockf)) 2585 ok := fn(gp, _g_.m.waitlock) 2586 _g_.m.waitunlockf = nil 2587 _g_.m.waitlock = nil 2588 if !ok { 2589 if trace.enabled { 2590 traceGoUnpark(gp, 2) 2591 } 2592 casgstatus(gp, _Gwaiting, _Grunnable) 2593 execute(gp, true) // Schedule it back, never returns. 2594 } 2595 } 2596 schedule() 2597 } 2598 2599 func goschedImpl(gp *g) { 2600 status := readgstatus(gp) 2601 if status&^_Gscan != _Grunning { 2602 dumpgstatus(gp) 2603 throw("bad g status") 2604 } 2605 casgstatus(gp, _Grunning, _Grunnable) 2606 dropg() 2607 lock(&sched.lock) 2608 globrunqput(gp) 2609 unlock(&sched.lock) 2610 2611 schedule() 2612 } 2613 2614 // Gosched continuation on g0. 2615 func gosched_m(gp *g) { 2616 if trace.enabled { 2617 traceGoSched() 2618 } 2619 goschedImpl(gp) 2620 } 2621 2622 // goschedguarded is a forbidden-states-avoided version of gosched_m 2623 func goschedguarded_m(gp *g) { 2624 2625 if gp.m.locks != 0 || gp.m.mallocing != 0 || gp.m.preemptoff != "" || gp.m.p.ptr().status != _Prunning { 2626 gogo(&gp.sched) // never return 2627 } 2628 2629 if trace.enabled { 2630 traceGoSched() 2631 } 2632 goschedImpl(gp) 2633 } 2634 2635 func gopreempt_m(gp *g) { 2636 if trace.enabled { 2637 traceGoPreempt() 2638 } 2639 goschedImpl(gp) 2640 } 2641 2642 // Finishes execution of the current goroutine. 2643 func goexit1() { 2644 if raceenabled { 2645 racegoend() 2646 } 2647 if trace.enabled { 2648 traceGoEnd() 2649 } 2650 mcall(goexit0) 2651 } 2652 2653 // goexit continuation on g0. 2654 func goexit0(gp *g) { 2655 _g_ := getg() 2656 2657 casgstatus(gp, _Grunning, _Gdead) 2658 if isSystemGoroutine(gp) { 2659 atomic.Xadd(&sched.ngsys, -1) 2660 } 2661 gp.m = nil 2662 locked := gp.lockedm != 0 2663 gp.lockedm = 0 2664 _g_.m.lockedg = 0 2665 gp.paniconfault = false 2666 gp._defer = nil // should be true already but just in case. 2667 gp._panic = nil // non-nil for Goexit during panic. points at stack-allocated data. 2668 gp.writebuf = nil 2669 gp.waitreason = "" 2670 gp.param = nil 2671 gp.labels = nil 2672 gp.timer = nil 2673 2674 if gcBlackenEnabled != 0 && gp.gcAssistBytes > 0 { 2675 // Flush assist credit to the global pool. This gives 2676 // better information to pacing if the application is 2677 // rapidly creating an exiting goroutines. 2678 scanCredit := int64(gcController.assistWorkPerByte * float64(gp.gcAssistBytes)) 2679 atomic.Xaddint64(&gcController.bgScanCredit, scanCredit) 2680 gp.gcAssistBytes = 0 2681 } 2682 2683 // Note that gp's stack scan is now "valid" because it has no 2684 // stack. 2685 gp.gcscanvalid = true 2686 dropg() 2687 2688 if _g_.m.lockedInt != 0 { 2689 print("invalid m->lockedInt = ", _g_.m.lockedInt, "\n") 2690 throw("internal lockOSThread error") 2691 } 2692 _g_.m.lockedExt = 0 2693 gfput(_g_.m.p.ptr(), gp) 2694 if locked { 2695 // The goroutine may have locked this thread because 2696 // it put it in an unusual kernel state. Kill it 2697 // rather than returning it to the thread pool. 2698 2699 // Return to mstart, which will release the P and exit 2700 // the thread. 2701 if GOOS != "plan9" { // See golang.org/issue/22227. 2702 gogo(&_g_.m.g0.sched) 2703 } 2704 } 2705 schedule() 2706 } 2707 2708 // save updates getg().sched to refer to pc and sp so that a following 2709 // gogo will restore pc and sp. 2710 // 2711 // save must not have write barriers because invoking a write barrier 2712 // can clobber getg().sched. 2713 // 2714 //go:nosplit 2715 //go:nowritebarrierrec 2716 func save(pc, sp uintptr) { 2717 _g_ := getg() 2718 2719 _g_.sched.pc = pc 2720 _g_.sched.sp = sp 2721 _g_.sched.lr = 0 2722 _g_.sched.ret = 0 2723 _g_.sched.g = guintptr(unsafe.Pointer(_g_)) 2724 // We need to ensure ctxt is zero, but can't have a write 2725 // barrier here. However, it should always already be zero. 2726 // Assert that. 2727 if _g_.sched.ctxt != nil { 2728 badctxt() 2729 } 2730 } 2731 2732 // The goroutine g is about to enter a system call. 2733 // Record that it's not using the cpu anymore. 2734 // This is called only from the go syscall library and cgocall, 2735 // not from the low-level system calls used by the runtime. 2736 // 2737 // Entersyscall cannot split the stack: the gosave must 2738 // make g->sched refer to the caller's stack segment, because 2739 // entersyscall is going to return immediately after. 2740 // 2741 // Nothing entersyscall calls can split the stack either. 2742 // We cannot safely move the stack during an active call to syscall, 2743 // because we do not know which of the uintptr arguments are 2744 // really pointers (back into the stack). 2745 // In practice, this means that we make the fast path run through 2746 // entersyscall doing no-split things, and the slow path has to use systemstack 2747 // to run bigger things on the system stack. 2748 // 2749 // reentersyscall is the entry point used by cgo callbacks, where explicitly 2750 // saved SP and PC are restored. This is needed when exitsyscall will be called 2751 // from a function further up in the call stack than the parent, as g->syscallsp 2752 // must always point to a valid stack frame. entersyscall below is the normal 2753 // entry point for syscalls, which obtains the SP and PC from the caller. 2754 // 2755 // Syscall tracing: 2756 // At the start of a syscall we emit traceGoSysCall to capture the stack trace. 2757 // If the syscall does not block, that is it, we do not emit any other events. 2758 // If the syscall blocks (that is, P is retaken), retaker emits traceGoSysBlock; 2759 // when syscall returns we emit traceGoSysExit and when the goroutine starts running 2760 // (potentially instantly, if exitsyscallfast returns true) we emit traceGoStart. 2761 // To ensure that traceGoSysExit is emitted strictly after traceGoSysBlock, 2762 // we remember current value of syscalltick in m (_g_.m.syscalltick = _g_.m.p.ptr().syscalltick), 2763 // whoever emits traceGoSysBlock increments p.syscalltick afterwards; 2764 // and we wait for the increment before emitting traceGoSysExit. 2765 // Note that the increment is done even if tracing is not enabled, 2766 // because tracing can be enabled in the middle of syscall. We don't want the wait to hang. 2767 // 2768 //go:nosplit 2769 func reentersyscall(pc, sp uintptr) { 2770 _g_ := getg() 2771 2772 // Disable preemption because during this function g is in Gsyscall status, 2773 // but can have inconsistent g->sched, do not let GC observe it. 2774 _g_.m.locks++ 2775 2776 // Entersyscall must not call any function that might split/grow the stack. 2777 // (See details in comment above.) 2778 // Catch calls that might, by replacing the stack guard with something that 2779 // will trip any stack check and leaving a flag to tell newstack to die. 2780 _g_.stackguard0 = stackPreempt 2781 _g_.throwsplit = true 2782 2783 // Leave SP around for GC and traceback. 2784 save(pc, sp) 2785 _g_.syscallsp = sp 2786 _g_.syscallpc = pc 2787 casgstatus(_g_, _Grunning, _Gsyscall) 2788 if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp { 2789 systemstack(func() { 2790 print("entersyscall inconsistent ", hex(_g_.syscallsp), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n") 2791 throw("entersyscall") 2792 }) 2793 } 2794 2795 if trace.enabled { 2796 systemstack(traceGoSysCall) 2797 // systemstack itself clobbers g.sched.{pc,sp} and we might 2798 // need them later when the G is genuinely blocked in a 2799 // syscall 2800 save(pc, sp) 2801 } 2802 2803 if atomic.Load(&sched.sysmonwait) != 0 { 2804 systemstack(entersyscall_sysmon) 2805 save(pc, sp) 2806 } 2807 2808 if _g_.m.p.ptr().runSafePointFn != 0 { 2809 // runSafePointFn may stack split if run on this stack 2810 systemstack(runSafePointFn) 2811 save(pc, sp) 2812 } 2813 2814 _g_.m.syscalltick = _g_.m.p.ptr().syscalltick 2815 _g_.sysblocktraced = true 2816 _g_.m.mcache = nil 2817 _g_.m.p.ptr().m = 0 2818 atomic.Store(&_g_.m.p.ptr().status, _Psyscall) 2819 if sched.gcwaiting != 0 { 2820 systemstack(entersyscall_gcwait) 2821 save(pc, sp) 2822 } 2823 2824 // Goroutines must not split stacks in Gsyscall status (it would corrupt g->sched). 2825 // We set _StackGuard to StackPreempt so that first split stack check calls morestack. 2826 // Morestack detects this case and throws. 2827 _g_.stackguard0 = stackPreempt 2828 _g_.m.locks-- 2829 } 2830 2831 // Standard syscall entry used by the go syscall library and normal cgo calls. 2832 //go:nosplit 2833 func entersyscall(dummy int32) { 2834 reentersyscall(getcallerpc(), getcallersp(unsafe.Pointer(&dummy))) 2835 } 2836 2837 func entersyscall_sysmon() { 2838 lock(&sched.lock) 2839 if atomic.Load(&sched.sysmonwait) != 0 { 2840 atomic.Store(&sched.sysmonwait, 0) 2841 notewakeup(&sched.sysmonnote) 2842 } 2843 unlock(&sched.lock) 2844 } 2845 2846 func entersyscall_gcwait() { 2847 _g_ := getg() 2848 _p_ := _g_.m.p.ptr() 2849 2850 lock(&sched.lock) 2851 if sched.stopwait > 0 && atomic.Cas(&_p_.status, _Psyscall, _Pgcstop) { 2852 if trace.enabled { 2853 traceGoSysBlock(_p_) 2854 traceProcStop(_p_) 2855 } 2856 _p_.syscalltick++ 2857 if sched.stopwait--; sched.stopwait == 0 { 2858 notewakeup(&sched.stopnote) 2859 } 2860 } 2861 unlock(&sched.lock) 2862 } 2863 2864 // The same as entersyscall(), but with a hint that the syscall is blocking. 2865 //go:nosplit 2866 func entersyscallblock(dummy int32) { 2867 _g_ := getg() 2868 2869 _g_.m.locks++ // see comment in entersyscall 2870 _g_.throwsplit = true 2871 _g_.stackguard0 = stackPreempt // see comment in entersyscall 2872 _g_.m.syscalltick = _g_.m.p.ptr().syscalltick 2873 _g_.sysblocktraced = true 2874 _g_.m.p.ptr().syscalltick++ 2875 2876 // Leave SP around for GC and traceback. 2877 pc := getcallerpc() 2878 sp := getcallersp(unsafe.Pointer(&dummy)) 2879 save(pc, sp) 2880 _g_.syscallsp = _g_.sched.sp 2881 _g_.syscallpc = _g_.sched.pc 2882 if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp { 2883 sp1 := sp 2884 sp2 := _g_.sched.sp 2885 sp3 := _g_.syscallsp 2886 systemstack(func() { 2887 print("entersyscallblock inconsistent ", hex(sp1), " ", hex(sp2), " ", hex(sp3), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n") 2888 throw("entersyscallblock") 2889 }) 2890 } 2891 casgstatus(_g_, _Grunning, _Gsyscall) 2892 if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp { 2893 systemstack(func() { 2894 print("entersyscallblock inconsistent ", hex(sp), " ", hex(_g_.sched.sp), " ", hex(_g_.syscallsp), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n") 2895 throw("entersyscallblock") 2896 }) 2897 } 2898 2899 systemstack(entersyscallblock_handoff) 2900 2901 // Resave for traceback during blocked call. 2902 save(getcallerpc(), getcallersp(unsafe.Pointer(&dummy))) 2903 2904 _g_.m.locks-- 2905 } 2906 2907 func entersyscallblock_handoff() { 2908 if trace.enabled { 2909 traceGoSysCall() 2910 traceGoSysBlock(getg().m.p.ptr()) 2911 } 2912 handoffp(releasep()) 2913 } 2914 2915 // The goroutine g exited its system call. 2916 // Arrange for it to run on a cpu again. 2917 // This is called only from the go syscall library, not 2918 // from the low-level system calls used by the runtime. 2919 // 2920 // Write barriers are not allowed because our P may have been stolen. 2921 // 2922 //go:nosplit 2923 //go:nowritebarrierrec 2924 func exitsyscall(dummy int32) { 2925 _g_ := getg() 2926 2927 _g_.m.locks++ // see comment in entersyscall 2928 if getcallersp(unsafe.Pointer(&dummy)) > _g_.syscallsp { 2929 // throw calls print which may try to grow the stack, 2930 // but throwsplit == true so the stack can not be grown; 2931 // use systemstack to avoid that possible problem. 2932 systemstack(func() { 2933 throw("exitsyscall: syscall frame is no longer valid") 2934 }) 2935 } 2936 2937 _g_.waitsince = 0 2938 oldp := _g_.m.p.ptr() 2939 if exitsyscallfast() { 2940 if _g_.m.mcache == nil { 2941 throw("lost mcache") 2942 } 2943 if trace.enabled { 2944 if oldp != _g_.m.p.ptr() || _g_.m.syscalltick != _g_.m.p.ptr().syscalltick { 2945 systemstack(traceGoStart) 2946 } 2947 } 2948 // There's a cpu for us, so we can run. 2949 _g_.m.p.ptr().syscalltick++ 2950 // We need to cas the status and scan before resuming... 2951 casgstatus(_g_, _Gsyscall, _Grunning) 2952 2953 // Garbage collector isn't running (since we are), 2954 // so okay to clear syscallsp. 2955 _g_.syscallsp = 0 2956 _g_.m.locks-- 2957 if _g_.preempt { 2958 // restore the preemption request in case we've cleared it in newstack 2959 _g_.stackguard0 = stackPreempt 2960 } else { 2961 // otherwise restore the real _StackGuard, we've spoiled it in entersyscall/entersyscallblock 2962 _g_.stackguard0 = _g_.stack.lo + _StackGuard 2963 } 2964 _g_.throwsplit = false 2965 return 2966 } 2967 2968 _g_.sysexitticks = 0 2969 if trace.enabled { 2970 // Wait till traceGoSysBlock event is emitted. 2971 // This ensures consistency of the trace (the goroutine is started after it is blocked). 2972 for oldp != nil && oldp.syscalltick == _g_.m.syscalltick { 2973 osyield() 2974 } 2975 // We can't trace syscall exit right now because we don't have a P. 2976 // Tracing code can invoke write barriers that cannot run without a P. 2977 // So instead we remember the syscall exit time and emit the event 2978 // in execute when we have a P. 2979 _g_.sysexitticks = cputicks() 2980 } 2981 2982 _g_.m.locks-- 2983 2984 // Call the scheduler. 2985 mcall(exitsyscall0) 2986 2987 if _g_.m.mcache == nil { 2988 throw("lost mcache") 2989 } 2990 2991 // Scheduler returned, so we're allowed to run now. 2992 // Delete the syscallsp information that we left for 2993 // the garbage collector during the system call. 2994 // Must wait until now because until gosched returns 2995 // we don't know for sure that the garbage collector 2996 // is not running. 2997 _g_.syscallsp = 0 2998 _g_.m.p.ptr().syscalltick++ 2999 _g_.throwsplit = false 3000 } 3001 3002 //go:nosplit 3003 func exitsyscallfast() bool { 3004 _g_ := getg() 3005 3006 // Freezetheworld sets stopwait but does not retake P's. 3007 if sched.stopwait == freezeStopWait { 3008 _g_.m.mcache = nil 3009 _g_.m.p = 0 3010 return false 3011 } 3012 3013 // Try to re-acquire the last P. 3014 if _g_.m.p != 0 && _g_.m.p.ptr().status == _Psyscall && atomic.Cas(&_g_.m.p.ptr().status, _Psyscall, _Prunning) { 3015 // There's a cpu for us, so we can run. 3016 exitsyscallfast_reacquired() 3017 return true 3018 } 3019 3020 // Try to get any other idle P. 3021 oldp := _g_.m.p.ptr() 3022 _g_.m.mcache = nil 3023 _g_.m.p = 0 3024 if sched.pidle != 0 { 3025 var ok bool 3026 systemstack(func() { 3027 ok = exitsyscallfast_pidle() 3028 if ok && trace.enabled { 3029 if oldp != nil { 3030 // Wait till traceGoSysBlock event is emitted. 3031 // This ensures consistency of the trace (the goroutine is started after it is blocked). 3032 for oldp.syscalltick == _g_.m.syscalltick { 3033 osyield() 3034 } 3035 } 3036 traceGoSysExit(0) 3037 } 3038 }) 3039 if ok { 3040 return true 3041 } 3042 } 3043 return false 3044 } 3045 3046 // exitsyscallfast_reacquired is the exitsyscall path on which this G 3047 // has successfully reacquired the P it was running on before the 3048 // syscall. 3049 // 3050 // This function is allowed to have write barriers because exitsyscall 3051 // has acquired a P at this point. 3052 // 3053 //go:yeswritebarrierrec 3054 //go:nosplit 3055 func exitsyscallfast_reacquired() { 3056 _g_ := getg() 3057 _g_.m.mcache = _g_.m.p.ptr().mcache 3058 _g_.m.p.ptr().m.set(_g_.m) 3059 if _g_.m.syscalltick != _g_.m.p.ptr().syscalltick { 3060 if trace.enabled { 3061 // The p was retaken and then enter into syscall again (since _g_.m.syscalltick has changed). 3062 // traceGoSysBlock for this syscall was already emitted, 3063 // but here we effectively retake the p from the new syscall running on the same p. 3064 systemstack(func() { 3065 // Denote blocking of the new syscall. 3066 traceGoSysBlock(_g_.m.p.ptr()) 3067 // Denote completion of the current syscall. 3068 traceGoSysExit(0) 3069 }) 3070 } 3071 _g_.m.p.ptr().syscalltick++ 3072 } 3073 } 3074 3075 func exitsyscallfast_pidle() bool { 3076 lock(&sched.lock) 3077 _p_ := pidleget() 3078 if _p_ != nil && atomic.Load(&sched.sysmonwait) != 0 { 3079 atomic.Store(&sched.sysmonwait, 0) 3080 notewakeup(&sched.sysmonnote) 3081 } 3082 unlock(&sched.lock) 3083 if _p_ != nil { 3084 acquirep(_p_) 3085 return true 3086 } 3087 return false 3088 } 3089 3090 // exitsyscall slow path on g0. 3091 // Failed to acquire P, enqueue gp as runnable. 3092 // 3093 //go:nowritebarrierrec 3094 func exitsyscall0(gp *g) { 3095 _g_ := getg() 3096 3097 casgstatus(gp, _Gsyscall, _Grunnable) 3098 dropg() 3099 lock(&sched.lock) 3100 _p_ := pidleget() 3101 if _p_ == nil { 3102 globrunqput(gp) 3103 } else if atomic.Load(&sched.sysmonwait) != 0 { 3104 atomic.Store(&sched.sysmonwait, 0) 3105 notewakeup(&sched.sysmonnote) 3106 } 3107 unlock(&sched.lock) 3108 if _p_ != nil { 3109 acquirep(_p_) 3110 execute(gp, false) // Never returns. 3111 } 3112 if _g_.m.lockedg != 0 { 3113 // Wait until another thread schedules gp and so m again. 3114 stoplockedm() 3115 execute(gp, false) // Never returns. 3116 } 3117 stopm() 3118 schedule() // Never returns. 3119 } 3120 3121 func beforefork() { 3122 gp := getg().m.curg 3123 3124 // Block signals during a fork, so that the child does not run 3125 // a signal handler before exec if a signal is sent to the process 3126 // group. See issue #18600. 3127 gp.m.locks++ 3128 msigsave(gp.m) 3129 sigblock() 3130 3131 // This function is called before fork in syscall package. 3132 // Code between fork and exec must not allocate memory nor even try to grow stack. 3133 // Here we spoil g->_StackGuard to reliably detect any attempts to grow stack. 3134 // runtime_AfterFork will undo this in parent process, but not in child. 3135 gp.stackguard0 = stackFork 3136 } 3137 3138 // Called from syscall package before fork. 3139 //go:linkname syscall_runtime_BeforeFork syscall.runtime_BeforeFork 3140 //go:nosplit 3141 func syscall_runtime_BeforeFork() { 3142 systemstack(beforefork) 3143 } 3144 3145 func afterfork() { 3146 gp := getg().m.curg 3147 3148 // See the comments in beforefork. 3149 gp.stackguard0 = gp.stack.lo + _StackGuard 3150 3151 msigrestore(gp.m.sigmask) 3152 3153 gp.m.locks-- 3154 } 3155 3156 // Called from syscall package after fork in parent. 3157 //go:linkname syscall_runtime_AfterFork syscall.runtime_AfterFork 3158 //go:nosplit 3159 func syscall_runtime_AfterFork() { 3160 systemstack(afterfork) 3161 } 3162 3163 // inForkedChild is true while manipulating signals in the child process. 3164 // This is used to avoid calling libc functions in case we are using vfork. 3165 var inForkedChild bool 3166 3167 // Called from syscall package after fork in child. 3168 // It resets non-sigignored signals to the default handler, and 3169 // restores the signal mask in preparation for the exec. 3170 // 3171 // Because this might be called during a vfork, and therefore may be 3172 // temporarily sharing address space with the parent process, this must 3173 // not change any global variables or calling into C code that may do so. 3174 // 3175 //go:linkname syscall_runtime_AfterForkInChild syscall.runtime_AfterForkInChild 3176 //go:nosplit 3177 //go:nowritebarrierrec 3178 func syscall_runtime_AfterForkInChild() { 3179 // It's OK to change the global variable inForkedChild here 3180 // because we are going to change it back. There is no race here, 3181 // because if we are sharing address space with the parent process, 3182 // then the parent process can not be running concurrently. 3183 inForkedChild = true 3184 3185 clearSignalHandlers() 3186 3187 // When we are the child we are the only thread running, 3188 // so we know that nothing else has changed gp.m.sigmask. 3189 msigrestore(getg().m.sigmask) 3190 3191 inForkedChild = false 3192 } 3193 3194 // Called from syscall package before Exec. 3195 //go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec 3196 func syscall_runtime_BeforeExec() { 3197 // Prevent thread creation during exec. 3198 execLock.lock() 3199 } 3200 3201 // Called from syscall package after Exec. 3202 //go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec 3203 func syscall_runtime_AfterExec() { 3204 execLock.unlock() 3205 } 3206 3207 // Allocate a new g, with a stack big enough for stacksize bytes. 3208 func malg(stacksize int32) *g { 3209 newg := new(g) 3210 if stacksize >= 0 { 3211 stacksize = round2(_StackSystem + stacksize) 3212 systemstack(func() { 3213 newg.stack = stackalloc(uint32(stacksize)) 3214 }) 3215 newg.stackguard0 = newg.stack.lo + _StackGuard 3216 newg.stackguard1 = ^uintptr(0) 3217 } 3218 return newg 3219 } 3220 3221 // Create a new g running fn with siz bytes of arguments. 3222 // Put it on the queue of g's waiting to run. 3223 // The compiler turns a go statement into a call to this. 3224 // Cannot split the stack because it assumes that the arguments 3225 // are available sequentially after &fn; they would not be 3226 // copied if a stack split occurred. 3227 //go:nosplit 3228 func newproc(siz int32, fn *funcval) { 3229 argp := add(unsafe.Pointer(&fn), sys.PtrSize) 3230 pc := getcallerpc() 3231 systemstack(func() { 3232 newproc1(fn, (*uint8)(argp), siz, pc) 3233 }) 3234 } 3235 3236 // Create a new g running fn with narg bytes of arguments starting 3237 // at argp. callerpc is the address of the go statement that created 3238 // this. The new g is put on the queue of g's waiting to run. 3239 func newproc1(fn *funcval, argp *uint8, narg int32, callerpc uintptr) { 3240 _g_ := getg() 3241 3242 if fn == nil { 3243 _g_.m.throwing = -1 // do not dump full stacks 3244 throw("go of nil func value") 3245 } 3246 _g_.m.locks++ // disable preemption because it can be holding p in a local var 3247 siz := narg 3248 siz = (siz + 7) &^ 7 3249 3250 // We could allocate a larger initial stack if necessary. 3251 // Not worth it: this is almost always an error. 3252 // 4*sizeof(uintreg): extra space added below 3253 // sizeof(uintreg): caller's LR (arm) or return address (x86, in gostartcall). 3254 if siz >= _StackMin-4*sys.RegSize-sys.RegSize { 3255 throw("newproc: function arguments too large for new goroutine") 3256 } 3257 3258 _p_ := _g_.m.p.ptr() 3259 newg := gfget(_p_) 3260 if newg == nil { 3261 newg = malg(_StackMin) 3262 casgstatus(newg, _Gidle, _Gdead) 3263 allgadd(newg) // publishes with a g->status of Gdead so GC scanner doesn't look at uninitialized stack. 3264 } 3265 if newg.stack.hi == 0 { 3266 throw("newproc1: newg missing stack") 3267 } 3268 3269 if readgstatus(newg) != _Gdead { 3270 throw("newproc1: new g is not Gdead") 3271 } 3272 3273 totalSize := 4*sys.RegSize + uintptr(siz) + sys.MinFrameSize // extra space in case of reads slightly beyond frame 3274 totalSize += -totalSize & (sys.SpAlign - 1) // align to spAlign 3275 sp := newg.stack.hi - totalSize 3276 spArg := sp 3277 if usesLR { 3278 // caller's LR 3279 *(*uintptr)(unsafe.Pointer(sp)) = 0 3280 prepGoExitFrame(sp) 3281 spArg += sys.MinFrameSize 3282 } 3283 if narg > 0 { 3284 memmove(unsafe.Pointer(spArg), unsafe.Pointer(argp), uintptr(narg)) 3285 // This is a stack-to-stack copy. If write barriers 3286 // are enabled and the source stack is grey (the 3287 // destination is always black), then perform a 3288 // barrier copy. We do this *after* the memmove 3289 // because the destination stack may have garbage on 3290 // it. 3291 if writeBarrier.needed && !_g_.m.curg.gcscandone { 3292 f := findfunc(fn.fn) 3293 stkmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps)) 3294 // We're in the prologue, so it's always stack map index 0. 3295 bv := stackmapdata(stkmap, 0) 3296 bulkBarrierBitmap(spArg, spArg, uintptr(narg), 0, bv.bytedata) 3297 } 3298 } 3299 3300 memclrNoHeapPointers(unsafe.Pointer(&newg.sched), unsafe.Sizeof(newg.sched)) 3301 newg.sched.sp = sp 3302 newg.stktopsp = sp 3303 newg.sched.pc = funcPC(goexit) + sys.PCQuantum // +PCQuantum so that previous instruction is in same function 3304 newg.sched.g = guintptr(unsafe.Pointer(newg)) 3305 gostartcallfn(&newg.sched, fn) 3306 newg.gopc = callerpc 3307 newg.startpc = fn.fn 3308 if _g_.m.curg != nil { 3309 newg.labels = _g_.m.curg.labels 3310 } 3311 if isSystemGoroutine(newg) { 3312 atomic.Xadd(&sched.ngsys, +1) 3313 } 3314 newg.gcscanvalid = false 3315 casgstatus(newg, _Gdead, _Grunnable) 3316 3317 if _p_.goidcache == _p_.goidcacheend { 3318 // Sched.goidgen is the last allocated id, 3319 // this batch must be [sched.goidgen+1, sched.goidgen+GoidCacheBatch]. 3320 // At startup sched.goidgen=0, so main goroutine receives goid=1. 3321 _p_.goidcache = atomic.Xadd64(&sched.goidgen, _GoidCacheBatch) 3322 _p_.goidcache -= _GoidCacheBatch - 1 3323 _p_.goidcacheend = _p_.goidcache + _GoidCacheBatch 3324 } 3325 newg.goid = int64(_p_.goidcache) 3326 _p_.goidcache++ 3327 if raceenabled { 3328 newg.racectx = racegostart(callerpc) 3329 } 3330 if trace.enabled { 3331 traceGoCreate(newg, newg.startpc) 3332 } 3333 runqput(_p_, newg, true) 3334 3335 if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 && mainStarted { 3336 wakep() 3337 } 3338 _g_.m.locks-- 3339 if _g_.m.locks == 0 && _g_.preempt { // restore the preemption request in case we've cleared it in newstack 3340 _g_.stackguard0 = stackPreempt 3341 } 3342 } 3343 3344 // Put on gfree list. 3345 // If local list is too long, transfer a batch to the global list. 3346 func gfput(_p_ *p, gp *g) { 3347 if readgstatus(gp) != _Gdead { 3348 throw("gfput: bad status (not Gdead)") 3349 } 3350 3351 stksize := gp.stack.hi - gp.stack.lo 3352 3353 if stksize != _FixedStack { 3354 // non-standard stack size - free it. 3355 stackfree(gp.stack) 3356 gp.stack.lo = 0 3357 gp.stack.hi = 0 3358 gp.stackguard0 = 0 3359 } 3360 3361 gp.schedlink.set(_p_.gfree) 3362 _p_.gfree = gp 3363 _p_.gfreecnt++ 3364 if _p_.gfreecnt >= 64 { 3365 lock(&sched.gflock) 3366 for _p_.gfreecnt >= 32 { 3367 _p_.gfreecnt-- 3368 gp = _p_.gfree 3369 _p_.gfree = gp.schedlink.ptr() 3370 if gp.stack.lo == 0 { 3371 gp.schedlink.set(sched.gfreeNoStack) 3372 sched.gfreeNoStack = gp 3373 } else { 3374 gp.schedlink.set(sched.gfreeStack) 3375 sched.gfreeStack = gp 3376 } 3377 sched.ngfree++ 3378 } 3379 unlock(&sched.gflock) 3380 } 3381 } 3382 3383 // Get from gfree list. 3384 // If local list is empty, grab a batch from global list. 3385 func gfget(_p_ *p) *g { 3386 retry: 3387 gp := _p_.gfree 3388 if gp == nil && (sched.gfreeStack != nil || sched.gfreeNoStack != nil) { 3389 lock(&sched.gflock) 3390 for _p_.gfreecnt < 32 { 3391 if sched.gfreeStack != nil { 3392 // Prefer Gs with stacks. 3393 gp = sched.gfreeStack 3394 sched.gfreeStack = gp.schedlink.ptr() 3395 } else if sched.gfreeNoStack != nil { 3396 gp = sched.gfreeNoStack 3397 sched.gfreeNoStack = gp.schedlink.ptr() 3398 } else { 3399 break 3400 } 3401 _p_.gfreecnt++ 3402 sched.ngfree-- 3403 gp.schedlink.set(_p_.gfree) 3404 _p_.gfree = gp 3405 } 3406 unlock(&sched.gflock) 3407 goto retry 3408 } 3409 if gp != nil { 3410 _p_.gfree = gp.schedlink.ptr() 3411 _p_.gfreecnt-- 3412 if gp.stack.lo == 0 { 3413 // Stack was deallocated in gfput. Allocate a new one. 3414 systemstack(func() { 3415 gp.stack = stackalloc(_FixedStack) 3416 }) 3417 gp.stackguard0 = gp.stack.lo + _StackGuard 3418 } else { 3419 if raceenabled { 3420 racemalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo) 3421 } 3422 if msanenabled { 3423 msanmalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo) 3424 } 3425 } 3426 } 3427 return gp 3428 } 3429 3430 // Purge all cached G's from gfree list to the global list. 3431 func gfpurge(_p_ *p) { 3432 lock(&sched.gflock) 3433 for _p_.gfreecnt != 0 { 3434 _p_.gfreecnt-- 3435 gp := _p_.gfree 3436 _p_.gfree = gp.schedlink.ptr() 3437 if gp.stack.lo == 0 { 3438 gp.schedlink.set(sched.gfreeNoStack) 3439 sched.gfreeNoStack = gp 3440 } else { 3441 gp.schedlink.set(sched.gfreeStack) 3442 sched.gfreeStack = gp 3443 } 3444 sched.ngfree++ 3445 } 3446 unlock(&sched.gflock) 3447 } 3448 3449 // Breakpoint executes a breakpoint trap. 3450 func Breakpoint() { 3451 breakpoint() 3452 } 3453 3454 // dolockOSThread is called by LockOSThread and lockOSThread below 3455 // after they modify m.locked. Do not allow preemption during this call, 3456 // or else the m might be different in this function than in the caller. 3457 //go:nosplit 3458 func dolockOSThread() { 3459 _g_ := getg() 3460 _g_.m.lockedg.set(_g_) 3461 _g_.lockedm.set(_g_.m) 3462 } 3463 3464 //go:nosplit 3465 3466 // LockOSThread wires the calling goroutine to its current operating system thread. 3467 // The calling goroutine will always execute in that thread, 3468 // and no other goroutine will execute in it, 3469 // until the calling goroutine has made as many calls to 3470 // UnlockOSThread as to LockOSThread. 3471 // If the calling goroutine exits without unlocking the thread, 3472 // the thread will be terminated. 3473 // 3474 // A goroutine should call LockOSThread before calling OS services or 3475 // non-Go library functions that depend on per-thread state. 3476 func LockOSThread() { 3477 if atomic.Load(&newmHandoff.haveTemplateThread) == 0 && GOOS != "plan9" { 3478 // If we need to start a new thread from the locked 3479 // thread, we need the template thread. Start it now 3480 // while we're in a known-good state. 3481 startTemplateThread() 3482 } 3483 _g_ := getg() 3484 _g_.m.lockedExt++ 3485 if _g_.m.lockedExt == 0 { 3486 _g_.m.lockedExt-- 3487 panic("LockOSThread nesting overflow") 3488 } 3489 dolockOSThread() 3490 } 3491 3492 //go:nosplit 3493 func lockOSThread() { 3494 getg().m.lockedInt++ 3495 dolockOSThread() 3496 } 3497 3498 // dounlockOSThread is called by UnlockOSThread and unlockOSThread below 3499 // after they update m->locked. Do not allow preemption during this call, 3500 // or else the m might be in different in this function than in the caller. 3501 //go:nosplit 3502 func dounlockOSThread() { 3503 _g_ := getg() 3504 if _g_.m.lockedInt != 0 || _g_.m.lockedExt != 0 { 3505 return 3506 } 3507 _g_.m.lockedg = 0 3508 _g_.lockedm = 0 3509 } 3510 3511 //go:nosplit 3512 3513 // UnlockOSThread undoes an earlier call to LockOSThread. 3514 // If this drops the number of active LockOSThread calls on the 3515 // calling goroutine to zero, it unwires the calling goroutine from 3516 // its fixed operating system thread. 3517 // If there are no active LockOSThread calls, this is a no-op. 3518 // 3519 // Before calling UnlockOSThread, the caller must ensure that the OS 3520 // thread is suitable for running other goroutines. If the caller made 3521 // any permanent changes to the state of the thread that would affect 3522 // other goroutines, it should not call this function and thus leave 3523 // the goroutine locked to the OS thread until the goroutine (and 3524 // hence the thread) exits. 3525 func UnlockOSThread() { 3526 _g_ := getg() 3527 if _g_.m.lockedExt == 0 { 3528 return 3529 } 3530 _g_.m.lockedExt-- 3531 dounlockOSThread() 3532 } 3533 3534 //go:nosplit 3535 func unlockOSThread() { 3536 _g_ := getg() 3537 if _g_.m.lockedInt == 0 { 3538 systemstack(badunlockosthread) 3539 } 3540 _g_.m.lockedInt-- 3541 dounlockOSThread() 3542 } 3543 3544 func badunlockosthread() { 3545 throw("runtime: internal error: misuse of lockOSThread/unlockOSThread") 3546 } 3547 3548 func gcount() int32 { 3549 n := int32(allglen) - sched.ngfree - int32(atomic.Load(&sched.ngsys)) 3550 for _, _p_ := range allp { 3551 n -= _p_.gfreecnt 3552 } 3553 3554 // All these variables can be changed concurrently, so the result can be inconsistent. 3555 // But at least the current goroutine is running. 3556 if n < 1 { 3557 n = 1 3558 } 3559 return n 3560 } 3561 3562 func mcount() int32 { 3563 return int32(sched.mnext - sched.nmfreed) 3564 } 3565 3566 var prof struct { 3567 signalLock uint32 3568 hz int32 3569 } 3570 3571 func _System() { _System() } 3572 func _ExternalCode() { _ExternalCode() } 3573 func _LostExternalCode() { _LostExternalCode() } 3574 func _GC() { _GC() } 3575 func _LostSIGPROFDuringAtomic64() { _LostSIGPROFDuringAtomic64() } 3576 3577 // Counts SIGPROFs received while in atomic64 critical section, on mips{,le} 3578 var lostAtomic64Count uint64 3579 3580 // Called if we receive a SIGPROF signal. 3581 // Called by the signal handler, may run during STW. 3582 //go:nowritebarrierrec 3583 func sigprof(pc, sp, lr uintptr, gp *g, mp *m) { 3584 if prof.hz == 0 { 3585 return 3586 } 3587 3588 // On mips{,le}, 64bit atomics are emulated with spinlocks, in 3589 // runtime/internal/atomic. If SIGPROF arrives while the program is inside 3590 // the critical section, it creates a deadlock (when writing the sample). 3591 // As a workaround, create a counter of SIGPROFs while in critical section 3592 // to store the count, and pass it to sigprof.add() later when SIGPROF is 3593 // received from somewhere else (with _LostSIGPROFDuringAtomic64 as pc). 3594 if GOARCH == "mips" || GOARCH == "mipsle" { 3595 if f := findfunc(pc); f.valid() { 3596 if hasprefix(funcname(f), "runtime/internal/atomic") { 3597 lostAtomic64Count++ 3598 return 3599 } 3600 } 3601 } 3602 3603 // Profiling runs concurrently with GC, so it must not allocate. 3604 // Set a trap in case the code does allocate. 3605 // Note that on windows, one thread takes profiles of all the 3606 // other threads, so mp is usually not getg().m. 3607 // In fact mp may not even be stopped. 3608 // See golang.org/issue/17165. 3609 getg().m.mallocing++ 3610 3611 // Define that a "user g" is a user-created goroutine, and a "system g" 3612 // is one that is m->g0 or m->gsignal. 3613 // 3614 // We might be interrupted for profiling halfway through a 3615 // goroutine switch. The switch involves updating three (or four) values: 3616 // g, PC, SP, and (on arm) LR. The PC must be the last to be updated, 3617 // because once it gets updated the new g is running. 3618 // 3619 // When switching from a user g to a system g, LR is not considered live, 3620 // so the update only affects g, SP, and PC. Since PC must be last, there 3621 // the possible partial transitions in ordinary execution are (1) g alone is updated, 3622 // (2) both g and SP are updated, and (3) SP alone is updated. 3623 // If SP or g alone is updated, we can detect the partial transition by checking 3624 // whether the SP is within g's stack bounds. (We could also require that SP 3625 // be changed only after g, but the stack bounds check is needed by other 3626 // cases, so there is no need to impose an additional requirement.) 3627 // 3628 // There is one exceptional transition to a system g, not in ordinary execution. 3629 // When a signal arrives, the operating system starts the signal handler running 3630 // with an updated PC and SP. The g is updated last, at the beginning of the 3631 // handler. There are two reasons this is okay. First, until g is updated the 3632 // g and SP do not match, so the stack bounds check detects the partial transition. 3633 // Second, signal handlers currently run with signals disabled, so a profiling 3634 // signal cannot arrive during the handler. 3635 // 3636 // When switching from a system g to a user g, there are three possibilities. 3637 // 3638 // First, it may be that the g switch has no PC update, because the SP 3639 // either corresponds to a user g throughout (as in asmcgocall) 3640 // or because it has been arranged to look like a user g frame 3641 // (as in cgocallback_gofunc). In this case, since the entire 3642 // transition is a g+SP update, a partial transition updating just one of 3643 // those will be detected by the stack bounds check. 3644 // 3645 // Second, when returning from a signal handler, the PC and SP updates 3646 // are performed by the operating system in an atomic update, so the g 3647 // update must be done before them. The stack bounds check detects 3648 // the partial transition here, and (again) signal handlers run with signals 3649 // disabled, so a profiling signal cannot arrive then anyway. 3650 // 3651 // Third, the common case: it may be that the switch updates g, SP, and PC 3652 // separately. If the PC is within any of the functions that does this, 3653 // we don't ask for a traceback. C.F. the function setsSP for more about this. 3654 // 3655 // There is another apparently viable approach, recorded here in case 3656 // the "PC within setsSP function" check turns out not to be usable. 3657 // It would be possible to delay the update of either g or SP until immediately 3658 // before the PC update instruction. Then, because of the stack bounds check, 3659 // the only problematic interrupt point is just before that PC update instruction, 3660 // and the sigprof handler can detect that instruction and simulate stepping past 3661 // it in order to reach a consistent state. On ARM, the update of g must be made 3662 // in two places (in R10 and also in a TLS slot), so the delayed update would 3663 // need to be the SP update. The sigprof handler must read the instruction at 3664 // the current PC and if it was the known instruction (for example, JMP BX or 3665 // MOV R2, PC), use that other register in place of the PC value. 3666 // The biggest drawback to this solution is that it requires that we can tell 3667 // whether it's safe to read from the memory pointed at by PC. 3668 // In a correct program, we can test PC == nil and otherwise read, 3669 // but if a profiling signal happens at the instant that a program executes 3670 // a bad jump (before the program manages to handle the resulting fault) 3671 // the profiling handler could fault trying to read nonexistent memory. 3672 // 3673 // To recap, there are no constraints on the assembly being used for the 3674 // transition. We simply require that g and SP match and that the PC is not 3675 // in gogo. 3676 traceback := true 3677 if gp == nil || sp < gp.stack.lo || gp.stack.hi < sp || setsSP(pc) { 3678 traceback = false 3679 } 3680 var stk [maxCPUProfStack]uintptr 3681 n := 0 3682 if mp.ncgo > 0 && mp.curg != nil && mp.curg.syscallpc != 0 && mp.curg.syscallsp != 0 { 3683 cgoOff := 0 3684 // Check cgoCallersUse to make sure that we are not 3685 // interrupting other code that is fiddling with 3686 // cgoCallers. We are running in a signal handler 3687 // with all signals blocked, so we don't have to worry 3688 // about any other code interrupting us. 3689 if atomic.Load(&mp.cgoCallersUse) == 0 && mp.cgoCallers != nil && mp.cgoCallers[0] != 0 { 3690 for cgoOff < len(mp.cgoCallers) && mp.cgoCallers[cgoOff] != 0 { 3691 cgoOff++ 3692 } 3693 copy(stk[:], mp.cgoCallers[:cgoOff]) 3694 mp.cgoCallers[0] = 0 3695 } 3696 3697 // Collect Go stack that leads to the cgo call. 3698 n = gentraceback(mp.curg.syscallpc, mp.curg.syscallsp, 0, mp.curg, 0, &stk[cgoOff], len(stk)-cgoOff, nil, nil, 0) 3699 } else if traceback { 3700 n = gentraceback(pc, sp, lr, gp, 0, &stk[0], len(stk), nil, nil, _TraceTrap|_TraceJumpStack) 3701 } 3702 3703 if n <= 0 { 3704 // Normal traceback is impossible or has failed. 3705 // See if it falls into several common cases. 3706 n = 0 3707 if GOOS == "windows" && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 { 3708 // Libcall, i.e. runtime syscall on windows. 3709 // Collect Go stack that leads to the call. 3710 n = gentraceback(mp.libcallpc, mp.libcallsp, 0, mp.libcallg.ptr(), 0, &stk[0], len(stk), nil, nil, 0) 3711 } 3712 if n == 0 { 3713 // If all of the above has failed, account it against abstract "System" or "GC". 3714 n = 2 3715 // "ExternalCode" is better than "etext". 3716 if pc > firstmoduledata.etext { 3717 pc = funcPC(_ExternalCode) + sys.PCQuantum 3718 } 3719 stk[0] = pc 3720 if mp.preemptoff != "" || mp.helpgc != 0 { 3721 stk[1] = funcPC(_GC) + sys.PCQuantum 3722 } else { 3723 stk[1] = funcPC(_System) + sys.PCQuantum 3724 } 3725 } 3726 } 3727 3728 if prof.hz != 0 { 3729 if (GOARCH == "mips" || GOARCH == "mipsle") && lostAtomic64Count > 0 { 3730 cpuprof.addLostAtomic64(lostAtomic64Count) 3731 lostAtomic64Count = 0 3732 } 3733 cpuprof.add(gp, stk[:n]) 3734 } 3735 getg().m.mallocing-- 3736 } 3737 3738 // If the signal handler receives a SIGPROF signal on a non-Go thread, 3739 // it tries to collect a traceback into sigprofCallers. 3740 // sigprofCallersUse is set to non-zero while sigprofCallers holds a traceback. 3741 var sigprofCallers cgoCallers 3742 var sigprofCallersUse uint32 3743 3744 // sigprofNonGo is called if we receive a SIGPROF signal on a non-Go thread, 3745 // and the signal handler collected a stack trace in sigprofCallers. 3746 // When this is called, sigprofCallersUse will be non-zero. 3747 // g is nil, and what we can do is very limited. 3748 //go:nosplit 3749 //go:nowritebarrierrec 3750 func sigprofNonGo() { 3751 if prof.hz != 0 { 3752 n := 0 3753 for n < len(sigprofCallers) && sigprofCallers[n] != 0 { 3754 n++ 3755 } 3756 cpuprof.addNonGo(sigprofCallers[:n]) 3757 } 3758 3759 atomic.Store(&sigprofCallersUse, 0) 3760 } 3761 3762 // sigprofNonGoPC is called when a profiling signal arrived on a 3763 // non-Go thread and we have a single PC value, not a stack trace. 3764 // g is nil, and what we can do is very limited. 3765 //go:nosplit 3766 //go:nowritebarrierrec 3767 func sigprofNonGoPC(pc uintptr) { 3768 if prof.hz != 0 { 3769 stk := []uintptr{ 3770 pc, 3771 funcPC(_ExternalCode) + sys.PCQuantum, 3772 } 3773 cpuprof.addNonGo(stk) 3774 } 3775 } 3776 3777 // Reports whether a function will set the SP 3778 // to an absolute value. Important that 3779 // we don't traceback when these are at the bottom 3780 // of the stack since we can't be sure that we will 3781 // find the caller. 3782 // 3783 // If the function is not on the bottom of the stack 3784 // we assume that it will have set it up so that traceback will be consistent, 3785 // either by being a traceback terminating function 3786 // or putting one on the stack at the right offset. 3787 func setsSP(pc uintptr) bool { 3788 f := findfunc(pc) 3789 if !f.valid() { 3790 // couldn't find the function for this PC, 3791 // so assume the worst and stop traceback 3792 return true 3793 } 3794 switch f.entry { 3795 case gogoPC, systemstackPC, mcallPC, morestackPC: 3796 return true 3797 } 3798 return false 3799 } 3800 3801 // setcpuprofilerate sets the CPU profiling rate to hz times per second. 3802 // If hz <= 0, setcpuprofilerate turns off CPU profiling. 3803 func setcpuprofilerate(hz int32) { 3804 // Force sane arguments. 3805 if hz < 0 { 3806 hz = 0 3807 } 3808 3809 // Disable preemption, otherwise we can be rescheduled to another thread 3810 // that has profiling enabled. 3811 _g_ := getg() 3812 _g_.m.locks++ 3813 3814 // Stop profiler on this thread so that it is safe to lock prof. 3815 // if a profiling signal came in while we had prof locked, 3816 // it would deadlock. 3817 setThreadCPUProfiler(0) 3818 3819 for !atomic.Cas(&prof.signalLock, 0, 1) { 3820 osyield() 3821 } 3822 if prof.hz != hz { 3823 setProcessCPUProfiler(hz) 3824 prof.hz = hz 3825 } 3826 atomic.Store(&prof.signalLock, 0) 3827 3828 lock(&sched.lock) 3829 sched.profilehz = hz 3830 unlock(&sched.lock) 3831 3832 if hz != 0 { 3833 setThreadCPUProfiler(hz) 3834 } 3835 3836 _g_.m.locks-- 3837 } 3838 3839 // Change number of processors. The world is stopped, sched is locked. 3840 // gcworkbufs are not being modified by either the GC or 3841 // the write barrier code. 3842 // Returns list of Ps with local work, they need to be scheduled by the caller. 3843 func procresize(nprocs int32) *p { 3844 old := gomaxprocs 3845 if old < 0 || nprocs <= 0 { 3846 throw("procresize: invalid arg") 3847 } 3848 if trace.enabled { 3849 traceGomaxprocs(nprocs) 3850 } 3851 3852 // update statistics 3853 now := nanotime() 3854 if sched.procresizetime != 0 { 3855 sched.totaltime += int64(old) * (now - sched.procresizetime) 3856 } 3857 sched.procresizetime = now 3858 3859 // Grow allp if necessary. 3860 if nprocs > int32(len(allp)) { 3861 // Synchronize with retake, which could be running 3862 // concurrently since it doesn't run on a P. 3863 lock(&allpLock) 3864 if nprocs <= int32(cap(allp)) { 3865 allp = allp[:nprocs] 3866 } else { 3867 nallp := make([]*p, nprocs) 3868 // Copy everything up to allp's cap so we 3869 // never lose old allocated Ps. 3870 copy(nallp, allp[:cap(allp)]) 3871 allp = nallp 3872 } 3873 unlock(&allpLock) 3874 } 3875 3876 // initialize new P's 3877 for i := int32(0); i < nprocs; i++ { 3878 pp := allp[i] 3879 if pp == nil { 3880 pp = new(p) 3881 pp.id = i 3882 pp.status = _Pgcstop 3883 pp.sudogcache = pp.sudogbuf[:0] 3884 for i := range pp.deferpool { 3885 pp.deferpool[i] = pp.deferpoolbuf[i][:0] 3886 } 3887 pp.wbBuf.reset() 3888 atomicstorep(unsafe.Pointer(&allp[i]), unsafe.Pointer(pp)) 3889 } 3890 if pp.mcache == nil { 3891 if old == 0 && i == 0 { 3892 if getg().m.mcache == nil { 3893 throw("missing mcache?") 3894 } 3895 pp.mcache = getg().m.mcache // bootstrap 3896 } else { 3897 pp.mcache = allocmcache() 3898 } 3899 } 3900 if raceenabled && pp.racectx == 0 { 3901 if old == 0 && i == 0 { 3902 pp.racectx = raceprocctx0 3903 raceprocctx0 = 0 // bootstrap 3904 } else { 3905 pp.racectx = raceproccreate() 3906 } 3907 } 3908 } 3909 3910 // free unused P's 3911 for i := nprocs; i < old; i++ { 3912 p := allp[i] 3913 if trace.enabled && p == getg().m.p.ptr() { 3914 // moving to p[0], pretend that we were descheduled 3915 // and then scheduled again to keep the trace sane. 3916 traceGoSched() 3917 traceProcStop(p) 3918 } 3919 // move all runnable goroutines to the global queue 3920 for p.runqhead != p.runqtail { 3921 // pop from tail of local queue 3922 p.runqtail-- 3923 gp := p.runq[p.runqtail%uint32(len(p.runq))].ptr() 3924 // push onto head of global queue 3925 globrunqputhead(gp) 3926 } 3927 if p.runnext != 0 { 3928 globrunqputhead(p.runnext.ptr()) 3929 p.runnext = 0 3930 } 3931 // if there's a background worker, make it runnable and put 3932 // it on the global queue so it can clean itself up 3933 if gp := p.gcBgMarkWorker.ptr(); gp != nil { 3934 casgstatus(gp, _Gwaiting, _Grunnable) 3935 if trace.enabled { 3936 traceGoUnpark(gp, 0) 3937 } 3938 globrunqput(gp) 3939 // This assignment doesn't race because the 3940 // world is stopped. 3941 p.gcBgMarkWorker.set(nil) 3942 } 3943 // Flush p's write barrier buffer. 3944 if gcphase != _GCoff { 3945 wbBufFlush1(p) 3946 p.gcw.dispose() 3947 } 3948 for i := range p.sudogbuf { 3949 p.sudogbuf[i] = nil 3950 } 3951 p.sudogcache = p.sudogbuf[:0] 3952 for i := range p.deferpool { 3953 for j := range p.deferpoolbuf[i] { 3954 p.deferpoolbuf[i][j] = nil 3955 } 3956 p.deferpool[i] = p.deferpoolbuf[i][:0] 3957 } 3958 freemcache(p.mcache) 3959 p.mcache = nil 3960 gfpurge(p) 3961 traceProcFree(p) 3962 if raceenabled { 3963 raceprocdestroy(p.racectx) 3964 p.racectx = 0 3965 } 3966 p.gcAssistTime = 0 3967 p.status = _Pdead 3968 // can't free P itself because it can be referenced by an M in syscall 3969 } 3970 3971 // Trim allp. 3972 if int32(len(allp)) != nprocs { 3973 lock(&allpLock) 3974 allp = allp[:nprocs] 3975 unlock(&allpLock) 3976 } 3977 3978 _g_ := getg() 3979 if _g_.m.p != 0 && _g_.m.p.ptr().id < nprocs { 3980 // continue to use the current P 3981 _g_.m.p.ptr().status = _Prunning 3982 } else { 3983 // release the current P and acquire allp[0] 3984 if _g_.m.p != 0 { 3985 _g_.m.p.ptr().m = 0 3986 } 3987 _g_.m.p = 0 3988 _g_.m.mcache = nil 3989 p := allp[0] 3990 p.m = 0 3991 p.status = _Pidle 3992 acquirep(p) 3993 if trace.enabled { 3994 traceGoStart() 3995 } 3996 } 3997 var runnablePs *p 3998 for i := nprocs - 1; i >= 0; i-- { 3999 p := allp[i] 4000 if _g_.m.p.ptr() == p { 4001 continue 4002 } 4003 p.status = _Pidle 4004 if runqempty(p) { 4005 pidleput(p) 4006 } else { 4007 p.m.set(mget()) 4008 p.link.set(runnablePs) 4009 runnablePs = p 4010 } 4011 } 4012 stealOrder.reset(uint32(nprocs)) 4013 var int32p *int32 = &gomaxprocs // make compiler check that gomaxprocs is an int32 4014 atomic.Store((*uint32)(unsafe.Pointer(int32p)), uint32(nprocs)) 4015 return runnablePs 4016 } 4017 4018 // Associate p and the current m. 4019 // 4020 // This function is allowed to have write barriers even if the caller 4021 // isn't because it immediately acquires _p_. 4022 // 4023 //go:yeswritebarrierrec 4024 func acquirep(_p_ *p) { 4025 // Do the part that isn't allowed to have write barriers. 4026 acquirep1(_p_) 4027 4028 // have p; write barriers now allowed 4029 _g_ := getg() 4030 _g_.m.mcache = _p_.mcache 4031 4032 if trace.enabled { 4033 traceProcStart() 4034 } 4035 } 4036 4037 // acquirep1 is the first step of acquirep, which actually acquires 4038 // _p_. This is broken out so we can disallow write barriers for this 4039 // part, since we don't yet have a P. 4040 // 4041 //go:nowritebarrierrec 4042 func acquirep1(_p_ *p) { 4043 _g_ := getg() 4044 4045 if _g_.m.p != 0 || _g_.m.mcache != nil { 4046 throw("acquirep: already in go") 4047 } 4048 if _p_.m != 0 || _p_.status != _Pidle { 4049 id := int64(0) 4050 if _p_.m != 0 { 4051 id = _p_.m.ptr().id 4052 } 4053 print("acquirep: p->m=", _p_.m, "(", id, ") p->status=", _p_.status, "\n") 4054 throw("acquirep: invalid p state") 4055 } 4056 _g_.m.p.set(_p_) 4057 _p_.m.set(_g_.m) 4058 _p_.status = _Prunning 4059 } 4060 4061 // Disassociate p and the current m. 4062 func releasep() *p { 4063 _g_ := getg() 4064 4065 if _g_.m.p == 0 || _g_.m.mcache == nil { 4066 throw("releasep: invalid arg") 4067 } 4068 _p_ := _g_.m.p.ptr() 4069 if _p_.m.ptr() != _g_.m || _p_.mcache != _g_.m.mcache || _p_.status != _Prunning { 4070 print("releasep: m=", _g_.m, " m->p=", _g_.m.p.ptr(), " p->m=", _p_.m, " m->mcache=", _g_.m.mcache, " p->mcache=", _p_.mcache, " p->status=", _p_.status, "\n") 4071 throw("releasep: invalid p state") 4072 } 4073 if trace.enabled { 4074 traceProcStop(_g_.m.p.ptr()) 4075 } 4076 _g_.m.p = 0 4077 _g_.m.mcache = nil 4078 _p_.m = 0 4079 _p_.status = _Pidle 4080 return _p_ 4081 } 4082 4083 func incidlelocked(v int32) { 4084 lock(&sched.lock) 4085 sched.nmidlelocked += v 4086 if v > 0 { 4087 checkdead() 4088 } 4089 unlock(&sched.lock) 4090 } 4091 4092 // Check for deadlock situation. 4093 // The check is based on number of running M's, if 0 -> deadlock. 4094 // sched.lock must be held. 4095 func checkdead() { 4096 // For -buildmode=c-shared or -buildmode=c-archive it's OK if 4097 // there are no running goroutines. The calling program is 4098 // assumed to be running. 4099 if islibrary || isarchive { 4100 return 4101 } 4102 4103 // If we are dying because of a signal caught on an already idle thread, 4104 // freezetheworld will cause all running threads to block. 4105 // And runtime will essentially enter into deadlock state, 4106 // except that there is a thread that will call exit soon. 4107 if panicking > 0 { 4108 return 4109 } 4110 4111 run := mcount() - sched.nmidle - sched.nmidlelocked - sched.nmsys 4112 if run > 0 { 4113 return 4114 } 4115 if run < 0 { 4116 print("runtime: checkdead: nmidle=", sched.nmidle, " nmidlelocked=", sched.nmidlelocked, " mcount=", mcount(), " nmsys=", sched.nmsys, "\n") 4117 throw("checkdead: inconsistent counts") 4118 } 4119 4120 grunning := 0 4121 lock(&allglock) 4122 for i := 0; i < len(allgs); i++ { 4123 gp := allgs[i] 4124 if isSystemGoroutine(gp) { 4125 continue 4126 } 4127 s := readgstatus(gp) 4128 switch s &^ _Gscan { 4129 case _Gwaiting: 4130 grunning++ 4131 case _Grunnable, 4132 _Grunning, 4133 _Gsyscall: 4134 unlock(&allglock) 4135 print("runtime: checkdead: find g ", gp.goid, " in status ", s, "\n") 4136 throw("checkdead: runnable g") 4137 } 4138 } 4139 unlock(&allglock) 4140 if grunning == 0 { // possible if main goroutine calls runtime·Goexit() 4141 throw("no goroutines (main called runtime.Goexit) - deadlock!") 4142 } 4143 4144 // Maybe jump time forward for playground. 4145 gp := timejump() 4146 if gp != nil { 4147 casgstatus(gp, _Gwaiting, _Grunnable) 4148 globrunqput(gp) 4149 _p_ := pidleget() 4150 if _p_ == nil { 4151 throw("checkdead: no p for timer") 4152 } 4153 mp := mget() 4154 if mp == nil { 4155 // There should always be a free M since 4156 // nothing is running. 4157 throw("checkdead: no m for timer") 4158 } 4159 mp.nextp.set(_p_) 4160 notewakeup(&mp.park) 4161 return 4162 } 4163 4164 getg().m.throwing = -1 // do not dump full stacks 4165 throw("all goroutines are asleep - deadlock!") 4166 } 4167 4168 // forcegcperiod is the maximum time in nanoseconds between garbage 4169 // collections. If we go this long without a garbage collection, one 4170 // is forced to run. 4171 // 4172 // This is a variable for testing purposes. It normally doesn't change. 4173 var forcegcperiod int64 = 2 * 60 * 1e9 4174 4175 // Always runs without a P, so write barriers are not allowed. 4176 // 4177 //go:nowritebarrierrec 4178 func sysmon() { 4179 lock(&sched.lock) 4180 sched.nmsys++ 4181 checkdead() 4182 unlock(&sched.lock) 4183 4184 // If a heap span goes unused for 5 minutes after a garbage collection, 4185 // we hand it back to the operating system. 4186 scavengelimit := int64(5 * 60 * 1e9) 4187 4188 if debug.scavenge > 0 { 4189 // Scavenge-a-lot for testing. 4190 forcegcperiod = 10 * 1e6 4191 scavengelimit = 20 * 1e6 4192 } 4193 4194 lastscavenge := nanotime() 4195 nscavenge := 0 4196 4197 lasttrace := int64(0) 4198 idle := 0 // how many cycles in succession we had not wokeup somebody 4199 delay := uint32(0) 4200 for { 4201 if idle == 0 { // start with 20us sleep... 4202 delay = 20 4203 } else if idle > 50 { // start doubling the sleep after 1ms... 4204 delay *= 2 4205 } 4206 if delay > 10*1000 { // up to 10ms 4207 delay = 10 * 1000 4208 } 4209 usleep(delay) 4210 if debug.schedtrace <= 0 && (sched.gcwaiting != 0 || atomic.Load(&sched.npidle) == uint32(gomaxprocs)) { 4211 lock(&sched.lock) 4212 if atomic.Load(&sched.gcwaiting) != 0 || atomic.Load(&sched.npidle) == uint32(gomaxprocs) { 4213 atomic.Store(&sched.sysmonwait, 1) 4214 unlock(&sched.lock) 4215 // Make wake-up period small enough 4216 // for the sampling to be correct. 4217 maxsleep := forcegcperiod / 2 4218 if scavengelimit < forcegcperiod { 4219 maxsleep = scavengelimit / 2 4220 } 4221 shouldRelax := true 4222 if osRelaxMinNS > 0 { 4223 next := timeSleepUntil() 4224 now := nanotime() 4225 if next-now < osRelaxMinNS { 4226 shouldRelax = false 4227 } 4228 } 4229 if shouldRelax { 4230 osRelax(true) 4231 } 4232 notetsleep(&sched.sysmonnote, maxsleep) 4233 if shouldRelax { 4234 osRelax(false) 4235 } 4236 lock(&sched.lock) 4237 atomic.Store(&sched.sysmonwait, 0) 4238 noteclear(&sched.sysmonnote) 4239 idle = 0 4240 delay = 20 4241 } 4242 unlock(&sched.lock) 4243 } 4244 // trigger libc interceptors if needed 4245 if *cgo_yield != nil { 4246 asmcgocall(*cgo_yield, nil) 4247 } 4248 // poll network if not polled for more than 10ms 4249 lastpoll := int64(atomic.Load64(&sched.lastpoll)) 4250 now := nanotime() 4251 if netpollinited() && lastpoll != 0 && lastpoll+10*1000*1000 < now { 4252 atomic.Cas64(&sched.lastpoll, uint64(lastpoll), uint64(now)) 4253 gp := netpoll(false) // non-blocking - returns list of goroutines 4254 if gp != nil { 4255 // Need to decrement number of idle locked M's 4256 // (pretending that one more is running) before injectglist. 4257 // Otherwise it can lead to the following situation: 4258 // injectglist grabs all P's but before it starts M's to run the P's, 4259 // another M returns from syscall, finishes running its G, 4260 // observes that there is no work to do and no other running M's 4261 // and reports deadlock. 4262 incidlelocked(-1) 4263 injectglist(gp) 4264 incidlelocked(1) 4265 } 4266 } 4267 // retake P's blocked in syscalls 4268 // and preempt long running G's 4269 if retake(now) != 0 { 4270 idle = 0 4271 } else { 4272 idle++ 4273 } 4274 // check if we need to force a GC 4275 if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && atomic.Load(&forcegc.idle) != 0 { 4276 lock(&forcegc.lock) 4277 forcegc.idle = 0 4278 forcegc.g.schedlink = 0 4279 injectglist(forcegc.g) 4280 unlock(&forcegc.lock) 4281 } 4282 // scavenge heap once in a while 4283 if lastscavenge+scavengelimit/2 < now { 4284 mheap_.scavenge(int32(nscavenge), uint64(now), uint64(scavengelimit)) 4285 lastscavenge = now 4286 nscavenge++ 4287 } 4288 if debug.schedtrace > 0 && lasttrace+int64(debug.schedtrace)*1000000 <= now { 4289 lasttrace = now 4290 schedtrace(debug.scheddetail > 0) 4291 } 4292 } 4293 } 4294 4295 type sysmontick struct { 4296 schedtick uint32 4297 schedwhen int64 4298 syscalltick uint32 4299 syscallwhen int64 4300 } 4301 4302 // forcePreemptNS is the time slice given to a G before it is 4303 // preempted. 4304 const forcePreemptNS = 10 * 1000 * 1000 // 10ms 4305 4306 func retake(now int64) uint32 { 4307 n := 0 4308 // Prevent allp slice changes. This lock will be completely 4309 // uncontended unless we're already stopping the world. 4310 lock(&allpLock) 4311 // We can't use a range loop over allp because we may 4312 // temporarily drop the allpLock. Hence, we need to re-fetch 4313 // allp each time around the loop. 4314 for i := 0; i < len(allp); i++ { 4315 _p_ := allp[i] 4316 if _p_ == nil { 4317 // This can happen if procresize has grown 4318 // allp but not yet created new Ps. 4319 continue 4320 } 4321 pd := &_p_.sysmontick 4322 s := _p_.status 4323 if s == _Psyscall { 4324 // Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us). 4325 t := int64(_p_.syscalltick) 4326 if int64(pd.syscalltick) != t { 4327 pd.syscalltick = uint32(t) 4328 pd.syscallwhen = now 4329 continue 4330 } 4331 // On the one hand we don't want to retake Ps if there is no other work to do, 4332 // but on the other hand we want to retake them eventually 4333 // because they can prevent the sysmon thread from deep sleep. 4334 if runqempty(_p_) && atomic.Load(&sched.nmspinning)+atomic.Load(&sched.npidle) > 0 && pd.syscallwhen+10*1000*1000 > now { 4335 continue 4336 } 4337 // Drop allpLock so we can take sched.lock. 4338 unlock(&allpLock) 4339 // Need to decrement number of idle locked M's 4340 // (pretending that one more is running) before the CAS. 4341 // Otherwise the M from which we retake can exit the syscall, 4342 // increment nmidle and report deadlock. 4343 incidlelocked(-1) 4344 if atomic.Cas(&_p_.status, s, _Pidle) { 4345 if trace.enabled { 4346 traceGoSysBlock(_p_) 4347 traceProcStop(_p_) 4348 } 4349 n++ 4350 _p_.syscalltick++ 4351 handoffp(_p_) 4352 } 4353 incidlelocked(1) 4354 lock(&allpLock) 4355 } else if s == _Prunning { 4356 // Preempt G if it's running for too long. 4357 t := int64(_p_.schedtick) 4358 if int64(pd.schedtick) != t { 4359 pd.schedtick = uint32(t) 4360 pd.schedwhen = now 4361 continue 4362 } 4363 if pd.schedwhen+forcePreemptNS > now { 4364 continue 4365 } 4366 preemptone(_p_) 4367 } 4368 } 4369 unlock(&allpLock) 4370 return uint32(n) 4371 } 4372 4373 // Tell all goroutines that they have been preempted and they should stop. 4374 // This function is purely best-effort. It can fail to inform a goroutine if a 4375 // processor just started running it. 4376 // No locks need to be held. 4377 // Returns true if preemption request was issued to at least one goroutine. 4378 func preemptall() bool { 4379 res := false 4380 for _, _p_ := range allp { 4381 if _p_.status != _Prunning { 4382 continue 4383 } 4384 if preemptone(_p_) { 4385 res = true 4386 } 4387 } 4388 return res 4389 } 4390 4391 // Tell the goroutine running on processor P to stop. 4392 // This function is purely best-effort. It can incorrectly fail to inform the 4393 // goroutine. It can send inform the wrong goroutine. Even if it informs the 4394 // correct goroutine, that goroutine might ignore the request if it is 4395 // simultaneously executing newstack. 4396 // No lock needs to be held. 4397 // Returns true if preemption request was issued. 4398 // The actual preemption will happen at some point in the future 4399 // and will be indicated by the gp->status no longer being 4400 // Grunning 4401 func preemptone(_p_ *p) bool { 4402 mp := _p_.m.ptr() 4403 if mp == nil || mp == getg().m { 4404 return false 4405 } 4406 gp := mp.curg 4407 if gp == nil || gp == mp.g0 { 4408 return false 4409 } 4410 4411 gp.preempt = true 4412 4413 // Every call in a go routine checks for stack overflow by 4414 // comparing the current stack pointer to gp->stackguard0. 4415 // Setting gp->stackguard0 to StackPreempt folds 4416 // preemption into the normal stack overflow check. 4417 gp.stackguard0 = stackPreempt 4418 return true 4419 } 4420 4421 var starttime int64 4422 4423 func schedtrace(detailed bool) { 4424 now := nanotime() 4425 if starttime == 0 { 4426 starttime = now 4427 } 4428 4429 lock(&sched.lock) 4430 print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle, " threads=", mcount(), " spinningthreads=", sched.nmspinning, " idlethreads=", sched.nmidle, " runqueue=", sched.runqsize) 4431 if detailed { 4432 print(" gcwaiting=", sched.gcwaiting, " nmidlelocked=", sched.nmidlelocked, " stopwait=", sched.stopwait, " sysmonwait=", sched.sysmonwait, "\n") 4433 } 4434 // We must be careful while reading data from P's, M's and G's. 4435 // Even if we hold schedlock, most data can be changed concurrently. 4436 // E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil. 4437 for i, _p_ := range allp { 4438 mp := _p_.m.ptr() 4439 h := atomic.Load(&_p_.runqhead) 4440 t := atomic.Load(&_p_.runqtail) 4441 if detailed { 4442 id := int64(-1) 4443 if mp != nil { 4444 id = mp.id 4445 } 4446 print(" P", i, ": status=", _p_.status, " schedtick=", _p_.schedtick, " syscalltick=", _p_.syscalltick, " m=", id, " runqsize=", t-h, " gfreecnt=", _p_.gfreecnt, "\n") 4447 } else { 4448 // In non-detailed mode format lengths of per-P run queues as: 4449 // [len1 len2 len3 len4] 4450 print(" ") 4451 if i == 0 { 4452 print("[") 4453 } 4454 print(t - h) 4455 if i == len(allp)-1 { 4456 print("]\n") 4457 } 4458 } 4459 } 4460 4461 if !detailed { 4462 unlock(&sched.lock) 4463 return 4464 } 4465 4466 for mp := allm; mp != nil; mp = mp.alllink { 4467 _p_ := mp.p.ptr() 4468 gp := mp.curg 4469 lockedg := mp.lockedg.ptr() 4470 id1 := int32(-1) 4471 if _p_ != nil { 4472 id1 = _p_.id 4473 } 4474 id2 := int64(-1) 4475 if gp != nil { 4476 id2 = gp.goid 4477 } 4478 id3 := int64(-1) 4479 if lockedg != nil { 4480 id3 = lockedg.goid 4481 } 4482 print(" M", mp.id, ": p=", id1, " curg=", id2, " mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, ""+" locks=", mp.locks, " dying=", mp.dying, " helpgc=", mp.helpgc, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=", id3, "\n") 4483 } 4484 4485 lock(&allglock) 4486 for gi := 0; gi < len(allgs); gi++ { 4487 gp := allgs[gi] 4488 mp := gp.m 4489 lockedm := gp.lockedm.ptr() 4490 id1 := int64(-1) 4491 if mp != nil { 4492 id1 = mp.id 4493 } 4494 id2 := int64(-1) 4495 if lockedm != nil { 4496 id2 = lockedm.id 4497 } 4498 print(" G", gp.goid, ": status=", readgstatus(gp), "(", gp.waitreason, ") m=", id1, " lockedm=", id2, "\n") 4499 } 4500 unlock(&allglock) 4501 unlock(&sched.lock) 4502 } 4503 4504 // Put mp on midle list. 4505 // Sched must be locked. 4506 // May run during STW, so write barriers are not allowed. 4507 //go:nowritebarrierrec 4508 func mput(mp *m) { 4509 mp.schedlink = sched.midle 4510 sched.midle.set(mp) 4511 sched.nmidle++ 4512 checkdead() 4513 } 4514 4515 // Try to get an m from midle list. 4516 // Sched must be locked. 4517 // May run during STW, so write barriers are not allowed. 4518 //go:nowritebarrierrec 4519 func mget() *m { 4520 mp := sched.midle.ptr() 4521 if mp != nil { 4522 sched.midle = mp.schedlink 4523 sched.nmidle-- 4524 } 4525 return mp 4526 } 4527 4528 // Put gp on the global runnable queue. 4529 // Sched must be locked. 4530 // May run during STW, so write barriers are not allowed. 4531 //go:nowritebarrierrec 4532 func globrunqput(gp *g) { 4533 gp.schedlink = 0 4534 if sched.runqtail != 0 { 4535 sched.runqtail.ptr().schedlink.set(gp) 4536 } else { 4537 sched.runqhead.set(gp) 4538 } 4539 sched.runqtail.set(gp) 4540 sched.runqsize++ 4541 } 4542 4543 // Put gp at the head of the global runnable queue. 4544 // Sched must be locked. 4545 // May run during STW, so write barriers are not allowed. 4546 //go:nowritebarrierrec 4547 func globrunqputhead(gp *g) { 4548 gp.schedlink = sched.runqhead 4549 sched.runqhead.set(gp) 4550 if sched.runqtail == 0 { 4551 sched.runqtail.set(gp) 4552 } 4553 sched.runqsize++ 4554 } 4555 4556 // Put a batch of runnable goroutines on the global runnable queue. 4557 // Sched must be locked. 4558 func globrunqputbatch(ghead *g, gtail *g, n int32) { 4559 gtail.schedlink = 0 4560 if sched.runqtail != 0 { 4561 sched.runqtail.ptr().schedlink.set(ghead) 4562 } else { 4563 sched.runqhead.set(ghead) 4564 } 4565 sched.runqtail.set(gtail) 4566 sched.runqsize += n 4567 } 4568 4569 // Try get a batch of G's from the global runnable queue. 4570 // Sched must be locked. 4571 func globrunqget(_p_ *p, max int32) *g { 4572 if sched.runqsize == 0 { 4573 return nil 4574 } 4575 4576 n := sched.runqsize/gomaxprocs + 1 4577 if n > sched.runqsize { 4578 n = sched.runqsize 4579 } 4580 if max > 0 && n > max { 4581 n = max 4582 } 4583 if n > int32(len(_p_.runq))/2 { 4584 n = int32(len(_p_.runq)) / 2 4585 } 4586 4587 sched.runqsize -= n 4588 if sched.runqsize == 0 { 4589 sched.runqtail = 0 4590 } 4591 4592 gp := sched.runqhead.ptr() 4593 sched.runqhead = gp.schedlink 4594 n-- 4595 for ; n > 0; n-- { 4596 gp1 := sched.runqhead.ptr() 4597 sched.runqhead = gp1.schedlink 4598 runqput(_p_, gp1, false) 4599 } 4600 return gp 4601 } 4602 4603 // Put p to on _Pidle list. 4604 // Sched must be locked. 4605 // May run during STW, so write barriers are not allowed. 4606 //go:nowritebarrierrec 4607 func pidleput(_p_ *p) { 4608 if !runqempty(_p_) { 4609 throw("pidleput: P has non-empty run queue") 4610 } 4611 _p_.link = sched.pidle 4612 sched.pidle.set(_p_) 4613 atomic.Xadd(&sched.npidle, 1) // TODO: fast atomic 4614 } 4615 4616 // Try get a p from _Pidle list. 4617 // Sched must be locked. 4618 // May run during STW, so write barriers are not allowed. 4619 //go:nowritebarrierrec 4620 func pidleget() *p { 4621 _p_ := sched.pidle.ptr() 4622 if _p_ != nil { 4623 sched.pidle = _p_.link 4624 atomic.Xadd(&sched.npidle, -1) // TODO: fast atomic 4625 } 4626 return _p_ 4627 } 4628 4629 // runqempty returns true if _p_ has no Gs on its local run queue. 4630 // It never returns true spuriously. 4631 func runqempty(_p_ *p) bool { 4632 // Defend against a race where 1) _p_ has G1 in runqnext but runqhead == runqtail, 4633 // 2) runqput on _p_ kicks G1 to the runq, 3) runqget on _p_ empties runqnext. 4634 // Simply observing that runqhead == runqtail and then observing that runqnext == nil 4635 // does not mean the queue is empty. 4636 for { 4637 head := atomic.Load(&_p_.runqhead) 4638 tail := atomic.Load(&_p_.runqtail) 4639 runnext := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&_p_.runnext))) 4640 if tail == atomic.Load(&_p_.runqtail) { 4641 return head == tail && runnext == 0 4642 } 4643 } 4644 } 4645 4646 // To shake out latent assumptions about scheduling order, 4647 // we introduce some randomness into scheduling decisions 4648 // when running with the race detector. 4649 // The need for this was made obvious by changing the 4650 // (deterministic) scheduling order in Go 1.5 and breaking 4651 // many poorly-written tests. 4652 // With the randomness here, as long as the tests pass 4653 // consistently with -race, they shouldn't have latent scheduling 4654 // assumptions. 4655 const randomizeScheduler = raceenabled 4656 4657 // runqput tries to put g on the local runnable queue. 4658 // If next if false, runqput adds g to the tail of the runnable queue. 4659 // If next is true, runqput puts g in the _p_.runnext slot. 4660 // If the run queue is full, runnext puts g on the global queue. 4661 // Executed only by the owner P. 4662 func runqput(_p_ *p, gp *g, next bool) { 4663 if randomizeScheduler && next && fastrand()%2 == 0 { 4664 next = false 4665 } 4666 4667 if next { 4668 retryNext: 4669 oldnext := _p_.runnext 4670 if !_p_.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) { 4671 goto retryNext 4672 } 4673 if oldnext == 0 { 4674 return 4675 } 4676 // Kick the old runnext out to the regular run queue. 4677 gp = oldnext.ptr() 4678 } 4679 4680 retry: 4681 h := atomic.Load(&_p_.runqhead) // load-acquire, synchronize with consumers 4682 t := _p_.runqtail 4683 if t-h < uint32(len(_p_.runq)) { 4684 _p_.runq[t%uint32(len(_p_.runq))].set(gp) 4685 atomic.Store(&_p_.runqtail, t+1) // store-release, makes the item available for consumption 4686 return 4687 } 4688 if runqputslow(_p_, gp, h, t) { 4689 return 4690 } 4691 // the queue is not full, now the put above must succeed 4692 goto retry 4693 } 4694 4695 // Put g and a batch of work from local runnable queue on global queue. 4696 // Executed only by the owner P. 4697 func runqputslow(_p_ *p, gp *g, h, t uint32) bool { 4698 var batch [len(_p_.runq)/2 + 1]*g 4699 4700 // First, grab a batch from local queue. 4701 n := t - h 4702 n = n / 2 4703 if n != uint32(len(_p_.runq)/2) { 4704 throw("runqputslow: queue is not full") 4705 } 4706 for i := uint32(0); i < n; i++ { 4707 batch[i] = _p_.runq[(h+i)%uint32(len(_p_.runq))].ptr() 4708 } 4709 if !atomic.Cas(&_p_.runqhead, h, h+n) { // cas-release, commits consume 4710 return false 4711 } 4712 batch[n] = gp 4713 4714 if randomizeScheduler { 4715 for i := uint32(1); i <= n; i++ { 4716 j := fastrandn(i + 1) 4717 batch[i], batch[j] = batch[j], batch[i] 4718 } 4719 } 4720 4721 // Link the goroutines. 4722 for i := uint32(0); i < n; i++ { 4723 batch[i].schedlink.set(batch[i+1]) 4724 } 4725 4726 // Now put the batch on global queue. 4727 lock(&sched.lock) 4728 globrunqputbatch(batch[0], batch[n], int32(n+1)) 4729 unlock(&sched.lock) 4730 return true 4731 } 4732 4733 // Get g from local runnable queue. 4734 // If inheritTime is true, gp should inherit the remaining time in the 4735 // current time slice. Otherwise, it should start a new time slice. 4736 // Executed only by the owner P. 4737 func runqget(_p_ *p) (gp *g, inheritTime bool) { 4738 // If there's a runnext, it's the next G to run. 4739 for { 4740 next := _p_.runnext 4741 if next == 0 { 4742 break 4743 } 4744 if _p_.runnext.cas(next, 0) { 4745 return next.ptr(), true 4746 } 4747 } 4748 4749 for { 4750 h := atomic.Load(&_p_.runqhead) // load-acquire, synchronize with other consumers 4751 t := _p_.runqtail 4752 if t == h { 4753 return nil, false 4754 } 4755 gp := _p_.runq[h%uint32(len(_p_.runq))].ptr() 4756 if atomic.Cas(&_p_.runqhead, h, h+1) { // cas-release, commits consume 4757 return gp, false 4758 } 4759 } 4760 } 4761 4762 // Grabs a batch of goroutines from _p_'s runnable queue into batch. 4763 // Batch is a ring buffer starting at batchHead. 4764 // Returns number of grabbed goroutines. 4765 // Can be executed by any P. 4766 func runqgrab(_p_ *p, batch *[256]guintptr, batchHead uint32, stealRunNextG bool) uint32 { 4767 for { 4768 h := atomic.Load(&_p_.runqhead) // load-acquire, synchronize with other consumers 4769 t := atomic.Load(&_p_.runqtail) // load-acquire, synchronize with the producer 4770 n := t - h 4771 n = n - n/2 4772 if n == 0 { 4773 if stealRunNextG { 4774 // Try to steal from _p_.runnext. 4775 if next := _p_.runnext; next != 0 { 4776 // Sleep to ensure that _p_ isn't about to run the g we 4777 // are about to steal. 4778 // The important use case here is when the g running on _p_ 4779 // ready()s another g and then almost immediately blocks. 4780 // Instead of stealing runnext in this window, back off 4781 // to give _p_ a chance to schedule runnext. This will avoid 4782 // thrashing gs between different Ps. 4783 // A sync chan send/recv takes ~50ns as of time of writing, 4784 // so 3us gives ~50x overshoot. 4785 if GOOS != "windows" { 4786 usleep(3) 4787 } else { 4788 // On windows system timer granularity is 1-15ms, 4789 // which is way too much for this optimization. 4790 // So just yield. 4791 osyield() 4792 } 4793 if !_p_.runnext.cas(next, 0) { 4794 continue 4795 } 4796 batch[batchHead%uint32(len(batch))] = next 4797 return 1 4798 } 4799 } 4800 return 0 4801 } 4802 if n > uint32(len(_p_.runq)/2) { // read inconsistent h and t 4803 continue 4804 } 4805 for i := uint32(0); i < n; i++ { 4806 g := _p_.runq[(h+i)%uint32(len(_p_.runq))] 4807 batch[(batchHead+i)%uint32(len(batch))] = g 4808 } 4809 if atomic.Cas(&_p_.runqhead, h, h+n) { // cas-release, commits consume 4810 return n 4811 } 4812 } 4813 } 4814 4815 // Steal half of elements from local runnable queue of p2 4816 // and put onto local runnable queue of p. 4817 // Returns one of the stolen elements (or nil if failed). 4818 func runqsteal(_p_, p2 *p, stealRunNextG bool) *g { 4819 t := _p_.runqtail 4820 n := runqgrab(p2, &_p_.runq, t, stealRunNextG) 4821 if n == 0 { 4822 return nil 4823 } 4824 n-- 4825 gp := _p_.runq[(t+n)%uint32(len(_p_.runq))].ptr() 4826 if n == 0 { 4827 return gp 4828 } 4829 h := atomic.Load(&_p_.runqhead) // load-acquire, synchronize with consumers 4830 if t-h+n >= uint32(len(_p_.runq)) { 4831 throw("runqsteal: runq overflow") 4832 } 4833 atomic.Store(&_p_.runqtail, t+n) // store-release, makes the item available for consumption 4834 return gp 4835 } 4836 4837 //go:linkname setMaxThreads runtime/debug.setMaxThreads 4838 func setMaxThreads(in int) (out int) { 4839 lock(&sched.lock) 4840 out = int(sched.maxmcount) 4841 if in > 0x7fffffff { // MaxInt32 4842 sched.maxmcount = 0x7fffffff 4843 } else { 4844 sched.maxmcount = int32(in) 4845 } 4846 checkmcount() 4847 unlock(&sched.lock) 4848 return 4849 } 4850 4851 func haveexperiment(name string) bool { 4852 if name == "framepointer" { 4853 return framepointer_enabled // set by linker 4854 } 4855 x := sys.Goexperiment 4856 for x != "" { 4857 xname := "" 4858 i := index(x, ",") 4859 if i < 0 { 4860 xname, x = x, "" 4861 } else { 4862 xname, x = x[:i], x[i+1:] 4863 } 4864 if xname == name { 4865 return true 4866 } 4867 if len(xname) > 2 && xname[:2] == "no" && xname[2:] == name { 4868 return false 4869 } 4870 } 4871 return false 4872 } 4873 4874 //go:nosplit 4875 func procPin() int { 4876 _g_ := getg() 4877 mp := _g_.m 4878 4879 mp.locks++ 4880 return int(mp.p.ptr().id) 4881 } 4882 4883 //go:nosplit 4884 func procUnpin() { 4885 _g_ := getg() 4886 _g_.m.locks-- 4887 } 4888 4889 //go:linkname sync_runtime_procPin sync.runtime_procPin 4890 //go:nosplit 4891 func sync_runtime_procPin() int { 4892 return procPin() 4893 } 4894 4895 //go:linkname sync_runtime_procUnpin sync.runtime_procUnpin 4896 //go:nosplit 4897 func sync_runtime_procUnpin() { 4898 procUnpin() 4899 } 4900 4901 //go:linkname sync_atomic_runtime_procPin sync/atomic.runtime_procPin 4902 //go:nosplit 4903 func sync_atomic_runtime_procPin() int { 4904 return procPin() 4905 } 4906 4907 //go:linkname sync_atomic_runtime_procUnpin sync/atomic.runtime_procUnpin 4908 //go:nosplit 4909 func sync_atomic_runtime_procUnpin() { 4910 procUnpin() 4911 } 4912 4913 // Active spinning for sync.Mutex. 4914 //go:linkname sync_runtime_canSpin sync.runtime_canSpin 4915 //go:nosplit 4916 func sync_runtime_canSpin(i int) bool { 4917 // sync.Mutex is cooperative, so we are conservative with spinning. 4918 // Spin only few times and only if running on a multicore machine and 4919 // GOMAXPROCS>1 and there is at least one other running P and local runq is empty. 4920 // As opposed to runtime mutex we don't do passive spinning here, 4921 // because there can be work on global runq on on other Ps. 4922 if i >= active_spin || ncpu <= 1 || gomaxprocs <= int32(sched.npidle+sched.nmspinning)+1 { 4923 return false 4924 } 4925 if p := getg().m.p.ptr(); !runqempty(p) { 4926 return false 4927 } 4928 return true 4929 } 4930 4931 //go:linkname sync_runtime_doSpin sync.runtime_doSpin 4932 //go:nosplit 4933 func sync_runtime_doSpin() { 4934 procyield(active_spin_cnt) 4935 } 4936 4937 var stealOrder randomOrder 4938 4939 // randomOrder/randomEnum are helper types for randomized work stealing. 4940 // They allow to enumerate all Ps in different pseudo-random orders without repetitions. 4941 // The algorithm is based on the fact that if we have X such that X and GOMAXPROCS 4942 // are coprime, then a sequences of (i + X) % GOMAXPROCS gives the required enumeration. 4943 type randomOrder struct { 4944 count uint32 4945 coprimes []uint32 4946 } 4947 4948 type randomEnum struct { 4949 i uint32 4950 count uint32 4951 pos uint32 4952 inc uint32 4953 } 4954 4955 func (ord *randomOrder) reset(count uint32) { 4956 ord.count = count 4957 ord.coprimes = ord.coprimes[:0] 4958 for i := uint32(1); i <= count; i++ { 4959 if gcd(i, count) == 1 { 4960 ord.coprimes = append(ord.coprimes, i) 4961 } 4962 } 4963 } 4964 4965 func (ord *randomOrder) start(i uint32) randomEnum { 4966 return randomEnum{ 4967 count: ord.count, 4968 pos: i % ord.count, 4969 inc: ord.coprimes[i%uint32(len(ord.coprimes))], 4970 } 4971 } 4972 4973 func (enum *randomEnum) done() bool { 4974 return enum.i == enum.count 4975 } 4976 4977 func (enum *randomEnum) next() { 4978 enum.i++ 4979 enum.pos = (enum.pos + enum.inc) % enum.count 4980 } 4981 4982 func (enum *randomEnum) position() uint32 { 4983 return enum.pos 4984 } 4985 4986 func gcd(a, b uint32) uint32 { 4987 for b != 0 { 4988 a, b = b, a%b 4989 } 4990 return a 4991 }