/* * Create and initialize a new Thread structure attached to a given proc. */ static int newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp) { int id; Thread *t; if(stacksize < 32) sysfatal("bad stacksize %d", stacksize); t = _threadmalloc(sizeof(Thread), 1); t->stksize = stacksize; t->stk = _threadmalloc(stacksize, 0); memset(t->stk, 0xFE, stacksize); _threadinitstack(t, f, arg); t->grp = grp; if(name) t->cmdname = strdup(name); t->id = nextID(); id = t->id; t->next = (Thread*)~0; t->proc = p; _threaddebug(DBGSCHED, "create thread %d.%d name %s", p->pid, t->id, name); lock(&p->lock); p->nthreads++; if(p->threads.head == nil) p->threads.head = t; else *p->threads.tail = t; p->threads.tail = &t->nextt; t->nextt = nil; t->state = Ready; _threadready(t); unlock(&p->lock); return id; }
void main(int argc, char **argv) { Mainarg *a; Proc *p; rfork(RFREND); mainp = &p; if(setjmp(_mainjmp)) _schedinit(p); //_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0; _systhreadinit(); _qlockinit(_threadrendezvous); _sysfatal = _threadsysfatal; _dial = _threaddial; __assert = _threadassert; notify(_threadnote); if(mainstacksize == 0) mainstacksize = 8*1024; a = _threadmalloc(sizeof *a, 1); a->argc = argc; a->argv = argv; p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0); _schedinit(p); abort(); /* not reached */ }
Channel* chancreate(int elemsize, int elemcnt) { Channel *c; if(elemcnt < 0 || elemsize <= 0) return nil; c = _threadmalloc(sizeof(Channel)+elemsize*elemcnt, 1); c->e = elemsize; c->s = elemcnt; _threaddebug(DBGCHAN, "chancreate %p", c); return c; }
/* * Create and initialize a new Proc structure with a single Thread * running inside it. Add the Proc to the global process list. */ Proc* _newproc(void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp, int rforkflag) { Proc *p; p = _threadmalloc(sizeof *p, 1); p->pid = -1; p->rforkflag = rforkflag; newthread(p, f, arg, stacksize, name, grp); lock(&_threadpq.lock); if(_threadpq.head == nil) _threadpq.head = p; else *_threadpq.tail = p; _threadpq.tail = &p->next; unlock(&_threadpq.lock); return p; }