1 76193d7c 2003-09-30 devnull #include "threadimpl.h"
3 76193d7c 2003-09-30 devnull Pqueue _threadpq;
5 76193d7c 2003-09-30 devnull static int nextID(void);
8 76193d7c 2003-09-30 devnull * Create and initialize a new Thread structure attached to a given proc.
11 76193d7c 2003-09-30 devnull _stackfree(void *v)
16 76193d7c 2003-09-30 devnull static int
17 76193d7c 2003-09-30 devnull newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp)
20 76193d7c 2003-09-30 devnull Thread *t;
23 76193d7c 2003-09-30 devnull if(stacksize < 32)
24 76193d7c 2003-09-30 devnull sysfatal("bad stacksize %d", stacksize);
25 76193d7c 2003-09-30 devnull t = _threadmalloc(sizeof(Thread), 1);
26 cd7ddc9b 2003-11-23 devnull s = _threadmalloc(stacksize, 0);
27 76193d7c 2003-09-30 devnull t->stk = (char*)s;
28 cd7ddc9b 2003-11-23 devnull t->stksize = stacksize;
29 cd7ddc9b 2003-11-23 devnull _threaddebugmemset(s, 0xFE, stacksize);
30 76193d7c 2003-09-30 devnull _threadinitstack(t, f, arg);
31 76193d7c 2003-09-30 devnull t->proc = p;
32 76193d7c 2003-09-30 devnull t->grp = grp;
34 76193d7c 2003-09-30 devnull t->cmdname = strdup(name);
35 76193d7c 2003-09-30 devnull t->id = nextID();
36 76193d7c 2003-09-30 devnull id = t->id;
37 76193d7c 2003-09-30 devnull t->next = (Thread*)~0;
38 76193d7c 2003-09-30 devnull _threaddebug(DBGSCHED, "create thread %d.%d name %s", p->pid, t->id, name);
39 76193d7c 2003-09-30 devnull lock(&p->lock);
40 76193d7c 2003-09-30 devnull p->nthreads++;
41 76193d7c 2003-09-30 devnull if(p->threads.head == nil)
42 76193d7c 2003-09-30 devnull p->threads.head = t;
44 76193d7c 2003-09-30 devnull t->prevt = p->threads.tail;
45 76193d7c 2003-09-30 devnull t->prevt->nextt = t;
47 76193d7c 2003-09-30 devnull p->threads.tail = t;
48 76193d7c 2003-09-30 devnull t->state = Ready;
49 76193d7c 2003-09-30 devnull _threadready(t);
50 76193d7c 2003-09-30 devnull unlock(&p->lock);
51 76193d7c 2003-09-30 devnull return id;
54 76193d7c 2003-09-30 devnull static int
55 76193d7c 2003-09-30 devnull nextID(void)
57 76193d7c 2003-09-30 devnull static Lock l;
58 76193d7c 2003-09-30 devnull static int id;
61 76193d7c 2003-09-30 devnull lock(&l);
62 76193d7c 2003-09-30 devnull i = ++id;
63 76193d7c 2003-09-30 devnull unlock(&l);
64 76193d7c 2003-09-30 devnull return i;
68 76193d7c 2003-09-30 devnull procrfork(void (*f)(void *), void *arg, uint stacksize, int rforkflag)
73 76193d7c 2003-09-30 devnull p = _threadgetproc();
74 76193d7c 2003-09-30 devnull assert(p->newproc == nil);
75 76193d7c 2003-09-30 devnull p->newproc = _newproc(f, arg, stacksize, nil, p->thread->grp, rforkflag);
76 76193d7c 2003-09-30 devnull id = p->newproc->threads.head->id;
77 76193d7c 2003-09-30 devnull _sched();
78 76193d7c 2003-09-30 devnull return id;
82 76193d7c 2003-09-30 devnull proccreate(void (*f)(void*), void *arg, uint stacksize)
84 76193d7c 2003-09-30 devnull return procrfork(f, arg, stacksize, 0);
88 76193d7c 2003-09-30 devnull _freeproc(Proc *p)
90 76193d7c 2003-09-30 devnull Thread *t, *nextt;
92 76193d7c 2003-09-30 devnull for(t = p->threads.head; t; t = nextt){
93 76193d7c 2003-09-30 devnull if(t->cmdname)
94 76193d7c 2003-09-30 devnull free(t->cmdname);
95 76193d7c 2003-09-30 devnull assert(t->stk != nil);
96 cd7ddc9b 2003-11-23 devnull _stackfree(t->stk);
97 76193d7c 2003-09-30 devnull nextt = t->nextt;
100 76193d7c 2003-09-30 devnull free(p);
104 76193d7c 2003-09-30 devnull * Create a new thread and schedule it to run.
105 76193d7c 2003-09-30 devnull * The thread grp is inherited from the currently running thread.
108 76193d7c 2003-09-30 devnull threadcreate(void (*f)(void *arg), void *arg, uint stacksize)
110 76193d7c 2003-09-30 devnull return newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
114 76193d7c 2003-09-30 devnull * Create and initialize a new Proc structure with a single Thread
115 76193d7c 2003-09-30 devnull * running inside it. Add the Proc to the global process list.
118 76193d7c 2003-09-30 devnull _newproc(void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp, int rforkflag)
120 76193d7c 2003-09-30 devnull Proc *p;
122 76193d7c 2003-09-30 devnull p = _threadmalloc(sizeof *p, 1);
123 76193d7c 2003-09-30 devnull p->pid = -1;
124 76193d7c 2003-09-30 devnull p->rforkflag = rforkflag;
125 76193d7c 2003-09-30 devnull newthread(p, f, arg, stacksize, name, grp);
127 76193d7c 2003-09-30 devnull lock(&_threadpq.lock);
128 76193d7c 2003-09-30 devnull if(_threadpq.head == nil)
129 76193d7c 2003-09-30 devnull _threadpq.head = p;
131 76193d7c 2003-09-30 devnull *_threadpq.tail = p;
132 76193d7c 2003-09-30 devnull _threadpq.tail = &p->next;
133 76193d7c 2003-09-30 devnull unlock(&_threadpq.lock);
134 76193d7c 2003-09-30 devnull return p;