1 76193d7c 2003-09-30 devnull #include "threadimpl.h"
3 7966faa9 2004-09-23 devnull Pqueue _threadpq; /* list of all procs */
4 7966faa9 2004-09-23 devnull int _threadnprocs; /* count of procs */
6 7966faa9 2004-09-23 devnull static int newthreadid(void);
7 7966faa9 2004-09-23 devnull static int newprocid(void);
10 76193d7c 2003-09-30 devnull * Create and initialize a new Thread structure attached to a given proc.
13 7966faa9 2004-09-23 devnull _newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize,
14 7966faa9 2004-09-23 devnull char *name, int grp)
17 76193d7c 2003-09-30 devnull Thread *t;
19 76193d7c 2003-09-30 devnull t = _threadmalloc(sizeof(Thread), 1);
20 76193d7c 2003-09-30 devnull t->proc = p;
21 5093c3fa 2004-10-22 devnull t->nextproc = p;
22 5093c3fa 2004-10-22 devnull t->homeproc = p;
24 76193d7c 2003-09-30 devnull t->grp = grp;
25 7966faa9 2004-09-23 devnull t->id = id = newthreadid();
27 7966faa9 2004-09-23 devnull t->name = strdup(name);
28 7966faa9 2004-09-23 devnull _threaddebug(DBGSCHED, "create thread %d.%d name %s", p->id, id, name);
31 7966faa9 2004-09-23 devnull * Allocate and clear stack.
33 7966faa9 2004-09-23 devnull if(stacksize < 1024)
34 7966faa9 2004-09-23 devnull sysfatal("bad stacksize %d", stacksize);
35 7966faa9 2004-09-23 devnull t->stk = _threadmalloc(stacksize, 0);
36 7966faa9 2004-09-23 devnull t->stksize = stacksize;
37 7966faa9 2004-09-23 devnull _threaddebugmemset(t->stk, 0xFE, stacksize);
40 7966faa9 2004-09-23 devnull * Set up t->context to call f(arg).
42 7966faa9 2004-09-23 devnull _threadinitstack(t, f, arg);
45 7966faa9 2004-09-23 devnull * Add thread to proc.
47 76193d7c 2003-09-30 devnull lock(&p->lock);
48 5093c3fa 2004-10-22 devnull _procaddthread(p, t);
51 7966faa9 2004-09-23 devnull * Mark thread as ready to run.
53 76193d7c 2003-09-30 devnull t->state = Ready;
54 76193d7c 2003-09-30 devnull _threadready(t);
55 76193d7c 2003-09-30 devnull unlock(&p->lock);
57 76193d7c 2003-09-30 devnull return id;
61 7966faa9 2004-09-23 devnull * Free a Thread structure.
64 7966faa9 2004-09-23 devnull _threadfree(Thread *t)
66 7966faa9 2004-09-23 devnull free(t->stk);
67 7966faa9 2004-09-23 devnull free(t->name);
72 7966faa9 2004-09-23 devnull * Create and initialize a new Proc structure with a single Thread
73 7966faa9 2004-09-23 devnull * running inside it. Add the Proc to the global process list.
76 7966faa9 2004-09-23 devnull _newproc(void)
81 7966faa9 2004-09-23 devnull * Allocate.
83 7966faa9 2004-09-23 devnull p = _threadmalloc(sizeof *p, 1);
84 7966faa9 2004-09-23 devnull p->id = newprocid();
87 7966faa9 2004-09-23 devnull * Add to list. Record if we're now multiprocess.
89 7966faa9 2004-09-23 devnull lock(&_threadpq.lock);
90 7966faa9 2004-09-23 devnull if(_threadpq.head == nil)
91 7966faa9 2004-09-23 devnull _threadpq.head = p;
93 7966faa9 2004-09-23 devnull *_threadpq.tail = p;
94 7966faa9 2004-09-23 devnull _threadpq.tail = &p->next;
95 7966faa9 2004-09-23 devnull if(_threadnprocs == 1)
96 7966faa9 2004-09-23 devnull _threadmultiproc();
97 7966faa9 2004-09-23 devnull _threadnprocs++;
98 7966faa9 2004-09-23 devnull unlock(&_threadpq.lock);
100 7966faa9 2004-09-23 devnull return p;
104 7966faa9 2004-09-23 devnull * Allocate a new thread running f(arg) on a stack of size stacksize.
105 7966faa9 2004-09-23 devnull * Return the thread id. The thread group inherits from the current thread.
108 7966faa9 2004-09-23 devnull threadcreate(void (*f)(void*), void *arg, uint stacksize)
110 7966faa9 2004-09-23 devnull return _newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
114 7966faa9 2004-09-23 devnull * Allocate a new idle thread. Only allowed in a single-proc program.
117 7966faa9 2004-09-23 devnull threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
121 5093c3fa 2004-10-22 devnull assert(_threadpq.head->next == nil); /* only 1 */
123 7966faa9 2004-09-23 devnull id = threadcreate(f, arg, stacksize);
124 7966faa9 2004-09-23 devnull _threaddebug(DBGSCHED, "idle is %d", id);
125 7966faa9 2004-09-23 devnull _threadsetidle(id);
126 7966faa9 2004-09-23 devnull return id;
130 7966faa9 2004-09-23 devnull * Threadcreate, but do it inside a fresh proc.
133 7966faa9 2004-09-23 devnull proccreate(void (*f)(void*), void *arg, uint stacksize)
136 7966faa9 2004-09-23 devnull Proc *p, *np;
138 7966faa9 2004-09-23 devnull p = _threadgetproc();
139 7966faa9 2004-09-23 devnull np = _newproc();
140 7966faa9 2004-09-23 devnull p->newproc = np;
141 19564553 2004-11-08 devnull p->schedfn = _kthreadstartproc;
142 7966faa9 2004-09-23 devnull id = _newthread(np, f, arg, stacksize, nil, p->thread->grp);
143 7966faa9 2004-09-23 devnull _sched(); /* call into scheduler to create proc XXX */
144 e97ceade 2003-12-06 devnull return id;
148 7966faa9 2004-09-23 devnull * Allocate a new thread id.
150 7966faa9 2004-09-23 devnull static int
151 7966faa9 2004-09-23 devnull newthreadid(void)
153 7966faa9 2004-09-23 devnull static Lock l;
154 7966faa9 2004-09-23 devnull static int id;
157 7966faa9 2004-09-23 devnull lock(&l);
158 7966faa9 2004-09-23 devnull i = ++id;
159 7966faa9 2004-09-23 devnull unlock(&l);
160 7966faa9 2004-09-23 devnull return i;
164 7966faa9 2004-09-23 devnull * Allocate a new proc id.
166 7966faa9 2004-09-23 devnull static int
167 7966faa9 2004-09-23 devnull newprocid(void)
169 7966faa9 2004-09-23 devnull static Lock l;
170 7966faa9 2004-09-23 devnull static int id;
173 7966faa9 2004-09-23 devnull lock(&l);
174 7966faa9 2004-09-23 devnull i = ++id;
175 7966faa9 2004-09-23 devnull unlock(&l);
176 7966faa9 2004-09-23 devnull return i;
180 5093c3fa 2004-10-22 devnull * Add thread to proc's list.
183 5093c3fa 2004-10-22 devnull _procaddthread(Proc *p, Thread *t)
185 5093c3fa 2004-10-22 devnull p->nthreads++;
186 5093c3fa 2004-10-22 devnull if(p->threads.head == nil)
187 5093c3fa 2004-10-22 devnull p->threads.head = t;
189 5093c3fa 2004-10-22 devnull t->prevt = p->threads.tail;
190 5093c3fa 2004-10-22 devnull t->prevt->nextt = t;
192 5093c3fa 2004-10-22 devnull p->threads.tail = t;
193 5093c3fa 2004-10-22 devnull t->next = (Thread*)~0;
197 5093c3fa 2004-10-22 devnull * Remove thread from proc's list.
200 5093c3fa 2004-10-22 devnull _procdelthread(Proc *p, Thread *t)
202 5093c3fa 2004-10-22 devnull if(t->prevt)
203 5093c3fa 2004-10-22 devnull t->prevt->nextt = t->nextt;
205 5093c3fa 2004-10-22 devnull p->threads.head = t->nextt;
206 5093c3fa 2004-10-22 devnull if(t->nextt)
207 5093c3fa 2004-10-22 devnull t->nextt->prevt = t->prevt;
209 5093c3fa 2004-10-22 devnull p->threads.tail = t->prevt;
210 5093c3fa 2004-10-22 devnull p->nthreads--;