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 <errno.h>
6 #include <limits.h>
7 #include <signal.h>
8 #include <stdlib.h>
9 #include <pthread.h>
10 #include <unistd.h>
11 
12 #include "config.h"
13 
14 #ifdef HAVE_DL_ITERATE_PHDR
15 #include <link.h>
16 #endif
17 
18 #include "runtime.h"
19 #include "arch.h"
20 #include "defs.h"
21 #include "go-type.h"
22 
23 #ifdef USING_SPLIT_STACK
24 
25 /* FIXME: These are not declared anywhere.  */
26 
27 extern void __splitstack_getcontext(void *context[10]);
28 
29 extern void __splitstack_setcontext(void *context[10]);
30 
31 extern void *__splitstack_makecontext(size_t, void *context[10], size_t *);
32 
33 extern void * __splitstack_resetcontext(void *context[10], size_t *);
34 
35 extern void __splitstack_releasecontext(void *context[10]);
36 
37 extern void *__splitstack_find(void *, void *, size_t *, void **, void **,
38 			       void **);
39 
40 extern void __splitstack_block_signals (int *, int *);
41 
42 extern void __splitstack_block_signals_context (void *context[10], int *,
43 						int *);
44 
45 #endif
46 
47 #ifndef PTHREAD_STACK_MIN
48 # define PTHREAD_STACK_MIN 8192
49 #endif
50 
51 #if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK)
52 # define StackMin PTHREAD_STACK_MIN
53 #else
54 # define StackMin ((sizeof(char *) < 8) ? 2 * 1024 * 1024 : 4 * 1024 * 1024)
55 #endif
56 
57 uintptr runtime_stacks_sys;
58 
59 void gtraceback(G*)
60   __asm__(GOSYM_PREFIX "runtime.gtraceback");
61 
62 #ifdef __rtems__
63 #define __thread
64 #endif
65 
66 static __thread G *g;
67 
68 #ifndef SETCONTEXT_CLOBBERS_TLS
69 
70 static inline void
initcontext(void)71 initcontext(void)
72 {
73 }
74 
75 static inline void
fixcontext(ucontext_t * c)76 fixcontext(ucontext_t *c __attribute__ ((unused)))
77 {
78 }
79 
80 #else
81 
82 # if defined(__x86_64__) && defined(__sun__)
83 
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
89 // same.
90 
91 static __thread greg_t fs;
92 
93 static inline void
initcontext(void)94 initcontext(void)
95 {
96 	ucontext_t c;
97 
98 	getcontext(&c);
99 	fs = c.uc_mcontext.gregs[REG_FSBASE];
100 }
101 
102 static inline void
fixcontext(ucontext_t * c)103 fixcontext(ucontext_t* c)
104 {
105 	c->uc_mcontext.gregs[REG_FSBASE] = fs;
106 }
107 
108 # elif defined(__NetBSD__)
109 
110 // NetBSD has a bug: setcontext clobbers tlsbase, we need to save
111 // and restore it ourselves.
112 
113 static __thread __greg_t tlsbase;
114 
115 static inline void
initcontext(void)116 initcontext(void)
117 {
118 	ucontext_t c;
119 
120 	getcontext(&c);
121 	tlsbase = c.uc_mcontext._mc_tlsbase;
122 }
123 
124 static inline void
fixcontext(ucontext_t * c)125 fixcontext(ucontext_t* c)
126 {
127 	c->uc_mcontext._mc_tlsbase = tlsbase;
128 }
129 
130 # elif defined(__sparc__)
131 
132 static inline void
initcontext(void)133 initcontext(void)
134 {
135 }
136 
137 static inline void
fixcontext(ucontext_t * c)138 fixcontext(ucontext_t *c)
139 {
140 	/* ??? Using
141 	     register unsigned long thread __asm__("%g7");
142 	     c->uc_mcontext.gregs[REG_G7] = thread;
143 	   results in
144 	     error: variable ‘thread’ might be clobbered by \
145 		‘longjmp’ or ‘vfork’ [-Werror=clobbered]
146 	   which ought to be false, as %g7 is a fixed register.  */
147 
148 	if (sizeof (c->uc_mcontext.gregs[REG_G7]) == 8)
149 		asm ("stx %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7]));
150 	else
151 		asm ("st %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7]));
152 }
153 
154 # elif defined(_AIX)
155 
156 static inline void
initcontext(void)157 initcontext(void)
158 {
159 }
160 
161 static inline void
fixcontext(ucontext_t * c)162 fixcontext(ucontext_t* c)
163 {
164 	// Thread pointer is in r13, per 64-bit ABI.
165 	if (sizeof (c->uc_mcontext.jmp_context.gpr[13]) == 8)
166 		asm ("std 13, %0" : "=m"(c->uc_mcontext.jmp_context.gpr[13]));
167 }
168 
169 # else
170 
171 #  error unknown case for SETCONTEXT_CLOBBERS_TLS
172 
173 # endif
174 
175 #endif
176 
177 // ucontext_arg returns a properly aligned ucontext_t value.  On some
178 // systems a ucontext_t value must be aligned to a 16-byte boundary.
179 // The g structure that has fields of type ucontext_t is defined in
180 // Go, and Go has no simple way to align a field to such a boundary.
181 // So we make the field larger in runtime2.go and pick an appropriate
182 // offset within the field here.
183 static ucontext_t*
ucontext_arg(uintptr_t * go_ucontext)184 ucontext_arg(uintptr_t* go_ucontext)
185 {
186 	uintptr_t p = (uintptr_t)go_ucontext;
187 	size_t align = __alignof__(ucontext_t);
188 	if(align > 16) {
189 		// We only ensured space for up to a 16 byte alignment
190 		// in libgo/go/runtime/runtime2.go.
191 		runtime_throw("required alignment of ucontext_t too large");
192 	}
193 	p = (p + align - 1) &~ (uintptr_t)(align - 1);
194 	return (ucontext_t*)p;
195 }
196 
197 // We can not always refer to the TLS variables directly.  The
198 // compiler will call tls_get_addr to get the address of the variable,
199 // and it may hold it in a register across a call to schedule.  When
200 // we get back from the call we may be running in a different thread,
201 // in which case the register now points to the TLS variable for a
202 // different thread.  We use non-inlinable functions to avoid this
203 // when necessary.
204 
205 G* runtime_g(void) __attribute__ ((noinline, no_split_stack));
206 
207 G*
runtime_g(void)208 runtime_g(void)
209 {
210 	return g;
211 }
212 
213 M* runtime_m(void) __attribute__ ((noinline, no_split_stack));
214 
215 M*
runtime_m(void)216 runtime_m(void)
217 {
218 	if(g == nil)
219 		return nil;
220 	return g->m;
221 }
222 
223 // Set g.
224 void
runtime_setg(G * gp)225 runtime_setg(G* gp)
226 {
227 	g = gp;
228 }
229 
230 void runtime_newosproc(M *)
231   __asm__(GOSYM_PREFIX "runtime.newosproc");
232 
233 // Start a new thread.
234 void
runtime_newosproc(M * mp)235 runtime_newosproc(M *mp)
236 {
237 	pthread_attr_t attr;
238 	sigset_t clear, old;
239 	pthread_t tid;
240 	int tries;
241 	int ret;
242 
243 	if(pthread_attr_init(&attr) != 0)
244 		runtime_throw("pthread_attr_init");
245 	if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
246 		runtime_throw("pthread_attr_setdetachstate");
247 
248 	// Block signals during pthread_create so that the new thread
249 	// starts with signals disabled.  It will enable them in minit.
250 	sigfillset(&clear);
251 
252 #ifdef SIGTRAP
253 	// Blocking SIGTRAP reportedly breaks gdb on Alpha GNU/Linux.
254 	sigdelset(&clear, SIGTRAP);
255 #endif
256 
257 	sigemptyset(&old);
258 	pthread_sigmask(SIG_BLOCK, &clear, &old);
259 
260 	for (tries = 0; tries < 20; tries++) {
261 		ret = pthread_create(&tid, &attr, runtime_mstart, mp);
262 		if (ret != EAGAIN) {
263 			break;
264 		}
265 		runtime_usleep((tries + 1) * 1000); // Milliseconds.
266 	}
267 
268 	pthread_sigmask(SIG_SETMASK, &old, nil);
269 
270 	if (ret != 0) {
271 		runtime_printf("pthread_create failed: %d\n", ret);
272 		runtime_throw("pthread_create");
273 	}
274 
275 	if(pthread_attr_destroy(&attr) != 0)
276 		runtime_throw("pthread_attr_destroy");
277 }
278 
279 // Switch context to a different goroutine.  This is like longjmp.
280 void runtime_gogo(G*) __attribute__ ((noinline));
281 void
runtime_gogo(G * newg)282 runtime_gogo(G* newg)
283 {
284 #ifdef USING_SPLIT_STACK
285 	__splitstack_setcontext((void*)(&newg->stackcontext[0]));
286 #endif
287 	g = newg;
288 	newg->fromgogo = true;
289 	fixcontext(ucontext_arg(&newg->context[0]));
290 	setcontext(ucontext_arg(&newg->context[0]));
291 	runtime_throw("gogo setcontext returned");
292 }
293 
294 // Save context and call fn passing g as a parameter.  This is like
295 // setjmp.  Because getcontext always returns 0, unlike setjmp, we use
296 // g->fromgogo as a code.  It will be true if we got here via
297 // setcontext.  g == nil the first time this is called in a new m.
298 void runtime_mcall(FuncVal *) __attribute__ ((noinline));
299 void
runtime_mcall(FuncVal * fv)300 runtime_mcall(FuncVal *fv)
301 {
302 	M *mp;
303 	G *gp;
304 #ifndef USING_SPLIT_STACK
305 	void *afterregs;
306 #endif
307 
308 	// Ensure that all registers are on the stack for the garbage
309 	// collector.
310 	__builtin_unwind_init();
311 	flush_registers_to_secondary_stack();
312 
313 	gp = g;
314 	mp = gp->m;
315 	if(gp == mp->g0)
316 		runtime_throw("runtime: mcall called on m->g0 stack");
317 
318 	if(gp != nil) {
319 
320 #ifdef USING_SPLIT_STACK
321 		__splitstack_getcontext((void*)(&g->stackcontext[0]));
322 #else
323 		// We have to point to an address on the stack that is
324 		// below the saved registers.
325 		gp->gcnextsp = (uintptr)(&afterregs);
326 		gp->gcnextsp2 = (uintptr)(secondary_stack_pointer());
327 #endif
328 		gp->fromgogo = false;
329 		getcontext(ucontext_arg(&gp->context[0]));
330 
331 		// When we return from getcontext, we may be running
332 		// in a new thread.  That means that g may have
333 		// changed.  It is a global variables so we will
334 		// reload it, but the address of g may be cached in
335 		// our local stack frame, and that address may be
336 		// wrong.  Call the function to reload the value for
337 		// this thread.
338 		gp = runtime_g();
339 		mp = gp->m;
340 
341 		if(gp->traceback != nil)
342 			gtraceback(gp);
343 	}
344 	if (gp == nil || !gp->fromgogo) {
345 #ifdef USING_SPLIT_STACK
346 		__splitstack_setcontext((void*)(&mp->g0->stackcontext[0]));
347 #endif
348 		mp->g0->entry = fv;
349 		mp->g0->param = gp;
350 
351 		// It's OK to set g directly here because this case
352 		// can not occur if we got here via a setcontext to
353 		// the getcontext call just above.
354 		g = mp->g0;
355 
356 		fixcontext(ucontext_arg(&mp->g0->context[0]));
357 		setcontext(ucontext_arg(&mp->g0->context[0]));
358 		runtime_throw("runtime: mcall function returned");
359 	}
360 }
361 
362 // Goroutine scheduler
363 // The scheduler's job is to distribute ready-to-run goroutines over worker threads.
364 //
365 // The main concepts are:
366 // G - goroutine.
367 // M - worker thread, or machine.
368 // P - processor, a resource that is required to execute Go code.
369 //     M must have an associated P to execute Go code, however it can be
370 //     blocked or in a syscall w/o an associated P.
371 //
372 // Design doc at http://golang.org/s/go11sched.
373 
374 extern G* allocg(void)
375   __asm__ (GOSYM_PREFIX "runtime.allocg");
376 
377 Sched*	runtime_sched;
378 
379 bool	runtime_isarchive;
380 
381 extern void kickoff(void)
382   __asm__(GOSYM_PREFIX "runtime.kickoff");
383 extern void minit(void)
384   __asm__(GOSYM_PREFIX "runtime.minit");
385 extern void mstart1(int32)
386   __asm__(GOSYM_PREFIX "runtime.mstart1");
387 extern void stopm(void)
388   __asm__(GOSYM_PREFIX "runtime.stopm");
389 extern void mexit(bool)
390   __asm__(GOSYM_PREFIX "runtime.mexit");
391 extern void handoffp(P*)
392   __asm__(GOSYM_PREFIX "runtime.handoffp");
393 extern void wakep(void)
394   __asm__(GOSYM_PREFIX "runtime.wakep");
395 extern void stoplockedm(void)
396   __asm__(GOSYM_PREFIX "runtime.stoplockedm");
397 extern void schedule(void)
398   __asm__(GOSYM_PREFIX "runtime.schedule");
399 extern void execute(G*, bool)
400   __asm__(GOSYM_PREFIX "runtime.execute");
401 extern void reentersyscall(uintptr, uintptr)
402   __asm__(GOSYM_PREFIX "runtime.reentersyscall");
403 extern void reentersyscallblock(uintptr, uintptr)
404   __asm__(GOSYM_PREFIX "runtime.reentersyscallblock");
405 extern G* gfget(P*)
406   __asm__(GOSYM_PREFIX "runtime.gfget");
407 extern void acquirep(P*)
408   __asm__(GOSYM_PREFIX "runtime.acquirep");
409 extern P* releasep(void)
410   __asm__(GOSYM_PREFIX "runtime.releasep");
411 extern void incidlelocked(int32)
412   __asm__(GOSYM_PREFIX "runtime.incidlelocked");
413 extern void globrunqput(G*)
414   __asm__(GOSYM_PREFIX "runtime.globrunqput");
415 extern P* pidleget(void)
416   __asm__(GOSYM_PREFIX "runtime.pidleget");
417 extern struct mstats* getMemstats(void)
418   __asm__(GOSYM_PREFIX "runtime.getMemstats");
419 
420 bool runtime_isstarted;
421 
422 // Used to determine the field alignment.
423 
424 struct field_align
425 {
426   char c;
427   Hchan *p;
428 };
429 
430 void getTraceback(G*, G*) __asm__(GOSYM_PREFIX "runtime.getTraceback");
431 
432 // getTraceback stores a traceback of gp in the g's traceback field
433 // and then returns to me.  We expect that gp's traceback is not nil.
434 // It works by saving me's current context, and checking gp's traceback field.
435 // If gp's traceback field is not nil, it starts running gp.
436 // In places where we call getcontext, we check the traceback field.
437 // If it is not nil, we collect a traceback, and then return to the
438 // goroutine stored in the traceback field, which is me.
getTraceback(G * me,G * gp)439 void getTraceback(G* me, G* gp)
440 {
441 #ifdef USING_SPLIT_STACK
442 	__splitstack_getcontext((void*)(&me->stackcontext[0]));
443 #endif
444 	getcontext(ucontext_arg(&me->context[0]));
445 
446 	if (gp->traceback != nil) {
447 		runtime_gogo(gp);
448 	}
449 }
450 
451 // Do a stack trace of gp, and then restore the context to
452 // gp->traceback->gp.
453 
454 void
gtraceback(G * gp)455 gtraceback(G* gp)
456 {
457 	Traceback* traceback;
458 	M* holdm;
459 
460 	traceback = gp->traceback;
461 	gp->traceback = nil;
462 	holdm = gp->m;
463 	if(holdm != nil && holdm != g->m)
464 		runtime_throw("gtraceback: m is not nil");
465 	gp->m = traceback->gp->m;
466 	traceback->c = runtime_callers(1, traceback->locbuf,
467 		sizeof traceback->locbuf / sizeof traceback->locbuf[0], false);
468 	gp->m = holdm;
469 	runtime_gogo(traceback->gp);
470 }
471 
472 // Called by pthread_create to start an M.
473 void*
runtime_mstart(void * arg)474 runtime_mstart(void *arg)
475 {
476 	M* mp;
477 	G* gp;
478 
479 	mp = (M*)(arg);
480 	gp = mp->g0;
481 	gp->m = mp;
482 
483 	g = gp;
484 
485 	gp->entry = nil;
486 	gp->param = nil;
487 
488 	// We have to call minit before we call getcontext,
489 	// because getcontext will copy the signal mask.
490 	minit();
491 
492 	initcontext();
493 
494 	// Record top of stack for use by mcall.
495 	// Once we call schedule we're never coming back,
496 	// so other calls can reuse this stack space.
497 #ifdef USING_SPLIT_STACK
498 	__splitstack_getcontext((void*)(&gp->stackcontext[0]));
499 #else
500 	gp->gcinitialsp = &arg;
501 	// Setting gcstacksize to 0 is a marker meaning that gcinitialsp
502 	// is the top of the stack, not the bottom.
503 	gp->gcstacksize = 0;
504 	gp->gcnextsp = (uintptr)(&arg);
505 	gp->gcinitialsp2 = secondary_stack_pointer();
506 	gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
507 #endif
508 
509 	// Save the currently active context.  This will return
510 	// multiple times via the setcontext call in mcall.
511 	getcontext(ucontext_arg(&gp->context[0]));
512 
513 	if(gp->traceback != nil) {
514 		// Got here from getTraceback.
515 		// I'm not sure this ever actually happens--getTraceback
516 		// may always go to the getcontext call in mcall.
517 		gtraceback(gp);
518 	}
519 
520 	if(gp->entry != nil) {
521 		// Got here from mcall.
522 		FuncVal *fv = gp->entry;
523 		void (*pfn)(G*) = (void (*)(G*))fv->fn;
524 		G* gp1 = (G*)gp->param;
525 		gp->entry = nil;
526 		gp->param = nil;
527 		__builtin_call_with_static_chain(pfn(gp1), fv);
528 		*(int*)0x21 = 0x21;
529 	}
530 
531 	if(mp->exiting) {
532 		mexit(true);
533 		return nil;
534 	}
535 
536 	// Initial call to getcontext--starting thread.
537 
538 #ifdef USING_SPLIT_STACK
539 	{
540 		int dont_block_signals = 0;
541 		__splitstack_block_signals(&dont_block_signals, nil);
542 	}
543 #endif
544 
545 	mstart1(0);
546 
547 	// mstart1 does not return, but we need a return statement
548 	// here to avoid a compiler warning.
549 	return nil;
550 }
551 
552 typedef struct CgoThreadStart CgoThreadStart;
553 struct CgoThreadStart
554 {
555 	M *m;
556 	G *g;
557 	uintptr *tls;
558 	void (*fn)(void);
559 };
560 
561 void setGContext(void) __asm__ (GOSYM_PREFIX "runtime.setGContext");
562 
563 // setGContext sets up a new goroutine context for the current g.
564 void
setGContext(void)565 setGContext(void)
566 {
567 	int val;
568 	G *gp;
569 
570 	initcontext();
571 	gp = g;
572 	gp->entry = nil;
573 	gp->param = nil;
574 #ifdef USING_SPLIT_STACK
575 	__splitstack_getcontext((void*)(&gp->stackcontext[0]));
576 	val = 0;
577 	__splitstack_block_signals(&val, nil);
578 #else
579 	gp->gcinitialsp = &val;
580 	gp->gcstack = 0;
581 	gp->gcstacksize = 0;
582 	gp->gcnextsp = (uintptr)(&val);
583 	gp->gcinitialsp2 = secondary_stack_pointer();
584 	gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
585 #endif
586 	getcontext(ucontext_arg(&gp->context[0]));
587 
588 	if(gp->entry != nil) {
589 		// Got here from mcall.
590 		FuncVal *fv = gp->entry;
591 		void (*pfn)(G*) = (void (*)(G*))fv->fn;
592 		G* gp1 = (G*)gp->param;
593 		gp->entry = nil;
594 		gp->param = nil;
595 		__builtin_call_with_static_chain(pfn(gp1), fv);
596 		*(int*)0x22 = 0x22;
597 	}
598 }
599 
600 void makeGContext(G*, byte*, uintptr)
601 	__asm__(GOSYM_PREFIX "runtime.makeGContext");
602 
603 // makeGContext makes a new context for a g.
604 void
makeGContext(G * gp,byte * sp,uintptr spsize)605 makeGContext(G* gp, byte* sp, uintptr spsize) {
606 	ucontext_t *uc;
607 
608 	uc = ucontext_arg(&gp->context[0]);
609 	getcontext(uc);
610 	uc->uc_stack.ss_sp = sp;
611 	uc->uc_stack.ss_size = (size_t)spsize;
612 	makecontext(uc, kickoff, 0);
613 }
614 
615 // The goroutine g is about to enter a system call.
616 // Record that it's not using the cpu anymore.
617 // This is called only from the go syscall library and cgocall,
618 // not from the low-level system calls used by the runtime.
619 //
620 // Entersyscall cannot split the stack: the runtime_gosave must
621 // make g->sched refer to the caller's stack segment, because
622 // entersyscall is going to return immediately after.
623 
624 void runtime_entersyscall(int32) __attribute__ ((no_split_stack));
625 static void doentersyscall(uintptr, uintptr)
626   __attribute__ ((no_split_stack, noinline));
627 
628 void
runtime_entersyscall(int32 dummy)629 runtime_entersyscall(int32 dummy __attribute__ ((unused)))
630 {
631 	// Save the registers in the g structure so that any pointers
632 	// held in registers will be seen by the garbage collector.
633 	getcontext(ucontext_arg(&g->gcregs[0]));
634 
635 	// Note that if this function does save any registers itself,
636 	// we might store the wrong value in the call to getcontext.
637 	// FIXME: This assumes that we do not need to save any
638 	// callee-saved registers to access the TLS variable g.  We
639 	// don't want to put the ucontext_t on the stack because it is
640 	// large and we can not split the stack here.
641 	doentersyscall((uintptr)runtime_getcallerpc(&dummy),
642 		       (uintptr)runtime_getcallersp(&dummy));
643 }
644 
645 static void
doentersyscall(uintptr pc,uintptr sp)646 doentersyscall(uintptr pc, uintptr sp)
647 {
648 	// Leave SP around for GC and traceback.
649 #ifdef USING_SPLIT_STACK
650 	{
651 	  size_t gcstacksize;
652 	  g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
653 						   (void**)(&g->gcnextsegment),
654 						   (void**)(&g->gcnextsp),
655 						   &g->gcinitialsp));
656 	  g->gcstacksize = (uintptr)gcstacksize;
657 	}
658 #else
659 	{
660 		void *v;
661 
662 		g->gcnextsp = (uintptr)(&v);
663 		g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
664 	}
665 #endif
666 
667 	reentersyscall(pc, sp);
668 }
669 
670 static void doentersyscallblock(uintptr, uintptr)
671   __attribute__ ((no_split_stack, noinline));
672 
673 // The same as runtime_entersyscall(), but with a hint that the syscall is blocking.
674 void
runtime_entersyscallblock(int32 dummy)675 runtime_entersyscallblock(int32 dummy __attribute__ ((unused)))
676 {
677 	// Save the registers in the g structure so that any pointers
678 	// held in registers will be seen by the garbage collector.
679 	getcontext(ucontext_arg(&g->gcregs[0]));
680 
681 	// See comment in runtime_entersyscall.
682 	doentersyscallblock((uintptr)runtime_getcallerpc(&dummy),
683 			    (uintptr)runtime_getcallersp(&dummy));
684 }
685 
686 static void
doentersyscallblock(uintptr pc,uintptr sp)687 doentersyscallblock(uintptr pc, uintptr sp)
688 {
689 	// Leave SP around for GC and traceback.
690 #ifdef USING_SPLIT_STACK
691 	{
692 	  size_t gcstacksize;
693 	  g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
694 						   (void**)(&g->gcnextsegment),
695 						   (void**)(&g->gcnextsp),
696 						   &g->gcinitialsp));
697 	  g->gcstacksize = (uintptr)gcstacksize;
698 	}
699 #else
700 	{
701 		void *v;
702 
703 		g->gcnextsp = (uintptr)(&v);
704 		g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
705 	}
706 #endif
707 
708 	reentersyscallblock(pc, sp);
709 }
710 
711 // Allocate a new g, with a stack big enough for stacksize bytes.
712 G*
runtime_malg(bool allocatestack,bool signalstack,byte ** ret_stack,uintptr * ret_stacksize)713 runtime_malg(bool allocatestack, bool signalstack, byte** ret_stack, uintptr* ret_stacksize)
714 {
715 	uintptr stacksize;
716 	G *newg;
717 	byte* unused_stack;
718 	uintptr unused_stacksize;
719 #if USING_SPLIT_STACK
720 	int dont_block_signals = 0;
721 	size_t ss_stacksize;
722 #endif
723 
724 	if (ret_stack == nil) {
725 		ret_stack = &unused_stack;
726 	}
727 	if (ret_stacksize == nil) {
728 		ret_stacksize = &unused_stacksize;
729 	}
730 	newg = allocg();
731 	if(allocatestack) {
732 		stacksize = StackMin;
733 		if(signalstack) {
734 			stacksize = 32 * 1024; // OS X wants >= 8K, GNU/Linux >= 2K
735 #ifdef SIGSTKSZ
736 			if(stacksize < SIGSTKSZ)
737 				stacksize = SIGSTKSZ;
738 #endif
739 		}
740 
741 #if USING_SPLIT_STACK
742 		*ret_stack = __splitstack_makecontext(stacksize,
743 						      (void*)(&newg->stackcontext[0]),
744 						      &ss_stacksize);
745 		*ret_stacksize = (uintptr)ss_stacksize;
746 		__splitstack_block_signals_context((void*)(&newg->stackcontext[0]),
747 						   &dont_block_signals, nil);
748 #else
749                 // In 64-bit mode, the maximum Go allocation space is
750                 // 128G.  Our stack size is 4M, which only permits 32K
751                 // goroutines.  In order to not limit ourselves,
752                 // allocate the stacks out of separate memory.  In
753                 // 32-bit mode, the Go allocation space is all of
754                 // memory anyhow.
755 		if(sizeof(void*) == 8) {
756 			void *p = runtime_sysAlloc(stacksize, &getMemstats()->stacks_sys);
757 			if(p == nil)
758 				runtime_throw("runtime: cannot allocate memory for goroutine stack");
759 			*ret_stack = (byte*)p;
760 		} else {
761 			*ret_stack = runtime_mallocgc(stacksize, nil, false);
762 			runtime_xadd(&runtime_stacks_sys, stacksize);
763 		}
764 		*ret_stacksize = (uintptr)stacksize;
765 		newg->gcinitialsp = *ret_stack;
766 		newg->gcstacksize = (uintptr)stacksize;
767 		newg->gcinitialsp2 = initial_secondary_stack_pointer(*ret_stack);
768 #endif
769 	}
770 	return newg;
771 }
772 
773 void stackfree(G*)
774   __asm__(GOSYM_PREFIX "runtime.stackfree");
775 
776 // stackfree frees the stack of a g.
777 void
stackfree(G * gp)778 stackfree(G* gp)
779 {
780 #if USING_SPLIT_STACK
781   __splitstack_releasecontext((void*)(&gp->stackcontext[0]));
782 #else
783   // If gcstacksize is 0, the stack is allocated by libc and will be
784   // released when the thread exits. Otherwise, in 64-bit mode it was
785   // allocated using sysAlloc and in 32-bit mode it was allocated
786   // using garbage collected memory.
787   if (gp->gcstacksize != 0) {
788     if (sizeof(void*) == 8) {
789       runtime_sysFree(gp->gcinitialsp, gp->gcstacksize, &getMemstats()->stacks_sys);
790     }
791     gp->gcinitialsp = nil;
792     gp->gcstacksize = 0;
793   }
794 #endif
795 }
796 
797 void resetNewG(G*, void **, uintptr*)
798   __asm__(GOSYM_PREFIX "runtime.resetNewG");
799 
800 // Reset stack information for g pulled out of the cache to start a
801 // new goroutine.
802 void
resetNewG(G * newg,void ** sp,uintptr * spsize)803 resetNewG(G *newg, void **sp, uintptr *spsize)
804 {
805 #ifdef USING_SPLIT_STACK
806   int dont_block_signals = 0;
807   size_t ss_spsize;
808 
809   *sp = __splitstack_resetcontext((void*)(&newg->stackcontext[0]), &ss_spsize);
810   *spsize = ss_spsize;
811   __splitstack_block_signals_context((void*)(&newg->stackcontext[0]),
812 				     &dont_block_signals, nil);
813 #else
814   *sp = newg->gcinitialsp;
815   *spsize = newg->gcstacksize;
816   if(*spsize == 0)
817     runtime_throw("bad spsize in resetNewG");
818   newg->gcnextsp = (uintptr)(*sp);
819   newg->gcnextsp2 = (uintptr)(newg->gcinitialsp2);
820 #endif
821 }
822 
823 // Return whether we are waiting for a GC.  This gc toolchain uses
824 // preemption instead.
825 bool
runtime_gcwaiting(void)826 runtime_gcwaiting(void)
827 {
828 	return runtime_sched->gcwaiting;
829 }
830