/* * 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 _schedinit(void *arg) { Proc *p; Thread *t, **l; p = arg; _threadsetproc(p); p->pid = _tos->pid; //getpid(); while(setjmp(p->sched)) ; _threaddebug(DBGSCHED, "top of schedinit, _threadexitsallstatus=%p", _threadexitsallstatus); if(_threadexitsallstatus) exits(_threadexitsallstatus); lock(&p->lock); if((t=p->thread) != nil){ p->thread = nil; if(t->moribund){ t->state = Dead; for(l=&p->threads.head; *l; l=&(*l)->nextt) if(*l == t){ *l = t->nextt; if(*l==nil) p->threads.tail = l; p->nthreads--; break; } unlock(&p->lock); if(t->inrendez){ _threadflagrendez(t); _threadbreakrendez(); } free(t->stk); free(t->cmdname); free(t); /* XXX how do we know there are no references? */ t = nil; _sched(); } if(p->needexec){ t->ret = _schedexec(&p->exec); p->needexec = 0; } if(p->newproc){ t->ret = _schedfork(p->newproc); p->newproc = nil; } t->state = t->nextstate; if(t->state == Ready) _threadready(t); } unlock(&p->lock); _sched(); }