// Called to start an M. void* runtime_mstart(void* mp) { m = (M*)mp; g = m->g0; initcontext(); g->entry = nil; g->param = nil; // Record top of stack for use by mcall. // Once we call schedule we're never coming back, // so other calls can reuse this stack space. #ifdef USING_SPLIT_STACK __splitstack_getcontext(&g->stack_context[0]); #else g->gcinitial_sp = ∓ // Setting gcstack_size to 0 is a marker meaning that gcinitial_sp // is the top of the stack, not the bottom. g->gcstack_size = 0; g->gcnext_sp = ∓ #endif getcontext(&g->context); if(g->entry != nil) { // Got here from mcall. void (*pfn)(G*) = (void (*)(G*))g->entry; G* gp = (G*)g->param; pfn(gp); *(int*)0x21 = 0x21; } runtime_minit(); #ifdef USING_SPLIT_STACK { int dont_block_signals = 0; __splitstack_block_signals(&dont_block_signals, nil); } #endif // Install signal handlers; after minit so that minit can // prepare the thread to be able to handle the signals. if(m == &runtime_m0) runtime_initsig(); schedule(nil); return nil; }
// The bootstrap sequence is: // // call osinit // call schedinit // make & queue new G // call runtime_mstart // // The new G calls runtime_main. void runtime_schedinit(void) { int32 n; const byte *p; m = &runtime_m0; g = &runtime_g0; m->g0 = g; m->curg = g; g->m = m; initcontext(); inittlssize(); m->nomemprof++; runtime_mallocinit(); mcommoninit(m); runtime_goargs(); runtime_goenvs(); // For debugging: // Allocate internal symbol table representation now, // so that we don't need to call malloc when we crash. // runtime_findfunc(0); runtime_gomaxprocs = 1; p = runtime_getenv("GOMAXPROCS"); if(p != nil && (n = runtime_atoi(p)) != 0) { if(n > maxgomaxprocs) n = maxgomaxprocs; runtime_gomaxprocs = n; } // wait for the main goroutine to start before taking // GOMAXPROCS into account. setmcpumax(1); runtime_singleproc = runtime_gomaxprocs == 1; canaddmcpu(); // mcpu++ to account for bootstrap m m->helpgc = 1; // flag to tell schedule() to mcpu-- runtime_sched.grunning++; // Can not enable GC until all roots are registered. // mstats.enablegc = 1; m->nomemprof--; }
void ILThread::run() { mThreadContext = new evalcontext( false, mId ); initcontext( mThreadContext, false ); do { if ( renderSync ) disped = renderSync->dispcount; mThreadContext->cycles->threadfun( threadcom, mParcnt, mPars ); if ( renderSync ) { std::unique_lock<std::mutex> lk(renderSync->dispmut); renderSync->dispsync.wait(lk,[&]{return renderSync->dispcount > disped;}); } } while ( looping && !getstopped() ); done = true; while( !getstopped() ); }
int main (int argc, char **argv) { LISP expr, val; char *progname, *prog = 0; progname = *argv++; for (--argc; argc>0 && **argv=='-'; --argc, ++argv) { char *p; for (p=1+*argv; *p; ++p) switch (*p) { case 'h': fprintf (stderr, "Usage: %s [-h] [-v] [-t] [-m#] prog [arg...]\n", progname); return (0); case 't': ++trace; break; case 'v': ++verbose; break; case 'm': if (! *++p) { if (argc <= 1) break; p = *++argv; --argc; } memsz = atoi (p); p += strlen (p) - 1; break; } } if (argc > 0) { prog = *argv++; --argc; } if (memsz < 1000) memsz = (sizeof (unsigned) < 4 ? 64000 : 256000) / sizeof (cell); if (verbose) { fprintf (stderr, "Micro Scheme Interpreter, Release 1.0\n"); fprintf (stderr, "Memory size = %d bytes\n", memsz * sizeof (cell)); } mem = (cell *) malloc (sizeof (cell) * memsz); gclabel = malloc (memsz); if (!mem || !gclabel) { fprintf (stderr, "Out of memory\n"); return (-1); } if (prog && freopen (prog, "r", stdin) != stdin) { fprintf (stderr, "Cannot open %s\n", prog); return (-1); } initmem (); T = alloc (TBOOL); /* логическая истина #t */ ZERO = number (0); /* целый ноль */ ENV = cons (cons (symbol ("version"), number (10)), NIL); initcontext (stdfunc); for (;;) { gc (); if (isatty (0)) printf ("> "); expr = getexpr (); if (feof (stdin)) break; val = eval (expr, 0); if (verbose) { putexpr (expr, stdout); printf (" --> "); putexpr (val, stdout); putchar ('\n'); } } return (0); }