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.
13 #ifdef HAVE_DL_ITERATE_PHDR
25 #ifdef USING_SPLIT_STACK
27 /* FIXME: These are not declared anywhere. */
29 extern void __splitstack_getcontext(void *context
[10]);
31 extern void __splitstack_setcontext(void *context
[10]);
33 extern void *__splitstack_makecontext(size_t, void *context
[10], size_t *);
35 extern void * __splitstack_resetcontext(void *context
[10], size_t *);
37 extern void *__splitstack_find(void *, void *, size_t *, void **, void **,
40 extern void __splitstack_block_signals (int *, int *);
42 extern void __splitstack_block_signals_context (void *context
[10], int *,
47 #ifndef PTHREAD_STACK_MIN
48 # define PTHREAD_STACK_MIN 8192
51 #if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK)
52 # define StackMin PTHREAD_STACK_MIN
54 # define StackMin 2 * 1024 * 1024
57 uintptr runtime_stacks_sys
;
59 static void gtraceback(G
*);
68 #ifndef SETCONTEXT_CLOBBERS_TLS
76 fixcontext(ucontext_t
*c
__attribute__ ((unused
)))
82 # if defined(__x86_64__) && defined(__sun__)
84 // x86_64 Solaris 10 and 11 have a bug: setcontext switches the %fs
85 // register to that of the thread which called getcontext. The effect
86 // is that the address of all __thread variables changes. This bug
87 // also affects pthread_self() and pthread_getspecific. We work
88 // around it by clobbering the context field directly to keep %fs the
91 static __thread greg_t fs
;
99 fs
= c
.uc_mcontext
.gregs
[REG_FSBASE
];
103 fixcontext(ucontext_t
* c
)
105 c
->uc_mcontext
.gregs
[REG_FSBASE
] = fs
;
108 # elif defined(__NetBSD__)
110 // NetBSD has a bug: setcontext clobbers tlsbase, we need to save
111 // and restore it ourselves.
113 static __thread __greg_t tlsbase
;
121 tlsbase
= c
.uc_mcontext
._mc_tlsbase
;
125 fixcontext(ucontext_t
* c
)
127 c
->uc_mcontext
._mc_tlsbase
= tlsbase
;
132 # error unknown case for SETCONTEXT_CLOBBERS_TLS
138 // We can not always refer to the TLS variables directly. The
139 // compiler will call tls_get_addr to get the address of the variable,
140 // and it may hold it in a register across a call to schedule. When
141 // we get back from the call we may be running in a different thread,
142 // in which case the register now points to the TLS variable for a
143 // different thread. We use non-inlinable functions to avoid this
146 G
* runtime_g(void) __attribute__ ((noinline
, no_split_stack
));
154 M
* runtime_m(void) __attribute__ ((noinline
, no_split_stack
));
164 runtime_setmg(M
* mp
, G
* gp
)
170 // The static TLS size. See runtime_newm.
173 // Start a new thread.
175 runtime_newosproc(M
*mp
)
183 if(pthread_attr_init(&attr
) != 0)
184 runtime_throw("pthread_attr_init");
185 if(pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
) != 0)
186 runtime_throw("pthread_attr_setdetachstate");
188 stacksize
= PTHREAD_STACK_MIN
;
190 // With glibc before version 2.16 the static TLS size is taken
191 // out of the stack size, and we get an error or a crash if
192 // there is not enough stack space left. Add it back in if we
193 // can, in case the program uses a lot of TLS space. FIXME:
194 // This can be disabled in glibc 2.16 and later, if the bug is
195 // indeed fixed then.
196 stacksize
+= tlssize
;
198 if(pthread_attr_setstacksize(&attr
, stacksize
) != 0)
199 runtime_throw("pthread_attr_setstacksize");
201 // Block signals during pthread_create so that the new thread
202 // starts with signals disabled. It will enable them in minit.
206 // Blocking SIGTRAP reportedly breaks gdb on Alpha GNU/Linux.
207 sigdelset(&clear
, SIGTRAP
);
211 pthread_sigmask(SIG_BLOCK
, &clear
, &old
);
212 ret
= pthread_create(&tid
, &attr
, runtime_mstart
, mp
);
213 pthread_sigmask(SIG_SETMASK
, &old
, nil
);
216 runtime_throw("pthread_create");
219 // First function run by a new goroutine. This replaces gogocall.
225 if(g
->traceback
!= nil
)
228 fn
= (void (*)(void*))(g
->entry
);
233 // Switch context to a different goroutine. This is like longjmp.
234 void runtime_gogo(G
*) __attribute__ ((noinline
));
236 runtime_gogo(G
* newg
)
238 #ifdef USING_SPLIT_STACK
239 __splitstack_setcontext(&newg
->stack_context
[0]);
242 newg
->fromgogo
= true;
243 fixcontext(&newg
->context
);
244 setcontext(&newg
->context
);
245 runtime_throw("gogo setcontext returned");
248 // Save context and call fn passing g as a parameter. This is like
249 // setjmp. Because getcontext always returns 0, unlike setjmp, we use
250 // g->fromgogo as a code. It will be true if we got here via
251 // setcontext. g == nil the first time this is called in a new m.
252 void runtime_mcall(void (*)(G
*)) __attribute__ ((noinline
));
254 runtime_mcall(void (*pfn
)(G
*))
258 #ifndef USING_SPLIT_STACK
262 // Ensure that all registers are on the stack for the garbage
264 __builtin_unwind_init();
269 runtime_throw("runtime: mcall called on m->g0 stack");
273 #ifdef USING_SPLIT_STACK
274 __splitstack_getcontext(&g
->stack_context
[0]);
278 gp
->fromgogo
= false;
279 getcontext(&gp
->context
);
281 // When we return from getcontext, we may be running
282 // in a new thread. That means that m and g may have
283 // changed. They are global variables so we will
284 // reload them, but the addresses of m and g may be
285 // cached in our local stack frame, and those
286 // addresses may be wrong. Call functions to reload
287 // the values for this thread.
291 if(gp
->traceback
!= nil
)
294 if (gp
== nil
|| !gp
->fromgogo
) {
295 #ifdef USING_SPLIT_STACK
296 __splitstack_setcontext(&mp
->g0
->stack_context
[0]);
298 mp
->g0
->entry
= (byte
*)pfn
;
301 // It's OK to set g directly here because this case
302 // can not occur if we got here via a setcontext to
303 // the getcontext call just above.
306 fixcontext(&mp
->g0
->context
);
307 setcontext(&mp
->g0
->context
);
308 runtime_throw("runtime: mcall function returned");
312 #ifdef HAVE_DL_ITERATE_PHDR
314 // Called via dl_iterate_phdr.
317 addtls(struct dl_phdr_info
* info
, size_t size
__attribute__ ((unused
)), void *data
)
319 size_t *total
= (size_t *)data
;
322 for(i
= 0; i
< info
->dlpi_phnum
; ++i
) {
323 if(info
->dlpi_phdr
[i
].p_type
== PT_TLS
)
324 *total
+= info
->dlpi_phdr
[i
].p_memsz
;
329 // Set the total TLS size.
336 dl_iterate_phdr(addtls
, (void *)&total
);
349 // Goroutine scheduler
350 // The scheduler's job is to distribute ready-to-run goroutines over worker threads.
352 // The main concepts are:
354 // M - worker thread, or machine.
355 // P - processor, a resource that is required to execute Go code.
356 // M must have an associated P to execute Go code, however it can be
357 // blocked or in a syscall w/o an associated P.
359 // Design doc at http://golang.org/s/go11sched.
361 typedef struct Sched Sched
;
366 M
* midle
; // idle m's waiting for work
367 int32 nmidle
; // number of idle m's waiting for work
368 int32 nmidlelocked
; // number of locked m's waiting for work
369 int32 mcount
; // number of m's that have been created
370 int32 maxmcount
; // maximum number of m's allowed (or die)
372 P
* pidle
; // idle P's
376 // Global runnable queue.
381 // Global cache of dead G's.
385 uint32 gcwaiting
; // gc is waiting to run
392 int32 profilehz
; // cpu profiling rate
395 // The max value of GOMAXPROCS.
396 // There are no fundamental restrictions on the value.
397 enum { MaxGomaxprocs
= 1<<8 };
400 int32 runtime_gomaxprocs
;
401 uint32 runtime_needextram
= 1;
402 bool runtime_iscgo
= true;
404 G runtime_g0
; // idle goroutine for m0
412 bool runtime_precisestack
;
413 static int32 newprocs
;
415 void* runtime_mstart(void*);
416 static void runqput(P
*, G
*);
417 static G
* runqget(P
*);
418 static void runqgrow(P
*);
419 static G
* runqsteal(P
*, P
*);
420 static void mput(M
*);
421 static M
* mget(void);
422 static void mcommoninit(M
*);
423 static void schedule(void);
424 static void procresize(int32
);
425 static void acquirep(P
*);
426 static P
* releasep(void);
427 static void newm(void(*)(void), P
*);
428 static void stopm(void);
429 static void startm(P
*, bool);
430 static void handoffp(P
*);
431 static void wakep(void);
432 static void stoplockedm(void);
433 static void startlockedm(G
*);
434 static void sysmon(void);
435 static uint32
retake(int64
);
436 static void incidlelocked(int32
);
437 static void checkdead(void);
438 static void exitsyscall0(G
*);
439 static void park0(G
*);
440 static void goexit0(G
*);
441 static void gfput(P
*, G
*);
443 static void gfpurge(P
*);
444 static void globrunqput(G
*);
445 static G
* globrunqget(P
*, int32
);
446 static P
* pidleget(void);
447 static void pidleput(P
*);
448 static void injectglist(G
*);
449 static bool preemptall(void);
450 static bool exitsyscallfast(void);
452 // The bootstrap sequence is:
456 // make & queue new G
457 // call runtime_mstart
459 // The new G calls runtime_main.
461 runtime_schedinit(void)
476 runtime_sched
.maxmcount
= 10000;
477 runtime_precisestack
= 0;
480 runtime_mallocinit();
483 // Initialize the itable value for newErrorCString,
484 // so that the next time it gets called, possibly
485 // in a fault during a garbage collection, it will not
486 // need to allocated memory.
487 runtime_newErrorCString(0, &i
);
491 runtime_parsedebugvars();
493 runtime_sched
.lastpoll
= runtime_nanotime();
495 p
= runtime_getenv("GOMAXPROCS");
496 if(p
!= nil
&& (n
= runtime_atoi(p
)) > 0) {
497 if(n
> MaxGomaxprocs
)
501 runtime_allp
= runtime_malloc((MaxGomaxprocs
+1)*sizeof(runtime_allp
[0]));
504 // Can not enable GC until all roots are registered.
505 // mstats.enablegc = 1;
508 // g->racectx = runtime_raceinit();
511 extern void main_init(void) __asm__ (GOSYM_PREFIX
"__go_init_main");
512 extern void main_main(void) __asm__ (GOSYM_PREFIX
"main.main");
515 initDone(void *arg
__attribute__ ((unused
))) {
516 runtime_unlockOSThread();
519 // The main goroutine.
521 runtime_main(void* dummy
__attribute__((unused
)))
528 // Lock the main goroutine onto this, the main OS thread,
529 // during initialization. Most programs won't care, but a few
530 // do require certain calls to be made by the main thread.
531 // Those can arrange for main.main to run in the main thread
532 // by calling runtime.LockOSThread during initialization
533 // to preserve the lock.
534 runtime_lockOSThread();
536 // Defer unlock so that runtime.Goexit during init does the unlock too.
540 d
.__panic
= g
->panic
;
542 d
.__makefunc_can_recover
= 0;
548 runtime_throw("runtime_main not on m0");
549 __go_go(runtime_MHeap_Scavenger
, nil
);
552 if(g
->defer
!= &d
|| d
.__pfn
!= initDone
)
553 runtime_throw("runtime: bad defer entry after init");
555 runtime_unlockOSThread();
557 // For gccgo we have to wait until after main is initialized
558 // to enable GC, because initializing main registers the GC
566 // Make racy client program work: if panicking on
567 // another goroutine at the same time as main returns,
568 // let the other goroutine finish printing the panic trace.
569 // Once it does, it will exit. See issue 3934.
570 if(runtime_panicking
)
571 runtime_park(nil
, nil
, "panicwait");
579 runtime_goroutineheader(G
*gp
)
598 status
= gp
->waitreason
;
606 runtime_printf("goroutine %D [%s]:\n", gp
->goid
, status
);
610 runtime_printcreatedby(G
*g
)
612 if(g
!= nil
&& g
->gopc
!= 0 && g
->goid
!= 1) {
617 if(__go_file_line(g
->gopc
- 1, &fn
, &file
, &line
)) {
618 runtime_printf("created by %S\n", fn
);
619 runtime_printf("\t%S:%D\n", file
, (int64
) line
);
627 Location locbuf
[100];
632 runtime_tracebackothers(G
* volatile me
)
639 traceback
= runtime_gotraceback(nil
);
641 // Show the current goroutine first, if we haven't already.
642 if((gp
= m
->curg
) != nil
&& gp
!= me
) {
643 runtime_printf("\n");
644 runtime_goroutineheader(gp
);
647 #ifdef USING_SPLIT_STACK
648 __splitstack_getcontext(&me
->stack_context
[0]);
650 getcontext(&me
->context
);
652 if(gp
->traceback
!= nil
) {
656 runtime_printtrace(tb
.locbuf
, tb
.c
, false);
657 runtime_printcreatedby(gp
);
660 for(gp
= runtime_allg
; gp
!= nil
; gp
= gp
->alllink
) {
661 if(gp
== me
|| gp
== m
->curg
|| gp
->status
== Gdead
)
663 if(gp
->issystem
&& traceback
< 2)
665 runtime_printf("\n");
666 runtime_goroutineheader(gp
);
668 // Our only mechanism for doing a stack trace is
669 // _Unwind_Backtrace. And that only works for the
670 // current thread, not for other random goroutines.
671 // So we need to switch context to the goroutine, get
672 // the backtrace, and then switch back.
674 // This means that if g is running or in a syscall, we
675 // can't reliably print a stack trace. FIXME.
677 if(gp
->status
== Grunning
) {
678 runtime_printf("\tgoroutine running on other thread; stack unavailable\n");
679 runtime_printcreatedby(gp
);
680 } else if(gp
->status
== Gsyscall
) {
681 runtime_printf("\tgoroutine in C code; stack unavailable\n");
682 runtime_printcreatedby(gp
);
686 #ifdef USING_SPLIT_STACK
687 __splitstack_getcontext(&me
->stack_context
[0]);
689 getcontext(&me
->context
);
691 if(gp
->traceback
!= nil
) {
695 runtime_printtrace(tb
.locbuf
, tb
.c
, false);
696 runtime_printcreatedby(gp
);
704 // sched lock is held
705 if(runtime_sched
.mcount
> runtime_sched
.maxmcount
) {
706 runtime_printf("runtime: program exceeds %d-thread limit\n", runtime_sched
.maxmcount
);
707 runtime_throw("thread exhaustion");
711 // Do a stack trace of gp, and then restore the context to
717 Traceback
* traceback
;
719 traceback
= gp
->traceback
;
721 traceback
->c
= runtime_callers(1, traceback
->locbuf
,
722 sizeof traceback
->locbuf
/ sizeof traceback
->locbuf
[0]);
723 runtime_gogo(traceback
->gp
);
729 // If there is no mcache runtime_callers() will crash,
730 // and we are most likely in sysmon thread so the stack is senseless anyway.
732 runtime_callers(1, mp
->createstack
, nelem(mp
->createstack
));
734 mp
->fastrand
= 0x49f6428aUL
+ mp
->id
+ runtime_cputicks();
736 runtime_lock(&runtime_sched
);
737 mp
->id
= runtime_sched
.mcount
++;
739 runtime_mpreinit(mp
);
741 // Add to runtime_allm so garbage collector doesn't free m
742 // when it is just in a register or thread-local storage.
743 mp
->alllink
= runtime_allm
;
744 // runtime_NumCgoCall() iterates over allm w/o schedlock,
745 // so we need to publish it safely.
746 runtime_atomicstorep(&runtime_allm
, mp
);
747 runtime_unlock(&runtime_sched
);
750 // Mark gp ready to run.
755 m
->locks
++; // disable preemption because it can be holding p in a local var
756 if(gp
->status
!= Gwaiting
) {
757 runtime_printf("goroutine %D has status %d\n", gp
->goid
, gp
->status
);
758 runtime_throw("bad g->status in ready");
760 gp
->status
= Grunnable
;
762 if(runtime_atomicload(&runtime_sched
.npidle
) != 0 && runtime_atomicload(&runtime_sched
.nmspinning
) == 0) // TODO: fast atomic
768 runtime_gcprocs(void)
772 // Figure out how many CPUs to use during GC.
773 // Limited by gomaxprocs, number of actual CPUs, and MaxGcproc.
774 runtime_lock(&runtime_sched
);
775 n
= runtime_gomaxprocs
;
777 n
= runtime_ncpu
> 0 ? runtime_ncpu
: 1;
780 if(n
> runtime_sched
.nmidle
+1) // one M is currently running
781 n
= runtime_sched
.nmidle
+1;
782 runtime_unlock(&runtime_sched
);
791 runtime_lock(&runtime_sched
);
792 n
= runtime_gomaxprocs
;
797 n
-= runtime_sched
.nmidle
+1; // one M is currently running
798 runtime_unlock(&runtime_sched
);
803 runtime_helpgc(int32 nproc
)
808 runtime_lock(&runtime_sched
);
810 for(n
= 1; n
< nproc
; n
++) { // one M is currently running
811 if(runtime_allp
[pos
]->mcache
== m
->mcache
)
815 runtime_throw("runtime_gcprocs inconsistency");
817 mp
->mcache
= runtime_allp
[pos
]->mcache
;
819 runtime_notewakeup(&mp
->park
);
821 runtime_unlock(&runtime_sched
);
824 // Similar to stoptheworld but best-effort and can be called several times.
825 // There is no reverse operation, used during crashing.
826 // This function must not lock any mutexes.
828 runtime_freezetheworld(void)
832 if(runtime_gomaxprocs
== 1)
834 // stopwait and preemption requests can be lost
835 // due to races with concurrently executing threads,
836 // so try several times
837 for(i
= 0; i
< 5; i
++) {
838 // this should tell the scheduler to not start any new goroutines
839 runtime_sched
.stopwait
= 0x7fffffff;
840 runtime_atomicstore((uint32
*)&runtime_sched
.gcwaiting
, 1);
841 // this should stop running goroutines
843 break; // no running goroutines
844 runtime_usleep(1000);
847 runtime_usleep(1000);
849 runtime_usleep(1000);
853 runtime_stoptheworld(void)
860 runtime_lock(&runtime_sched
);
861 runtime_sched
.stopwait
= runtime_gomaxprocs
;
862 runtime_atomicstore((uint32
*)&runtime_sched
.gcwaiting
, 1);
865 m
->p
->status
= Pgcstop
;
866 runtime_sched
.stopwait
--;
867 // try to retake all P's in Psyscall status
868 for(i
= 0; i
< runtime_gomaxprocs
; i
++) {
871 if(s
== Psyscall
&& runtime_cas(&p
->status
, s
, Pgcstop
))
872 runtime_sched
.stopwait
--;
875 while((p
= pidleget()) != nil
) {
877 runtime_sched
.stopwait
--;
879 wait
= runtime_sched
.stopwait
> 0;
880 runtime_unlock(&runtime_sched
);
882 // wait for remaining P's to stop voluntarily
884 runtime_notesleep(&runtime_sched
.stopnote
);
885 runtime_noteclear(&runtime_sched
.stopnote
);
887 if(runtime_sched
.stopwait
)
888 runtime_throw("stoptheworld: not stopped");
889 for(i
= 0; i
< runtime_gomaxprocs
; i
++) {
891 if(p
->status
!= Pgcstop
)
892 runtime_throw("stoptheworld: not stopped");
903 runtime_starttheworld(void)
910 m
->locks
++; // disable preemption because it can be holding p in a local var
911 gp
= runtime_netpoll(false); // non-blocking
913 add
= needaddgcproc();
914 runtime_lock(&runtime_sched
);
916 procresize(newprocs
);
919 procresize(runtime_gomaxprocs
);
920 runtime_sched
.gcwaiting
= 0;
923 while((p
= pidleget()) != nil
) {
924 // procresize() puts p's with work at the beginning of the list.
925 // Once we reach a p without a run queue, the rest don't have one either.
926 if(p
->runqhead
== p
->runqtail
) {
934 if(runtime_sched
.sysmonwait
) {
935 runtime_sched
.sysmonwait
= false;
936 runtime_notewakeup(&runtime_sched
.sysmonnote
);
938 runtime_unlock(&runtime_sched
);
947 runtime_throw("starttheworld: inconsistent mp->nextp");
949 runtime_notewakeup(&mp
->park
);
951 // Start M to run P. Do not start another M below.
958 // If GC could have used another helper proc, start one now,
959 // in the hope that it will be available next time.
960 // It would have been even better to start it before the collection,
961 // but doing so requires allocating memory, so it's tricky to
962 // coordinate. This lazy approach works out in practice:
963 // we don't mind if the first couple gc rounds don't have quite
964 // the maximum number of procs.
970 // Called to start an M.
972 runtime_mstart(void* mp
)
982 // Record top of stack for use by mcall.
983 // Once we call schedule we're never coming back,
984 // so other calls can reuse this stack space.
985 #ifdef USING_SPLIT_STACK
986 __splitstack_getcontext(&g
->stack_context
[0]);
988 g
->gcinitial_sp
= &mp
;
989 // Setting gcstack_size to 0 is a marker meaning that gcinitial_sp
990 // is the top of the stack, not the bottom.
994 getcontext(&g
->context
);
996 if(g
->entry
!= nil
) {
997 // Got here from mcall.
998 void (*pfn
)(G
*) = (void (*)(G
*))g
->entry
;
999 G
* gp
= (G
*)g
->param
;
1005 #ifdef USING_SPLIT_STACK
1007 int dont_block_signals
= 0;
1008 __splitstack_block_signals(&dont_block_signals
, nil
);
1012 // Install signal handlers; after minit so that minit can
1013 // prepare the thread to be able to handle the signals.
1014 if(m
== &runtime_m0
)
1023 } else if(m
!= &runtime_m0
) {
1029 // TODO(brainman): This point is never reached, because scheduler
1030 // does not release os threads at the moment. But once this path
1031 // is enabled, we must remove our seh here.
1036 typedef struct CgoThreadStart CgoThreadStart
;
1037 struct CgoThreadStart
1044 // Allocate a new m unassociated with any thread.
1045 // Can use p for allocation context if needed.
1047 runtime_allocm(P
*p
, int32 stacksize
, byte
** ret_g0_stack
, size_t* ret_g0_stacksize
)
1051 m
->locks
++; // disable GC because it can be called from sysmon
1053 acquirep(p
); // temporarily borrow p for mallocs in this function
1057 runtime_gc_m_ptr(&e
);
1058 mtype
= ((const PtrType
*)e
.__type_descriptor
)->__element_type
;
1062 mp
= runtime_mal(sizeof *mp
);
1064 mp
->g0
= runtime_malg(stacksize
, ret_g0_stack
, ret_g0_stacksize
);
1073 static M
* lockextra(bool nilokay
);
1074 static void unlockextra(M
*);
1076 // needm is called when a cgo callback happens on a
1077 // thread without an m (a thread not created by Go).
1078 // In this case, needm is expected to find an m to use
1079 // and return with m, g initialized correctly.
1080 // Since m and g are not set now (likely nil, but see below)
1081 // needm is limited in what routines it can call. In particular
1082 // it can only call nosplit functions (textflag 7) and cannot
1083 // do any scheduling that requires an m.
1085 // In order to avoid needing heavy lifting here, we adopt
1086 // the following strategy: there is a stack of available m's
1087 // that can be stolen. Using compare-and-swap
1088 // to pop from the stack has ABA races, so we simulate
1089 // a lock by doing an exchange (via casp) to steal the stack
1090 // head and replace the top pointer with MLOCKED (1).
1091 // This serves as a simple spin lock that we can use even
1092 // without an m. The thread that locks the stack in this way
1093 // unlocks the stack by storing a valid stack head pointer.
1095 // In order to make sure that there is always an m structure
1096 // available to be stolen, we maintain the invariant that there
1097 // is always one more than needed. At the beginning of the
1098 // program (if cgo is in use) the list is seeded with a single m.
1099 // If needm finds that it has taken the last m off the list, its job
1100 // is - once it has installed its own m so that it can do things like
1101 // allocate memory - to create a spare m and put it on the list.
1103 // Each of these extra m's also has a g0 and a curg that are
1104 // pressed into service as the scheduling stack and current
1105 // goroutine for the duration of the cgo callback.
1107 // When the callback is done with the m, it calls dropm to
1108 // put the m back on the list.
1110 // Unlike the gc toolchain, we start running on curg, since we are
1111 // just going to return and let the caller continue.
1117 if(runtime_needextram
) {
1118 // Can happen if C/C++ code calls Go from a global ctor.
1119 // Can not throw, because scheduler is not initialized yet.
1120 runtime_write(2, "fatal error: cgo callback before cgo call\n",
1121 sizeof("fatal error: cgo callback before cgo call\n")-1);
1125 // Lock extra list, take head, unlock popped list.
1126 // nilokay=false is safe here because of the invariant above,
1127 // that the extra list always contains or will soon contain
1129 mp
= lockextra(false);
1131 // Set needextram when we've just emptied the list,
1132 // so that the eventual call into cgocallbackg will
1133 // allocate a new m for the extra list. We delay the
1134 // allocation until then so that it can be done
1135 // after exitsyscall makes sure it is okay to be
1136 // running at all (that is, there's no garbage collection
1137 // running right now).
1138 mp
->needextram
= mp
->schedlink
== nil
;
1139 unlockextra(mp
->schedlink
);
1141 // Install m and g (= m->curg).
1142 runtime_setmg(mp
, mp
->curg
);
1144 // Initialize g's context as in mstart.
1146 g
->status
= Gsyscall
;
1149 #ifdef USING_SPLIT_STACK
1150 __splitstack_getcontext(&g
->stack_context
[0]);
1152 g
->gcinitial_sp
= &mp
;
1153 g
->gcstack_size
= 0;
1156 getcontext(&g
->context
);
1158 if(g
->entry
!= nil
) {
1159 // Got here from mcall.
1160 void (*pfn
)(G
*) = (void (*)(G
*))g
->entry
;
1161 G
* gp
= (G
*)g
->param
;
1166 // Initialize this thread to use the m.
1169 #ifdef USING_SPLIT_STACK
1171 int dont_block_signals
= 0;
1172 __splitstack_block_signals(&dont_block_signals
, nil
);
1177 // newextram allocates an m and puts it on the extra list.
1178 // It is called with a working local m, so that it can do things
1179 // like call schedlock and allocate.
1181 runtime_newextram(void)
1186 size_t g0_spsize
, spsize
;
1188 // Create extra goroutine locked to extra m.
1189 // The goroutine is the context in which the cgo callback will run.
1190 // The sched.pc will never be returned to, but setting it to
1191 // runtime.goexit makes clear to the traceback routines where
1192 // the goroutine stack ends.
1193 mp
= runtime_allocm(nil
, StackMin
, &g0_sp
, &g0_spsize
);
1194 gp
= runtime_malg(StackMin
, &sp
, &spsize
);
1197 mp
->locked
= LockInternal
;
1200 gp
->goid
= runtime_xadd64(&runtime_sched
.goidgen
, 1);
1201 // put on allg for garbage collector
1202 runtime_lock(&runtime_sched
);
1203 if(runtime_lastg
== nil
)
1206 runtime_lastg
->alllink
= gp
;
1208 runtime_unlock(&runtime_sched
);
1209 gp
->goid
= runtime_xadd64(&runtime_sched
.goidgen
, 1);
1211 // The context for gp will be set up in runtime_needm. But
1212 // here we need to set up the context for g0.
1213 getcontext(&mp
->g0
->context
);
1214 mp
->g0
->context
.uc_stack
.ss_sp
= g0_sp
;
1215 #ifdef MAKECONTEXT_STACK_TOP
1216 mp
->g0
->context
.uc_stack
.ss_sp
+= g0_spsize
;
1218 mp
->g0
->context
.uc_stack
.ss_size
= g0_spsize
;
1219 makecontext(&mp
->g0
->context
, kickoff
, 0);
1221 // Add m to the extra list.
1222 mnext
= lockextra(true);
1223 mp
->schedlink
= mnext
;
1227 // dropm is called when a cgo callback has called needm but is now
1228 // done with the callback and returning back into the non-Go thread.
1229 // It puts the current m back onto the extra list.
1231 // The main expense here is the call to signalstack to release the
1232 // m's signal stack, and then the call to needm on the next callback
1233 // from this thread. It is tempting to try to save the m for next time,
1234 // which would eliminate both these costs, but there might not be
1235 // a next time: the current thread (which Go does not control) might exit.
1236 // If we saved the m for that thread, there would be an m leak each time
1237 // such a thread exited. Instead, we acquire and release an m on each
1238 // call. These should typically not be scheduling operations, just a few
1239 // atomics, so the cost should be small.
1241 // TODO(rsc): An alternative would be to allocate a dummy pthread per-thread
1242 // variable using pthread_key_create. Unlike the pthread keys we already use
1243 // on OS X, this dummy key would never be read by Go code. It would exist
1244 // only so that we could register at thread-exit-time destructor.
1245 // That destructor would put the m back onto the extra list.
1246 // This is purely a performance optimization. The current version,
1247 // in which dropm happens on each cgo call, is still correct too.
1248 // We may have to keep the current version on systems with cgo
1249 // but without pthreads, like Windows.
1255 // Undo whatever initialization minit did during needm.
1258 // Clear m and g, and return m to the extra list.
1259 // After the call to setmg we can only call nosplit functions.
1261 runtime_setmg(nil
, nil
);
1263 mp
->curg
->status
= Gdead
;
1265 mnext
= lockextra(true);
1266 mp
->schedlink
= mnext
;
1270 #define MLOCKED ((M*)1)
1272 // lockextra locks the extra list and returns the list head.
1273 // The caller must unlock the list by storing a new list head
1274 // to runtime.extram. If nilokay is true, then lockextra will
1275 // return a nil list head if that's what it finds. If nilokay is false,
1276 // lockextra will keep waiting until the list head is no longer nil.
1278 lockextra(bool nilokay
)
1281 void (*yield
)(void);
1284 mp
= runtime_atomicloadp(&runtime_extram
);
1286 yield
= runtime_osyield
;
1290 if(mp
== nil
&& !nilokay
) {
1294 if(!runtime_casp(&runtime_extram
, mp
, MLOCKED
)) {
1295 yield
= runtime_osyield
;
1307 runtime_atomicstorep(&runtime_extram
, mp
);
1317 mp
= runtime_atomicloadp(&runtime_extram
);
1322 if(!runtime_casp(&runtime_extram
, mp
, MLOCKED
)) {
1327 for(mc
= mp
; mc
!= nil
; mc
= mc
->schedlink
)
1329 runtime_atomicstorep(&runtime_extram
, mp
);
1334 // Create a new m. It will start off with a call to fn, or else the scheduler.
1336 newm(void(*fn
)(void), P
*p
)
1340 mp
= runtime_allocm(p
, -1, nil
, nil
);
1344 runtime_newosproc(mp
);
1347 // Stops execution of the current m until new work is available.
1348 // Returns with acquired P.
1353 runtime_throw("stopm holding locks");
1355 runtime_throw("stopm holding p");
1357 m
->spinning
= false;
1358 runtime_xadd(&runtime_sched
.nmspinning
, -1);
1362 runtime_lock(&runtime_sched
);
1364 runtime_unlock(&runtime_sched
);
1365 runtime_notesleep(&m
->park
);
1366 runtime_noteclear(&m
->park
);
1383 // Schedules some M to run the p (creates an M if necessary).
1384 // If p==nil, tries to get an idle P, if no idle P's returns false.
1386 startm(P
*p
, bool spinning
)
1391 runtime_lock(&runtime_sched
);
1395 runtime_unlock(&runtime_sched
);
1397 runtime_xadd(&runtime_sched
.nmspinning
, -1);
1402 runtime_unlock(&runtime_sched
);
1411 runtime_throw("startm: m is spinning");
1413 runtime_throw("startm: m has p");
1414 mp
->spinning
= spinning
;
1416 runtime_notewakeup(&mp
->park
);
1419 // Hands off P from syscall or locked M.
1423 // if it has local work, start it straight away
1424 if(p
->runqhead
!= p
->runqtail
|| runtime_sched
.runqsize
) {
1428 // no local work, check that there are no spinning/idle M's,
1429 // otherwise our help is not required
1430 if(runtime_atomicload(&runtime_sched
.nmspinning
) + runtime_atomicload(&runtime_sched
.npidle
) == 0 && // TODO: fast atomic
1431 runtime_cas(&runtime_sched
.nmspinning
, 0, 1)) {
1435 runtime_lock(&runtime_sched
);
1436 if(runtime_sched
.gcwaiting
) {
1437 p
->status
= Pgcstop
;
1438 if(--runtime_sched
.stopwait
== 0)
1439 runtime_notewakeup(&runtime_sched
.stopnote
);
1440 runtime_unlock(&runtime_sched
);
1443 if(runtime_sched
.runqsize
) {
1444 runtime_unlock(&runtime_sched
);
1448 // If this is the last running P and nobody is polling network,
1449 // need to wakeup another M to poll network.
1450 if(runtime_sched
.npidle
== (uint32
)runtime_gomaxprocs
-1 && runtime_atomicload64(&runtime_sched
.lastpoll
) != 0) {
1451 runtime_unlock(&runtime_sched
);
1456 runtime_unlock(&runtime_sched
);
1459 // Tries to add one more P to execute G's.
1460 // Called when a G is made runnable (newproc, ready).
1464 // be conservative about spinning threads
1465 if(!runtime_cas(&runtime_sched
.nmspinning
, 0, 1))
1470 // Stops execution of the current m that is locked to a g until the g is runnable again.
1471 // Returns with acquired P.
1477 if(m
->lockedg
== nil
|| m
->lockedg
->lockedm
!= m
)
1478 runtime_throw("stoplockedm: inconsistent locking");
1480 // Schedule another M to run this p.
1485 // Wait until another thread schedules lockedg again.
1486 runtime_notesleep(&m
->park
);
1487 runtime_noteclear(&m
->park
);
1488 if(m
->lockedg
->status
!= Grunnable
)
1489 runtime_throw("stoplockedm: not runnable");
1494 // Schedules the locked m to run the locked gp.
1503 runtime_throw("startlockedm: locked to me");
1505 runtime_throw("startlockedm: m has p");
1506 // directly handoff current P to the locked m
1510 runtime_notewakeup(&mp
->park
);
1514 // Stops the current m for stoptheworld.
1515 // Returns when the world is restarted.
1521 if(!runtime_sched
.gcwaiting
)
1522 runtime_throw("gcstopm: not waiting for gc");
1524 m
->spinning
= false;
1525 runtime_xadd(&runtime_sched
.nmspinning
, -1);
1528 runtime_lock(&runtime_sched
);
1529 p
->status
= Pgcstop
;
1530 if(--runtime_sched
.stopwait
== 0)
1531 runtime_notewakeup(&runtime_sched
.stopnote
);
1532 runtime_unlock(&runtime_sched
);
1536 // Schedules gp to run on the current M.
1543 if(gp
->status
!= Grunnable
) {
1544 runtime_printf("execute: bad g status %d\n", gp
->status
);
1545 runtime_throw("execute: bad g status");
1547 gp
->status
= Grunning
;
1552 // Check whether the profiler needs to be turned on or off.
1553 hz
= runtime_sched
.profilehz
;
1554 if(m
->profilehz
!= hz
)
1555 runtime_resetcpuprofiler(hz
);
1560 // Finds a runnable goroutine to execute.
1561 // Tries to steal from other P's, get g from global queue, poll network.
1570 if(runtime_sched
.gcwaiting
) {
1579 if(runtime_sched
.runqsize
) {
1580 runtime_lock(&runtime_sched
);
1581 gp
= globrunqget(m
->p
, 0);
1582 runtime_unlock(&runtime_sched
);
1587 gp
= runtime_netpoll(false); // non-blocking
1589 injectglist(gp
->schedlink
);
1590 gp
->status
= Grunnable
;
1593 // If number of spinning M's >= number of busy P's, block.
1594 // This is necessary to prevent excessive CPU consumption
1595 // when GOMAXPROCS>>1 but the program parallelism is low.
1596 if(!m
->spinning
&& 2 * runtime_atomicload(&runtime_sched
.nmspinning
) >= runtime_gomaxprocs
- runtime_atomicload(&runtime_sched
.npidle
)) // TODO: fast atomic
1600 runtime_xadd(&runtime_sched
.nmspinning
, 1);
1602 // random steal from other P's
1603 for(i
= 0; i
< 2*runtime_gomaxprocs
; i
++) {
1604 if(runtime_sched
.gcwaiting
)
1606 p
= runtime_allp
[runtime_fastrand1()%runtime_gomaxprocs
];
1610 gp
= runqsteal(m
->p
, p
);
1615 // return P and block
1616 runtime_lock(&runtime_sched
);
1617 if(runtime_sched
.gcwaiting
) {
1618 runtime_unlock(&runtime_sched
);
1621 if(runtime_sched
.runqsize
) {
1622 gp
= globrunqget(m
->p
, 0);
1623 runtime_unlock(&runtime_sched
);
1628 runtime_unlock(&runtime_sched
);
1630 m
->spinning
= false;
1631 runtime_xadd(&runtime_sched
.nmspinning
, -1);
1633 // check all runqueues once again
1634 for(i
= 0; i
< runtime_gomaxprocs
; i
++) {
1635 p
= runtime_allp
[i
];
1636 if(p
&& p
->runqhead
!= p
->runqtail
) {
1637 runtime_lock(&runtime_sched
);
1639 runtime_unlock(&runtime_sched
);
1648 if(runtime_xchg64(&runtime_sched
.lastpoll
, 0) != 0) {
1650 runtime_throw("findrunnable: netpoll with p");
1652 runtime_throw("findrunnable: netpoll with spinning");
1653 gp
= runtime_netpoll(true); // block until new work is available
1654 runtime_atomicstore64(&runtime_sched
.lastpoll
, runtime_nanotime());
1656 runtime_lock(&runtime_sched
);
1658 runtime_unlock(&runtime_sched
);
1661 injectglist(gp
->schedlink
);
1662 gp
->status
= Grunnable
;
1678 m
->spinning
= false;
1679 nmspinning
= runtime_xadd(&runtime_sched
.nmspinning
, -1);
1681 runtime_throw("findrunnable: negative nmspinning");
1683 nmspinning
= runtime_atomicload(&runtime_sched
.nmspinning
);
1685 // M wakeup policy is deliberately somewhat conservative (see nmspinning handling),
1686 // so see if we need to wakeup another P here.
1687 if (nmspinning
== 0 && runtime_atomicload(&runtime_sched
.npidle
) > 0)
1691 // Injects the list of runnable G's into the scheduler.
1692 // Can run concurrently with GC.
1694 injectglist(G
*glist
)
1701 runtime_lock(&runtime_sched
);
1702 for(n
= 0; glist
; n
++) {
1704 glist
= gp
->schedlink
;
1705 gp
->status
= Grunnable
;
1708 runtime_unlock(&runtime_sched
);
1710 for(; n
&& runtime_sched
.npidle
; n
--)
1714 // One round of scheduler: find a runnable goroutine and execute it.
1723 runtime_throw("schedule: holding locks");
1726 if(runtime_sched
.gcwaiting
) {
1732 // Check the global runnable queue once in a while to ensure fairness.
1733 // Otherwise two goroutines can completely occupy the local runqueue
1734 // by constantly respawning each other.
1735 tick
= m
->p
->schedtick
;
1736 // This is a fancy way to say tick%61==0,
1737 // it uses 2 MUL instructions instead of a single DIV and so is faster on modern processors.
1738 if(tick
- (((uint64
)tick
*0x4325c53fu
)>>36)*61 == 0 && runtime_sched
.runqsize
> 0) {
1739 runtime_lock(&runtime_sched
);
1740 gp
= globrunqget(m
->p
, 1);
1741 runtime_unlock(&runtime_sched
);
1747 if(gp
&& m
->spinning
)
1748 runtime_throw("schedule: spinning with local work");
1751 gp
= findrunnable(); // blocks until work is available
1756 // Hands off own p to the locked m,
1757 // then blocks waiting for a new p.
1765 // Puts the current goroutine into a waiting state and unlocks the lock.
1766 // The goroutine can be made runnable again by calling runtime_ready(gp).
1768 runtime_park(void(*unlockf
)(Lock
*), Lock
*lock
, const char *reason
)
1771 m
->waitunlockf
= unlockf
;
1772 g
->waitreason
= reason
;
1773 runtime_mcall(park0
);
1776 // runtime_park continuation on g0.
1780 gp
->status
= Gwaiting
;
1783 if(m
->waitunlockf
) {
1784 m
->waitunlockf(m
->waitlock
);
1785 m
->waitunlockf
= nil
;
1790 execute(gp
); // Never returns.
1797 runtime_gosched(void)
1799 runtime_mcall(runtime_gosched0
);
1802 // runtime_gosched continuation on g0.
1804 runtime_gosched0(G
*gp
)
1806 gp
->status
= Grunnable
;
1809 runtime_lock(&runtime_sched
);
1811 runtime_unlock(&runtime_sched
);
1814 execute(gp
); // Never returns.
1819 // Finishes execution of the current goroutine.
1820 // Need to mark it as nosplit, because it runs with sp > stackbase (as runtime_lessstack).
1821 // Since it does not return it does not matter. But if it is preempted
1822 // at the split stack check, GC will complain about inconsistent sp.
1824 runtime_goexit(void)
1827 runtime_racegoend();
1828 runtime_mcall(goexit0
);
1831 // runtime_goexit continuation on g0.
1841 if(m
->locked
& ~LockExternal
) {
1842 runtime_printf("invalid m->locked = %d\n", m
->locked
);
1843 runtime_throw("internal lockOSThread error");
1850 // The goroutine g is about to enter a system call.
1851 // Record that it's not using the cpu anymore.
1852 // This is called only from the go syscall library and cgocall,
1853 // not from the low-level system calls used by the runtime.
1855 // Entersyscall cannot split the stack: the runtime_gosave must
1856 // make g->sched refer to the caller's stack segment, because
1857 // entersyscall is going to return immediately after.
1859 void runtime_entersyscall(void) __attribute__ ((no_split_stack
));
1860 static void doentersyscall(void) __attribute__ ((no_split_stack
, noinline
));
1863 runtime_entersyscall()
1865 // Save the registers in the g structure so that any pointers
1866 // held in registers will be seen by the garbage collector.
1867 getcontext(&g
->gcregs
);
1869 // Do the work in a separate function, so that this function
1870 // doesn't save any registers on its own stack. If this
1871 // function does save any registers, we might store the wrong
1872 // value in the call to getcontext.
1874 // FIXME: This assumes that we do not need to save any
1875 // callee-saved registers to access the TLS variable g. We
1876 // don't want to put the ucontext_t on the stack because it is
1877 // large and we can not split the stack here.
1884 // Disable preemption because during this function g is in Gsyscall status,
1885 // but can have inconsistent g->sched, do not let GC observe it.
1888 // Leave SP around for GC and traceback.
1889 #ifdef USING_SPLIT_STACK
1890 g
->gcstack
= __splitstack_find(nil
, nil
, &g
->gcstack_size
,
1891 &g
->gcnext_segment
, &g
->gcnext_sp
,
1897 g
->gcnext_sp
= (byte
*) &v
;
1901 g
->status
= Gsyscall
;
1903 if(runtime_atomicload(&runtime_sched
.sysmonwait
)) { // TODO: fast atomic
1904 runtime_lock(&runtime_sched
);
1905 if(runtime_atomicload(&runtime_sched
.sysmonwait
)) {
1906 runtime_atomicstore(&runtime_sched
.sysmonwait
, 0);
1907 runtime_notewakeup(&runtime_sched
.sysmonnote
);
1909 runtime_unlock(&runtime_sched
);
1914 runtime_atomicstore(&m
->p
->status
, Psyscall
);
1915 if(runtime_sched
.gcwaiting
) {
1916 runtime_lock(&runtime_sched
);
1917 if (runtime_sched
.stopwait
> 0 && runtime_cas(&m
->p
->status
, Psyscall
, Pgcstop
)) {
1918 if(--runtime_sched
.stopwait
== 0)
1919 runtime_notewakeup(&runtime_sched
.stopnote
);
1921 runtime_unlock(&runtime_sched
);
1927 // The same as runtime_entersyscall(), but with a hint that the syscall is blocking.
1929 runtime_entersyscallblock(void)
1933 m
->locks
++; // see comment in entersyscall
1935 // Leave SP around for GC and traceback.
1936 #ifdef USING_SPLIT_STACK
1937 g
->gcstack
= __splitstack_find(nil
, nil
, &g
->gcstack_size
,
1938 &g
->gcnext_segment
, &g
->gcnext_sp
,
1941 g
->gcnext_sp
= (byte
*) &p
;
1944 // Save the registers in the g structure so that any pointers
1945 // held in registers will be seen by the garbage collector.
1946 getcontext(&g
->gcregs
);
1948 g
->status
= Gsyscall
;
1952 if(g
->isbackground
) // do not consider blocked scavenger for deadlock detection
1958 // The goroutine g exited its system call.
1959 // Arrange for it to run on a cpu again.
1960 // This is called only from the go syscall library, not
1961 // from the low-level system calls used by the runtime.
1963 runtime_exitsyscall(void)
1967 m
->locks
++; // see comment in entersyscall
1970 if(gp
->isbackground
) // do not consider blocked scavenger for deadlock detection
1973 if(exitsyscallfast()) {
1974 // There's a cpu for us, so we can run.
1975 m
->p
->syscalltick
++;
1976 gp
->status
= Grunning
;
1977 // Garbage collector isn't running (since we are),
1978 // so okay to clear gcstack and gcsp.
1979 #ifdef USING_SPLIT_STACK
1982 gp
->gcnext_sp
= nil
;
1983 runtime_memclr(&gp
->gcregs
, sizeof gp
->gcregs
);
1990 // Call the scheduler.
1991 runtime_mcall(exitsyscall0
);
1993 // Scheduler returned, so we're allowed to run now.
1994 // Delete the gcstack information that we left for
1995 // the garbage collector during the system call.
1996 // Must wait until now because until gosched returns
1997 // we don't know for sure that the garbage collector
1999 #ifdef USING_SPLIT_STACK
2002 gp
->gcnext_sp
= nil
;
2003 runtime_memclr(&gp
->gcregs
, sizeof gp
->gcregs
);
2005 // Don't refer to m again, we might be running on a different
2006 // thread after returning from runtime_mcall.
2007 runtime_m()->p
->syscalltick
++;
2011 exitsyscallfast(void)
2015 // Freezetheworld sets stopwait but does not retake P's.
2016 if(runtime_sched
.stopwait
) {
2021 // Try to re-acquire the last P.
2022 if(m
->p
&& m
->p
->status
== Psyscall
&& runtime_cas(&m
->p
->status
, Psyscall
, Prunning
)) {
2023 // There's a cpu for us, so we can run.
2024 m
->mcache
= m
->p
->mcache
;
2028 // Try to get any other idle P.
2030 if(runtime_sched
.pidle
) {
2031 runtime_lock(&runtime_sched
);
2033 if(p
&& runtime_atomicload(&runtime_sched
.sysmonwait
)) {
2034 runtime_atomicstore(&runtime_sched
.sysmonwait
, 0);
2035 runtime_notewakeup(&runtime_sched
.sysmonnote
);
2037 runtime_unlock(&runtime_sched
);
2046 // runtime_exitsyscall slow path on g0.
2047 // Failed to acquire P, enqueue gp as runnable.
2053 gp
->status
= Grunnable
;
2056 runtime_lock(&runtime_sched
);
2060 else if(runtime_atomicload(&runtime_sched
.sysmonwait
)) {
2061 runtime_atomicstore(&runtime_sched
.sysmonwait
, 0);
2062 runtime_notewakeup(&runtime_sched
.sysmonnote
);
2064 runtime_unlock(&runtime_sched
);
2067 execute(gp
); // Never returns.
2070 // Wait until another thread schedules gp and so m again.
2072 execute(gp
); // Never returns.
2075 schedule(); // Never returns.
2078 // Called from syscall package before fork.
2079 void syscall_runtime_BeforeFork(void)
2080 __asm__(GOSYM_PREFIX
"syscall.runtime_BeforeFork");
2082 syscall_runtime_BeforeFork(void)
2084 // Fork can hang if preempted with signals frequently enough (see issue 5517).
2085 // Ensure that we stay on the same M where we disable profiling.
2087 if(m
->profilehz
!= 0)
2088 runtime_resetcpuprofiler(0);
2091 // Called from syscall package after fork in parent.
2092 void syscall_runtime_AfterFork(void)
2093 __asm__(GOSYM_PREFIX
"syscall.runtime_AfterFork");
2095 syscall_runtime_AfterFork(void)
2099 hz
= runtime_sched
.profilehz
;
2101 runtime_resetcpuprofiler(hz
);
2105 // Allocate a new g, with a stack big enough for stacksize bytes.
2107 runtime_malg(int32 stacksize
, byte
** ret_stack
, size_t* ret_stacksize
)
2111 newg
= runtime_malloc(sizeof(G
));
2112 if(stacksize
>= 0) {
2113 #if USING_SPLIT_STACK
2114 int dont_block_signals
= 0;
2116 *ret_stack
= __splitstack_makecontext(stacksize
,
2117 &newg
->stack_context
[0],
2119 __splitstack_block_signals_context(&newg
->stack_context
[0],
2120 &dont_block_signals
, nil
);
2122 *ret_stack
= runtime_mallocgc(stacksize
, 0, FlagNoProfiling
|FlagNoGC
);
2123 *ret_stacksize
= stacksize
;
2124 newg
->gcinitial_sp
= *ret_stack
;
2125 newg
->gcstack_size
= stacksize
;
2126 runtime_xadd(&runtime_stacks_sys
, stacksize
);
2132 /* For runtime package testing. */
2135 // Create a new g running fn with siz bytes of arguments.
2136 // Put it on the queue of g's waiting to run.
2137 // The compiler turns a go statement into a call to this.
2138 // Cannot split the stack because it assumes that the arguments
2139 // are available sequentially after &fn; they would not be
2140 // copied if a stack split occurred. It's OK for this to call
2141 // functions that split the stack.
2142 void runtime_testing_entersyscall(void)
2143 __asm__ (GOSYM_PREFIX
"runtime.entersyscall");
2145 runtime_testing_entersyscall()
2147 runtime_entersyscall();
2150 void runtime_testing_exitsyscall(void)
2151 __asm__ (GOSYM_PREFIX
"runtime.exitsyscall");
2154 runtime_testing_exitsyscall()
2156 runtime_exitsyscall();
2160 __go_go(void (*fn
)(void*), void* arg
)
2166 //runtime_printf("newproc1 %p %p narg=%d nret=%d\n", fn->fn, argp, narg, nret);
2167 m
->locks
++; // disable preemption because it can be holding p in a local var
2169 if((newg
= gfget(m
->p
)) != nil
) {
2170 #ifdef USING_SPLIT_STACK
2171 int dont_block_signals
= 0;
2173 sp
= __splitstack_resetcontext(&newg
->stack_context
[0],
2175 __splitstack_block_signals_context(&newg
->stack_context
[0],
2176 &dont_block_signals
, nil
);
2178 sp
= newg
->gcinitial_sp
;
2179 spsize
= newg
->gcstack_size
;
2181 runtime_throw("bad spsize in __go_go");
2182 newg
->gcnext_sp
= sp
;
2185 newg
= runtime_malg(StackMin
, &sp
, &spsize
);
2186 runtime_lock(&runtime_sched
);
2187 if(runtime_lastg
== nil
)
2188 runtime_allg
= newg
;
2190 runtime_lastg
->alllink
= newg
;
2191 runtime_lastg
= newg
;
2192 runtime_unlock(&runtime_sched
);
2195 newg
->entry
= (byte
*)fn
;
2197 newg
->gopc
= (uintptr
)__builtin_return_address(0);
2198 newg
->status
= Grunnable
;
2199 newg
->goid
= runtime_xadd64(&runtime_sched
.goidgen
, 1);
2202 // Avoid warnings about variables clobbered by
2204 byte
* volatile vsp
= sp
;
2205 size_t volatile vspsize
= spsize
;
2206 G
* volatile vnewg
= newg
;
2208 getcontext(&vnewg
->context
);
2209 vnewg
->context
.uc_stack
.ss_sp
= vsp
;
2210 #ifdef MAKECONTEXT_STACK_TOP
2211 vnewg
->context
.uc_stack
.ss_sp
+= vspsize
;
2213 vnewg
->context
.uc_stack
.ss_size
= vspsize
;
2214 makecontext(&vnewg
->context
, kickoff
, 0);
2216 runqput(m
->p
, vnewg
);
2218 if(runtime_atomicload(&runtime_sched
.npidle
) != 0 && runtime_atomicload(&runtime_sched
.nmspinning
) == 0 && fn
!= runtime_main
) // TODO: fast atomic
2225 // Put on gfree list.
2226 // If local list is too long, transfer a batch to the global list.
2230 gp
->schedlink
= p
->gfree
;
2233 if(p
->gfreecnt
>= 64) {
2234 runtime_lock(&runtime_sched
.gflock
);
2235 while(p
->gfreecnt
>= 32) {
2238 p
->gfree
= gp
->schedlink
;
2239 gp
->schedlink
= runtime_sched
.gfree
;
2240 runtime_sched
.gfree
= gp
;
2242 runtime_unlock(&runtime_sched
.gflock
);
2246 // Get from gfree list.
2247 // If local list is empty, grab a batch from global list.
2255 if(gp
== nil
&& runtime_sched
.gfree
) {
2256 runtime_lock(&runtime_sched
.gflock
);
2257 while(p
->gfreecnt
< 32 && runtime_sched
.gfree
) {
2259 gp
= runtime_sched
.gfree
;
2260 runtime_sched
.gfree
= gp
->schedlink
;
2261 gp
->schedlink
= p
->gfree
;
2264 runtime_unlock(&runtime_sched
.gflock
);
2268 p
->gfree
= gp
->schedlink
;
2274 // Purge all cached G's from gfree list to the global list.
2280 runtime_lock(&runtime_sched
.gflock
);
2281 while(p
->gfreecnt
) {
2284 p
->gfree
= gp
->schedlink
;
2285 gp
->schedlink
= runtime_sched
.gfree
;
2286 runtime_sched
.gfree
= gp
;
2288 runtime_unlock(&runtime_sched
.gflock
);
2292 runtime_Breakpoint(void)
2294 runtime_breakpoint();
2297 void runtime_Gosched (void) __asm__ (GOSYM_PREFIX
"runtime.Gosched");
2300 runtime_Gosched(void)
2305 // Implementation of runtime.GOMAXPROCS.
2306 // delete when scheduler is even stronger
2308 runtime_gomaxprocsfunc(int32 n
)
2312 if(n
> MaxGomaxprocs
)
2314 runtime_lock(&runtime_sched
);
2315 ret
= runtime_gomaxprocs
;
2316 if(n
<= 0 || n
== ret
) {
2317 runtime_unlock(&runtime_sched
);
2320 runtime_unlock(&runtime_sched
);
2322 runtime_semacquire(&runtime_worldsema
, false);
2324 runtime_stoptheworld();
2327 runtime_semrelease(&runtime_worldsema
);
2328 runtime_starttheworld();
2333 // lockOSThread is called by runtime.LockOSThread and runtime.lockOSThread below
2334 // after they modify m->locked. Do not allow preemption during this call,
2335 // or else the m might be different in this function than in the caller.
2343 void runtime_LockOSThread(void) __asm__ (GOSYM_PREFIX
"runtime.LockOSThread");
2345 runtime_LockOSThread(void)
2347 m
->locked
|= LockExternal
;
2352 runtime_lockOSThread(void)
2354 m
->locked
+= LockInternal
;
2359 // unlockOSThread is called by runtime.UnlockOSThread and runtime.unlockOSThread below
2360 // after they update m->locked. Do not allow preemption during this call,
2361 // or else the m might be in different in this function than in the caller.
2363 unlockOSThread(void)
2371 void runtime_UnlockOSThread(void) __asm__ (GOSYM_PREFIX
"runtime.UnlockOSThread");
2374 runtime_UnlockOSThread(void)
2376 m
->locked
&= ~LockExternal
;
2381 runtime_unlockOSThread(void)
2383 if(m
->locked
< LockInternal
)
2384 runtime_throw("runtime: internal error: misuse of lockOSThread/unlockOSThread");
2385 m
->locked
-= LockInternal
;
2390 runtime_lockedOSThread(void)
2392 return g
->lockedm
!= nil
&& m
->lockedg
!= nil
;
2395 // for testing of callbacks
2397 _Bool
runtime_golockedOSThread(void)
2398 __asm__ (GOSYM_PREFIX
"runtime.golockedOSThread");
2401 runtime_golockedOSThread(void)
2403 return runtime_lockedOSThread();
2406 intgo
runtime_NumGoroutine (void)
2407 __asm__ (GOSYM_PREFIX
"runtime.NumGoroutine");
2410 runtime_NumGoroutine()
2412 return runtime_gcount();
2416 runtime_gcount(void)
2422 runtime_lock(&runtime_sched
);
2423 // TODO(dvyukov): runtime.NumGoroutine() is O(N).
2424 // We do not want to increment/decrement centralized counter in newproc/goexit,
2425 // just to make runtime.NumGoroutine() faster.
2426 // Compromise solution is to introduce per-P counters of active goroutines.
2427 for(gp
= runtime_allg
; gp
; gp
= gp
->alllink
) {
2429 if(s
== Grunnable
|| s
== Grunning
|| s
== Gsyscall
|| s
== Gwaiting
)
2432 runtime_unlock(&runtime_sched
);
2437 runtime_mcount(void)
2439 return runtime_sched
.mcount
;
2444 void (*fn
)(uintptr
*, int32
);
2447 Location locbuf
[100];
2455 // Called if we receive a SIGPROF signal.
2462 if(prof
.fn
== nil
|| prof
.hz
== 0)
2465 // Windows does profiling in a dedicated thread w/o m.
2466 if(!Windows
&& (m
== nil
|| m
->mcache
== nil
))
2469 runtime_lock(&prof
);
2470 if(prof
.fn
== nil
) {
2471 runtime_unlock(&prof
);
2476 if(runtime_atomicload(&runtime_in_callers
) > 0) {
2477 // If SIGPROF arrived while already fetching runtime
2478 // callers we can have trouble on older systems
2479 // because the unwind library calls dl_iterate_phdr
2480 // which was not recursive in the past.
2485 n
= runtime_callers(0, prof
.locbuf
, nelem(prof
.locbuf
));
2486 for(i
= 0; i
< n
; i
++)
2487 prof
.pcbuf
[i
] = prof
.locbuf
[i
].pc
;
2489 if (!traceback
|| n
<= 0) {
2491 prof
.pcbuf
[0] = (uintptr
)runtime_getcallerpc(&n
);
2492 prof
.pcbuf
[1] = (uintptr
)System
+ 1;
2494 prof
.fn(prof
.pcbuf
, n
);
2495 runtime_unlock(&prof
);
2498 // Arrange to call fn with a traceback hz times a second.
2500 runtime_setcpuprofilerate(void (*fn
)(uintptr
*, int32
), int32 hz
)
2502 // Force sane arguments.
2510 // Disable preemption, otherwise we can be rescheduled to another thread
2511 // that has profiling enabled.
2514 // Stop profiler on this thread so that it is safe to lock prof.
2515 // if a profiling signal came in while we had prof locked,
2516 // it would deadlock.
2517 runtime_resetcpuprofiler(0);
2519 runtime_lock(&prof
);
2522 runtime_unlock(&prof
);
2523 runtime_lock(&runtime_sched
);
2524 runtime_sched
.profilehz
= hz
;
2525 runtime_unlock(&runtime_sched
);
2528 runtime_resetcpuprofiler(hz
);
2533 // Change number of processors. The world is stopped, sched is locked.
2535 procresize(int32
new)
2541 old
= runtime_gomaxprocs
;
2542 if(old
< 0 || old
> MaxGomaxprocs
|| new <= 0 || new >MaxGomaxprocs
)
2543 runtime_throw("procresize: invalid arg");
2544 // initialize new P's
2545 for(i
= 0; i
< new; i
++) {
2546 p
= runtime_allp
[i
];
2548 p
= (P
*)runtime_mallocgc(sizeof(*p
), 0, FlagNoInvokeGC
);
2550 p
->status
= Pgcstop
;
2551 runtime_atomicstorep(&runtime_allp
[i
], p
);
2553 if(p
->mcache
== nil
) {
2555 p
->mcache
= m
->mcache
; // bootstrap
2557 p
->mcache
= runtime_allocmcache();
2559 if(p
->runq
== nil
) {
2561 p
->runq
= (G
**)runtime_mallocgc(p
->runqsize
*sizeof(G
*), 0, FlagNoInvokeGC
);
2565 // redistribute runnable G's evenly
2566 for(i
= 0; i
< old
; i
++) {
2567 p
= runtime_allp
[i
];
2568 while((gp
= runqget(p
)) != nil
)
2571 // start at 1 because current M already executes some G and will acquire allp[0] below,
2572 // so if we have a spare G we want to put it into allp[1].
2573 for(i
= 1; runtime_sched
.runqhead
; i
++) {
2574 gp
= runtime_sched
.runqhead
;
2575 runtime_sched
.runqhead
= gp
->schedlink
;
2576 runqput(runtime_allp
[i
%new], gp
);
2578 runtime_sched
.runqtail
= nil
;
2579 runtime_sched
.runqsize
= 0;
2582 for(i
= new; i
< old
; i
++) {
2583 p
= runtime_allp
[i
];
2584 runtime_freemcache(p
->mcache
);
2588 // can't free P itself because it can be referenced by an M in syscall
2595 p
= runtime_allp
[0];
2599 for(i
= new-1; i
> 0; i
--) {
2600 p
= runtime_allp
[i
];
2604 runtime_atomicstore((uint32
*)&runtime_gomaxprocs
, new);
2607 // Associate p and the current m.
2611 if(m
->p
|| m
->mcache
)
2612 runtime_throw("acquirep: already in go");
2613 if(p
->m
|| p
->status
!= Pidle
) {
2614 runtime_printf("acquirep: p->m=%p(%d) p->status=%d\n", p
->m
, p
->m
? p
->m
->id
: 0, p
->status
);
2615 runtime_throw("acquirep: invalid p state");
2617 m
->mcache
= p
->mcache
;
2620 p
->status
= Prunning
;
2623 // Disassociate p and the current m.
2629 if(m
->p
== nil
|| m
->mcache
== nil
)
2630 runtime_throw("releasep: invalid arg");
2632 if(p
->m
!= m
|| p
->mcache
!= m
->mcache
|| p
->status
!= Prunning
) {
2633 runtime_printf("releasep: m=%p m->p=%p p->m=%p m->mcache=%p p->mcache=%p p->status=%d\n",
2634 m
, m
->p
, p
->m
, m
->mcache
, p
->mcache
, p
->status
);
2635 runtime_throw("releasep: invalid p state");
2645 incidlelocked(int32 v
)
2647 runtime_lock(&runtime_sched
);
2648 runtime_sched
.nmidlelocked
+= v
;
2651 runtime_unlock(&runtime_sched
);
2654 // Check for deadlock situation.
2655 // The check is based on number of running M's, if 0 -> deadlock.
2660 int32 run
, grunning
, s
;
2663 run
= runtime_sched
.mcount
- runtime_sched
.nmidle
- runtime_sched
.nmidlelocked
- 1 - countextra();
2667 runtime_printf("checkdead: nmidle=%d nmidlelocked=%d mcount=%d\n",
2668 runtime_sched
.nmidle
, runtime_sched
.nmidlelocked
, runtime_sched
.mcount
);
2669 runtime_throw("checkdead: inconsistent counts");
2672 for(gp
= runtime_allg
; gp
; gp
= gp
->alllink
) {
2673 if(gp
->isbackground
)
2678 else if(s
== Grunnable
|| s
== Grunning
|| s
== Gsyscall
) {
2679 runtime_printf("checkdead: find g %D in status %d\n", gp
->goid
, s
);
2680 runtime_throw("checkdead: runnable g");
2683 if(grunning
== 0) // possible if main goroutine calls runtime_Goexit()
2685 m
->throwing
= -1; // do not dump full stacks
2686 runtime_throw("all goroutines are asleep - deadlock!");
2693 int64 now
, lastpoll
, lasttrace
;
2697 idle
= 0; // how many cycles in succession we had not wokeup somebody
2700 if(idle
== 0) // start with 20us sleep...
2702 else if(idle
> 50) // start doubling the sleep after 1ms...
2704 if(delay
> 10*1000) // up to 10ms
2706 runtime_usleep(delay
);
2707 if(runtime_debug
.schedtrace
<= 0 &&
2708 (runtime_sched
.gcwaiting
|| runtime_atomicload(&runtime_sched
.npidle
) == (uint32
)runtime_gomaxprocs
)) { // TODO: fast atomic
2709 runtime_lock(&runtime_sched
);
2710 if(runtime_atomicload(&runtime_sched
.gcwaiting
) || runtime_atomicload(&runtime_sched
.npidle
) == (uint32
)runtime_gomaxprocs
) {
2711 runtime_atomicstore(&runtime_sched
.sysmonwait
, 1);
2712 runtime_unlock(&runtime_sched
);
2713 runtime_notesleep(&runtime_sched
.sysmonnote
);
2714 runtime_noteclear(&runtime_sched
.sysmonnote
);
2718 runtime_unlock(&runtime_sched
);
2720 // poll network if not polled for more than 10ms
2721 lastpoll
= runtime_atomicload64(&runtime_sched
.lastpoll
);
2722 now
= runtime_nanotime();
2723 if(lastpoll
!= 0 && lastpoll
+ 10*1000*1000 < now
) {
2724 runtime_cas64(&runtime_sched
.lastpoll
, lastpoll
, now
);
2725 gp
= runtime_netpoll(false); // non-blocking
2727 // Need to decrement number of idle locked M's
2728 // (pretending that one more is running) before injectglist.
2729 // Otherwise it can lead to the following situation:
2730 // injectglist grabs all P's but before it starts M's to run the P's,
2731 // another M returns from syscall, finishes running its G,
2732 // observes that there is no work to do and no other running M's
2733 // and reports deadlock.
2739 // retake P's blocked in syscalls
2740 // and preempt long running G's
2746 if(runtime_debug
.schedtrace
> 0 && lasttrace
+ runtime_debug
.schedtrace
*1000000ll <= now
) {
2748 runtime_schedtrace(runtime_debug
.scheddetail
);
2753 typedef struct Pdesc Pdesc
;
2761 static Pdesc pdesc
[MaxGomaxprocs
];
2772 for(i
= 0; i
< (uint32
)runtime_gomaxprocs
; i
++) {
2773 p
= runtime_allp
[i
];
2779 // Retake P from syscall if it's there for more than 1 sysmon tick (20us).
2780 // But only if there is other work to do.
2782 if(pd
->syscalltick
!= t
) {
2783 pd
->syscalltick
= t
;
2784 pd
->syscallwhen
= now
;
2787 if(p
->runqhead
== p
->runqtail
&&
2788 runtime_atomicload(&runtime_sched
.nmspinning
) + runtime_atomicload(&runtime_sched
.npidle
) > 0)
2790 // Need to decrement number of idle locked M's
2791 // (pretending that one more is running) before the CAS.
2792 // Otherwise the M from which we retake can exit the syscall,
2793 // increment nmidle and report deadlock.
2795 if(runtime_cas(&p
->status
, s
, Pidle
)) {
2800 } else if(s
== Prunning
) {
2801 // Preempt G if it's running for more than 10ms.
2803 if(pd
->schedtick
!= t
) {
2805 pd
->schedwhen
= now
;
2808 if(pd
->schedwhen
+ 10*1000*1000 > now
)
2816 // Tell all goroutines that they have been preempted and they should stop.
2817 // This function is purely best-effort. It can fail to inform a goroutine if a
2818 // processor just started running it.
2819 // No locks need to be held.
2820 // Returns true if preemption request was issued to at least one goroutine.
2828 runtime_schedtrace(bool detailed
)
2830 static int64 starttime
;
2832 int64 id1
, id2
, id3
;
2833 int32 i
, q
, t
, h
, s
;
2839 now
= runtime_nanotime();
2843 runtime_lock(&runtime_sched
);
2844 runtime_printf("SCHED %Dms: gomaxprocs=%d idleprocs=%d threads=%d idlethreads=%d runqueue=%d",
2845 (now
-starttime
)/1000000, runtime_gomaxprocs
, runtime_sched
.npidle
, runtime_sched
.mcount
,
2846 runtime_sched
.nmidle
, runtime_sched
.runqsize
);
2848 runtime_printf(" gcwaiting=%d nmidlelocked=%d nmspinning=%d stopwait=%d sysmonwait=%d\n",
2849 runtime_sched
.gcwaiting
, runtime_sched
.nmidlelocked
, runtime_sched
.nmspinning
,
2850 runtime_sched
.stopwait
, runtime_sched
.sysmonwait
);
2852 // We must be careful while reading data from P's, M's and G's.
2853 // Even if we hold schedlock, most data can be changed concurrently.
2854 // E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil.
2855 for(i
= 0; i
< runtime_gomaxprocs
; i
++) {
2856 p
= runtime_allp
[i
];
2867 runtime_printf(" P%d: status=%d schedtick=%d syscalltick=%d m=%d runqsize=%d/%d gfreecnt=%d\n",
2868 i
, p
->status
, p
->schedtick
, p
->syscalltick
, mp
? mp
->id
: -1, q
, s
, p
->gfreecnt
);
2870 // In non-detailed mode format lengths of per-P run queues as:
2871 // [len1 len2 len3 len4]
2873 if(runtime_gomaxprocs
== 1)
2877 else if(i
== runtime_gomaxprocs
-1)
2879 runtime_printf(fmt
, q
);
2883 runtime_unlock(&runtime_sched
);
2886 for(mp
= runtime_allm
; mp
; mp
= mp
->alllink
) {
2889 lockedg
= mp
->lockedg
;
2898 id3
= lockedg
->goid
;
2899 runtime_printf(" M%d: p=%D curg=%D mallocing=%d throwing=%d gcing=%d"
2900 " locks=%d dying=%d helpgc=%d spinning=%d lockedg=%D\n",
2902 mp
->mallocing
, mp
->throwing
, mp
->gcing
, mp
->locks
, mp
->dying
, mp
->helpgc
,
2905 for(gp
= runtime_allg
; gp
; gp
= gp
->alllink
) {
2907 lockedm
= gp
->lockedm
;
2908 runtime_printf(" G%D: status=%d(%s) m=%d lockedm=%d\n",
2909 gp
->goid
, gp
->status
, gp
->waitreason
, mp
? mp
->id
: -1,
2910 lockedm
? lockedm
->id
: -1);
2912 runtime_unlock(&runtime_sched
);
2915 // Put mp on midle list.
2916 // Sched must be locked.
2920 mp
->schedlink
= runtime_sched
.midle
;
2921 runtime_sched
.midle
= mp
;
2922 runtime_sched
.nmidle
++;
2926 // Try to get an m from midle list.
2927 // Sched must be locked.
2933 if((mp
= runtime_sched
.midle
) != nil
){
2934 runtime_sched
.midle
= mp
->schedlink
;
2935 runtime_sched
.nmidle
--;
2940 // Put gp on the global runnable queue.
2941 // Sched must be locked.
2945 gp
->schedlink
= nil
;
2946 if(runtime_sched
.runqtail
)
2947 runtime_sched
.runqtail
->schedlink
= gp
;
2949 runtime_sched
.runqhead
= gp
;
2950 runtime_sched
.runqtail
= gp
;
2951 runtime_sched
.runqsize
++;
2954 // Try get a batch of G's from the global runnable queue.
2955 // Sched must be locked.
2957 globrunqget(P
*p
, int32 max
)
2962 if(runtime_sched
.runqsize
== 0)
2964 n
= runtime_sched
.runqsize
/runtime_gomaxprocs
+1;
2965 if(n
> runtime_sched
.runqsize
)
2966 n
= runtime_sched
.runqsize
;
2967 if(max
> 0 && n
> max
)
2969 runtime_sched
.runqsize
-= n
;
2970 if(runtime_sched
.runqsize
== 0)
2971 runtime_sched
.runqtail
= nil
;
2972 gp
= runtime_sched
.runqhead
;
2973 runtime_sched
.runqhead
= gp
->schedlink
;
2976 gp1
= runtime_sched
.runqhead
;
2977 runtime_sched
.runqhead
= gp1
->schedlink
;
2983 // Put p to on pidle list.
2984 // Sched must be locked.
2988 p
->link
= runtime_sched
.pidle
;
2989 runtime_sched
.pidle
= p
;
2990 runtime_xadd(&runtime_sched
.npidle
, 1); // TODO: fast atomic
2993 // Try get a p from pidle list.
2994 // Sched must be locked.
3000 p
= runtime_sched
.pidle
;
3002 runtime_sched
.pidle
= p
->link
;
3003 runtime_xadd(&runtime_sched
.npidle
, -1); // TODO: fast atomic
3008 // Put g on local runnable queue.
3009 // TODO(dvyukov): consider using lock-free queue.
3011 runqput(P
*p
, G
*gp
)
3020 if(t
== h
-1 || (h
== 0 && t
== s
-1)) {
3031 // Get g from local runnable queue.
3038 if(p
->runqhead
== p
->runqtail
)
3056 // Grow local runnable queue.
3057 // TODO(dvyukov): consider using fixed-size array
3058 // and transfer excess to the global list (local queue can grow way too big).
3069 q
= runtime_malloc(2*s
*sizeof(*q
));
3071 q
[t2
++] = p
->runq
[h
++];
3075 runtime_free(p
->runq
);
3082 // Steal half of elements from local runnable queue of p2
3083 // and put onto local runnable queue of p.
3084 // Returns one of the stolen elements (or nil if failed).
3086 runqsteal(P
*p
, P
*p2
)
3089 int32 t
, h
, s
, t2
, h2
, s2
, c
, i
;
3091 if(p2
->runqhead
== p2
->runqtail
)
3093 // sort locks to prevent deadlocks
3097 if(p2
->runqhead
== p2
->runqtail
) {
3105 // now we've locked both queues and know the victim is not empty
3112 gp
= p2
->runq
[h2
++]; // return value
3115 // steal roughly half
3119 c
= (s2
- h2
+ t2
) / 2;
3121 for(i
= 0; i
!= c
; i
++) {
3122 // the target queue is full?
3123 if(t
== h
-1 || (h
== 0 && t
== s
-1))
3125 // the victim queue is empty?
3128 gp1
= p2
->runq
[h2
++];
3142 void runtime_testSchedLocalQueue(void)
3143 __asm__("runtime.testSchedLocalQueue");
3146 runtime_testSchedLocalQueue(void)
3152 runtime_memclr((byte
*)&p
, sizeof(p
));
3156 p
.runq
= runtime_malloc(p
.runqsize
*sizeof(*p
.runq
));
3158 for(i
= 0; i
< (int32
)nelem(gs
); i
++) {
3159 if(runqget(&p
) != nil
)
3160 runtime_throw("runq is not empty initially");
3161 for(j
= 0; j
< i
; j
++)
3162 runqput(&p
, &gs
[i
]);
3163 for(j
= 0; j
< i
; j
++) {
3164 if(runqget(&p
) != &gs
[i
]) {
3165 runtime_printf("bad element at iter %d/%d\n", i
, j
);
3166 runtime_throw("bad element");
3169 if(runqget(&p
) != nil
)
3170 runtime_throw("runq is not empty afterwards");
3174 void runtime_testSchedLocalQueueSteal(void)
3175 __asm__("runtime.testSchedLocalQueueSteal");
3178 runtime_testSchedLocalQueueSteal(void)
3184 runtime_memclr((byte
*)&p1
, sizeof(p1
));
3188 p1
.runq
= runtime_malloc(p1
.runqsize
*sizeof(*p1
.runq
));
3190 runtime_memclr((byte
*)&p2
, sizeof(p2
));
3191 p2
.runqsize
= nelem(gs
);
3194 p2
.runq
= runtime_malloc(p2
.runqsize
*sizeof(*p2
.runq
));
3196 for(i
= 0; i
< (int32
)nelem(gs
); i
++) {
3197 for(j
= 0; j
< i
; j
++) {
3199 runqput(&p1
, &gs
[j
]);
3201 gp
= runqsteal(&p2
, &p1
);
3207 while((gp
= runqget(&p2
)) != nil
) {
3211 while((gp
= runqget(&p1
)) != nil
)
3213 for(j
= 0; j
< i
; j
++) {
3214 if(gs
[j
].sig
!= 1) {
3215 runtime_printf("bad element %d(%d) at iter %d\n", j
, gs
[j
].sig
, i
);
3216 runtime_throw("bad element");
3219 if(s
!= i
/2 && s
!= i
/2+1) {
3220 runtime_printf("bad steal %d, want %d or %d, iter %d\n",
3222 runtime_throw("bad steal");
3227 intgo
runtime_debug_setMaxThreads(intgo
)
3228 __asm__(GOSYM_PREFIX
"runtime_debug.setMaxThreads");
3231 runtime_debug_setMaxThreads(intgo in
)
3235 runtime_lock(&runtime_sched
);
3236 out
= runtime_sched
.maxmcount
;
3237 runtime_sched
.maxmcount
= in
;
3239 runtime_unlock(&runtime_sched
);
3244 runtime_proc_scan(void (*addroot
)(Obj
))
3246 addroot((Obj
){(byte
*)&runtime_sched
, sizeof runtime_sched
, 0});
3249 // When a function calls a closure, it passes the closure value to
3250 // __go_set_closure immediately before the function call. When a
3251 // function uses a closure, it calls __go_get_closure immediately on
3252 // function entry. This is a hack, but it will work on any system.
3253 // It would be better to use the static chain register when there is
3254 // one. It is also worth considering expanding these functions
3255 // directly in the compiler.
3258 __go_set_closure(void* v
)
3264 __go_get_closure(void)
3269 // Return whether we are waiting for a GC. This gc toolchain uses
3270 // preemption instead.
3272 runtime_gcwaiting(void)
3274 return runtime_sched
.gcwaiting
;