// Create a new m. It will start off with a call to runtime_mstart. M* runtime_newm(void) { M *m; pthread_attr_t attr; pthread_t tid; size_t stacksize; m = runtime_malloc(sizeof(M)); mcommoninit(m); m->g0 = runtime_malg(-1, nil, nil); if(pthread_attr_init(&attr) != 0) runtime_throw("pthread_attr_init"); if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) runtime_throw("pthread_attr_setdetachstate"); stacksize = PTHREAD_STACK_MIN; // With glibc before version 2.16 the static TLS size is taken // out of the stack size, and we get an error or a crash if // there is not enough stack space left. Add it back in if we // can, in case the program uses a lot of TLS space. FIXME: // This can be disabled in glibc 2.16 and later, if the bug is // indeed fixed then. stacksize += tlssize; if(pthread_attr_setstacksize(&attr, stacksize) != 0) runtime_throw("pthread_attr_setstacksize"); if(pthread_create(&tid, &attr, runtime_mstart, m) != 0) runtime_throw("pthread_create"); return m; }
// Allocate a new g, with a stack big enough for stacksize bytes. G* runtime_malg(int32 stacksize, byte** ret_stack, size_t* ret_stacksize) { G *newg; newg = runtime_malloc(sizeof(G)); if(stacksize >= 0) { #if USING_SPLIT_STACK int dont_block_signals = 0; *ret_stack = __splitstack_makecontext(stacksize, &newg->stack_context[0], ret_stacksize); __splitstack_block_signals_context(&newg->stack_context[0], &dont_block_signals, nil); #else *ret_stack = runtime_mallocgc(stacksize, FlagNoProfiling|FlagNoGC, 0, 0); *ret_stacksize = stacksize; newg->gcinitial_sp = *ret_stack; newg->gcstack_size = stacksize; runtime_xadd(&runtime_stacks_sys, stacksize); #endif } return newg; }
static M* startm(void) { M *m; pthread_attr_t attr; pthread_t tid; m = runtime_malloc(sizeof(M)); mcommoninit(m); m->g0 = runtime_malg(-1, nil, nil); if(pthread_attr_init(&attr) != 0) runtime_throw("pthread_attr_init"); if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) runtime_throw("pthread_attr_setdetachstate"); #ifndef PTHREAD_STACK_MIN #define PTHREAD_STACK_MIN 8192 #endif if(pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN) != 0) runtime_throw("pthread_attr_setstacksize"); if(pthread_create(&tid, &attr, runtime_mstart, m) != 0) runtime_throw("pthread_create"); return m; }
static int callback (void *data, uintptr_t pc __attribute__ ((unused)), const char *filename, int lineno, const char *function) { struct caller *c = (struct caller *) data; if (function == NULL) { c->fn.str = NULL; c->fn.len = 0; } else { byte *s; c->fn.len = __builtin_strlen (function); s = runtime_malloc (c->fn.len); __builtin_memcpy (s, function, c->fn.len); c->fn.str = s; } if (filename == NULL) { c->file.str = NULL; c->file.len = 0; } else { byte *s; c->file.len = __builtin_strlen (filename); s = runtime_malloc (c->file.len); __builtin_memcpy (s, filename, c->file.len); c->file.str = s; } c->line = lineno; return 0; }
void runtime_goenvs_unix(void) { String *s; int32 i, n; for(n=0; argv[argc+1+n] != 0; n++) ; s = runtime_malloc(n*sizeof s[0]); for(i=0; i<n; i++) s[i] = runtime_gostringnocopy(argv[argc+1+i]); syscall_Envs.__values = (void*)s; syscall_Envs.__count = n; syscall_Envs.__capacity = n; }
// Allocate a Defer, usually using per-P pool. // Each defer must be released with freedefer. Defer* runtime_newdefer() { Defer *d; P *p; d = nil; p = runtime_m()->p; d = p->deferpool; if(d) p->deferpool = d->__next; if(d == nil) { // deferpool is empty d = runtime_malloc(sizeof(Defer)); } return d; }
struct __go_open_array __go_string_to_byte_array (String str) { uintptr cap; unsigned char *data; struct __go_open_array ret; cap = runtime_roundupsize (str.len); data = (unsigned char *) runtime_malloc (cap); __builtin_memcpy (data, str.str, str.len); if (cap != (uintptr) str.len) __builtin_memset (data + str.len, 0, cap - (uintptr) str.len); ret.__values = (void *) data; ret.__count = str.len; ret.__capacity = (intgo) cap; return ret; }
void runtime_goargs(void) { String *s; int32 i; // for windows implementation see "os" package if(Windows) return; s = runtime_malloc(argc*sizeof s[0]); for(i=0; i<argc; i++) s[i] = runtime_gostringnocopy((const byte*)argv[i]); os_Args.__values = (void*)s; os_Args.__count = argc; os_Args.__capacity = argc; }
G* runtime_malg(int32 stacksize, byte** ret_stack, size_t* ret_stacksize) { G *newg; newg = runtime_malloc(sizeof(G)); if(stacksize >= 0) { #if USING_SPLIT_STACK *ret_stack = __splitstack_makecontext(stacksize, &newg->stack_context[0], ret_stacksize); #else *ret_stack = runtime_mallocgc(stacksize, FlagNoProfiling|FlagNoGC, 0, 0); *ret_stacksize = stacksize; newg->gcinitial_sp = *ret_stack; newg->gcstack_size = stacksize; #endif } return newg; }