Blame


1 76193d7c 2003-09-30 devnull #include "threadimpl.h"
2 76193d7c 2003-09-30 devnull
3 7966faa9 2004-09-23 devnull Pqueue _threadpq; /* list of all procs */
4 7966faa9 2004-09-23 devnull int _threadnprocs; /* count of procs */
5 76193d7c 2003-09-30 devnull
6 7966faa9 2004-09-23 devnull static int newthreadid(void);
7 7966faa9 2004-09-23 devnull static int newprocid(void);
8 76193d7c 2003-09-30 devnull
9 76193d7c 2003-09-30 devnull /*
10 76193d7c 2003-09-30 devnull * Create and initialize a new Thread structure attached to a given proc.
11 76193d7c 2003-09-30 devnull */
12 7966faa9 2004-09-23 devnull int
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)
15 76193d7c 2003-09-30 devnull {
16 76193d7c 2003-09-30 devnull int id;
17 76193d7c 2003-09-30 devnull Thread *t;
18 76193d7c 2003-09-30 devnull
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;
23 5093c3fa 2004-10-22 devnull
24 76193d7c 2003-09-30 devnull t->grp = grp;
25 7966faa9 2004-09-23 devnull t->id = id = newthreadid();
26 76193d7c 2003-09-30 devnull if(name)
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);
29 7966faa9 2004-09-23 devnull
30 7966faa9 2004-09-23 devnull /*
31 7966faa9 2004-09-23 devnull * Allocate and clear stack.
32 7966faa9 2004-09-23 devnull */
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);
38 7966faa9 2004-09-23 devnull
39 7966faa9 2004-09-23 devnull /*
40 7966faa9 2004-09-23 devnull * Set up t->context to call f(arg).
41 7966faa9 2004-09-23 devnull */
42 7966faa9 2004-09-23 devnull _threadinitstack(t, f, arg);
43 7966faa9 2004-09-23 devnull
44 7966faa9 2004-09-23 devnull /*
45 7966faa9 2004-09-23 devnull * Add thread to proc.
46 7966faa9 2004-09-23 devnull */
47 76193d7c 2003-09-30 devnull lock(&p->lock);
48 5093c3fa 2004-10-22 devnull _procaddthread(p, t);
49 7966faa9 2004-09-23 devnull
50 7966faa9 2004-09-23 devnull /*
51 7966faa9 2004-09-23 devnull * Mark thread as ready to run.
52 7966faa9 2004-09-23 devnull */
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);
56 7966faa9 2004-09-23 devnull
57 76193d7c 2003-09-30 devnull return id;
58 76193d7c 2003-09-30 devnull }
59 76193d7c 2003-09-30 devnull
60 7966faa9 2004-09-23 devnull /*
61 7966faa9 2004-09-23 devnull * Free a Thread structure.
62 7966faa9 2004-09-23 devnull */
63 7966faa9 2004-09-23 devnull void
64 7966faa9 2004-09-23 devnull _threadfree(Thread *t)
65 76193d7c 2003-09-30 devnull {
66 7966faa9 2004-09-23 devnull free(t->stk);
67 7966faa9 2004-09-23 devnull free(t->name);
68 7966faa9 2004-09-23 devnull free(t);
69 76193d7c 2003-09-30 devnull }
70 7966faa9 2004-09-23 devnull
71 7966faa9 2004-09-23 devnull /*
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.
74 7966faa9 2004-09-23 devnull */
75 7966faa9 2004-09-23 devnull Proc*
76 7966faa9 2004-09-23 devnull _newproc(void)
77 76193d7c 2003-09-30 devnull {
78 76193d7c 2003-09-30 devnull Proc *p;
79 76193d7c 2003-09-30 devnull
80 7966faa9 2004-09-23 devnull /*
81 7966faa9 2004-09-23 devnull * Allocate.
82 7966faa9 2004-09-23 devnull */
83 7966faa9 2004-09-23 devnull p = _threadmalloc(sizeof *p, 1);
84 7966faa9 2004-09-23 devnull p->id = newprocid();
85 7966faa9 2004-09-23 devnull
86 7966faa9 2004-09-23 devnull /*
87 7966faa9 2004-09-23 devnull * Add to list. Record if we're now multiprocess.
88 7966faa9 2004-09-23 devnull */
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;
92 7966faa9 2004-09-23 devnull else
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);
99 7966faa9 2004-09-23 devnull
100 7966faa9 2004-09-23 devnull return p;
101 76193d7c 2003-09-30 devnull }
102 76193d7c 2003-09-30 devnull
103 7966faa9 2004-09-23 devnull /*
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.
106 7966faa9 2004-09-23 devnull */
107 76193d7c 2003-09-30 devnull int
108 7966faa9 2004-09-23 devnull threadcreate(void (*f)(void*), void *arg, uint stacksize)
109 76193d7c 2003-09-30 devnull {
110 7966faa9 2004-09-23 devnull return _newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
111 76193d7c 2003-09-30 devnull }
112 76193d7c 2003-09-30 devnull
113 76193d7c 2003-09-30 devnull /*
114 7966faa9 2004-09-23 devnull * Allocate a new idle thread. Only allowed in a single-proc program.
115 76193d7c 2003-09-30 devnull */
116 76193d7c 2003-09-30 devnull int
117 7966faa9 2004-09-23 devnull threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
118 76193d7c 2003-09-30 devnull {
119 7966faa9 2004-09-23 devnull int id;
120 7966faa9 2004-09-23 devnull
121 5093c3fa 2004-10-22 devnull assert(_threadpq.head->next == nil); /* only 1 */
122 7966faa9 2004-09-23 devnull
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;
127 76193d7c 2003-09-30 devnull }
128 76193d7c 2003-09-30 devnull
129 7966faa9 2004-09-23 devnull /*
130 7966faa9 2004-09-23 devnull * Threadcreate, but do it inside a fresh proc.
131 7966faa9 2004-09-23 devnull */
132 e97ceade 2003-12-06 devnull int
133 7966faa9 2004-09-23 devnull proccreate(void (*f)(void*), void *arg, uint stacksize)
134 e97ceade 2003-12-06 devnull {
135 e97ceade 2003-12-06 devnull int id;
136 7966faa9 2004-09-23 devnull Proc *p, *np;
137 e97ceade 2003-12-06 devnull
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;
145 e97ceade 2003-12-06 devnull }
146 e97ceade 2003-12-06 devnull
147 76193d7c 2003-09-30 devnull /*
148 7966faa9 2004-09-23 devnull * Allocate a new thread id.
149 76193d7c 2003-09-30 devnull */
150 7966faa9 2004-09-23 devnull static int
151 7966faa9 2004-09-23 devnull newthreadid(void)
152 76193d7c 2003-09-30 devnull {
153 7966faa9 2004-09-23 devnull static Lock l;
154 7966faa9 2004-09-23 devnull static int id;
155 7966faa9 2004-09-23 devnull int i;
156 76193d7c 2003-09-30 devnull
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;
161 7966faa9 2004-09-23 devnull }
162 76193d7c 2003-09-30 devnull
163 7966faa9 2004-09-23 devnull /*
164 7966faa9 2004-09-23 devnull * Allocate a new proc id.
165 7966faa9 2004-09-23 devnull */
166 7966faa9 2004-09-23 devnull static int
167 7966faa9 2004-09-23 devnull newprocid(void)
168 7966faa9 2004-09-23 devnull {
169 7966faa9 2004-09-23 devnull static Lock l;
170 7966faa9 2004-09-23 devnull static int id;
171 7966faa9 2004-09-23 devnull int i;
172 be36ff68 2004-04-29 devnull
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;
177 76193d7c 2003-09-30 devnull }
178 76193d7c 2003-09-30 devnull
179 5093c3fa 2004-10-22 devnull /*
180 5093c3fa 2004-10-22 devnull * Add thread to proc's list.
181 5093c3fa 2004-10-22 devnull */
182 5093c3fa 2004-10-22 devnull void
183 5093c3fa 2004-10-22 devnull _procaddthread(Proc *p, Thread *t)
184 5093c3fa 2004-10-22 devnull {
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;
188 5093c3fa 2004-10-22 devnull else{
189 5093c3fa 2004-10-22 devnull t->prevt = p->threads.tail;
190 5093c3fa 2004-10-22 devnull t->prevt->nextt = t;
191 5093c3fa 2004-10-22 devnull }
192 5093c3fa 2004-10-22 devnull p->threads.tail = t;
193 5093c3fa 2004-10-22 devnull t->next = (Thread*)~0;
194 5093c3fa 2004-10-22 devnull }
195 5093c3fa 2004-10-22 devnull
196 5093c3fa 2004-10-22 devnull /*
197 5093c3fa 2004-10-22 devnull * Remove thread from proc's list.
198 5093c3fa 2004-10-22 devnull */
199 5093c3fa 2004-10-22 devnull void
200 5093c3fa 2004-10-22 devnull _procdelthread(Proc *p, Thread *t)
201 5093c3fa 2004-10-22 devnull {
202 5093c3fa 2004-10-22 devnull if(t->prevt)
203 5093c3fa 2004-10-22 devnull t->prevt->nextt = t->nextt;
204 5093c3fa 2004-10-22 devnull else
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;
208 5093c3fa 2004-10-22 devnull else
209 5093c3fa 2004-10-22 devnull p->threads.tail = t->prevt;
210 5093c3fa 2004-10-22 devnull p->nthreads--;
211 5093c3fa 2004-10-22 devnull }