ada: Fix incorrect quoting in documentation
[official-gcc.git] / libgo / runtime / proc.c
blob3a30748d3291fb48fd876da6294fb5ce67724d06
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.
5 #include <errno.h>
6 #include <limits.h>
7 #include <signal.h>
8 #include <stdlib.h>
9 #include <pthread.h>
10 #include <unistd.h>
12 #include "config.h"
14 #ifdef HAVE_DL_ITERATE_PHDR
15 #include <link.h>
16 #endif
18 #include "runtime.h"
19 #include "arch.h"
20 #include "defs.h"
22 #ifdef USING_SPLIT_STACK
24 /* FIXME: These are not declared anywhere. */
26 extern void __splitstack_getcontext(void *context[10]);
28 extern void __splitstack_setcontext(void *context[10]);
30 extern void *__splitstack_makecontext(size_t, void *context[10], size_t *);
32 extern void * __splitstack_resetcontext(void *context[10], size_t *);
34 extern void __splitstack_releasecontext(void *context[10]);
36 extern void *__splitstack_find(void *, void *, size_t *, void **, void **,
37 void **);
39 extern void __splitstack_block_signals (int *, int *);
41 extern void __splitstack_block_signals_context (void *context[10], int *,
42 int *);
44 #endif
46 #ifndef PTHREAD_STACK_MIN
47 # define PTHREAD_STACK_MIN 8192
48 #endif
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
56 uintptr runtime_stacks_sys;
58 void gtraceback(G*)
59 __asm__(GOSYM_PREFIX "runtime.gtraceback");
61 static void gscanstack(G*);
63 #ifdef __rtems__
64 #define __thread
65 #endif
67 __thread G *g __asm__(GOSYM_PREFIX "runtime.g");
69 #ifndef SETCONTEXT_CLOBBERS_TLS
71 static inline void
72 initcontext(void)
76 static inline void
77 fixcontext(__go_context_t *c __attribute__ ((unused)))
81 #else
83 # if defined(__x86_64__) && defined(__sun__)
85 // x86_64 Solaris 10 and 11 have a bug: setcontext switches the %fs
86 // register to that of the thread which called getcontext. The effect
87 // is that the address of all __thread variables changes. This bug
88 // also affects pthread_self() and pthread_getspecific. We work
89 // around it by clobbering the context field directly to keep %fs the
90 // same.
92 static __thread greg_t fs;
94 static inline void
95 initcontext(void)
97 ucontext_t c;
99 getcontext(&c);
100 fs = c.uc_mcontext.gregs[REG_FSBASE];
103 static inline void
104 fixcontext(ucontext_t* c)
106 c->uc_mcontext.gregs[REG_FSBASE] = fs;
109 # elif defined(__NetBSD__)
111 // NetBSD has a bug: setcontext clobbers tlsbase, we need to save
112 // and restore it ourselves.
114 static __thread __greg_t tlsbase;
116 static inline void
117 initcontext(void)
119 ucontext_t c;
121 getcontext(&c);
122 tlsbase = c.uc_mcontext._mc_tlsbase;
125 static inline void
126 fixcontext(ucontext_t* c)
128 c->uc_mcontext._mc_tlsbase = tlsbase;
131 # elif defined(__sparc__)
133 static inline void
134 initcontext(void)
138 static inline void
139 fixcontext(ucontext_t *c)
141 /* ??? Using
142 register unsigned long thread __asm__("%g7");
143 c->uc_mcontext.gregs[REG_G7] = thread;
144 results in
145 error: variable ‘thread’ might be clobbered by \
146 ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
147 which ought to be false, as %g7 is a fixed register. */
149 if (sizeof (c->uc_mcontext.gregs[REG_G7]) == 8)
150 asm ("stx %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7]));
151 else
152 asm ("st %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7]));
155 # elif defined(_AIX)
157 static inline void
158 initcontext(void)
162 static inline void
163 fixcontext(ucontext_t* c)
165 // Thread pointer is in r13, per 64-bit ABI.
166 if (sizeof (c->uc_mcontext.jmp_context.gpr[13]) == 8)
167 asm ("std 13, %0" : "=m"(c->uc_mcontext.jmp_context.gpr[13]));
170 # else
172 # error unknown case for SETCONTEXT_CLOBBERS_TLS
174 # endif
176 #endif
178 // ucontext_arg returns a properly aligned ucontext_t value. On some
179 // systems a ucontext_t value must be aligned to a 16-byte boundary.
180 // The g structure that has fields of type ucontext_t is defined in
181 // Go, and Go has no simple way to align a field to such a boundary.
182 // So we make the field larger in runtime2.go and pick an appropriate
183 // offset within the field here.
184 static __go_context_t*
185 ucontext_arg(uintptr_t* go_ucontext)
187 uintptr_t p = (uintptr_t)go_ucontext;
188 size_t align = __alignof__(__go_context_t);
189 if(align > 16) {
190 // We only ensured space for up to a 16 byte alignment
191 // in libgo/go/runtime/runtime2.go.
192 runtime_throw("required alignment of __go_context_t too large");
194 p = (p + align - 1) &~ (uintptr_t)(align - 1);
195 return (__go_context_t*)p;
198 // We can not always refer to the TLS variables directly. The
199 // compiler will call tls_get_addr to get the address of the variable,
200 // and it may hold it in a register across a call to schedule. When
201 // we get back from the call we may be running in a different thread,
202 // in which case the register now points to the TLS variable for a
203 // different thread. We use non-inlinable functions to avoid this
204 // when necessary.
206 G* runtime_g(void) __attribute__ ((noinline, no_split_stack));
209 runtime_g(void)
211 return g;
214 M* runtime_m(void) __attribute__ ((noinline, no_split_stack));
217 runtime_m(void)
219 if(g == nil)
220 return nil;
221 return g->m;
224 // Set g.
226 void runtime_setg(G*) __attribute__ ((no_split_stack));
228 void
229 runtime_setg(G* gp)
231 g = gp;
234 void runtime_newosproc(M *)
235 __asm__(GOSYM_PREFIX "runtime.newosproc");
237 // Start a new thread.
238 void
239 runtime_newosproc(M *mp)
241 pthread_attr_t attr;
242 sigset_t clear, old;
243 pthread_t tid;
244 int tries;
245 int ret;
247 if(pthread_attr_init(&attr) != 0)
248 runtime_throw("pthread_attr_init");
249 if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
250 runtime_throw("pthread_attr_setdetachstate");
252 // Block signals during pthread_create so that the new thread
253 // starts with signals disabled. It will enable them in minit.
254 sigfillset(&clear);
256 #ifdef SIGTRAP
257 // Blocking SIGTRAP reportedly breaks gdb on Alpha GNU/Linux.
258 sigdelset(&clear, SIGTRAP);
259 #endif
261 sigemptyset(&old);
262 pthread_sigmask(SIG_BLOCK, &clear, &old);
264 for (tries = 0; tries < 20; tries++) {
265 ret = pthread_create(&tid, &attr, runtime_mstart, mp);
266 if (ret != EAGAIN) {
267 break;
269 runtime_usleep((tries + 1) * 1000); // Milliseconds.
272 pthread_sigmask(SIG_SETMASK, &old, nil);
274 if (ret != 0) {
275 runtime_printf("pthread_create failed: %d\n", ret);
276 runtime_throw("pthread_create");
279 if(pthread_attr_destroy(&attr) != 0)
280 runtime_throw("pthread_attr_destroy");
283 // Switch context to a different goroutine. This is like longjmp.
284 void runtime_gogo(G*) __attribute__ ((noinline));
285 void
286 runtime_gogo(G* newg)
288 #ifdef USING_SPLIT_STACK
289 __splitstack_setcontext((void*)(&newg->stackcontext[0]));
290 #endif
291 g = newg;
292 newg->fromgogo = true;
293 fixcontext(ucontext_arg(&newg->context[0]));
294 __go_setcontext(ucontext_arg(&newg->context[0]));
295 runtime_throw("gogo setcontext returned");
298 // Save context and call fn passing g as a parameter. This is like
299 // setjmp. Because getcontext always returns 0, unlike setjmp, we use
300 // g->fromgogo as a code. It will be true if we got here via
301 // setcontext. g == nil the first time this is called in a new m.
302 void runtime_mcall(FuncVal *) __attribute__ ((noinline));
303 void
304 runtime_mcall(FuncVal *fv)
306 M *mp;
307 G *gp;
308 #ifndef USING_SPLIT_STACK
309 void *afterregs;
310 #endif
312 // Ensure that all registers are on the stack for the garbage
313 // collector.
314 __builtin_unwind_init();
315 flush_registers_to_secondary_stack();
317 gp = g;
318 mp = gp->m;
319 if(gp == mp->g0)
320 runtime_throw("runtime: mcall called on m->g0 stack");
322 if(gp != nil) {
324 #ifdef USING_SPLIT_STACK
325 __splitstack_getcontext((void*)(&gp->stackcontext[0]));
326 #else
327 // We have to point to an address on the stack that is
328 // below the saved registers.
329 gp->gcnextsp = (uintptr)(&afterregs);
330 gp->gcnextsp2 = (uintptr)(secondary_stack_pointer());
331 #endif
332 gp->fromgogo = false;
333 __go_getcontext(ucontext_arg(&gp->context[0]));
335 // When we return from getcontext, we may be running
336 // in a new thread. That means that g may have
337 // changed. It is a global variables so we will
338 // reload it, but the address of g may be cached in
339 // our local stack frame, and that address may be
340 // wrong. Call the function to reload the value for
341 // this thread.
342 gp = runtime_g();
343 mp = gp->m;
345 if(gp->traceback != 0)
346 gtraceback(gp);
347 if(gp->scang != 0)
348 gscanstack(gp);
350 if (gp == nil || !gp->fromgogo) {
351 #ifdef USING_SPLIT_STACK
352 __splitstack_setcontext((void*)(&mp->g0->stackcontext[0]));
353 #endif
354 mp->g0->entry = fv;
355 mp->g0->param = gp;
357 // It's OK to set g directly here because this case
358 // can not occur if we got here via a setcontext to
359 // the getcontext call just above.
360 g = mp->g0;
362 fixcontext(ucontext_arg(&mp->g0->context[0]));
363 __go_setcontext(ucontext_arg(&mp->g0->context[0]));
364 runtime_throw("runtime: mcall function returned");
368 // Goroutine scheduler
369 // The scheduler's job is to distribute ready-to-run goroutines over worker threads.
371 // The main concepts are:
372 // G - goroutine.
373 // M - worker thread, or machine.
374 // P - processor, a resource that is required to execute Go code.
375 // M must have an associated P to execute Go code, however it can be
376 // blocked or in a syscall w/o an associated P.
378 // Design doc at http://golang.org/s/go11sched.
380 extern G* allocg(void)
381 __asm__ (GOSYM_PREFIX "runtime.allocg");
383 bool runtime_isarchive;
385 extern void kickoff(void)
386 __asm__(GOSYM_PREFIX "runtime.kickoff");
387 extern void minit(void)
388 __asm__(GOSYM_PREFIX "runtime.minit");
389 extern void mstart1()
390 __asm__(GOSYM_PREFIX "runtime.mstart1");
391 extern void stopm(void)
392 __asm__(GOSYM_PREFIX "runtime.stopm");
393 extern void mexit(bool)
394 __asm__(GOSYM_PREFIX "runtime.mexit");
395 extern void handoffp(P*)
396 __asm__(GOSYM_PREFIX "runtime.handoffp");
397 extern void wakep(void)
398 __asm__(GOSYM_PREFIX "runtime.wakep");
399 extern void stoplockedm(void)
400 __asm__(GOSYM_PREFIX "runtime.stoplockedm");
401 extern void schedule(void)
402 __asm__(GOSYM_PREFIX "runtime.schedule");
403 extern void execute(G*, bool)
404 __asm__(GOSYM_PREFIX "runtime.execute");
405 extern void reentersyscall(uintptr, uintptr)
406 __asm__(GOSYM_PREFIX "runtime.reentersyscall");
407 extern void reentersyscallblock(uintptr, uintptr)
408 __asm__(GOSYM_PREFIX "runtime.reentersyscallblock");
409 extern G* gfget(P*)
410 __asm__(GOSYM_PREFIX "runtime.gfget");
411 extern void acquirep(P*)
412 __asm__(GOSYM_PREFIX "runtime.acquirep");
413 extern P* releasep(void)
414 __asm__(GOSYM_PREFIX "runtime.releasep");
415 extern void incidlelocked(int32)
416 __asm__(GOSYM_PREFIX "runtime.incidlelocked");
417 extern void globrunqput(G*)
418 __asm__(GOSYM_PREFIX "runtime.globrunqput");
419 extern P* pidleget(void)
420 __asm__(GOSYM_PREFIX "runtime.pidleget");
421 extern struct mstats* getMemstats(void)
422 __asm__(GOSYM_PREFIX "runtime.getMemstats");
424 bool runtime_isstarted;
426 // Used to determine the field alignment.
428 struct field_align
430 char c;
431 Hchan *p;
434 void getTraceback(G*, G*) __asm__(GOSYM_PREFIX "runtime.getTraceback");
436 // getTraceback stores a traceback of gp in the g's traceback field
437 // and then returns to me. We expect that gp's traceback is not nil.
438 // It works by saving me's current context, and checking gp's traceback field.
439 // If gp's traceback field is not nil, it starts running gp.
440 // In places where we call getcontext, we check the traceback field.
441 // If it is not nil, we collect a traceback, and then return to the
442 // goroutine stored in the traceback field, which is me.
443 void getTraceback(G* me, G* gp)
445 M* holdm;
447 holdm = gp->m;
448 gp->m = me->m;
450 #ifdef USING_SPLIT_STACK
451 __splitstack_getcontext((void*)(&me->stackcontext[0]));
452 #endif
453 __go_getcontext(ucontext_arg(&me->context[0]));
455 if (gp->traceback != 0) {
456 runtime_gogo(gp);
459 gp->m = holdm;
462 // Do a stack trace of gp, and then restore the context to
463 // gp->traceback->gp.
465 void
466 gtraceback(G* gp)
468 Traceback* traceback;
470 traceback = (Traceback*)gp->traceback;
471 gp->traceback = 0;
472 traceback->c = runtime_callers(1, traceback->locbuf,
473 sizeof traceback->locbuf / sizeof traceback->locbuf[0], false);
474 runtime_gogo(traceback->gp);
477 void doscanstackswitch(G*, G*) __asm__(GOSYM_PREFIX "runtime.doscanstackswitch");
479 // Switch to gp and let it scan its stack.
480 // The first time gp->scang is set (to me). The second time here
481 // gp is done scanning, and has unset gp->scang, so we just return.
482 void
483 doscanstackswitch(G* me, G* gp)
485 M* holdm;
487 __go_assert(me->entry == nil);
488 me->fromgogo = false;
490 holdm = gp->m;
491 gp->m = me->m;
493 #ifdef USING_SPLIT_STACK
494 __splitstack_getcontext((void*)(&me->stackcontext[0]));
495 #endif
496 __go_getcontext(ucontext_arg(&me->context[0]));
498 if(me->entry != nil) {
499 // Got here from mcall.
500 // The stack scanning code may call systemstack, which calls
501 // mcall, which calls setcontext.
502 // Run the function, which at the end will switch back to gp.
503 FuncVal *fv = me->entry;
504 void (*pfn)(G*) = (void (*)(G*))fv->fn;
505 G* gp1 = (G*)me->param;
506 __go_assert(gp1 == gp);
507 me->entry = nil;
508 me->param = nil;
509 __builtin_call_with_static_chain(pfn(gp1), fv);
510 abort();
513 if (gp->scang != 0)
514 runtime_gogo(gp);
516 gp->m = holdm;
519 // Do a stack scan, then switch back to the g that triggers this scan.
520 // We come here from doscanstackswitch.
521 static void
522 gscanstack(G *gp)
524 G *oldg, *oldcurg;
526 oldg = (G*)gp->scang;
527 oldcurg = oldg->m->curg;
528 oldg->m->curg = gp;
529 gp->scang = 0;
531 doscanstack(gp, (void*)gp->scangcw);
533 gp->scangcw = 0;
534 oldg->m->curg = oldcurg;
535 runtime_gogo(oldg);
538 // Called by pthread_create to start an M.
539 void*
540 runtime_mstart(void *arg)
542 M* mp;
543 G* gp;
545 mp = (M*)(arg);
546 gp = mp->g0;
547 gp->m = mp;
549 g = gp;
551 gp->entry = nil;
552 gp->param = nil;
554 // We have to call minit before we call getcontext,
555 // because getcontext will copy the signal mask.
556 minit();
558 initcontext();
560 // Record top of stack for use by mcall.
561 // Once we call schedule we're never coming back,
562 // so other calls can reuse this stack space.
563 #ifdef USING_SPLIT_STACK
564 __splitstack_getcontext((void*)(&gp->stackcontext[0]));
565 #else
566 gp->gcinitialsp = &arg;
567 // Setting gcstacksize to 0 is a marker meaning that gcinitialsp
568 // is the top of the stack, not the bottom.
569 gp->gcstacksize = 0;
570 gp->gcnextsp = (uintptr)(&arg);
571 gp->gcinitialsp2 = secondary_stack_pointer();
572 gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
573 #endif
575 // Save the currently active context. This will return
576 // multiple times via the setcontext call in mcall.
577 __go_getcontext(ucontext_arg(&gp->context[0]));
579 if(gp->traceback != 0) {
580 // Got here from getTraceback.
581 // I'm not sure this ever actually happens--getTraceback
582 // may always go to the getcontext call in mcall.
583 gtraceback(gp);
585 if(gp->scang != 0)
586 // Got here from doscanswitch. Should not happen.
587 runtime_throw("mstart with scang");
589 if(gp->entry != nil) {
590 // Got here from mcall.
591 FuncVal *fv = gp->entry;
592 void (*pfn)(G*) = (void (*)(G*))fv->fn;
593 G* gp1 = (G*)gp->param;
594 gp->entry = nil;
595 gp->param = nil;
596 __builtin_call_with_static_chain(pfn(gp1), fv);
597 abort();
600 if(mp->exiting) {
601 mexit(true);
602 return nil;
605 // Initial call to getcontext--starting thread.
607 #ifdef USING_SPLIT_STACK
609 int dont_block_signals = 0;
610 __splitstack_block_signals(&dont_block_signals, nil);
612 #endif
614 mstart1();
616 // mstart1 does not return, but we need a return statement
617 // here to avoid a compiler warning.
618 return nil;
621 typedef struct CgoThreadStart CgoThreadStart;
622 struct CgoThreadStart
624 M *m;
625 G *g;
626 uintptr *tls;
627 void (*fn)(void);
630 void setGContext(void) __asm__ (GOSYM_PREFIX "runtime.setGContext");
632 // setGContext sets up a new goroutine context for the current g.
633 void
634 setGContext(void)
636 int val;
637 G *gp;
639 initcontext();
640 gp = g;
641 gp->entry = nil;
642 gp->param = nil;
643 #ifdef USING_SPLIT_STACK
644 __splitstack_getcontext((void*)(&gp->stackcontext[0]));
645 val = 0;
646 __splitstack_block_signals(&val, nil);
647 #else
648 gp->gcinitialsp = &val;
649 gp->gcstack = 0;
650 gp->gcstacksize = 0;
651 gp->gcnextsp = (uintptr)(&val);
652 gp->gcinitialsp2 = secondary_stack_pointer();
653 gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
654 #endif
655 __go_getcontext(ucontext_arg(&gp->context[0]));
657 if(gp->entry != nil) {
658 // Got here from mcall.
659 FuncVal *fv = gp->entry;
660 void (*pfn)(G*) = (void (*)(G*))fv->fn;
661 G* gp1 = (G*)gp->param;
662 gp->entry = nil;
663 gp->param = nil;
664 __builtin_call_with_static_chain(pfn(gp1), fv);
665 abort();
669 void makeGContext(G*, byte*, uintptr)
670 __asm__(GOSYM_PREFIX "runtime.makeGContext");
672 // makeGContext makes a new context for a g.
673 void
674 makeGContext(G* gp, byte* sp, uintptr spsize) {
675 __go_context_t *uc;
677 uc = ucontext_arg(&gp->context[0]);
678 __go_getcontext(uc);
679 __go_makecontext(uc, kickoff, sp, (size_t)spsize);
682 // The goroutine g is about to enter a system call.
683 // Record that it's not using the cpu anymore.
684 // This is called only from the go syscall library and cgocall,
685 // not from the low-level system calls used by the runtime.
687 // Entersyscall cannot split the stack: the runtime_gosave must
688 // make g->sched refer to the caller's stack segment, because
689 // entersyscall is going to return immediately after.
691 void runtime_entersyscall() __attribute__ ((no_split_stack));
692 static void doentersyscall(uintptr, uintptr)
693 __attribute__ ((no_split_stack, noinline));
695 void
696 runtime_entersyscall()
698 // Save the registers in the g structure so that any pointers
699 // held in registers will be seen by the garbage collector.
700 if (!runtime_usestackmaps)
701 __go_getcontext(ucontext_arg(&g->gcregs[0]));
703 // Note that if this function does save any registers itself,
704 // we might store the wrong value in the call to getcontext.
705 // FIXME: This assumes that we do not need to save any
706 // callee-saved registers to access the TLS variable g. We
707 // don't want to put the ucontext_t on the stack because it is
708 // large and we can not split the stack here.
709 doentersyscall((uintptr)runtime_getcallerpc(),
710 (uintptr)runtime_getcallersp());
713 static void
714 doentersyscall(uintptr pc, uintptr sp)
716 // Leave SP around for GC and traceback.
717 #ifdef USING_SPLIT_STACK
719 size_t gcstacksize;
720 g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
721 (void**)(&g->gcnextsegment),
722 (void**)(&g->gcnextsp),
723 &g->gcinitialsp));
724 g->gcstacksize = (uintptr)gcstacksize;
726 #else
728 void *v;
730 g->gcnextsp = (uintptr)(&v);
731 g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
733 #endif
735 reentersyscall(pc, sp);
738 static void doentersyscallblock(uintptr, uintptr)
739 __attribute__ ((no_split_stack, noinline));
741 // The same as runtime_entersyscall(), but with a hint that the syscall is blocking.
742 void
743 runtime_entersyscallblock()
745 // Save the registers in the g structure so that any pointers
746 // held in registers will be seen by the garbage collector.
747 if (!runtime_usestackmaps)
748 __go_getcontext(ucontext_arg(&g->gcregs[0]));
750 // See comment in runtime_entersyscall.
751 doentersyscallblock((uintptr)runtime_getcallerpc(),
752 (uintptr)runtime_getcallersp());
755 static void
756 doentersyscallblock(uintptr pc, uintptr sp)
758 // Leave SP around for GC and traceback.
759 #ifdef USING_SPLIT_STACK
761 size_t gcstacksize;
762 g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
763 (void**)(&g->gcnextsegment),
764 (void**)(&g->gcnextsp),
765 &g->gcinitialsp));
766 g->gcstacksize = (uintptr)gcstacksize;
768 #else
770 void *v;
772 g->gcnextsp = (uintptr)(&v);
773 g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
775 #endif
777 reentersyscallblock(pc, sp);
780 // Allocate a new g, with a stack big enough for stacksize bytes.
782 runtime_malg(bool allocatestack, bool signalstack, byte** ret_stack, uintptr* ret_stacksize)
784 uintptr stacksize;
785 G *newg;
786 byte* unused_stack;
787 uintptr unused_stacksize;
788 #ifdef USING_SPLIT_STACK
789 int dont_block_signals = 0;
790 size_t ss_stacksize;
791 #endif
793 if (ret_stack == nil) {
794 ret_stack = &unused_stack;
796 if (ret_stacksize == nil) {
797 ret_stacksize = &unused_stacksize;
799 newg = allocg();
800 if(allocatestack) {
801 stacksize = StackMin;
802 if(signalstack) {
803 stacksize = 32 * 1024; // OS X wants >= 8K, GNU/Linux >= 2K
804 #ifdef SIGSTKSZ
805 if(stacksize < (uintptr)(SIGSTKSZ))
806 stacksize = (uintptr)(SIGSTKSZ);
807 #endif
810 #ifdef USING_SPLIT_STACK
811 *ret_stack = __splitstack_makecontext(stacksize,
812 (void*)(&newg->stackcontext[0]),
813 &ss_stacksize);
814 *ret_stacksize = (uintptr)ss_stacksize;
815 __splitstack_block_signals_context((void*)(&newg->stackcontext[0]),
816 &dont_block_signals, nil);
817 #else
818 // In 64-bit mode, the maximum Go allocation space is
819 // 128G. Our stack size is 4M, which only permits 32K
820 // goroutines. In order to not limit ourselves,
821 // allocate the stacks out of separate memory. In
822 // 32-bit mode, the Go allocation space is all of
823 // memory anyhow.
824 if(sizeof(void*) == 8) {
825 void *p = runtime_sysAlloc(stacksize, &getMemstats()->stacks_sys);
826 if(p == nil)
827 runtime_throw("runtime: cannot allocate memory for goroutine stack");
828 *ret_stack = (byte*)p;
829 } else {
830 *ret_stack = runtime_mallocgc(stacksize, nil, false);
831 runtime_xadd(&runtime_stacks_sys, stacksize);
833 *ret_stacksize = (uintptr)stacksize;
834 newg->gcinitialsp = *ret_stack;
835 newg->gcstacksize = (uintptr)stacksize;
836 newg->gcinitialsp2 = initial_secondary_stack_pointer(*ret_stack);
837 #endif
839 return newg;
842 void stackfree(G*)
843 __asm__(GOSYM_PREFIX "runtime.stackfree");
845 // stackfree frees the stack of a g.
846 void
847 stackfree(G* gp)
849 #ifdef USING_SPLIT_STACK
850 __splitstack_releasecontext((void*)(&gp->stackcontext[0]));
851 #else
852 // If gcstacksize is 0, the stack is allocated by libc and will be
853 // released when the thread exits. Otherwise, in 64-bit mode it was
854 // allocated using sysAlloc and in 32-bit mode it was allocated
855 // using garbage collected memory.
856 if (gp->gcstacksize != 0) {
857 if (sizeof(void*) == 8) {
858 runtime_sysFree(gp->gcinitialsp, gp->gcstacksize, &getMemstats()->stacks_sys);
860 gp->gcinitialsp = nil;
861 gp->gcstacksize = 0;
863 #endif
866 void resetNewG(G*, void **, uintptr*)
867 __asm__(GOSYM_PREFIX "runtime.resetNewG");
869 // Reset stack information for g pulled out of the cache to start a
870 // new goroutine.
871 void
872 resetNewG(G *newg, void **sp, uintptr *spsize)
874 #ifdef USING_SPLIT_STACK
875 int dont_block_signals = 0;
876 size_t ss_spsize;
878 *sp = __splitstack_resetcontext((void*)(&newg->stackcontext[0]), &ss_spsize);
879 *spsize = ss_spsize;
880 __splitstack_block_signals_context((void*)(&newg->stackcontext[0]),
881 &dont_block_signals, nil);
882 #else
883 *sp = newg->gcinitialsp;
884 *spsize = newg->gcstacksize;
885 if(*spsize == 0)
886 runtime_throw("bad spsize in resetNewG");
887 newg->gcnextsp = (uintptr)(*sp);
888 newg->gcnextsp2 = (uintptr)(newg->gcinitialsp2);
889 #endif