github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/proc.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include <limits.h> 6 #include <signal.h> 7 #include <stdlib.h> 8 #include <pthread.h> 9 #include <unistd.h> 10 11 #include "config.h" 12 13 #ifdef HAVE_DL_ITERATE_PHDR 14 #include <link.h> 15 #endif 16 17 #include "runtime.h" 18 #include "arch.h" 19 #include "defs.h" 20 #include "malloc.h" 21 #include "go-type.h" 22 #include "go-defer.h" 23 24 #ifdef USING_SPLIT_STACK 25 26 /* FIXME: These are not declared anywhere. */ 27 28 extern void __splitstack_getcontext(void *context[10]); 29 30 extern void __splitstack_setcontext(void *context[10]); 31 32 extern void *__splitstack_makecontext(size_t, void *context[10], size_t *); 33 34 extern void * __splitstack_resetcontext(void *context[10], size_t *); 35 36 extern void *__splitstack_find(void *, void *, size_t *, void **, void **, 37 void **); 38 39 extern void __splitstack_block_signals (int *, int *); 40 41 extern void __splitstack_block_signals_context (void *context[10], int *, 42 int *); 43 44 #endif 45 46 #ifndef PTHREAD_STACK_MIN 47 # define PTHREAD_STACK_MIN 8192 48 #endif 49 50 #if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK) 51 # define StackMin PTHREAD_STACK_MIN 52 #else 53 # define StackMin ((sizeof(char *) < 8) ? 2 * 1024 * 1024 : 4 * 1024 * 1024) 54 #endif 55 56 uintptr runtime_stacks_sys; 57 58 static void gtraceback(G*); 59 60 #ifdef __rtems__ 61 #define __thread 62 #endif 63 64 static __thread G *g; 65 static __thread M *m; 66 67 #ifndef SETCONTEXT_CLOBBERS_TLS 68 69 static inline void 70 initcontext(void) 71 { 72 } 73 74 static inline void 75 fixcontext(ucontext_t *c __attribute__ ((unused))) 76 { 77 } 78 79 #else 80 81 # if defined(__x86_64__) && defined(__sun__) 82 83 // x86_64 Solaris 10 and 11 have a bug: setcontext switches the %fs 84 // register to that of the thread which called getcontext. The effect 85 // is that the address of all __thread variables changes. This bug 86 // also affects pthread_self() and pthread_getspecific. We work 87 // around it by clobbering the context field directly to keep %fs the 88 // same. 89 90 static __thread greg_t fs; 91 92 static inline void 93 initcontext(void) 94 { 95 ucontext_t c; 96 97 getcontext(&c); 98 fs = c.uc_mcontext.gregs[REG_FSBASE]; 99 } 100 101 static inline void 102 fixcontext(ucontext_t* c) 103 { 104 c->uc_mcontext.gregs[REG_FSBASE] = fs; 105 } 106 107 # elif defined(__NetBSD__) 108 109 // NetBSD has a bug: setcontext clobbers tlsbase, we need to save 110 // and restore it ourselves. 111 112 static __thread __greg_t tlsbase; 113 114 static inline void 115 initcontext(void) 116 { 117 ucontext_t c; 118 119 getcontext(&c); 120 tlsbase = c.uc_mcontext._mc_tlsbase; 121 } 122 123 static inline void 124 fixcontext(ucontext_t* c) 125 { 126 c->uc_mcontext._mc_tlsbase = tlsbase; 127 } 128 129 # elif defined(__sparc__) 130 131 static inline void 132 initcontext(void) 133 { 134 } 135 136 static inline void 137 fixcontext(ucontext_t *c) 138 { 139 /* ??? Using 140 register unsigned long thread __asm__("%g7"); 141 c->uc_mcontext.gregs[REG_G7] = thread; 142 results in 143 error: variable ‘thread’ might be clobbered by \ 144 ‘longjmp’ or ‘vfork’ [-Werror=clobbered] 145 which ought to be false, as %g7 is a fixed register. */ 146 147 if (sizeof (c->uc_mcontext.gregs[REG_G7]) == 8) 148 asm ("stx %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7])); 149 else 150 asm ("st %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7])); 151 } 152 153 # else 154 155 # error unknown case for SETCONTEXT_CLOBBERS_TLS 156 157 # endif 158 159 #endif 160 161 // We can not always refer to the TLS variables directly. The 162 // compiler will call tls_get_addr to get the address of the variable, 163 // and it may hold it in a register across a call to schedule. When 164 // we get back from the call we may be running in a different thread, 165 // in which case the register now points to the TLS variable for a 166 // different thread. We use non-inlinable functions to avoid this 167 // when necessary. 168 169 G* runtime_g(void) __attribute__ ((noinline, no_split_stack)); 170 171 G* 172 runtime_g(void) 173 { 174 return g; 175 } 176 177 M* runtime_m(void) __attribute__ ((noinline, no_split_stack)); 178 179 M* 180 runtime_m(void) 181 { 182 return m; 183 } 184 185 // Set m and g. 186 void 187 runtime_setmg(M* mp, G* gp) 188 { 189 m = mp; 190 g = gp; 191 } 192 193 // Start a new thread. 194 static void 195 runtime_newosproc(M *mp) 196 { 197 pthread_attr_t attr; 198 sigset_t clear, old; 199 pthread_t tid; 200 int ret; 201 202 if(pthread_attr_init(&attr) != 0) 203 runtime_throw("pthread_attr_init"); 204 if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) 205 runtime_throw("pthread_attr_setdetachstate"); 206 207 // Block signals during pthread_create so that the new thread 208 // starts with signals disabled. It will enable them in minit. 209 sigfillset(&clear); 210 211 #ifdef SIGTRAP 212 // Blocking SIGTRAP reportedly breaks gdb on Alpha GNU/Linux. 213 sigdelset(&clear, SIGTRAP); 214 #endif 215 216 sigemptyset(&old); 217 pthread_sigmask(SIG_BLOCK, &clear, &old); 218 ret = pthread_create(&tid, &attr, runtime_mstart, mp); 219 pthread_sigmask(SIG_SETMASK, &old, nil); 220 221 if (ret != 0) 222 runtime_throw("pthread_create"); 223 } 224 225 // First function run by a new goroutine. This replaces gogocall. 226 static void 227 kickoff(void) 228 { 229 void (*fn)(void*); 230 231 if(g->traceback != nil) 232 gtraceback(g); 233 234 fn = (void (*)(void*))(g->entry); 235 fn(g->param); 236 runtime_goexit(); 237 } 238 239 // Switch context to a different goroutine. This is like longjmp. 240 void runtime_gogo(G*) __attribute__ ((noinline)); 241 void 242 runtime_gogo(G* newg) 243 { 244 #ifdef USING_SPLIT_STACK 245 __splitstack_setcontext(&newg->stack_context[0]); 246 #endif 247 g = newg; 248 newg->fromgogo = true; 249 fixcontext(&newg->context); 250 setcontext(&newg->context); 251 runtime_throw("gogo setcontext returned"); 252 } 253 254 // Save context and call fn passing g as a parameter. This is like 255 // setjmp. Because getcontext always returns 0, unlike setjmp, we use 256 // g->fromgogo as a code. It will be true if we got here via 257 // setcontext. g == nil the first time this is called in a new m. 258 void runtime_mcall(void (*)(G*)) __attribute__ ((noinline)); 259 void 260 runtime_mcall(void (*pfn)(G*)) 261 { 262 M *mp; 263 G *gp; 264 265 // Ensure that all registers are on the stack for the garbage 266 // collector. 267 __builtin_unwind_init(); 268 269 mp = m; 270 gp = g; 271 if(gp == mp->g0) 272 runtime_throw("runtime: mcall called on m->g0 stack"); 273 274 if(gp != nil) { 275 276 #ifdef USING_SPLIT_STACK 277 __splitstack_getcontext(&g->stack_context[0]); 278 #else 279 gp->gcnext_sp = &pfn; 280 #endif 281 gp->fromgogo = false; 282 getcontext(&gp->context); 283 284 // When we return from getcontext, we may be running 285 // in a new thread. That means that m and g may have 286 // changed. They are global variables so we will 287 // reload them, but the addresses of m and g may be 288 // cached in our local stack frame, and those 289 // addresses may be wrong. Call functions to reload 290 // the values for this thread. 291 mp = runtime_m(); 292 gp = runtime_g(); 293 294 if(gp->traceback != nil) 295 gtraceback(gp); 296 } 297 if (gp == nil || !gp->fromgogo) { 298 #ifdef USING_SPLIT_STACK 299 __splitstack_setcontext(&mp->g0->stack_context[0]); 300 #endif 301 mp->g0->entry = (byte*)pfn; 302 mp->g0->param = gp; 303 304 // It's OK to set g directly here because this case 305 // can not occur if we got here via a setcontext to 306 // the getcontext call just above. 307 g = mp->g0; 308 309 fixcontext(&mp->g0->context); 310 setcontext(&mp->g0->context); 311 runtime_throw("runtime: mcall function returned"); 312 } 313 } 314 315 // Goroutine scheduler 316 // The scheduler's job is to distribute ready-to-run goroutines over worker threads. 317 // 318 // The main concepts are: 319 // G - goroutine. 320 // M - worker thread, or machine. 321 // P - processor, a resource that is required to execute Go code. 322 // M must have an associated P to execute Go code, however it can be 323 // blocked or in a syscall w/o an associated P. 324 // 325 // Design doc at http://golang.org/s/go11sched. 326 327 typedef struct Sched Sched; 328 struct Sched { 329 Lock lock; 330 331 uint64 goidgen; 332 M* midle; // idle m's waiting for work 333 int32 nmidle; // number of idle m's waiting for work 334 int32 nmidlelocked; // number of locked m's waiting for work 335 int32 mcount; // number of m's that have been created 336 int32 maxmcount; // maximum number of m's allowed (or die) 337 338 P* pidle; // idle P's 339 uint32 npidle; 340 uint32 nmspinning; 341 342 // Global runnable queue. 343 G* runqhead; 344 G* runqtail; 345 int32 runqsize; 346 347 // Global cache of dead G's. 348 Lock gflock; 349 G* gfree; 350 351 uint32 gcwaiting; // gc is waiting to run 352 int32 stopwait; 353 Note stopnote; 354 uint32 sysmonwait; 355 Note sysmonnote; 356 uint64 lastpoll; 357 358 int32 profilehz; // cpu profiling rate 359 }; 360 361 enum 362 { 363 // The max value of GOMAXPROCS. 364 // There are no fundamental restrictions on the value. 365 MaxGomaxprocs = 1<<8, 366 367 // Number of goroutine ids to grab from runtime_sched.goidgen to local per-P cache at once. 368 // 16 seems to provide enough amortization, but other than that it's mostly arbitrary number. 369 GoidCacheBatch = 16, 370 }; 371 372 Sched runtime_sched; 373 int32 runtime_gomaxprocs; 374 uint32 runtime_needextram = 1; 375 M runtime_m0; 376 G runtime_g0; // idle goroutine for m0 377 G* runtime_lastg; 378 M* runtime_allm; 379 P** runtime_allp; 380 M* runtime_extram; 381 int8* runtime_goos; 382 int32 runtime_ncpu; 383 bool runtime_precisestack; 384 static int32 newprocs; 385 386 static Lock allglock; // the following vars are protected by this lock or by stoptheworld 387 G** runtime_allg; 388 uintptr runtime_allglen; 389 static uintptr allgcap; 390 391 bool runtime_isarchive; 392 393 void* runtime_mstart(void*); 394 static void runqput(P*, G*); 395 static G* runqget(P*); 396 static bool runqputslow(P*, G*, uint32, uint32); 397 static G* runqsteal(P*, P*); 398 static void mput(M*); 399 static M* mget(void); 400 static void mcommoninit(M*); 401 static void schedule(void); 402 static void procresize(int32); 403 static void acquirep(P*); 404 static P* releasep(void); 405 static void newm(void(*)(void), P*); 406 static void stopm(void); 407 static void startm(P*, bool); 408 static void handoffp(P*); 409 static void wakep(void); 410 static void stoplockedm(void); 411 static void startlockedm(G*); 412 static void sysmon(void); 413 static uint32 retake(int64); 414 static void incidlelocked(int32); 415 static void checkdead(void); 416 static void exitsyscall0(G*); 417 static void park0(G*); 418 static void goexit0(G*); 419 static void gfput(P*, G*); 420 static G* gfget(P*); 421 static void gfpurge(P*); 422 static void globrunqput(G*); 423 static void globrunqputbatch(G*, G*, int32); 424 static G* globrunqget(P*, int32); 425 static P* pidleget(void); 426 static void pidleput(P*); 427 static void injectglist(G*); 428 static bool preemptall(void); 429 static bool exitsyscallfast(void); 430 static void allgadd(G*); 431 432 bool runtime_isstarted; 433 434 // The bootstrap sequence is: 435 // 436 // call osinit 437 // call schedinit 438 // make & queue new G 439 // call runtime_mstart 440 // 441 // The new G calls runtime_main. 442 void 443 runtime_schedinit(void) 444 { 445 int32 n, procs; 446 String s; 447 const byte *p; 448 Eface i; 449 450 m = &runtime_m0; 451 g = &runtime_g0; 452 m->g0 = g; 453 m->curg = g; 454 g->m = m; 455 456 initcontext(); 457 458 runtime_sched.maxmcount = 10000; 459 runtime_precisestack = 0; 460 461 // runtime_symtabinit(); 462 runtime_mallocinit(); 463 mcommoninit(m); 464 465 // Initialize the itable value for newErrorCString, 466 // so that the next time it gets called, possibly 467 // in a fault during a garbage collection, it will not 468 // need to allocated memory. 469 runtime_newErrorCString(0, &i); 470 471 // Initialize the cached gotraceback value, since 472 // gotraceback calls getenv, which mallocs on Plan 9. 473 runtime_gotraceback(nil); 474 475 runtime_goargs(); 476 runtime_goenvs(); 477 runtime_parsedebugvars(); 478 479 runtime_sched.lastpoll = runtime_nanotime(); 480 procs = 1; 481 s = runtime_getenv("GOMAXPROCS"); 482 p = s.str; 483 if(p != nil && (n = runtime_atoi(p, s.len)) > 0) { 484 if(n > MaxGomaxprocs) 485 n = MaxGomaxprocs; 486 procs = n; 487 } 488 runtime_allp = runtime_malloc((MaxGomaxprocs+1)*sizeof(runtime_allp[0])); 489 procresize(procs); 490 491 // Can not enable GC until all roots are registered. 492 // mstats.enablegc = 1; 493 } 494 495 extern void main_init(void) __asm__ (GOSYM_PREFIX "__go_init_main"); 496 extern void main_main(void) __asm__ (GOSYM_PREFIX "main.main"); 497 498 // Used to determine the field alignment. 499 500 struct field_align 501 { 502 char c; 503 Hchan *p; 504 }; 505 506 // main_init_done is a signal used by cgocallbackg that initialization 507 // has been completed. It is made before _cgo_notify_runtime_init_done, 508 // so all cgo calls can rely on it existing. When main_init is 509 // complete, it is closed, meaning cgocallbackg can reliably receive 510 // from it. 511 Hchan *runtime_main_init_done; 512 513 // The chan bool type, for runtime_main_init_done. 514 515 extern const struct __go_type_descriptor bool_type_descriptor 516 __asm__ (GOSYM_PREFIX "__go_tdn_bool"); 517 518 static struct __go_channel_type chan_bool_type_descriptor = 519 { 520 /* __common */ 521 { 522 /* __code */ 523 GO_CHAN, 524 /* __align */ 525 __alignof (Hchan *), 526 /* __field_align */ 527 offsetof (struct field_align, p) - 1, 528 /* __size */ 529 sizeof (Hchan *), 530 /* __hash */ 531 0, /* This value doesn't matter. */ 532 /* __hashfn */ 533 &__go_type_hash_error_descriptor, 534 /* __equalfn */ 535 &__go_type_equal_error_descriptor, 536 /* __gc */ 537 NULL, /* This value doesn't matter */ 538 /* __reflection */ 539 NULL, /* This value doesn't matter */ 540 /* __uncommon */ 541 NULL, 542 /* __pointer_to_this */ 543 NULL 544 }, 545 /* __element_type */ 546 &bool_type_descriptor, 547 /* __dir */ 548 CHANNEL_BOTH_DIR 549 }; 550 551 extern Hchan *__go_new_channel (ChanType *, uintptr); 552 extern void closechan(Hchan *) __asm__ (GOSYM_PREFIX "runtime.closechan"); 553 554 static void 555 initDone(void *arg __attribute__ ((unused))) { 556 runtime_unlockOSThread(); 557 }; 558 559 // The main goroutine. 560 // Note: C frames in general are not copyable during stack growth, for two reasons: 561 // 1) We don't know where in a frame to find pointers to other stack locations. 562 // 2) There's no guarantee that globals or heap values do not point into the frame. 563 // 564 // The C frame for runtime.main is copyable, because: 565 // 1) There are no pointers to other stack locations in the frame 566 // (d.fn points at a global, d.link is nil, d.argp is -1). 567 // 2) The only pointer into this frame is from the defer chain, 568 // which is explicitly handled during stack copying. 569 void 570 runtime_main(void* dummy __attribute__((unused))) 571 { 572 Defer d; 573 _Bool frame; 574 575 newm(sysmon, nil); 576 577 // Lock the main goroutine onto this, the main OS thread, 578 // during initialization. Most programs won't care, but a few 579 // do require certain calls to be made by the main thread. 580 // Those can arrange for main.main to run in the main thread 581 // by calling runtime.LockOSThread during initialization 582 // to preserve the lock. 583 runtime_lockOSThread(); 584 585 // Defer unlock so that runtime.Goexit during init does the unlock too. 586 d.__pfn = initDone; 587 d.__next = g->defer; 588 d.__arg = (void*)-1; 589 d.__panic = g->panic; 590 d.__retaddr = nil; 591 d.__makefunc_can_recover = 0; 592 d.__frame = &frame; 593 d.__special = true; 594 g->defer = &d; 595 596 if(m != &runtime_m0) 597 runtime_throw("runtime_main not on m0"); 598 __go_go(runtime_MHeap_Scavenger, nil); 599 600 runtime_main_init_done = __go_new_channel(&chan_bool_type_descriptor, 0); 601 602 _cgo_notify_runtime_init_done(); 603 604 main_init(); 605 606 closechan(runtime_main_init_done); 607 608 if(g->defer != &d || d.__pfn != initDone) 609 runtime_throw("runtime: bad defer entry after init"); 610 g->defer = d.__next; 611 runtime_unlockOSThread(); 612 613 // For gccgo we have to wait until after main is initialized 614 // to enable GC, because initializing main registers the GC 615 // roots. 616 mstats.enablegc = 1; 617 618 if(runtime_isarchive) { 619 // This is not a complete program, but is instead a 620 // library built using -buildmode=c-archive or 621 // c-shared. Now that we are initialized, there is 622 // nothing further to do. 623 return; 624 } 625 626 main_main(); 627 628 // Make racy client program work: if panicking on 629 // another goroutine at the same time as main returns, 630 // let the other goroutine finish printing the panic trace. 631 // Once it does, it will exit. See issue 3934. 632 if(runtime_panicking) 633 runtime_park(nil, nil, "panicwait"); 634 635 runtime_exit(0); 636 for(;;) 637 *(int32*)0 = 0; 638 } 639 640 void 641 runtime_goroutineheader(G *gp) 642 { 643 const char *status; 644 int64 waitfor; 645 646 switch(gp->status) { 647 case Gidle: 648 status = "idle"; 649 break; 650 case Grunnable: 651 status = "runnable"; 652 break; 653 case Grunning: 654 status = "running"; 655 break; 656 case Gsyscall: 657 status = "syscall"; 658 break; 659 case Gwaiting: 660 if(gp->waitreason) 661 status = gp->waitreason; 662 else 663 status = "waiting"; 664 break; 665 default: 666 status = "???"; 667 break; 668 } 669 670 // approx time the G is blocked, in minutes 671 waitfor = 0; 672 if((gp->status == Gwaiting || gp->status == Gsyscall) && gp->waitsince != 0) 673 waitfor = (runtime_nanotime() - gp->waitsince) / (60LL*1000*1000*1000); 674 675 if(waitfor < 1) 676 runtime_printf("goroutine %D [%s]:\n", gp->goid, status); 677 else 678 runtime_printf("goroutine %D [%s, %D minutes]:\n", gp->goid, status, waitfor); 679 } 680 681 void 682 runtime_printcreatedby(G *g) 683 { 684 if(g != nil && g->gopc != 0 && g->goid != 1) { 685 String fn; 686 String file; 687 intgo line; 688 689 if(__go_file_line(g->gopc - 1, &fn, &file, &line)) { 690 runtime_printf("created by %S\n", fn); 691 runtime_printf("\t%S:%D\n", file, (int64) line); 692 } 693 } 694 } 695 696 struct Traceback 697 { 698 G* gp; 699 Location locbuf[TracebackMaxFrames]; 700 int32 c; 701 }; 702 703 void 704 runtime_tracebackothers(G * volatile me) 705 { 706 G * volatile gp; 707 Traceback tb; 708 int32 traceback; 709 volatile uintptr i; 710 711 tb.gp = me; 712 traceback = runtime_gotraceback(nil); 713 714 // Show the current goroutine first, if we haven't already. 715 if((gp = m->curg) != nil && gp != me) { 716 runtime_printf("\n"); 717 runtime_goroutineheader(gp); 718 gp->traceback = &tb; 719 720 #ifdef USING_SPLIT_STACK 721 __splitstack_getcontext(&me->stack_context[0]); 722 #endif 723 getcontext(&me->context); 724 725 if(gp->traceback != nil) { 726 runtime_gogo(gp); 727 } 728 729 runtime_printtrace(tb.locbuf, tb.c, false); 730 runtime_printcreatedby(gp); 731 } 732 733 runtime_lock(&allglock); 734 for(i = 0; i < runtime_allglen; i++) { 735 gp = runtime_allg[i]; 736 if(gp == me || gp == m->curg || gp->status == Gdead) 737 continue; 738 if(gp->issystem && traceback < 2) 739 continue; 740 runtime_printf("\n"); 741 runtime_goroutineheader(gp); 742 743 // Our only mechanism for doing a stack trace is 744 // _Unwind_Backtrace. And that only works for the 745 // current thread, not for other random goroutines. 746 // So we need to switch context to the goroutine, get 747 // the backtrace, and then switch back. 748 749 // This means that if g is running or in a syscall, we 750 // can't reliably print a stack trace. FIXME. 751 752 if(gp->status == Grunning) { 753 runtime_printf("\tgoroutine running on other thread; stack unavailable\n"); 754 runtime_printcreatedby(gp); 755 } else if(gp->status == Gsyscall) { 756 runtime_printf("\tgoroutine in C code; stack unavailable\n"); 757 runtime_printcreatedby(gp); 758 } else { 759 gp->traceback = &tb; 760 761 #ifdef USING_SPLIT_STACK 762 __splitstack_getcontext(&me->stack_context[0]); 763 #endif 764 getcontext(&me->context); 765 766 if(gp->traceback != nil) { 767 runtime_gogo(gp); 768 } 769 770 runtime_printtrace(tb.locbuf, tb.c, false); 771 runtime_printcreatedby(gp); 772 } 773 } 774 runtime_unlock(&allglock); 775 } 776 777 static void 778 checkmcount(void) 779 { 780 // sched lock is held 781 if(runtime_sched.mcount > runtime_sched.maxmcount) { 782 runtime_printf("runtime: program exceeds %d-thread limit\n", runtime_sched.maxmcount); 783 runtime_throw("thread exhaustion"); 784 } 785 } 786 787 // Do a stack trace of gp, and then restore the context to 788 // gp->dotraceback. 789 790 static void 791 gtraceback(G* gp) 792 { 793 Traceback* traceback; 794 795 traceback = gp->traceback; 796 gp->traceback = nil; 797 traceback->c = runtime_callers(1, traceback->locbuf, 798 sizeof traceback->locbuf / sizeof traceback->locbuf[0], false); 799 runtime_gogo(traceback->gp); 800 } 801 802 static void 803 mcommoninit(M *mp) 804 { 805 // If there is no mcache runtime_callers() will crash, 806 // and we are most likely in sysmon thread so the stack is senseless anyway. 807 if(m->mcache) 808 runtime_callers(1, mp->createstack, nelem(mp->createstack), false); 809 810 mp->fastrand = 0x49f6428aUL + mp->id + runtime_cputicks(); 811 812 runtime_lock(&runtime_sched.lock); 813 mp->id = runtime_sched.mcount++; 814 checkmcount(); 815 runtime_mpreinit(mp); 816 817 // Add to runtime_allm so garbage collector doesn't free m 818 // when it is just in a register or thread-local storage. 819 mp->alllink = runtime_allm; 820 // runtime_NumCgoCall() iterates over allm w/o schedlock, 821 // so we need to publish it safely. 822 runtime_atomicstorep(&runtime_allm, mp); 823 runtime_unlock(&runtime_sched.lock); 824 } 825 826 // Mark gp ready to run. 827 void 828 runtime_ready(G *gp) 829 { 830 // Mark runnable. 831 m->locks++; // disable preemption because it can be holding p in a local var 832 if(gp->status != Gwaiting) { 833 runtime_printf("goroutine %D has status %d\n", gp->goid, gp->status); 834 runtime_throw("bad g->status in ready"); 835 } 836 gp->status = Grunnable; 837 runqput(m->p, gp); 838 if(runtime_atomicload(&runtime_sched.npidle) != 0 && runtime_atomicload(&runtime_sched.nmspinning) == 0) // TODO: fast atomic 839 wakep(); 840 m->locks--; 841 } 842 843 int32 844 runtime_gcprocs(void) 845 { 846 int32 n; 847 848 // Figure out how many CPUs to use during GC. 849 // Limited by gomaxprocs, number of actual CPUs, and MaxGcproc. 850 runtime_lock(&runtime_sched.lock); 851 n = runtime_gomaxprocs; 852 if(n > runtime_ncpu) 853 n = runtime_ncpu > 0 ? runtime_ncpu : 1; 854 if(n > MaxGcproc) 855 n = MaxGcproc; 856 if(n > runtime_sched.nmidle+1) // one M is currently running 857 n = runtime_sched.nmidle+1; 858 runtime_unlock(&runtime_sched.lock); 859 return n; 860 } 861 862 static bool 863 needaddgcproc(void) 864 { 865 int32 n; 866 867 runtime_lock(&runtime_sched.lock); 868 n = runtime_gomaxprocs; 869 if(n > runtime_ncpu) 870 n = runtime_ncpu; 871 if(n > MaxGcproc) 872 n = MaxGcproc; 873 n -= runtime_sched.nmidle+1; // one M is currently running 874 runtime_unlock(&runtime_sched.lock); 875 return n > 0; 876 } 877 878 void 879 runtime_helpgc(int32 nproc) 880 { 881 M *mp; 882 int32 n, pos; 883 884 runtime_lock(&runtime_sched.lock); 885 pos = 0; 886 for(n = 1; n < nproc; n++) { // one M is currently running 887 if(runtime_allp[pos]->mcache == m->mcache) 888 pos++; 889 mp = mget(); 890 if(mp == nil) 891 runtime_throw("runtime_gcprocs inconsistency"); 892 mp->helpgc = n; 893 mp->mcache = runtime_allp[pos]->mcache; 894 pos++; 895 runtime_notewakeup(&mp->park); 896 } 897 runtime_unlock(&runtime_sched.lock); 898 } 899 900 // Similar to stoptheworld but best-effort and can be called several times. 901 // There is no reverse operation, used during crashing. 902 // This function must not lock any mutexes. 903 void 904 runtime_freezetheworld(void) 905 { 906 int32 i; 907 908 if(runtime_gomaxprocs == 1) 909 return; 910 // stopwait and preemption requests can be lost 911 // due to races with concurrently executing threads, 912 // so try several times 913 for(i = 0; i < 5; i++) { 914 // this should tell the scheduler to not start any new goroutines 915 runtime_sched.stopwait = 0x7fffffff; 916 runtime_atomicstore((uint32*)&runtime_sched.gcwaiting, 1); 917 // this should stop running goroutines 918 if(!preemptall()) 919 break; // no running goroutines 920 runtime_usleep(1000); 921 } 922 // to be sure 923 runtime_usleep(1000); 924 preemptall(); 925 runtime_usleep(1000); 926 } 927 928 void 929 runtime_stoptheworld(void) 930 { 931 int32 i; 932 uint32 s; 933 P *p; 934 bool wait; 935 936 runtime_lock(&runtime_sched.lock); 937 runtime_sched.stopwait = runtime_gomaxprocs; 938 runtime_atomicstore((uint32*)&runtime_sched.gcwaiting, 1); 939 preemptall(); 940 // stop current P 941 m->p->status = Pgcstop; 942 runtime_sched.stopwait--; 943 // try to retake all P's in Psyscall status 944 for(i = 0; i < runtime_gomaxprocs; i++) { 945 p = runtime_allp[i]; 946 s = p->status; 947 if(s == Psyscall && runtime_cas(&p->status, s, Pgcstop)) 948 runtime_sched.stopwait--; 949 } 950 // stop idle P's 951 while((p = pidleget()) != nil) { 952 p->status = Pgcstop; 953 runtime_sched.stopwait--; 954 } 955 wait = runtime_sched.stopwait > 0; 956 runtime_unlock(&runtime_sched.lock); 957 958 // wait for remaining P's to stop voluntarily 959 if(wait) { 960 runtime_notesleep(&runtime_sched.stopnote); 961 runtime_noteclear(&runtime_sched.stopnote); 962 } 963 if(runtime_sched.stopwait) 964 runtime_throw("stoptheworld: not stopped"); 965 for(i = 0; i < runtime_gomaxprocs; i++) { 966 p = runtime_allp[i]; 967 if(p->status != Pgcstop) 968 runtime_throw("stoptheworld: not stopped"); 969 } 970 } 971 972 static void 973 mhelpgc(void) 974 { 975 m->helpgc = -1; 976 } 977 978 void 979 runtime_starttheworld(void) 980 { 981 P *p, *p1; 982 M *mp; 983 G *gp; 984 bool add; 985 986 m->locks++; // disable preemption because it can be holding p in a local var 987 gp = runtime_netpoll(false); // non-blocking 988 injectglist(gp); 989 add = needaddgcproc(); 990 runtime_lock(&runtime_sched.lock); 991 if(newprocs) { 992 procresize(newprocs); 993 newprocs = 0; 994 } else 995 procresize(runtime_gomaxprocs); 996 runtime_sched.gcwaiting = 0; 997 998 p1 = nil; 999 while((p = pidleget()) != nil) { 1000 // procresize() puts p's with work at the beginning of the list. 1001 // Once we reach a p without a run queue, the rest don't have one either. 1002 if(p->runqhead == p->runqtail) { 1003 pidleput(p); 1004 break; 1005 } 1006 p->m = mget(); 1007 p->link = p1; 1008 p1 = p; 1009 } 1010 if(runtime_sched.sysmonwait) { 1011 runtime_sched.sysmonwait = false; 1012 runtime_notewakeup(&runtime_sched.sysmonnote); 1013 } 1014 runtime_unlock(&runtime_sched.lock); 1015 1016 while(p1) { 1017 p = p1; 1018 p1 = p1->link; 1019 if(p->m) { 1020 mp = p->m; 1021 p->m = nil; 1022 if(mp->nextp) 1023 runtime_throw("starttheworld: inconsistent mp->nextp"); 1024 mp->nextp = p; 1025 runtime_notewakeup(&mp->park); 1026 } else { 1027 // Start M to run P. Do not start another M below. 1028 newm(nil, p); 1029 add = false; 1030 } 1031 } 1032 1033 if(add) { 1034 // If GC could have used another helper proc, start one now, 1035 // in the hope that it will be available next time. 1036 // It would have been even better to start it before the collection, 1037 // but doing so requires allocating memory, so it's tricky to 1038 // coordinate. This lazy approach works out in practice: 1039 // we don't mind if the first couple gc rounds don't have quite 1040 // the maximum number of procs. 1041 newm(mhelpgc, nil); 1042 } 1043 m->locks--; 1044 } 1045 1046 // Called to start an M. 1047 void* 1048 runtime_mstart(void* mp) 1049 { 1050 m = (M*)mp; 1051 g = m->g0; 1052 1053 initcontext(); 1054 1055 g->entry = nil; 1056 g->param = nil; 1057 1058 // Record top of stack for use by mcall. 1059 // Once we call schedule we're never coming back, 1060 // so other calls can reuse this stack space. 1061 #ifdef USING_SPLIT_STACK 1062 __splitstack_getcontext(&g->stack_context[0]); 1063 #else 1064 g->gcinitial_sp = ∓ 1065 // Setting gcstack_size to 0 is a marker meaning that gcinitial_sp 1066 // is the top of the stack, not the bottom. 1067 g->gcstack_size = 0; 1068 g->gcnext_sp = ∓ 1069 #endif 1070 getcontext(&g->context); 1071 1072 if(g->entry != nil) { 1073 // Got here from mcall. 1074 void (*pfn)(G*) = (void (*)(G*))g->entry; 1075 G* gp = (G*)g->param; 1076 pfn(gp); 1077 *(int*)0x21 = 0x21; 1078 } 1079 runtime_minit(); 1080 1081 #ifdef USING_SPLIT_STACK 1082 { 1083 int dont_block_signals = 0; 1084 __splitstack_block_signals(&dont_block_signals, nil); 1085 } 1086 #endif 1087 1088 // Install signal handlers; after minit so that minit can 1089 // prepare the thread to be able to handle the signals. 1090 if(m == &runtime_m0) { 1091 if(runtime_iscgo && !runtime_cgoHasExtraM) { 1092 runtime_cgoHasExtraM = true; 1093 runtime_newextram(); 1094 runtime_needextram = 0; 1095 } 1096 runtime_initsig(); 1097 } 1098 1099 if(m->mstartfn) 1100 m->mstartfn(); 1101 1102 if(m->helpgc) { 1103 m->helpgc = 0; 1104 stopm(); 1105 } else if(m != &runtime_m0) { 1106 acquirep(m->nextp); 1107 m->nextp = nil; 1108 } 1109 schedule(); 1110 1111 // TODO(brainman): This point is never reached, because scheduler 1112 // does not release os threads at the moment. But once this path 1113 // is enabled, we must remove our seh here. 1114 1115 return nil; 1116 } 1117 1118 typedef struct CgoThreadStart CgoThreadStart; 1119 struct CgoThreadStart 1120 { 1121 M *m; 1122 G *g; 1123 uintptr *tls; 1124 void (*fn)(void); 1125 }; 1126 1127 // Allocate a new m unassociated with any thread. 1128 // Can use p for allocation context if needed. 1129 M* 1130 runtime_allocm(P *p, int32 stacksize, byte** ret_g0_stack, size_t* ret_g0_stacksize) 1131 { 1132 M *mp; 1133 1134 m->locks++; // disable GC because it can be called from sysmon 1135 if(m->p == nil) 1136 acquirep(p); // temporarily borrow p for mallocs in this function 1137 #if 0 1138 if(mtype == nil) { 1139 Eface e; 1140 runtime_gc_m_ptr(&e); 1141 mtype = ((const PtrType*)e.__type_descriptor)->__element_type; 1142 } 1143 #endif 1144 1145 mp = runtime_mal(sizeof *mp); 1146 mcommoninit(mp); 1147 mp->g0 = runtime_malg(stacksize, ret_g0_stack, ret_g0_stacksize); 1148 1149 if(p == m->p) 1150 releasep(); 1151 m->locks--; 1152 1153 return mp; 1154 } 1155 1156 static G* 1157 allocg(void) 1158 { 1159 G *gp; 1160 // static Type *gtype; 1161 1162 // if(gtype == nil) { 1163 // Eface e; 1164 // runtime_gc_g_ptr(&e); 1165 // gtype = ((PtrType*)e.__type_descriptor)->__element_type; 1166 // } 1167 // gp = runtime_cnew(gtype); 1168 gp = runtime_malloc(sizeof(G)); 1169 return gp; 1170 } 1171 1172 static M* lockextra(bool nilokay); 1173 static void unlockextra(M*); 1174 1175 // needm is called when a cgo callback happens on a 1176 // thread without an m (a thread not created by Go). 1177 // In this case, needm is expected to find an m to use 1178 // and return with m, g initialized correctly. 1179 // Since m and g are not set now (likely nil, but see below) 1180 // needm is limited in what routines it can call. In particular 1181 // it can only call nosplit functions (textflag 7) and cannot 1182 // do any scheduling that requires an m. 1183 // 1184 // In order to avoid needing heavy lifting here, we adopt 1185 // the following strategy: there is a stack of available m's 1186 // that can be stolen. Using compare-and-swap 1187 // to pop from the stack has ABA races, so we simulate 1188 // a lock by doing an exchange (via casp) to steal the stack 1189 // head and replace the top pointer with MLOCKED (1). 1190 // This serves as a simple spin lock that we can use even 1191 // without an m. The thread that locks the stack in this way 1192 // unlocks the stack by storing a valid stack head pointer. 1193 // 1194 // In order to make sure that there is always an m structure 1195 // available to be stolen, we maintain the invariant that there 1196 // is always one more than needed. At the beginning of the 1197 // program (if cgo is in use) the list is seeded with a single m. 1198 // If needm finds that it has taken the last m off the list, its job 1199 // is - once it has installed its own m so that it can do things like 1200 // allocate memory - to create a spare m and put it on the list. 1201 // 1202 // Each of these extra m's also has a g0 and a curg that are 1203 // pressed into service as the scheduling stack and current 1204 // goroutine for the duration of the cgo callback. 1205 // 1206 // When the callback is done with the m, it calls dropm to 1207 // put the m back on the list. 1208 // 1209 // Unlike the gc toolchain, we start running on curg, since we are 1210 // just going to return and let the caller continue. 1211 void 1212 runtime_needm(void) 1213 { 1214 M *mp; 1215 1216 if(runtime_needextram) { 1217 // Can happen if C/C++ code calls Go from a global ctor. 1218 // Can not throw, because scheduler is not initialized yet. 1219 int rv __attribute__((unused)); 1220 rv = runtime_write(2, "fatal error: cgo callback before cgo call\n", 1221 sizeof("fatal error: cgo callback before cgo call\n")-1); 1222 runtime_exit(1); 1223 } 1224 1225 // Lock extra list, take head, unlock popped list. 1226 // nilokay=false is safe here because of the invariant above, 1227 // that the extra list always contains or will soon contain 1228 // at least one m. 1229 mp = lockextra(false); 1230 1231 // Set needextram when we've just emptied the list, 1232 // so that the eventual call into cgocallbackg will 1233 // allocate a new m for the extra list. We delay the 1234 // allocation until then so that it can be done 1235 // after exitsyscall makes sure it is okay to be 1236 // running at all (that is, there's no garbage collection 1237 // running right now). 1238 mp->needextram = mp->schedlink == nil; 1239 unlockextra(mp->schedlink); 1240 1241 // Install m and g (= m->curg). 1242 runtime_setmg(mp, mp->curg); 1243 1244 // Initialize g's context as in mstart. 1245 initcontext(); 1246 g->status = Gsyscall; 1247 g->entry = nil; 1248 g->param = nil; 1249 #ifdef USING_SPLIT_STACK 1250 __splitstack_getcontext(&g->stack_context[0]); 1251 #else 1252 g->gcinitial_sp = ∓ 1253 g->gcstack = nil; 1254 g->gcstack_size = 0; 1255 g->gcnext_sp = ∓ 1256 #endif 1257 getcontext(&g->context); 1258 1259 if(g->entry != nil) { 1260 // Got here from mcall. 1261 void (*pfn)(G*) = (void (*)(G*))g->entry; 1262 G* gp = (G*)g->param; 1263 pfn(gp); 1264 *(int*)0x22 = 0x22; 1265 } 1266 1267 // Initialize this thread to use the m. 1268 runtime_minit(); 1269 1270 #ifdef USING_SPLIT_STACK 1271 { 1272 int dont_block_signals = 0; 1273 __splitstack_block_signals(&dont_block_signals, nil); 1274 } 1275 #endif 1276 } 1277 1278 // newextram allocates an m and puts it on the extra list. 1279 // It is called with a working local m, so that it can do things 1280 // like call schedlock and allocate. 1281 void 1282 runtime_newextram(void) 1283 { 1284 M *mp, *mnext; 1285 G *gp; 1286 byte *g0_sp, *sp; 1287 size_t g0_spsize, spsize; 1288 1289 // Create extra goroutine locked to extra m. 1290 // The goroutine is the context in which the cgo callback will run. 1291 // The sched.pc will never be returned to, but setting it to 1292 // runtime.goexit makes clear to the traceback routines where 1293 // the goroutine stack ends. 1294 mp = runtime_allocm(nil, StackMin, &g0_sp, &g0_spsize); 1295 gp = runtime_malg(StackMin, &sp, &spsize); 1296 gp->status = Gdead; 1297 mp->curg = gp; 1298 mp->locked = LockInternal; 1299 mp->lockedg = gp; 1300 gp->lockedm = mp; 1301 gp->goid = runtime_xadd64(&runtime_sched.goidgen, 1); 1302 // put on allg for garbage collector 1303 allgadd(gp); 1304 1305 // The context for gp will be set up in runtime_needm. But 1306 // here we need to set up the context for g0. 1307 getcontext(&mp->g0->context); 1308 mp->g0->context.uc_stack.ss_sp = g0_sp; 1309 mp->g0->context.uc_stack.ss_size = g0_spsize; 1310 makecontext(&mp->g0->context, kickoff, 0); 1311 1312 // Add m to the extra list. 1313 mnext = lockextra(true); 1314 mp->schedlink = mnext; 1315 unlockextra(mp); 1316 } 1317 1318 // dropm is called when a cgo callback has called needm but is now 1319 // done with the callback and returning back into the non-Go thread. 1320 // It puts the current m back onto the extra list. 1321 // 1322 // The main expense here is the call to signalstack to release the 1323 // m's signal stack, and then the call to needm on the next callback 1324 // from this thread. It is tempting to try to save the m for next time, 1325 // which would eliminate both these costs, but there might not be 1326 // a next time: the current thread (which Go does not control) might exit. 1327 // If we saved the m for that thread, there would be an m leak each time 1328 // such a thread exited. Instead, we acquire and release an m on each 1329 // call. These should typically not be scheduling operations, just a few 1330 // atomics, so the cost should be small. 1331 // 1332 // TODO(rsc): An alternative would be to allocate a dummy pthread per-thread 1333 // variable using pthread_key_create. Unlike the pthread keys we already use 1334 // on OS X, this dummy key would never be read by Go code. It would exist 1335 // only so that we could register at thread-exit-time destructor. 1336 // That destructor would put the m back onto the extra list. 1337 // This is purely a performance optimization. The current version, 1338 // in which dropm happens on each cgo call, is still correct too. 1339 // We may have to keep the current version on systems with cgo 1340 // but without pthreads, like Windows. 1341 void 1342 runtime_dropm(void) 1343 { 1344 M *mp, *mnext; 1345 1346 // Undo whatever initialization minit did during needm. 1347 runtime_unminit(); 1348 1349 // Clear m and g, and return m to the extra list. 1350 // After the call to setmg we can only call nosplit functions. 1351 mp = m; 1352 runtime_setmg(nil, nil); 1353 1354 mp->curg->status = Gdead; 1355 mp->curg->gcstack = nil; 1356 mp->curg->gcnext_sp = nil; 1357 1358 mnext = lockextra(true); 1359 mp->schedlink = mnext; 1360 unlockextra(mp); 1361 } 1362 1363 #define MLOCKED ((M*)1) 1364 1365 // lockextra locks the extra list and returns the list head. 1366 // The caller must unlock the list by storing a new list head 1367 // to runtime.extram. If nilokay is true, then lockextra will 1368 // return a nil list head if that's what it finds. If nilokay is false, 1369 // lockextra will keep waiting until the list head is no longer nil. 1370 static M* 1371 lockextra(bool nilokay) 1372 { 1373 M *mp; 1374 void (*yield)(void); 1375 1376 for(;;) { 1377 mp = runtime_atomicloadp(&runtime_extram); 1378 if(mp == MLOCKED) { 1379 yield = runtime_osyield; 1380 yield(); 1381 continue; 1382 } 1383 if(mp == nil && !nilokay) { 1384 runtime_usleep(1); 1385 continue; 1386 } 1387 if(!runtime_casp(&runtime_extram, mp, MLOCKED)) { 1388 yield = runtime_osyield; 1389 yield(); 1390 continue; 1391 } 1392 break; 1393 } 1394 return mp; 1395 } 1396 1397 static void 1398 unlockextra(M *mp) 1399 { 1400 runtime_atomicstorep(&runtime_extram, mp); 1401 } 1402 1403 static int32 1404 countextra() 1405 { 1406 M *mp, *mc; 1407 int32 c; 1408 1409 for(;;) { 1410 mp = runtime_atomicloadp(&runtime_extram); 1411 if(mp == MLOCKED) { 1412 runtime_osyield(); 1413 continue; 1414 } 1415 if(!runtime_casp(&runtime_extram, mp, MLOCKED)) { 1416 runtime_osyield(); 1417 continue; 1418 } 1419 c = 0; 1420 for(mc = mp; mc != nil; mc = mc->schedlink) 1421 c++; 1422 runtime_atomicstorep(&runtime_extram, mp); 1423 return c; 1424 } 1425 } 1426 1427 // Create a new m. It will start off with a call to fn, or else the scheduler. 1428 static void 1429 newm(void(*fn)(void), P *p) 1430 { 1431 M *mp; 1432 1433 mp = runtime_allocm(p, -1, nil, nil); 1434 mp->nextp = p; 1435 mp->mstartfn = fn; 1436 1437 runtime_newosproc(mp); 1438 } 1439 1440 // Stops execution of the current m until new work is available. 1441 // Returns with acquired P. 1442 static void 1443 stopm(void) 1444 { 1445 if(m->locks) 1446 runtime_throw("stopm holding locks"); 1447 if(m->p) 1448 runtime_throw("stopm holding p"); 1449 if(m->spinning) { 1450 m->spinning = false; 1451 runtime_xadd(&runtime_sched.nmspinning, -1); 1452 } 1453 1454 retry: 1455 runtime_lock(&runtime_sched.lock); 1456 mput(m); 1457 runtime_unlock(&runtime_sched.lock); 1458 runtime_notesleep(&m->park); 1459 runtime_noteclear(&m->park); 1460 if(m->helpgc) { 1461 runtime_gchelper(); 1462 m->helpgc = 0; 1463 m->mcache = nil; 1464 goto retry; 1465 } 1466 acquirep(m->nextp); 1467 m->nextp = nil; 1468 } 1469 1470 static void 1471 mspinning(void) 1472 { 1473 m->spinning = true; 1474 } 1475 1476 // Schedules some M to run the p (creates an M if necessary). 1477 // If p==nil, tries to get an idle P, if no idle P's does nothing. 1478 static void 1479 startm(P *p, bool spinning) 1480 { 1481 M *mp; 1482 void (*fn)(void); 1483 1484 runtime_lock(&runtime_sched.lock); 1485 if(p == nil) { 1486 p = pidleget(); 1487 if(p == nil) { 1488 runtime_unlock(&runtime_sched.lock); 1489 if(spinning) 1490 runtime_xadd(&runtime_sched.nmspinning, -1); 1491 return; 1492 } 1493 } 1494 mp = mget(); 1495 runtime_unlock(&runtime_sched.lock); 1496 if(mp == nil) { 1497 fn = nil; 1498 if(spinning) 1499 fn = mspinning; 1500 newm(fn, p); 1501 return; 1502 } 1503 if(mp->spinning) 1504 runtime_throw("startm: m is spinning"); 1505 if(mp->nextp) 1506 runtime_throw("startm: m has p"); 1507 mp->spinning = spinning; 1508 mp->nextp = p; 1509 runtime_notewakeup(&mp->park); 1510 } 1511 1512 // Hands off P from syscall or locked M. 1513 static void 1514 handoffp(P *p) 1515 { 1516 // if it has local work, start it straight away 1517 if(p->runqhead != p->runqtail || runtime_sched.runqsize) { 1518 startm(p, false); 1519 return; 1520 } 1521 // no local work, check that there are no spinning/idle M's, 1522 // otherwise our help is not required 1523 if(runtime_atomicload(&runtime_sched.nmspinning) + runtime_atomicload(&runtime_sched.npidle) == 0 && // TODO: fast atomic 1524 runtime_cas(&runtime_sched.nmspinning, 0, 1)) { 1525 startm(p, true); 1526 return; 1527 } 1528 runtime_lock(&runtime_sched.lock); 1529 if(runtime_sched.gcwaiting) { 1530 p->status = Pgcstop; 1531 if(--runtime_sched.stopwait == 0) 1532 runtime_notewakeup(&runtime_sched.stopnote); 1533 runtime_unlock(&runtime_sched.lock); 1534 return; 1535 } 1536 if(runtime_sched.runqsize) { 1537 runtime_unlock(&runtime_sched.lock); 1538 startm(p, false); 1539 return; 1540 } 1541 // If this is the last running P and nobody is polling network, 1542 // need to wakeup another M to poll network. 1543 if(runtime_sched.npidle == (uint32)runtime_gomaxprocs-1 && runtime_atomicload64(&runtime_sched.lastpoll) != 0) { 1544 runtime_unlock(&runtime_sched.lock); 1545 startm(p, false); 1546 return; 1547 } 1548 pidleput(p); 1549 runtime_unlock(&runtime_sched.lock); 1550 } 1551 1552 // Tries to add one more P to execute G's. 1553 // Called when a G is made runnable (newproc, ready). 1554 static void 1555 wakep(void) 1556 { 1557 // be conservative about spinning threads 1558 if(!runtime_cas(&runtime_sched.nmspinning, 0, 1)) 1559 return; 1560 startm(nil, true); 1561 } 1562 1563 // Stops execution of the current m that is locked to a g until the g is runnable again. 1564 // Returns with acquired P. 1565 static void 1566 stoplockedm(void) 1567 { 1568 P *p; 1569 1570 if(m->lockedg == nil || m->lockedg->lockedm != m) 1571 runtime_throw("stoplockedm: inconsistent locking"); 1572 if(m->p) { 1573 // Schedule another M to run this p. 1574 p = releasep(); 1575 handoffp(p); 1576 } 1577 incidlelocked(1); 1578 // Wait until another thread schedules lockedg again. 1579 runtime_notesleep(&m->park); 1580 runtime_noteclear(&m->park); 1581 if(m->lockedg->status != Grunnable) 1582 runtime_throw("stoplockedm: not runnable"); 1583 acquirep(m->nextp); 1584 m->nextp = nil; 1585 } 1586 1587 // Schedules the locked m to run the locked gp. 1588 static void 1589 startlockedm(G *gp) 1590 { 1591 M *mp; 1592 P *p; 1593 1594 mp = gp->lockedm; 1595 if(mp == m) 1596 runtime_throw("startlockedm: locked to me"); 1597 if(mp->nextp) 1598 runtime_throw("startlockedm: m has p"); 1599 // directly handoff current P to the locked m 1600 incidlelocked(-1); 1601 p = releasep(); 1602 mp->nextp = p; 1603 runtime_notewakeup(&mp->park); 1604 stopm(); 1605 } 1606 1607 // Stops the current m for stoptheworld. 1608 // Returns when the world is restarted. 1609 static void 1610 gcstopm(void) 1611 { 1612 P *p; 1613 1614 if(!runtime_sched.gcwaiting) 1615 runtime_throw("gcstopm: not waiting for gc"); 1616 if(m->spinning) { 1617 m->spinning = false; 1618 runtime_xadd(&runtime_sched.nmspinning, -1); 1619 } 1620 p = releasep(); 1621 runtime_lock(&runtime_sched.lock); 1622 p->status = Pgcstop; 1623 if(--runtime_sched.stopwait == 0) 1624 runtime_notewakeup(&runtime_sched.stopnote); 1625 runtime_unlock(&runtime_sched.lock); 1626 stopm(); 1627 } 1628 1629 // Schedules gp to run on the current M. 1630 // Never returns. 1631 static void 1632 execute(G *gp) 1633 { 1634 int32 hz; 1635 1636 if(gp->status != Grunnable) { 1637 runtime_printf("execute: bad g status %d\n", gp->status); 1638 runtime_throw("execute: bad g status"); 1639 } 1640 gp->status = Grunning; 1641 gp->waitsince = 0; 1642 m->p->schedtick++; 1643 m->curg = gp; 1644 gp->m = m; 1645 1646 // Check whether the profiler needs to be turned on or off. 1647 hz = runtime_sched.profilehz; 1648 if(m->profilehz != hz) 1649 runtime_resetcpuprofiler(hz); 1650 1651 runtime_gogo(gp); 1652 } 1653 1654 // Finds a runnable goroutine to execute. 1655 // Tries to steal from other P's, get g from global queue, poll network. 1656 static G* 1657 findrunnable(void) 1658 { 1659 G *gp; 1660 P *p; 1661 int32 i; 1662 1663 top: 1664 if(runtime_sched.gcwaiting) { 1665 gcstopm(); 1666 goto top; 1667 } 1668 if(runtime_fingwait && runtime_fingwake && (gp = runtime_wakefing()) != nil) 1669 runtime_ready(gp); 1670 // local runq 1671 gp = runqget(m->p); 1672 if(gp) 1673 return gp; 1674 // global runq 1675 if(runtime_sched.runqsize) { 1676 runtime_lock(&runtime_sched.lock); 1677 gp = globrunqget(m->p, 0); 1678 runtime_unlock(&runtime_sched.lock); 1679 if(gp) 1680 return gp; 1681 } 1682 // poll network 1683 gp = runtime_netpoll(false); // non-blocking 1684 if(gp) { 1685 injectglist(gp->schedlink); 1686 gp->status = Grunnable; 1687 return gp; 1688 } 1689 // If number of spinning M's >= number of busy P's, block. 1690 // This is necessary to prevent excessive CPU consumption 1691 // when GOMAXPROCS>>1 but the program parallelism is low. 1692 if(!m->spinning && 2 * runtime_atomicload(&runtime_sched.nmspinning) >= runtime_gomaxprocs - runtime_atomicload(&runtime_sched.npidle)) // TODO: fast atomic 1693 goto stop; 1694 if(!m->spinning) { 1695 m->spinning = true; 1696 runtime_xadd(&runtime_sched.nmspinning, 1); 1697 } 1698 // random steal from other P's 1699 for(i = 0; i < 2*runtime_gomaxprocs; i++) { 1700 if(runtime_sched.gcwaiting) 1701 goto top; 1702 p = runtime_allp[runtime_fastrand1()%runtime_gomaxprocs]; 1703 if(p == m->p) 1704 gp = runqget(p); 1705 else 1706 gp = runqsteal(m->p, p); 1707 if(gp) 1708 return gp; 1709 } 1710 stop: 1711 // return P and block 1712 runtime_lock(&runtime_sched.lock); 1713 if(runtime_sched.gcwaiting) { 1714 runtime_unlock(&runtime_sched.lock); 1715 goto top; 1716 } 1717 if(runtime_sched.runqsize) { 1718 gp = globrunqget(m->p, 0); 1719 runtime_unlock(&runtime_sched.lock); 1720 return gp; 1721 } 1722 p = releasep(); 1723 pidleput(p); 1724 runtime_unlock(&runtime_sched.lock); 1725 if(m->spinning) { 1726 m->spinning = false; 1727 runtime_xadd(&runtime_sched.nmspinning, -1); 1728 } 1729 // check all runqueues once again 1730 for(i = 0; i < runtime_gomaxprocs; i++) { 1731 p = runtime_allp[i]; 1732 if(p && p->runqhead != p->runqtail) { 1733 runtime_lock(&runtime_sched.lock); 1734 p = pidleget(); 1735 runtime_unlock(&runtime_sched.lock); 1736 if(p) { 1737 acquirep(p); 1738 goto top; 1739 } 1740 break; 1741 } 1742 } 1743 // poll network 1744 if(runtime_xchg64(&runtime_sched.lastpoll, 0) != 0) { 1745 if(m->p) 1746 runtime_throw("findrunnable: netpoll with p"); 1747 if(m->spinning) 1748 runtime_throw("findrunnable: netpoll with spinning"); 1749 gp = runtime_netpoll(true); // block until new work is available 1750 runtime_atomicstore64(&runtime_sched.lastpoll, runtime_nanotime()); 1751 if(gp) { 1752 runtime_lock(&runtime_sched.lock); 1753 p = pidleget(); 1754 runtime_unlock(&runtime_sched.lock); 1755 if(p) { 1756 acquirep(p); 1757 injectglist(gp->schedlink); 1758 gp->status = Grunnable; 1759 return gp; 1760 } 1761 injectglist(gp); 1762 } 1763 } 1764 stopm(); 1765 goto top; 1766 } 1767 1768 static void 1769 resetspinning(void) 1770 { 1771 int32 nmspinning; 1772 1773 if(m->spinning) { 1774 m->spinning = false; 1775 nmspinning = runtime_xadd(&runtime_sched.nmspinning, -1); 1776 if(nmspinning < 0) 1777 runtime_throw("findrunnable: negative nmspinning"); 1778 } else 1779 nmspinning = runtime_atomicload(&runtime_sched.nmspinning); 1780 1781 // M wakeup policy is deliberately somewhat conservative (see nmspinning handling), 1782 // so see if we need to wakeup another P here. 1783 if (nmspinning == 0 && runtime_atomicload(&runtime_sched.npidle) > 0) 1784 wakep(); 1785 } 1786 1787 // Injects the list of runnable G's into the scheduler. 1788 // Can run concurrently with GC. 1789 static void 1790 injectglist(G *glist) 1791 { 1792 int32 n; 1793 G *gp; 1794 1795 if(glist == nil) 1796 return; 1797 runtime_lock(&runtime_sched.lock); 1798 for(n = 0; glist; n++) { 1799 gp = glist; 1800 glist = gp->schedlink; 1801 gp->status = Grunnable; 1802 globrunqput(gp); 1803 } 1804 runtime_unlock(&runtime_sched.lock); 1805 1806 for(; n && runtime_sched.npidle; n--) 1807 startm(nil, false); 1808 } 1809 1810 // One round of scheduler: find a runnable goroutine and execute it. 1811 // Never returns. 1812 static void 1813 schedule(void) 1814 { 1815 G *gp; 1816 uint32 tick; 1817 1818 if(m->locks) 1819 runtime_throw("schedule: holding locks"); 1820 1821 top: 1822 if(runtime_sched.gcwaiting) { 1823 gcstopm(); 1824 goto top; 1825 } 1826 1827 gp = nil; 1828 // Check the global runnable queue once in a while to ensure fairness. 1829 // Otherwise two goroutines can completely occupy the local runqueue 1830 // by constantly respawning each other. 1831 tick = m->p->schedtick; 1832 // This is a fancy way to say tick%61==0, 1833 // it uses 2 MUL instructions instead of a single DIV and so is faster on modern processors. 1834 if(tick - (((uint64)tick*0x4325c53fu)>>36)*61 == 0 && runtime_sched.runqsize > 0) { 1835 runtime_lock(&runtime_sched.lock); 1836 gp = globrunqget(m->p, 1); 1837 runtime_unlock(&runtime_sched.lock); 1838 if(gp) 1839 resetspinning(); 1840 } 1841 if(gp == nil) { 1842 gp = runqget(m->p); 1843 if(gp && m->spinning) 1844 runtime_throw("schedule: spinning with local work"); 1845 } 1846 if(gp == nil) { 1847 gp = findrunnable(); // blocks until work is available 1848 resetspinning(); 1849 } 1850 1851 if(gp->lockedm) { 1852 // Hands off own p to the locked m, 1853 // then blocks waiting for a new p. 1854 startlockedm(gp); 1855 goto top; 1856 } 1857 1858 execute(gp); 1859 } 1860 1861 // Puts the current goroutine into a waiting state and calls unlockf. 1862 // If unlockf returns false, the goroutine is resumed. 1863 void 1864 runtime_park(bool(*unlockf)(G*, void*), void *lock, const char *reason) 1865 { 1866 if(g->status != Grunning) 1867 runtime_throw("bad g status"); 1868 m->waitlock = lock; 1869 m->waitunlockf = unlockf; 1870 g->waitreason = reason; 1871 runtime_mcall(park0); 1872 } 1873 1874 static bool 1875 parkunlock(G *gp, void *lock) 1876 { 1877 USED(gp); 1878 runtime_unlock(lock); 1879 return true; 1880 } 1881 1882 // Puts the current goroutine into a waiting state and unlocks the lock. 1883 // The goroutine can be made runnable again by calling runtime_ready(gp). 1884 void 1885 runtime_parkunlock(Lock *lock, const char *reason) 1886 { 1887 runtime_park(parkunlock, lock, reason); 1888 } 1889 1890 // runtime_park continuation on g0. 1891 static void 1892 park0(G *gp) 1893 { 1894 bool ok; 1895 1896 gp->status = Gwaiting; 1897 gp->m = nil; 1898 m->curg = nil; 1899 if(m->waitunlockf) { 1900 ok = m->waitunlockf(gp, m->waitlock); 1901 m->waitunlockf = nil; 1902 m->waitlock = nil; 1903 if(!ok) { 1904 gp->status = Grunnable; 1905 execute(gp); // Schedule it back, never returns. 1906 } 1907 } 1908 if(m->lockedg) { 1909 stoplockedm(); 1910 execute(gp); // Never returns. 1911 } 1912 schedule(); 1913 } 1914 1915 // Scheduler yield. 1916 void 1917 runtime_gosched(void) 1918 { 1919 if(g->status != Grunning) 1920 runtime_throw("bad g status"); 1921 runtime_mcall(runtime_gosched0); 1922 } 1923 1924 // runtime_gosched continuation on g0. 1925 void 1926 runtime_gosched0(G *gp) 1927 { 1928 gp->status = Grunnable; 1929 gp->m = nil; 1930 m->curg = nil; 1931 runtime_lock(&runtime_sched.lock); 1932 globrunqput(gp); 1933 runtime_unlock(&runtime_sched.lock); 1934 if(m->lockedg) { 1935 stoplockedm(); 1936 execute(gp); // Never returns. 1937 } 1938 schedule(); 1939 } 1940 1941 // Finishes execution of the current goroutine. 1942 // Need to mark it as nosplit, because it runs with sp > stackbase (as runtime_lessstack). 1943 // Since it does not return it does not matter. But if it is preempted 1944 // at the split stack check, GC will complain about inconsistent sp. 1945 void runtime_goexit(void) __attribute__ ((noinline)); 1946 void 1947 runtime_goexit(void) 1948 { 1949 if(g->status != Grunning) 1950 runtime_throw("bad g status"); 1951 runtime_mcall(goexit0); 1952 } 1953 1954 // runtime_goexit continuation on g0. 1955 static void 1956 goexit0(G *gp) 1957 { 1958 gp->status = Gdead; 1959 gp->entry = nil; 1960 gp->m = nil; 1961 gp->lockedm = nil; 1962 gp->paniconfault = 0; 1963 gp->defer = nil; // should be true already but just in case. 1964 gp->panic = nil; // non-nil for Goexit during panic. points at stack-allocated data. 1965 gp->writenbuf = 0; 1966 gp->writebuf = nil; 1967 gp->waitreason = nil; 1968 gp->param = nil; 1969 m->curg = nil; 1970 m->lockedg = nil; 1971 if(m->locked & ~LockExternal) { 1972 runtime_printf("invalid m->locked = %d\n", m->locked); 1973 runtime_throw("internal lockOSThread error"); 1974 } 1975 m->locked = 0; 1976 gfput(m->p, gp); 1977 schedule(); 1978 } 1979 1980 // The goroutine g is about to enter a system call. 1981 // Record that it's not using the cpu anymore. 1982 // This is called only from the go syscall library and cgocall, 1983 // not from the low-level system calls used by the runtime. 1984 // 1985 // Entersyscall cannot split the stack: the runtime_gosave must 1986 // make g->sched refer to the caller's stack segment, because 1987 // entersyscall is going to return immediately after. 1988 1989 void runtime_entersyscall(void) __attribute__ ((no_split_stack)); 1990 static void doentersyscall(void) __attribute__ ((no_split_stack, noinline)); 1991 1992 void 1993 runtime_entersyscall() 1994 { 1995 // Save the registers in the g structure so that any pointers 1996 // held in registers will be seen by the garbage collector. 1997 getcontext(&g->gcregs); 1998 1999 // Do the work in a separate function, so that this function 2000 // doesn't save any registers on its own stack. If this 2001 // function does save any registers, we might store the wrong 2002 // value in the call to getcontext. 2003 // 2004 // FIXME: This assumes that we do not need to save any 2005 // callee-saved registers to access the TLS variable g. We 2006 // don't want to put the ucontext_t on the stack because it is 2007 // large and we can not split the stack here. 2008 doentersyscall(); 2009 } 2010 2011 static void 2012 doentersyscall() 2013 { 2014 // Disable preemption because during this function g is in Gsyscall status, 2015 // but can have inconsistent g->sched, do not let GC observe it. 2016 m->locks++; 2017 2018 // Leave SP around for GC and traceback. 2019 #ifdef USING_SPLIT_STACK 2020 g->gcstack = __splitstack_find(nil, nil, &g->gcstack_size, 2021 &g->gcnext_segment, &g->gcnext_sp, 2022 &g->gcinitial_sp); 2023 #else 2024 { 2025 void *v; 2026 2027 g->gcnext_sp = (byte *) &v; 2028 } 2029 #endif 2030 2031 g->status = Gsyscall; 2032 2033 if(runtime_atomicload(&runtime_sched.sysmonwait)) { // TODO: fast atomic 2034 runtime_lock(&runtime_sched.lock); 2035 if(runtime_atomicload(&runtime_sched.sysmonwait)) { 2036 runtime_atomicstore(&runtime_sched.sysmonwait, 0); 2037 runtime_notewakeup(&runtime_sched.sysmonnote); 2038 } 2039 runtime_unlock(&runtime_sched.lock); 2040 } 2041 2042 m->mcache = nil; 2043 m->p->m = nil; 2044 runtime_atomicstore(&m->p->status, Psyscall); 2045 if(runtime_sched.gcwaiting) { 2046 runtime_lock(&runtime_sched.lock); 2047 if (runtime_sched.stopwait > 0 && runtime_cas(&m->p->status, Psyscall, Pgcstop)) { 2048 if(--runtime_sched.stopwait == 0) 2049 runtime_notewakeup(&runtime_sched.stopnote); 2050 } 2051 runtime_unlock(&runtime_sched.lock); 2052 } 2053 2054 m->locks--; 2055 } 2056 2057 // The same as runtime_entersyscall(), but with a hint that the syscall is blocking. 2058 void 2059 runtime_entersyscallblock(void) 2060 { 2061 P *p; 2062 2063 m->locks++; // see comment in entersyscall 2064 2065 // Leave SP around for GC and traceback. 2066 #ifdef USING_SPLIT_STACK 2067 g->gcstack = __splitstack_find(nil, nil, &g->gcstack_size, 2068 &g->gcnext_segment, &g->gcnext_sp, 2069 &g->gcinitial_sp); 2070 #else 2071 g->gcnext_sp = (byte *) &p; 2072 #endif 2073 2074 // Save the registers in the g structure so that any pointers 2075 // held in registers will be seen by the garbage collector. 2076 getcontext(&g->gcregs); 2077 2078 g->status = Gsyscall; 2079 2080 p = releasep(); 2081 handoffp(p); 2082 if(g->isbackground) // do not consider blocked scavenger for deadlock detection 2083 incidlelocked(1); 2084 2085 m->locks--; 2086 } 2087 2088 // The goroutine g exited its system call. 2089 // Arrange for it to run on a cpu again. 2090 // This is called only from the go syscall library, not 2091 // from the low-level system calls used by the runtime. 2092 void 2093 runtime_exitsyscall(void) 2094 { 2095 G *gp; 2096 2097 m->locks++; // see comment in entersyscall 2098 2099 gp = g; 2100 if(gp->isbackground) // do not consider blocked scavenger for deadlock detection 2101 incidlelocked(-1); 2102 2103 g->waitsince = 0; 2104 if(exitsyscallfast()) { 2105 // There's a cpu for us, so we can run. 2106 m->p->syscalltick++; 2107 gp->status = Grunning; 2108 // Garbage collector isn't running (since we are), 2109 // so okay to clear gcstack and gcsp. 2110 #ifdef USING_SPLIT_STACK 2111 gp->gcstack = nil; 2112 #endif 2113 gp->gcnext_sp = nil; 2114 runtime_memclr(&gp->gcregs, sizeof gp->gcregs); 2115 m->locks--; 2116 return; 2117 } 2118 2119 m->locks--; 2120 2121 // Call the scheduler. 2122 runtime_mcall(exitsyscall0); 2123 2124 // Scheduler returned, so we're allowed to run now. 2125 // Delete the gcstack information that we left for 2126 // the garbage collector during the system call. 2127 // Must wait until now because until gosched returns 2128 // we don't know for sure that the garbage collector 2129 // is not running. 2130 #ifdef USING_SPLIT_STACK 2131 gp->gcstack = nil; 2132 #endif 2133 gp->gcnext_sp = nil; 2134 runtime_memclr(&gp->gcregs, sizeof gp->gcregs); 2135 2136 // Don't refer to m again, we might be running on a different 2137 // thread after returning from runtime_mcall. 2138 runtime_m()->p->syscalltick++; 2139 } 2140 2141 static bool 2142 exitsyscallfast(void) 2143 { 2144 P *p; 2145 2146 // Freezetheworld sets stopwait but does not retake P's. 2147 if(runtime_sched.stopwait) { 2148 m->p = nil; 2149 return false; 2150 } 2151 2152 // Try to re-acquire the last P. 2153 if(m->p && m->p->status == Psyscall && runtime_cas(&m->p->status, Psyscall, Prunning)) { 2154 // There's a cpu for us, so we can run. 2155 m->mcache = m->p->mcache; 2156 m->p->m = m; 2157 return true; 2158 } 2159 // Try to get any other idle P. 2160 m->p = nil; 2161 if(runtime_sched.pidle) { 2162 runtime_lock(&runtime_sched.lock); 2163 p = pidleget(); 2164 if(p && runtime_atomicload(&runtime_sched.sysmonwait)) { 2165 runtime_atomicstore(&runtime_sched.sysmonwait, 0); 2166 runtime_notewakeup(&runtime_sched.sysmonnote); 2167 } 2168 runtime_unlock(&runtime_sched.lock); 2169 if(p) { 2170 acquirep(p); 2171 return true; 2172 } 2173 } 2174 return false; 2175 } 2176 2177 // runtime_exitsyscall slow path on g0. 2178 // Failed to acquire P, enqueue gp as runnable. 2179 static void 2180 exitsyscall0(G *gp) 2181 { 2182 P *p; 2183 2184 gp->status = Grunnable; 2185 gp->m = nil; 2186 m->curg = nil; 2187 runtime_lock(&runtime_sched.lock); 2188 p = pidleget(); 2189 if(p == nil) 2190 globrunqput(gp); 2191 else if(runtime_atomicload(&runtime_sched.sysmonwait)) { 2192 runtime_atomicstore(&runtime_sched.sysmonwait, 0); 2193 runtime_notewakeup(&runtime_sched.sysmonnote); 2194 } 2195 runtime_unlock(&runtime_sched.lock); 2196 if(p) { 2197 acquirep(p); 2198 execute(gp); // Never returns. 2199 } 2200 if(m->lockedg) { 2201 // Wait until another thread schedules gp and so m again. 2202 stoplockedm(); 2203 execute(gp); // Never returns. 2204 } 2205 stopm(); 2206 schedule(); // Never returns. 2207 } 2208 2209 // Called from syscall package before fork. 2210 void syscall_runtime_BeforeFork(void) 2211 __asm__(GOSYM_PREFIX "syscall.runtime_BeforeFork"); 2212 void 2213 syscall_runtime_BeforeFork(void) 2214 { 2215 // Fork can hang if preempted with signals frequently enough (see issue 5517). 2216 // Ensure that we stay on the same M where we disable profiling. 2217 runtime_m()->locks++; 2218 if(runtime_m()->profilehz != 0) 2219 runtime_resetcpuprofiler(0); 2220 } 2221 2222 // Called from syscall package after fork in parent. 2223 void syscall_runtime_AfterFork(void) 2224 __asm__(GOSYM_PREFIX "syscall.runtime_AfterFork"); 2225 void 2226 syscall_runtime_AfterFork(void) 2227 { 2228 int32 hz; 2229 2230 hz = runtime_sched.profilehz; 2231 if(hz != 0) 2232 runtime_resetcpuprofiler(hz); 2233 runtime_m()->locks--; 2234 } 2235 2236 // Allocate a new g, with a stack big enough for stacksize bytes. 2237 G* 2238 runtime_malg(int32 stacksize, byte** ret_stack, size_t* ret_stacksize) 2239 { 2240 G *newg; 2241 2242 newg = allocg(); 2243 if(stacksize >= 0) { 2244 #if USING_SPLIT_STACK 2245 int dont_block_signals = 0; 2246 2247 *ret_stack = __splitstack_makecontext(stacksize, 2248 &newg->stack_context[0], 2249 ret_stacksize); 2250 __splitstack_block_signals_context(&newg->stack_context[0], 2251 &dont_block_signals, nil); 2252 #else 2253 // In 64-bit mode, the maximum Go allocation space is 2254 // 128G. Our stack size is 4M, which only permits 32K 2255 // goroutines. In order to not limit ourselves, 2256 // allocate the stacks out of separate memory. In 2257 // 32-bit mode, the Go allocation space is all of 2258 // memory anyhow. 2259 if(sizeof(void*) == 8) { 2260 void *p = runtime_SysAlloc(stacksize, &mstats.other_sys); 2261 if(p == nil) 2262 runtime_throw("runtime: cannot allocate memory for goroutine stack"); 2263 *ret_stack = (byte*)p; 2264 } else { 2265 *ret_stack = runtime_mallocgc(stacksize, 0, FlagNoProfiling|FlagNoGC); 2266 runtime_xadd(&runtime_stacks_sys, stacksize); 2267 } 2268 *ret_stacksize = stacksize; 2269 newg->gcinitial_sp = *ret_stack; 2270 newg->gcstack_size = stacksize; 2271 #endif 2272 } 2273 return newg; 2274 } 2275 2276 /* For runtime package testing. */ 2277 2278 2279 // Create a new g running fn with siz bytes of arguments. 2280 // Put it on the queue of g's waiting to run. 2281 // The compiler turns a go statement into a call to this. 2282 // Cannot split the stack because it assumes that the arguments 2283 // are available sequentially after &fn; they would not be 2284 // copied if a stack split occurred. It's OK for this to call 2285 // functions that split the stack. 2286 void runtime_testing_entersyscall(int32) 2287 __asm__ (GOSYM_PREFIX "runtime.entersyscall"); 2288 void 2289 runtime_testing_entersyscall(int32 dummy __attribute__ ((unused))) 2290 { 2291 runtime_entersyscall(); 2292 } 2293 2294 void runtime_testing_exitsyscall(int32) 2295 __asm__ (GOSYM_PREFIX "runtime.exitsyscall"); 2296 2297 void 2298 runtime_testing_exitsyscall(int32 dummy __attribute__ ((unused))) 2299 { 2300 runtime_exitsyscall(); 2301 } 2302 2303 G* 2304 __go_go(void (*fn)(void*), void* arg) 2305 { 2306 byte *sp; 2307 size_t spsize; 2308 G *newg; 2309 P *p; 2310 2311 //runtime_printf("newproc1 %p %p narg=%d nret=%d\n", fn->fn, argp, narg, nret); 2312 if(fn == nil) { 2313 m->throwing = -1; // do not dump full stacks 2314 runtime_throw("go of nil func value"); 2315 } 2316 m->locks++; // disable preemption because it can be holding p in a local var 2317 2318 p = m->p; 2319 if((newg = gfget(p)) != nil) { 2320 #ifdef USING_SPLIT_STACK 2321 int dont_block_signals = 0; 2322 2323 sp = __splitstack_resetcontext(&newg->stack_context[0], 2324 &spsize); 2325 __splitstack_block_signals_context(&newg->stack_context[0], 2326 &dont_block_signals, nil); 2327 #else 2328 sp = newg->gcinitial_sp; 2329 spsize = newg->gcstack_size; 2330 if(spsize == 0) 2331 runtime_throw("bad spsize in __go_go"); 2332 newg->gcnext_sp = sp; 2333 #endif 2334 } else { 2335 newg = runtime_malg(StackMin, &sp, &spsize); 2336 allgadd(newg); 2337 } 2338 2339 newg->entry = (byte*)fn; 2340 newg->param = arg; 2341 newg->gopc = (uintptr)__builtin_return_address(0); 2342 newg->status = Grunnable; 2343 if(p->goidcache == p->goidcacheend) { 2344 p->goidcache = runtime_xadd64(&runtime_sched.goidgen, GoidCacheBatch); 2345 p->goidcacheend = p->goidcache + GoidCacheBatch; 2346 } 2347 newg->goid = p->goidcache++; 2348 2349 { 2350 // Avoid warnings about variables clobbered by 2351 // longjmp. 2352 byte * volatile vsp = sp; 2353 size_t volatile vspsize = spsize; 2354 G * volatile vnewg = newg; 2355 2356 getcontext(&vnewg->context); 2357 vnewg->context.uc_stack.ss_sp = vsp; 2358 #ifdef MAKECONTEXT_STACK_TOP 2359 vnewg->context.uc_stack.ss_sp += vspsize; 2360 #endif 2361 vnewg->context.uc_stack.ss_size = vspsize; 2362 makecontext(&vnewg->context, kickoff, 0); 2363 2364 runqput(p, vnewg); 2365 2366 if(runtime_atomicload(&runtime_sched.npidle) != 0 && runtime_atomicload(&runtime_sched.nmspinning) == 0 && fn != runtime_main) // TODO: fast atomic 2367 wakep(); 2368 m->locks--; 2369 return vnewg; 2370 } 2371 } 2372 2373 static void 2374 allgadd(G *gp) 2375 { 2376 G **new; 2377 uintptr cap; 2378 2379 runtime_lock(&allglock); 2380 if(runtime_allglen >= allgcap) { 2381 cap = 4096/sizeof(new[0]); 2382 if(cap < 2*allgcap) 2383 cap = 2*allgcap; 2384 new = runtime_malloc(cap*sizeof(new[0])); 2385 if(new == nil) 2386 runtime_throw("runtime: cannot allocate memory"); 2387 if(runtime_allg != nil) { 2388 runtime_memmove(new, runtime_allg, runtime_allglen*sizeof(new[0])); 2389 runtime_free(runtime_allg); 2390 } 2391 runtime_allg = new; 2392 allgcap = cap; 2393 } 2394 runtime_allg[runtime_allglen++] = gp; 2395 runtime_unlock(&allglock); 2396 } 2397 2398 // Put on gfree list. 2399 // If local list is too long, transfer a batch to the global list. 2400 static void 2401 gfput(P *p, G *gp) 2402 { 2403 gp->schedlink = p->gfree; 2404 p->gfree = gp; 2405 p->gfreecnt++; 2406 if(p->gfreecnt >= 64) { 2407 runtime_lock(&runtime_sched.gflock); 2408 while(p->gfreecnt >= 32) { 2409 p->gfreecnt--; 2410 gp = p->gfree; 2411 p->gfree = gp->schedlink; 2412 gp->schedlink = runtime_sched.gfree; 2413 runtime_sched.gfree = gp; 2414 } 2415 runtime_unlock(&runtime_sched.gflock); 2416 } 2417 } 2418 2419 // Get from gfree list. 2420 // If local list is empty, grab a batch from global list. 2421 static G* 2422 gfget(P *p) 2423 { 2424 G *gp; 2425 2426 retry: 2427 gp = p->gfree; 2428 if(gp == nil && runtime_sched.gfree) { 2429 runtime_lock(&runtime_sched.gflock); 2430 while(p->gfreecnt < 32 && runtime_sched.gfree) { 2431 p->gfreecnt++; 2432 gp = runtime_sched.gfree; 2433 runtime_sched.gfree = gp->schedlink; 2434 gp->schedlink = p->gfree; 2435 p->gfree = gp; 2436 } 2437 runtime_unlock(&runtime_sched.gflock); 2438 goto retry; 2439 } 2440 if(gp) { 2441 p->gfree = gp->schedlink; 2442 p->gfreecnt--; 2443 } 2444 return gp; 2445 } 2446 2447 // Purge all cached G's from gfree list to the global list. 2448 static void 2449 gfpurge(P *p) 2450 { 2451 G *gp; 2452 2453 runtime_lock(&runtime_sched.gflock); 2454 while(p->gfreecnt) { 2455 p->gfreecnt--; 2456 gp = p->gfree; 2457 p->gfree = gp->schedlink; 2458 gp->schedlink = runtime_sched.gfree; 2459 runtime_sched.gfree = gp; 2460 } 2461 runtime_unlock(&runtime_sched.gflock); 2462 } 2463 2464 void 2465 runtime_Breakpoint(void) 2466 { 2467 runtime_breakpoint(); 2468 } 2469 2470 void runtime_Gosched (void) __asm__ (GOSYM_PREFIX "runtime.Gosched"); 2471 2472 void 2473 runtime_Gosched(void) 2474 { 2475 runtime_gosched(); 2476 } 2477 2478 // Implementation of runtime.GOMAXPROCS. 2479 // delete when scheduler is even stronger 2480 int32 2481 runtime_gomaxprocsfunc(int32 n) 2482 { 2483 int32 ret; 2484 2485 if(n > MaxGomaxprocs) 2486 n = MaxGomaxprocs; 2487 runtime_lock(&runtime_sched.lock); 2488 ret = runtime_gomaxprocs; 2489 if(n <= 0 || n == ret) { 2490 runtime_unlock(&runtime_sched.lock); 2491 return ret; 2492 } 2493 runtime_unlock(&runtime_sched.lock); 2494 2495 runtime_semacquire(&runtime_worldsema, false); 2496 m->gcing = 1; 2497 runtime_stoptheworld(); 2498 newprocs = n; 2499 m->gcing = 0; 2500 runtime_semrelease(&runtime_worldsema); 2501 runtime_starttheworld(); 2502 2503 return ret; 2504 } 2505 2506 // lockOSThread is called by runtime.LockOSThread and runtime.lockOSThread below 2507 // after they modify m->locked. Do not allow preemption during this call, 2508 // or else the m might be different in this function than in the caller. 2509 static void 2510 lockOSThread(void) 2511 { 2512 m->lockedg = g; 2513 g->lockedm = m; 2514 } 2515 2516 void runtime_LockOSThread(void) __asm__ (GOSYM_PREFIX "runtime.LockOSThread"); 2517 void 2518 runtime_LockOSThread(void) 2519 { 2520 m->locked |= LockExternal; 2521 lockOSThread(); 2522 } 2523 2524 void 2525 runtime_lockOSThread(void) 2526 { 2527 m->locked += LockInternal; 2528 lockOSThread(); 2529 } 2530 2531 2532 // unlockOSThread is called by runtime.UnlockOSThread and runtime.unlockOSThread below 2533 // after they update m->locked. Do not allow preemption during this call, 2534 // or else the m might be in different in this function than in the caller. 2535 static void 2536 unlockOSThread(void) 2537 { 2538 if(m->locked != 0) 2539 return; 2540 m->lockedg = nil; 2541 g->lockedm = nil; 2542 } 2543 2544 void runtime_UnlockOSThread(void) __asm__ (GOSYM_PREFIX "runtime.UnlockOSThread"); 2545 2546 void 2547 runtime_UnlockOSThread(void) 2548 { 2549 m->locked &= ~LockExternal; 2550 unlockOSThread(); 2551 } 2552 2553 void 2554 runtime_unlockOSThread(void) 2555 { 2556 if(m->locked < LockInternal) 2557 runtime_throw("runtime: internal error: misuse of lockOSThread/unlockOSThread"); 2558 m->locked -= LockInternal; 2559 unlockOSThread(); 2560 } 2561 2562 bool 2563 runtime_lockedOSThread(void) 2564 { 2565 return g->lockedm != nil && m->lockedg != nil; 2566 } 2567 2568 int32 2569 runtime_gcount(void) 2570 { 2571 G *gp; 2572 int32 n, s; 2573 uintptr i; 2574 2575 n = 0; 2576 runtime_lock(&allglock); 2577 // TODO(dvyukov): runtime.NumGoroutine() is O(N). 2578 // We do not want to increment/decrement centralized counter in newproc/goexit, 2579 // just to make runtime.NumGoroutine() faster. 2580 // Compromise solution is to introduce per-P counters of active goroutines. 2581 for(i = 0; i < runtime_allglen; i++) { 2582 gp = runtime_allg[i]; 2583 s = gp->status; 2584 if(s == Grunnable || s == Grunning || s == Gsyscall || s == Gwaiting) 2585 n++; 2586 } 2587 runtime_unlock(&allglock); 2588 return n; 2589 } 2590 2591 int32 2592 runtime_mcount(void) 2593 { 2594 return runtime_sched.mcount; 2595 } 2596 2597 static struct { 2598 Lock lock; 2599 void (*fn)(uintptr*, int32); 2600 int32 hz; 2601 uintptr pcbuf[TracebackMaxFrames]; 2602 Location locbuf[TracebackMaxFrames]; 2603 } prof; 2604 2605 static void System(void) {} 2606 static void GC(void) {} 2607 2608 // Called if we receive a SIGPROF signal. 2609 void 2610 runtime_sigprof() 2611 { 2612 M *mp = m; 2613 int32 n, i; 2614 bool traceback; 2615 2616 if(prof.fn == nil || prof.hz == 0) 2617 return; 2618 2619 if(mp == nil) 2620 return; 2621 2622 // Profiling runs concurrently with GC, so it must not allocate. 2623 mp->mallocing++; 2624 2625 traceback = true; 2626 2627 if(mp->mcache == nil) 2628 traceback = false; 2629 2630 runtime_lock(&prof.lock); 2631 if(prof.fn == nil) { 2632 runtime_unlock(&prof.lock); 2633 mp->mallocing--; 2634 return; 2635 } 2636 n = 0; 2637 2638 if(runtime_atomicload(&runtime_in_callers) > 0) { 2639 // If SIGPROF arrived while already fetching runtime 2640 // callers we can have trouble on older systems 2641 // because the unwind library calls dl_iterate_phdr 2642 // which was not recursive in the past. 2643 traceback = false; 2644 } 2645 2646 if(traceback) { 2647 n = runtime_callers(0, prof.locbuf, nelem(prof.locbuf), false); 2648 for(i = 0; i < n; i++) 2649 prof.pcbuf[i] = prof.locbuf[i].pc; 2650 } 2651 if(!traceback || n <= 0) { 2652 n = 2; 2653 prof.pcbuf[0] = (uintptr)runtime_getcallerpc(&n); 2654 if(mp->gcing || mp->helpgc) 2655 prof.pcbuf[1] = (uintptr)GC; 2656 else 2657 prof.pcbuf[1] = (uintptr)System; 2658 } 2659 prof.fn(prof.pcbuf, n); 2660 runtime_unlock(&prof.lock); 2661 mp->mallocing--; 2662 } 2663 2664 // Arrange to call fn with a traceback hz times a second. 2665 void 2666 runtime_setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) 2667 { 2668 // Force sane arguments. 2669 if(hz < 0) 2670 hz = 0; 2671 if(hz == 0) 2672 fn = nil; 2673 if(fn == nil) 2674 hz = 0; 2675 2676 // Disable preemption, otherwise we can be rescheduled to another thread 2677 // that has profiling enabled. 2678 m->locks++; 2679 2680 // Stop profiler on this thread so that it is safe to lock prof. 2681 // if a profiling signal came in while we had prof locked, 2682 // it would deadlock. 2683 runtime_resetcpuprofiler(0); 2684 2685 runtime_lock(&prof.lock); 2686 prof.fn = fn; 2687 prof.hz = hz; 2688 runtime_unlock(&prof.lock); 2689 runtime_lock(&runtime_sched.lock); 2690 runtime_sched.profilehz = hz; 2691 runtime_unlock(&runtime_sched.lock); 2692 2693 if(hz != 0) 2694 runtime_resetcpuprofiler(hz); 2695 2696 m->locks--; 2697 } 2698 2699 // Change number of processors. The world is stopped, sched is locked. 2700 static void 2701 procresize(int32 new) 2702 { 2703 int32 i, old; 2704 bool empty; 2705 G *gp; 2706 P *p; 2707 2708 old = runtime_gomaxprocs; 2709 if(old < 0 || old > MaxGomaxprocs || new <= 0 || new >MaxGomaxprocs) 2710 runtime_throw("procresize: invalid arg"); 2711 // initialize new P's 2712 for(i = 0; i < new; i++) { 2713 p = runtime_allp[i]; 2714 if(p == nil) { 2715 p = (P*)runtime_mallocgc(sizeof(*p), 0, FlagNoInvokeGC); 2716 p->id = i; 2717 p->status = Pgcstop; 2718 runtime_atomicstorep(&runtime_allp[i], p); 2719 } 2720 if(p->mcache == nil) { 2721 if(old==0 && i==0) 2722 p->mcache = m->mcache; // bootstrap 2723 else 2724 p->mcache = runtime_allocmcache(); 2725 } 2726 } 2727 2728 // redistribute runnable G's evenly 2729 // collect all runnable goroutines in global queue preserving FIFO order 2730 // FIFO order is required to ensure fairness even during frequent GCs 2731 // see http://golang.org/issue/7126 2732 empty = false; 2733 while(!empty) { 2734 empty = true; 2735 for(i = 0; i < old; i++) { 2736 p = runtime_allp[i]; 2737 if(p->runqhead == p->runqtail) 2738 continue; 2739 empty = false; 2740 // pop from tail of local queue 2741 p->runqtail--; 2742 gp = p->runq[p->runqtail%nelem(p->runq)]; 2743 // push onto head of global queue 2744 gp->schedlink = runtime_sched.runqhead; 2745 runtime_sched.runqhead = gp; 2746 if(runtime_sched.runqtail == nil) 2747 runtime_sched.runqtail = gp; 2748 runtime_sched.runqsize++; 2749 } 2750 } 2751 // fill local queues with at most nelem(p->runq)/2 goroutines 2752 // start at 1 because current M already executes some G and will acquire allp[0] below, 2753 // so if we have a spare G we want to put it into allp[1]. 2754 for(i = 1; (uint32)i < (uint32)new * nelem(p->runq)/2 && runtime_sched.runqsize > 0; i++) { 2755 gp = runtime_sched.runqhead; 2756 runtime_sched.runqhead = gp->schedlink; 2757 if(runtime_sched.runqhead == nil) 2758 runtime_sched.runqtail = nil; 2759 runtime_sched.runqsize--; 2760 runqput(runtime_allp[i%new], gp); 2761 } 2762 2763 // free unused P's 2764 for(i = new; i < old; i++) { 2765 p = runtime_allp[i]; 2766 runtime_freemcache(p->mcache); 2767 p->mcache = nil; 2768 gfpurge(p); 2769 p->status = Pdead; 2770 // can't free P itself because it can be referenced by an M in syscall 2771 } 2772 2773 if(m->p) 2774 m->p->m = nil; 2775 m->p = nil; 2776 m->mcache = nil; 2777 p = runtime_allp[0]; 2778 p->m = nil; 2779 p->status = Pidle; 2780 acquirep(p); 2781 for(i = new-1; i > 0; i--) { 2782 p = runtime_allp[i]; 2783 p->status = Pidle; 2784 pidleput(p); 2785 } 2786 runtime_atomicstore((uint32*)&runtime_gomaxprocs, new); 2787 } 2788 2789 // Associate p and the current m. 2790 static void 2791 acquirep(P *p) 2792 { 2793 if(m->p || m->mcache) 2794 runtime_throw("acquirep: already in go"); 2795 if(p->m || p->status != Pidle) { 2796 runtime_printf("acquirep: p->m=%p(%d) p->status=%d\n", p->m, p->m ? p->m->id : 0, p->status); 2797 runtime_throw("acquirep: invalid p state"); 2798 } 2799 m->mcache = p->mcache; 2800 m->p = p; 2801 p->m = m; 2802 p->status = Prunning; 2803 } 2804 2805 // Disassociate p and the current m. 2806 static P* 2807 releasep(void) 2808 { 2809 P *p; 2810 2811 if(m->p == nil || m->mcache == nil) 2812 runtime_throw("releasep: invalid arg"); 2813 p = m->p; 2814 if(p->m != m || p->mcache != m->mcache || p->status != Prunning) { 2815 runtime_printf("releasep: m=%p m->p=%p p->m=%p m->mcache=%p p->mcache=%p p->status=%d\n", 2816 m, m->p, p->m, m->mcache, p->mcache, p->status); 2817 runtime_throw("releasep: invalid p state"); 2818 } 2819 m->p = nil; 2820 m->mcache = nil; 2821 p->m = nil; 2822 p->status = Pidle; 2823 return p; 2824 } 2825 2826 static void 2827 incidlelocked(int32 v) 2828 { 2829 runtime_lock(&runtime_sched.lock); 2830 runtime_sched.nmidlelocked += v; 2831 if(v > 0) 2832 checkdead(); 2833 runtime_unlock(&runtime_sched.lock); 2834 } 2835 2836 // Check for deadlock situation. 2837 // The check is based on number of running M's, if 0 -> deadlock. 2838 static void 2839 checkdead(void) 2840 { 2841 G *gp; 2842 int32 run, grunning, s; 2843 uintptr i; 2844 2845 // For -buildmode=c-shared or -buildmode=c-archive it's OK if 2846 // there are no running goroutines. The calling program is 2847 // assumed to be running. 2848 if(runtime_isarchive) { 2849 return; 2850 } 2851 2852 // -1 for sysmon 2853 run = runtime_sched.mcount - runtime_sched.nmidle - runtime_sched.nmidlelocked - 1 - countextra(); 2854 if(run > 0) 2855 return; 2856 // If we are dying because of a signal caught on an already idle thread, 2857 // freezetheworld will cause all running threads to block. 2858 // And runtime will essentially enter into deadlock state, 2859 // except that there is a thread that will call runtime_exit soon. 2860 if(runtime_panicking > 0) 2861 return; 2862 if(run < 0) { 2863 runtime_printf("runtime: checkdead: nmidle=%d nmidlelocked=%d mcount=%d\n", 2864 runtime_sched.nmidle, runtime_sched.nmidlelocked, runtime_sched.mcount); 2865 runtime_throw("checkdead: inconsistent counts"); 2866 } 2867 grunning = 0; 2868 runtime_lock(&allglock); 2869 for(i = 0; i < runtime_allglen; i++) { 2870 gp = runtime_allg[i]; 2871 if(gp->isbackground) 2872 continue; 2873 s = gp->status; 2874 if(s == Gwaiting) 2875 grunning++; 2876 else if(s == Grunnable || s == Grunning || s == Gsyscall) { 2877 runtime_unlock(&allglock); 2878 runtime_printf("runtime: checkdead: find g %D in status %d\n", gp->goid, s); 2879 runtime_throw("checkdead: runnable g"); 2880 } 2881 } 2882 runtime_unlock(&allglock); 2883 if(grunning == 0) // possible if main goroutine calls runtime_Goexit() 2884 runtime_throw("no goroutines (main called runtime.Goexit) - deadlock!"); 2885 m->throwing = -1; // do not dump full stacks 2886 runtime_throw("all goroutines are asleep - deadlock!"); 2887 } 2888 2889 static void 2890 sysmon(void) 2891 { 2892 uint32 idle, delay; 2893 int64 now, lastpoll, lasttrace; 2894 G *gp; 2895 2896 lasttrace = 0; 2897 idle = 0; // how many cycles in succession we had not wokeup somebody 2898 delay = 0; 2899 for(;;) { 2900 if(idle == 0) // start with 20us sleep... 2901 delay = 20; 2902 else if(idle > 50) // start doubling the sleep after 1ms... 2903 delay *= 2; 2904 if(delay > 10*1000) // up to 10ms 2905 delay = 10*1000; 2906 runtime_usleep(delay); 2907 if(runtime_debug.schedtrace <= 0 && 2908 (runtime_sched.gcwaiting || runtime_atomicload(&runtime_sched.npidle) == (uint32)runtime_gomaxprocs)) { // TODO: fast atomic 2909 runtime_lock(&runtime_sched.lock); 2910 if(runtime_atomicload(&runtime_sched.gcwaiting) || runtime_atomicload(&runtime_sched.npidle) == (uint32)runtime_gomaxprocs) { 2911 runtime_atomicstore(&runtime_sched.sysmonwait, 1); 2912 runtime_unlock(&runtime_sched.lock); 2913 runtime_notesleep(&runtime_sched.sysmonnote); 2914 runtime_noteclear(&runtime_sched.sysmonnote); 2915 idle = 0; 2916 delay = 20; 2917 } else 2918 runtime_unlock(&runtime_sched.lock); 2919 } 2920 // poll network if not polled for more than 10ms 2921 lastpoll = runtime_atomicload64(&runtime_sched.lastpoll); 2922 now = runtime_nanotime(); 2923 if(lastpoll != 0 && lastpoll + 10*1000*1000 < now) { 2924 runtime_cas64(&runtime_sched.lastpoll, lastpoll, now); 2925 gp = runtime_netpoll(false); // non-blocking 2926 if(gp) { 2927 // Need to decrement number of idle locked M's 2928 // (pretending that one more is running) before injectglist. 2929 // Otherwise it can lead to the following situation: 2930 // injectglist grabs all P's but before it starts M's to run the P's, 2931 // another M returns from syscall, finishes running its G, 2932 // observes that there is no work to do and no other running M's 2933 // and reports deadlock. 2934 incidlelocked(-1); 2935 injectglist(gp); 2936 incidlelocked(1); 2937 } 2938 } 2939 // retake P's blocked in syscalls 2940 // and preempt long running G's 2941 if(retake(now)) 2942 idle = 0; 2943 else 2944 idle++; 2945 2946 if(runtime_debug.schedtrace > 0 && lasttrace + runtime_debug.schedtrace*1000000ll <= now) { 2947 lasttrace = now; 2948 runtime_schedtrace(runtime_debug.scheddetail); 2949 } 2950 } 2951 } 2952 2953 typedef struct Pdesc Pdesc; 2954 struct Pdesc 2955 { 2956 uint32 schedtick; 2957 int64 schedwhen; 2958 uint32 syscalltick; 2959 int64 syscallwhen; 2960 }; 2961 static Pdesc pdesc[MaxGomaxprocs]; 2962 2963 static uint32 2964 retake(int64 now) 2965 { 2966 uint32 i, s, n; 2967 int64 t; 2968 P *p; 2969 Pdesc *pd; 2970 2971 n = 0; 2972 for(i = 0; i < (uint32)runtime_gomaxprocs; i++) { 2973 p = runtime_allp[i]; 2974 if(p==nil) 2975 continue; 2976 pd = &pdesc[i]; 2977 s = p->status; 2978 if(s == Psyscall) { 2979 // Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us). 2980 t = p->syscalltick; 2981 if(pd->syscalltick != t) { 2982 pd->syscalltick = t; 2983 pd->syscallwhen = now; 2984 continue; 2985 } 2986 // On the one hand we don't want to retake Ps if there is no other work to do, 2987 // but on the other hand we want to retake them eventually 2988 // because they can prevent the sysmon thread from deep sleep. 2989 if(p->runqhead == p->runqtail && 2990 runtime_atomicload(&runtime_sched.nmspinning) + runtime_atomicload(&runtime_sched.npidle) > 0 && 2991 pd->syscallwhen + 10*1000*1000 > now) 2992 continue; 2993 // Need to decrement number of idle locked M's 2994 // (pretending that one more is running) before the CAS. 2995 // Otherwise the M from which we retake can exit the syscall, 2996 // increment nmidle and report deadlock. 2997 incidlelocked(-1); 2998 if(runtime_cas(&p->status, s, Pidle)) { 2999 n++; 3000 handoffp(p); 3001 } 3002 incidlelocked(1); 3003 } else if(s == Prunning) { 3004 // Preempt G if it's running for more than 10ms. 3005 t = p->schedtick; 3006 if(pd->schedtick != t) { 3007 pd->schedtick = t; 3008 pd->schedwhen = now; 3009 continue; 3010 } 3011 if(pd->schedwhen + 10*1000*1000 > now) 3012 continue; 3013 // preemptone(p); 3014 } 3015 } 3016 return n; 3017 } 3018 3019 // Tell all goroutines that they have been preempted and they should stop. 3020 // This function is purely best-effort. It can fail to inform a goroutine if a 3021 // processor just started running it. 3022 // No locks need to be held. 3023 // Returns true if preemption request was issued to at least one goroutine. 3024 static bool 3025 preemptall(void) 3026 { 3027 return false; 3028 } 3029 3030 void 3031 runtime_schedtrace(bool detailed) 3032 { 3033 static int64 starttime; 3034 int64 now; 3035 int64 id1, id2, id3; 3036 int32 i, t, h; 3037 uintptr gi; 3038 const char *fmt; 3039 M *mp, *lockedm; 3040 G *gp, *lockedg; 3041 P *p; 3042 3043 now = runtime_nanotime(); 3044 if(starttime == 0) 3045 starttime = now; 3046 3047 runtime_lock(&runtime_sched.lock); 3048 runtime_printf("SCHED %Dms: gomaxprocs=%d idleprocs=%d threads=%d idlethreads=%d runqueue=%d", 3049 (now-starttime)/1000000, runtime_gomaxprocs, runtime_sched.npidle, runtime_sched.mcount, 3050 runtime_sched.nmidle, runtime_sched.runqsize); 3051 if(detailed) { 3052 runtime_printf(" gcwaiting=%d nmidlelocked=%d nmspinning=%d stopwait=%d sysmonwait=%d\n", 3053 runtime_sched.gcwaiting, runtime_sched.nmidlelocked, runtime_sched.nmspinning, 3054 runtime_sched.stopwait, runtime_sched.sysmonwait); 3055 } 3056 // We must be careful while reading data from P's, M's and G's. 3057 // Even if we hold schedlock, most data can be changed concurrently. 3058 // E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil. 3059 for(i = 0; i < runtime_gomaxprocs; i++) { 3060 p = runtime_allp[i]; 3061 if(p == nil) 3062 continue; 3063 mp = p->m; 3064 h = runtime_atomicload(&p->runqhead); 3065 t = runtime_atomicload(&p->runqtail); 3066 if(detailed) 3067 runtime_printf(" P%d: status=%d schedtick=%d syscalltick=%d m=%d runqsize=%d gfreecnt=%d\n", 3068 i, p->status, p->schedtick, p->syscalltick, mp ? mp->id : -1, t-h, p->gfreecnt); 3069 else { 3070 // In non-detailed mode format lengths of per-P run queues as: 3071 // [len1 len2 len3 len4] 3072 fmt = " %d"; 3073 if(runtime_gomaxprocs == 1) 3074 fmt = " [%d]\n"; 3075 else if(i == 0) 3076 fmt = " [%d"; 3077 else if(i == runtime_gomaxprocs-1) 3078 fmt = " %d]\n"; 3079 runtime_printf(fmt, t-h); 3080 } 3081 } 3082 if(!detailed) { 3083 runtime_unlock(&runtime_sched.lock); 3084 return; 3085 } 3086 for(mp = runtime_allm; mp; mp = mp->alllink) { 3087 p = mp->p; 3088 gp = mp->curg; 3089 lockedg = mp->lockedg; 3090 id1 = -1; 3091 if(p) 3092 id1 = p->id; 3093 id2 = -1; 3094 if(gp) 3095 id2 = gp->goid; 3096 id3 = -1; 3097 if(lockedg) 3098 id3 = lockedg->goid; 3099 runtime_printf(" M%d: p=%D curg=%D mallocing=%d throwing=%d gcing=%d" 3100 " locks=%d dying=%d helpgc=%d spinning=%d blocked=%d lockedg=%D\n", 3101 mp->id, id1, id2, 3102 mp->mallocing, mp->throwing, mp->gcing, mp->locks, mp->dying, mp->helpgc, 3103 mp->spinning, m->blocked, id3); 3104 } 3105 runtime_lock(&allglock); 3106 for(gi = 0; gi < runtime_allglen; gi++) { 3107 gp = runtime_allg[gi]; 3108 mp = gp->m; 3109 lockedm = gp->lockedm; 3110 runtime_printf(" G%D: status=%d(%s) m=%d lockedm=%d\n", 3111 gp->goid, gp->status, gp->waitreason, mp ? mp->id : -1, 3112 lockedm ? lockedm->id : -1); 3113 } 3114 runtime_unlock(&allglock); 3115 runtime_unlock(&runtime_sched.lock); 3116 } 3117 3118 // Put mp on midle list. 3119 // Sched must be locked. 3120 static void 3121 mput(M *mp) 3122 { 3123 mp->schedlink = runtime_sched.midle; 3124 runtime_sched.midle = mp; 3125 runtime_sched.nmidle++; 3126 checkdead(); 3127 } 3128 3129 // Try to get an m from midle list. 3130 // Sched must be locked. 3131 static M* 3132 mget(void) 3133 { 3134 M *mp; 3135 3136 if((mp = runtime_sched.midle) != nil){ 3137 runtime_sched.midle = mp->schedlink; 3138 runtime_sched.nmidle--; 3139 } 3140 return mp; 3141 } 3142 3143 // Put gp on the global runnable queue. 3144 // Sched must be locked. 3145 static void 3146 globrunqput(G *gp) 3147 { 3148 gp->schedlink = nil; 3149 if(runtime_sched.runqtail) 3150 runtime_sched.runqtail->schedlink = gp; 3151 else 3152 runtime_sched.runqhead = gp; 3153 runtime_sched.runqtail = gp; 3154 runtime_sched.runqsize++; 3155 } 3156 3157 // Put a batch of runnable goroutines on the global runnable queue. 3158 // Sched must be locked. 3159 static void 3160 globrunqputbatch(G *ghead, G *gtail, int32 n) 3161 { 3162 gtail->schedlink = nil; 3163 if(runtime_sched.runqtail) 3164 runtime_sched.runqtail->schedlink = ghead; 3165 else 3166 runtime_sched.runqhead = ghead; 3167 runtime_sched.runqtail = gtail; 3168 runtime_sched.runqsize += n; 3169 } 3170 3171 // Try get a batch of G's from the global runnable queue. 3172 // Sched must be locked. 3173 static G* 3174 globrunqget(P *p, int32 max) 3175 { 3176 G *gp, *gp1; 3177 int32 n; 3178 3179 if(runtime_sched.runqsize == 0) 3180 return nil; 3181 n = runtime_sched.runqsize/runtime_gomaxprocs+1; 3182 if(n > runtime_sched.runqsize) 3183 n = runtime_sched.runqsize; 3184 if(max > 0 && n > max) 3185 n = max; 3186 if((uint32)n > nelem(p->runq)/2) 3187 n = nelem(p->runq)/2; 3188 runtime_sched.runqsize -= n; 3189 if(runtime_sched.runqsize == 0) 3190 runtime_sched.runqtail = nil; 3191 gp = runtime_sched.runqhead; 3192 runtime_sched.runqhead = gp->schedlink; 3193 n--; 3194 while(n--) { 3195 gp1 = runtime_sched.runqhead; 3196 runtime_sched.runqhead = gp1->schedlink; 3197 runqput(p, gp1); 3198 } 3199 return gp; 3200 } 3201 3202 // Put p to on pidle list. 3203 // Sched must be locked. 3204 static void 3205 pidleput(P *p) 3206 { 3207 p->link = runtime_sched.pidle; 3208 runtime_sched.pidle = p; 3209 runtime_xadd(&runtime_sched.npidle, 1); // TODO: fast atomic 3210 } 3211 3212 // Try get a p from pidle list. 3213 // Sched must be locked. 3214 static P* 3215 pidleget(void) 3216 { 3217 P *p; 3218 3219 p = runtime_sched.pidle; 3220 if(p) { 3221 runtime_sched.pidle = p->link; 3222 runtime_xadd(&runtime_sched.npidle, -1); // TODO: fast atomic 3223 } 3224 return p; 3225 } 3226 3227 // Try to put g on local runnable queue. 3228 // If it's full, put onto global queue. 3229 // Executed only by the owner P. 3230 static void 3231 runqput(P *p, G *gp) 3232 { 3233 uint32 h, t; 3234 3235 retry: 3236 h = runtime_atomicload(&p->runqhead); // load-acquire, synchronize with consumers 3237 t = p->runqtail; 3238 if(t - h < nelem(p->runq)) { 3239 p->runq[t%nelem(p->runq)] = gp; 3240 runtime_atomicstore(&p->runqtail, t+1); // store-release, makes the item available for consumption 3241 return; 3242 } 3243 if(runqputslow(p, gp, h, t)) 3244 return; 3245 // the queue is not full, now the put above must suceed 3246 goto retry; 3247 } 3248 3249 // Put g and a batch of work from local runnable queue on global queue. 3250 // Executed only by the owner P. 3251 static bool 3252 runqputslow(P *p, G *gp, uint32 h, uint32 t) 3253 { 3254 G *batch[nelem(p->runq)/2+1]; 3255 uint32 n, i; 3256 3257 // First, grab a batch from local queue. 3258 n = t-h; 3259 n = n/2; 3260 if(n != nelem(p->runq)/2) 3261 runtime_throw("runqputslow: queue is not full"); 3262 for(i=0; i<n; i++) 3263 batch[i] = p->runq[(h+i)%nelem(p->runq)]; 3264 if(!runtime_cas(&p->runqhead, h, h+n)) // cas-release, commits consume 3265 return false; 3266 batch[n] = gp; 3267 // Link the goroutines. 3268 for(i=0; i<n; i++) 3269 batch[i]->schedlink = batch[i+1]; 3270 // Now put the batch on global queue. 3271 runtime_lock(&runtime_sched.lock); 3272 globrunqputbatch(batch[0], batch[n], n+1); 3273 runtime_unlock(&runtime_sched.lock); 3274 return true; 3275 } 3276 3277 // Get g from local runnable queue. 3278 // Executed only by the owner P. 3279 static G* 3280 runqget(P *p) 3281 { 3282 G *gp; 3283 uint32 t, h; 3284 3285 for(;;) { 3286 h = runtime_atomicload(&p->runqhead); // load-acquire, synchronize with other consumers 3287 t = p->runqtail; 3288 if(t == h) 3289 return nil; 3290 gp = p->runq[h%nelem(p->runq)]; 3291 if(runtime_cas(&p->runqhead, h, h+1)) // cas-release, commits consume 3292 return gp; 3293 } 3294 } 3295 3296 // Grabs a batch of goroutines from local runnable queue. 3297 // batch array must be of size nelem(p->runq)/2. Returns number of grabbed goroutines. 3298 // Can be executed by any P. 3299 static uint32 3300 runqgrab(P *p, G **batch) 3301 { 3302 uint32 t, h, n, i; 3303 3304 for(;;) { 3305 h = runtime_atomicload(&p->runqhead); // load-acquire, synchronize with other consumers 3306 t = runtime_atomicload(&p->runqtail); // load-acquire, synchronize with the producer 3307 n = t-h; 3308 n = n - n/2; 3309 if(n == 0) 3310 break; 3311 if(n > nelem(p->runq)/2) // read inconsistent h and t 3312 continue; 3313 for(i=0; i<n; i++) 3314 batch[i] = p->runq[(h+i)%nelem(p->runq)]; 3315 if(runtime_cas(&p->runqhead, h, h+n)) // cas-release, commits consume 3316 break; 3317 } 3318 return n; 3319 } 3320 3321 // Steal half of elements from local runnable queue of p2 3322 // and put onto local runnable queue of p. 3323 // Returns one of the stolen elements (or nil if failed). 3324 static G* 3325 runqsteal(P *p, P *p2) 3326 { 3327 G *gp; 3328 G *batch[nelem(p->runq)/2]; 3329 uint32 t, h, n, i; 3330 3331 n = runqgrab(p2, batch); 3332 if(n == 0) 3333 return nil; 3334 n--; 3335 gp = batch[n]; 3336 if(n == 0) 3337 return gp; 3338 h = runtime_atomicload(&p->runqhead); // load-acquire, synchronize with consumers 3339 t = p->runqtail; 3340 if(t - h + n >= nelem(p->runq)) 3341 runtime_throw("runqsteal: runq overflow"); 3342 for(i=0; i<n; i++, t++) 3343 p->runq[t%nelem(p->runq)] = batch[i]; 3344 runtime_atomicstore(&p->runqtail, t); // store-release, makes the item available for consumption 3345 return gp; 3346 } 3347 3348 void runtime_testSchedLocalQueue(void) 3349 __asm__("runtime.testSchedLocalQueue"); 3350 3351 void 3352 runtime_testSchedLocalQueue(void) 3353 { 3354 P p; 3355 G gs[nelem(p.runq)]; 3356 int32 i, j; 3357 3358 runtime_memclr((byte*)&p, sizeof(p)); 3359 3360 for(i = 0; i < (int32)nelem(gs); i++) { 3361 if(runqget(&p) != nil) 3362 runtime_throw("runq is not empty initially"); 3363 for(j = 0; j < i; j++) 3364 runqput(&p, &gs[i]); 3365 for(j = 0; j < i; j++) { 3366 if(runqget(&p) != &gs[i]) { 3367 runtime_printf("bad element at iter %d/%d\n", i, j); 3368 runtime_throw("bad element"); 3369 } 3370 } 3371 if(runqget(&p) != nil) 3372 runtime_throw("runq is not empty afterwards"); 3373 } 3374 } 3375 3376 void runtime_testSchedLocalQueueSteal(void) 3377 __asm__("runtime.testSchedLocalQueueSteal"); 3378 3379 void 3380 runtime_testSchedLocalQueueSteal(void) 3381 { 3382 P p1, p2; 3383 G gs[nelem(p1.runq)], *gp; 3384 int32 i, j, s; 3385 3386 runtime_memclr((byte*)&p1, sizeof(p1)); 3387 runtime_memclr((byte*)&p2, sizeof(p2)); 3388 3389 for(i = 0; i < (int32)nelem(gs); i++) { 3390 for(j = 0; j < i; j++) { 3391 gs[j].sig = 0; 3392 runqput(&p1, &gs[j]); 3393 } 3394 gp = runqsteal(&p2, &p1); 3395 s = 0; 3396 if(gp) { 3397 s++; 3398 gp->sig++; 3399 } 3400 while((gp = runqget(&p2)) != nil) { 3401 s++; 3402 gp->sig++; 3403 } 3404 while((gp = runqget(&p1)) != nil) 3405 gp->sig++; 3406 for(j = 0; j < i; j++) { 3407 if(gs[j].sig != 1) { 3408 runtime_printf("bad element %d(%d) at iter %d\n", j, gs[j].sig, i); 3409 runtime_throw("bad element"); 3410 } 3411 } 3412 if(s != i/2 && s != i/2+1) { 3413 runtime_printf("bad steal %d, want %d or %d, iter %d\n", 3414 s, i/2, i/2+1, i); 3415 runtime_throw("bad steal"); 3416 } 3417 } 3418 } 3419 3420 int32 3421 runtime_setmaxthreads(int32 in) 3422 { 3423 int32 out; 3424 3425 runtime_lock(&runtime_sched.lock); 3426 out = runtime_sched.maxmcount; 3427 runtime_sched.maxmcount = in; 3428 checkmcount(); 3429 runtime_unlock(&runtime_sched.lock); 3430 return out; 3431 } 3432 3433 void 3434 runtime_proc_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj)) 3435 { 3436 enqueue1(wbufp, (Obj){(byte*)&runtime_sched, sizeof runtime_sched, 0}); 3437 enqueue1(wbufp, (Obj){(byte*)&runtime_main_init_done, sizeof runtime_main_init_done, 0}); 3438 } 3439 3440 // Return whether we are waiting for a GC. This gc toolchain uses 3441 // preemption instead. 3442 bool 3443 runtime_gcwaiting(void) 3444 { 3445 return runtime_sched.gcwaiting; 3446 } 3447 3448 // os_beforeExit is called from os.Exit(0). 3449 //go:linkname os_beforeExit os.runtime_beforeExit 3450 3451 extern void os_beforeExit() __asm__ (GOSYM_PREFIX "os.runtime_beforeExit"); 3452 3453 void 3454 os_beforeExit() 3455 { 3456 } 3457 3458 // Active spinning for sync.Mutex. 3459 //go:linkname sync_runtime_canSpin sync.runtime_canSpin 3460 3461 enum 3462 { 3463 ACTIVE_SPIN = 4, 3464 ACTIVE_SPIN_CNT = 30, 3465 }; 3466 3467 extern _Bool sync_runtime_canSpin(intgo i) 3468 __asm__ (GOSYM_PREFIX "sync.runtime_canSpin"); 3469 3470 _Bool 3471 sync_runtime_canSpin(intgo i) 3472 { 3473 P *p; 3474 3475 // sync.Mutex is cooperative, so we are conservative with spinning. 3476 // Spin only few times and only if running on a multicore machine and 3477 // GOMAXPROCS>1 and there is at least one other running P and local runq is empty. 3478 // As opposed to runtime mutex we don't do passive spinning here, 3479 // because there can be work on global runq on on other Ps. 3480 if (i >= ACTIVE_SPIN || runtime_ncpu <= 1 || runtime_gomaxprocs <= (int32)(runtime_sched.npidle+runtime_sched.nmspinning)+1) { 3481 return false; 3482 } 3483 p = m->p; 3484 return p != nil && p->runqhead == p->runqtail; 3485 } 3486 3487 //go:linkname sync_runtime_doSpin sync.runtime_doSpin 3488 //go:nosplit 3489 3490 extern void sync_runtime_doSpin(void) 3491 __asm__ (GOSYM_PREFIX "sync.runtime_doSpin"); 3492 3493 void 3494 sync_runtime_doSpin() 3495 { 3496 runtime_procyield(ACTIVE_SPIN_CNT); 3497 }