github.com/golang/gofrontend@v0.0.0-20240429183944-60f985a78526/libgo/runtime/proc.c (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include <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  
    22  #ifdef USING_SPLIT_STACK
    23  
    24  /* FIXME: These are not declared anywhere.  */
    25  
    26  extern void __splitstack_getcontext(void *context[10]);
    27  
    28  extern void __splitstack_setcontext(void *context[10]);
    29  
    30  extern void *__splitstack_makecontext(size_t, void *context[10], size_t *);
    31  
    32  extern void * __splitstack_resetcontext(void *context[10], size_t *);
    33  
    34  extern void __splitstack_releasecontext(void *context[10]);
    35  
    36  extern void *__splitstack_find(void *, void *, size_t *, void **, void **,
    37  			       void **);
    38  
    39  extern void __splitstack_block_signals (int *, int *);
    40  
    41  extern void __splitstack_block_signals_context (void *context[10], int *,
    42  						int *);
    43  
    44  #endif
    45  
    46  #ifndef PTHREAD_STACK_MIN
    47  # define PTHREAD_STACK_MIN 8192
    48  #endif
    49  
    50  #if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK)
    51  # define StackMin PTHREAD_STACK_MIN
    52  #else
    53  # define StackMin ((sizeof(char *) < 8) ? 2 * 1024 * 1024 : 4 * 1024 * 1024)
    54  #endif
    55  
    56  uintptr runtime_stacks_sys;
    57  
    58  void gtraceback(G*)
    59    __asm__(GOSYM_PREFIX "runtime.gtraceback");
    60  
    61  static void gscanstack(G*);
    62  
    63  #ifdef __rtems__
    64  #define __thread
    65  #endif
    66  
    67  __thread G *g __asm__(GOSYM_PREFIX "runtime.g");
    68  
    69  #ifndef SETCONTEXT_CLOBBERS_TLS
    70  
    71  static inline void
    72  initcontext(void)
    73  {
    74  }
    75  
    76  static inline void
    77  fixcontext(__go_context_t *c __attribute__ ((unused)))
    78  {
    79  }
    80  
    81  #else
    82  
    83  # if defined(__x86_64__) && defined(__sun__)
    84  
    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.
    91  
    92  static __thread greg_t fs;
    93  
    94  static inline void
    95  initcontext(void)
    96  {
    97  	ucontext_t c;
    98  
    99  	getcontext(&c);
   100  	fs = c.uc_mcontext.gregs[REG_FSBASE];
   101  }
   102  
   103  static inline void
   104  fixcontext(ucontext_t* c)
   105  {
   106  	c->uc_mcontext.gregs[REG_FSBASE] = fs;
   107  }
   108  
   109  # elif defined(__NetBSD__)
   110  
   111  // NetBSD has a bug: setcontext clobbers tlsbase, we need to save
   112  // and restore it ourselves.
   113  
   114  static __thread __greg_t tlsbase;
   115  
   116  static inline void
   117  initcontext(void)
   118  {
   119  	ucontext_t c;
   120  
   121  	getcontext(&c);
   122  	tlsbase = c.uc_mcontext._mc_tlsbase;
   123  }
   124  
   125  static inline void
   126  fixcontext(ucontext_t* c)
   127  {
   128  	c->uc_mcontext._mc_tlsbase = tlsbase;
   129  }
   130  
   131  # elif defined(__sparc__)
   132  
   133  static inline void
   134  initcontext(void)
   135  {
   136  }
   137  
   138  static inline void
   139  fixcontext(ucontext_t *c)
   140  {
   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.  */
   148  
   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]));
   153  }
   154  
   155  # elif defined(_AIX)
   156  
   157  static inline void
   158  initcontext(void)
   159  {
   160  }
   161  
   162  static inline void
   163  fixcontext(ucontext_t* c)
   164  {
   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]));
   168  }
   169  
   170  # else
   171  
   172  #  error unknown case for SETCONTEXT_CLOBBERS_TLS
   173  
   174  # endif
   175  
   176  #endif
   177  
   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)
   186  {
   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");
   193  	}
   194  	p = (p + align - 1) &~ (uintptr_t)(align - 1);
   195  	return (__go_context_t*)p;
   196  }
   197  
   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.
   205  
   206  G* runtime_g(void) __attribute__ ((noinline, no_split_stack));
   207  
   208  G*
   209  runtime_g(void)
   210  {
   211  	return g;
   212  }
   213  
   214  M* runtime_m(void) __attribute__ ((noinline, no_split_stack));
   215  
   216  M*
   217  runtime_m(void)
   218  {
   219  	if(g == nil)
   220  		return nil;
   221  	return g->m;
   222  }
   223  
   224  // Set g.
   225  
   226  void runtime_setg(G*) __attribute__ ((no_split_stack));
   227  
   228  void
   229  runtime_setg(G* gp)
   230  {
   231  	g = gp;
   232  }
   233  
   234  void runtime_newosproc(M *)
   235    __asm__(GOSYM_PREFIX "runtime.newosproc");
   236  
   237  // Start a new thread.
   238  void
   239  runtime_newosproc(M *mp)
   240  {
   241  	pthread_attr_t attr;
   242  	sigset_t clear, old;
   243  	pthread_t tid;
   244  	int tries;
   245  	int ret;
   246  
   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");
   251  
   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);
   255  
   256  #ifdef SIGTRAP
   257  	// Blocking SIGTRAP reportedly breaks gdb on Alpha GNU/Linux.
   258  	sigdelset(&clear, SIGTRAP);
   259  #endif
   260  
   261  	sigemptyset(&old);
   262  	pthread_sigmask(SIG_BLOCK, &clear, &old);
   263  
   264  	for (tries = 0; tries < 20; tries++) {
   265  		ret = pthread_create(&tid, &attr, runtime_mstart, mp);
   266  		if (ret != EAGAIN) {
   267  			break;
   268  		}
   269  		runtime_usleep((tries + 1) * 1000); // Milliseconds.
   270  	}
   271  
   272  	pthread_sigmask(SIG_SETMASK, &old, nil);
   273  
   274  	if (ret != 0) {
   275  		runtime_printf("pthread_create failed: %d\n", ret);
   276  		runtime_throw("pthread_create");
   277  	}
   278  
   279  	if(pthread_attr_destroy(&attr) != 0)
   280  		runtime_throw("pthread_attr_destroy");
   281  }
   282  
   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)
   287  {
   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");
   296  }
   297  
   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)
   305  {
   306  	M *mp;
   307  	G *gp;
   308  #ifndef USING_SPLIT_STACK
   309  	void *afterregs;
   310  #endif
   311  
   312  	// Ensure that all registers are on the stack for the garbage
   313  	// collector.
   314  	__builtin_unwind_init();
   315  	flush_registers_to_secondary_stack();
   316  
   317  	gp = g;
   318  	mp = gp->m;
   319  	if(gp == mp->g0)
   320  		runtime_throw("runtime: mcall called on m->g0 stack");
   321  
   322  	if(gp != nil) {
   323  
   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]));
   334  
   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;
   344  
   345  		if(gp->traceback != 0)
   346  			gtraceback(gp);
   347  		if(gp->scang != 0)
   348  			gscanstack(gp);
   349  	}
   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;
   356  
   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;
   361  
   362  		fixcontext(ucontext_arg(&mp->g0->context[0]));
   363  		__go_setcontext(ucontext_arg(&mp->g0->context[0]));
   364  		runtime_throw("runtime: mcall function returned");
   365  	}
   366  }
   367  
   368  // Goroutine scheduler
   369  // The scheduler's job is to distribute ready-to-run goroutines over worker threads.
   370  //
   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.
   377  //
   378  // Design doc at http://golang.org/s/go11sched.
   379  
   380  extern G* allocg(void)
   381    __asm__ (GOSYM_PREFIX "runtime.allocg");
   382  
   383  bool	runtime_isarchive;
   384  
   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");
   423  
   424  bool runtime_isstarted;
   425  
   426  // Used to determine the field alignment.
   427  
   428  struct field_align
   429  {
   430    char c;
   431    Hchan *p;
   432  };
   433  
   434  void getTraceback(G*, G*) __asm__(GOSYM_PREFIX "runtime.getTraceback");
   435  
   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)
   444  {
   445  	M* holdm;
   446  
   447  	holdm = gp->m;
   448  	gp->m = me->m;
   449  
   450  #ifdef USING_SPLIT_STACK
   451  	__splitstack_getcontext((void*)(&me->stackcontext[0]));
   452  #endif
   453  	__go_getcontext(ucontext_arg(&me->context[0]));
   454  
   455  	if (gp->traceback != 0) {
   456  		runtime_gogo(gp);
   457  	}
   458  
   459  	gp->m = holdm;
   460  }
   461  
   462  // Do a stack trace of gp, and then restore the context to
   463  // gp->traceback->gp.
   464  
   465  void
   466  gtraceback(G* gp)
   467  {
   468  	Traceback* traceback;
   469  
   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);
   475  }
   476  
   477  void doscanstackswitch(G*, G*) __asm__(GOSYM_PREFIX "runtime.doscanstackswitch");
   478  
   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)
   484  {
   485  	M* holdm;
   486  
   487  	__go_assert(me->entry == nil);
   488  	me->fromgogo = false;
   489  
   490  	holdm = gp->m;
   491  	gp->m = me->m;
   492  
   493  #ifdef USING_SPLIT_STACK
   494  	__splitstack_getcontext((void*)(&me->stackcontext[0]));
   495  #endif
   496  	__go_getcontext(ucontext_arg(&me->context[0]));
   497  
   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();
   511  	}
   512  
   513  	if (gp->scang != 0)
   514  		runtime_gogo(gp);
   515  
   516  	gp->m = holdm;
   517  }
   518  
   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)
   523  {
   524  	G *oldg, *oldcurg;
   525  
   526  	oldg = (G*)gp->scang;
   527  	oldcurg = oldg->m->curg;
   528  	oldg->m->curg = gp;
   529  	gp->scang = 0;
   530  
   531  	doscanstack(gp, (void*)gp->scangcw);
   532  
   533  	gp->scangcw = 0;
   534  	oldg->m->curg = oldcurg;
   535  	runtime_gogo(oldg);
   536  }
   537  
   538  // Called by pthread_create to start an M.
   539  void*
   540  runtime_mstart(void *arg)
   541  {
   542  	M* mp;
   543  	G* gp;
   544  
   545  	mp = (M*)(arg);
   546  	gp = mp->g0;
   547  	gp->m = mp;
   548  
   549  	g = gp;
   550  
   551  	gp->entry = nil;
   552  	gp->param = nil;
   553  
   554  	// We have to call minit before we call getcontext,
   555  	// because getcontext will copy the signal mask.
   556  	minit();
   557  
   558  	initcontext();
   559  
   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
   574  
   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]));
   578  
   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);
   584  	}
   585  	if(gp->scang != 0)
   586  		// Got here from doscanswitch. Should not happen.
   587  		runtime_throw("mstart with scang");
   588  
   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();
   598  	}
   599  
   600  	if(mp->exiting) {
   601  		mexit(true);
   602  		return nil;
   603  	}
   604  
   605  	// Initial call to getcontext--starting thread.
   606  
   607  #ifdef USING_SPLIT_STACK
   608  	{
   609  		int dont_block_signals = 0;
   610  		__splitstack_block_signals(&dont_block_signals, nil);
   611  	}
   612  #endif
   613  
   614  	mstart1();
   615  
   616  	// mstart1 does not return, but we need a return statement
   617  	// here to avoid a compiler warning.
   618  	return nil;
   619  }
   620  
   621  typedef struct CgoThreadStart CgoThreadStart;
   622  struct CgoThreadStart
   623  {
   624  	M *m;
   625  	G *g;
   626  	uintptr *tls;
   627  	void (*fn)(void);
   628  };
   629  
   630  void setGContext(void) __asm__ (GOSYM_PREFIX "runtime.setGContext");
   631  
   632  // setGContext sets up a new goroutine context for the current g.
   633  void
   634  setGContext(void)
   635  {
   636  	int val;
   637  	G *gp;
   638  
   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]));
   656  
   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();
   666  	}
   667  }
   668  
   669  void makeGContext(G*, byte*, uintptr)
   670  	__asm__(GOSYM_PREFIX "runtime.makeGContext");
   671  
   672  // makeGContext makes a new context for a g.
   673  void
   674  makeGContext(G* gp, byte* sp, uintptr spsize) {
   675  	__go_context_t *uc;
   676  
   677  	uc = ucontext_arg(&gp->context[0]);
   678  	__go_getcontext(uc);
   679  	__go_makecontext(uc, kickoff, sp, (size_t)spsize);
   680  }
   681  
   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.
   686  //
   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.
   690  
   691  void runtime_entersyscall() __attribute__ ((no_split_stack));
   692  static void doentersyscall(uintptr, uintptr)
   693    __attribute__ ((no_split_stack, noinline));
   694  
   695  void
   696  runtime_entersyscall()
   697  {
   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]));
   702  
   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());
   711  }
   712  
   713  static void
   714  doentersyscall(uintptr pc, uintptr sp)
   715  {
   716  	// Leave SP around for GC and traceback.
   717  #ifdef USING_SPLIT_STACK
   718  	{
   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;
   725  	}
   726  #else
   727  	{
   728  		void *v;
   729  
   730  		g->gcnextsp = (uintptr)(&v);
   731  		g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
   732  	}
   733  #endif
   734  
   735  	reentersyscall(pc, sp);
   736  }
   737  
   738  static void doentersyscallblock(uintptr, uintptr)
   739    __attribute__ ((no_split_stack, noinline));
   740  
   741  // The same as runtime_entersyscall(), but with a hint that the syscall is blocking.
   742  void
   743  runtime_entersyscallblock()
   744  {
   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]));
   749  
   750  	// See comment in runtime_entersyscall.
   751  	doentersyscallblock((uintptr)runtime_getcallerpc(),
   752  			    (uintptr)runtime_getcallersp());
   753  }
   754  
   755  static void
   756  doentersyscallblock(uintptr pc, uintptr sp)
   757  {
   758  	// Leave SP around for GC and traceback.
   759  #ifdef USING_SPLIT_STACK
   760  	{
   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;
   767  	}
   768  #else
   769  	{
   770  		void *v;
   771  
   772  		g->gcnextsp = (uintptr)(&v);
   773  		g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
   774  	}
   775  #endif
   776  
   777  	reentersyscallblock(pc, sp);
   778  }
   779  
   780  // Allocate a new g, with a stack big enough for stacksize bytes.
   781  G*
   782  runtime_malg(bool allocatestack, bool signalstack, byte** ret_stack, uintptr* ret_stacksize)
   783  {
   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
   792  
   793  	if (ret_stack == nil) {
   794  		ret_stack = &unused_stack;
   795  	}
   796  	if (ret_stacksize == nil) {
   797  		ret_stacksize = &unused_stacksize;
   798  	}
   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
   808  		}
   809  
   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);
   832  		}
   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
   838  	}
   839  	return newg;
   840  }
   841  
   842  void stackfree(G*)
   843    __asm__(GOSYM_PREFIX "runtime.stackfree");
   844  
   845  // stackfree frees the stack of a g.
   846  void
   847  stackfree(G* gp)
   848  {
   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);
   859      }
   860      gp->gcinitialsp = nil;
   861      gp->gcstacksize = 0;
   862    }
   863  #endif
   864  }
   865  
   866  void resetNewG(G*, void **, uintptr*)
   867    __asm__(GOSYM_PREFIX "runtime.resetNewG");
   868  
   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)
   873  {
   874  #ifdef USING_SPLIT_STACK
   875    int dont_block_signals = 0;
   876    size_t ss_spsize;
   877  
   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
   890  }