Rev 248 | Rev 414 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 248 | Rev 413 | ||
---|---|---|---|
Line 65... | Line 65... | ||
65 | * |
65 | * |
66 | * This wrapper is provided to ensure that every thread |
66 | * This wrapper is provided to ensure that every thread |
67 | * makes a call to thread_exit() when its implementing |
67 | * makes a call to thread_exit() when its implementing |
68 | * function returns. |
68 | * function returns. |
69 | * |
69 | * |
70 | * cpu_priority_high() is assumed. |
70 | * interrupts_disable() is assumed. |
71 | * |
71 | * |
72 | */ |
72 | */ |
73 | void cushion(void) |
73 | void cushion(void) |
74 | { |
74 | { |
75 | void (*f)(void *) = THREAD->thread_code; |
75 | void (*f)(void *) = THREAD->thread_code; |
Line 77... | Line 77... | ||
77 | 77 | ||
78 | /* this is where each thread wakes up after its creation */ |
78 | /* this is where each thread wakes up after its creation */ |
79 | before_thread_runs(); |
79 | before_thread_runs(); |
80 | 80 | ||
81 | spinlock_unlock(&THREAD->lock); |
81 | spinlock_unlock(&THREAD->lock); |
82 | cpu_priority_low(); |
82 | interrupts_enable(); |
83 | 83 | ||
84 | f(arg); |
84 | f(arg); |
85 | thread_exit(); |
85 | thread_exit(); |
86 | /* not reached */ |
86 | /* not reached */ |
87 | } |
87 | } |
Line 110... | Line 110... | ||
110 | */ |
110 | */ |
111 | void thread_ready(thread_t *t) |
111 | void thread_ready(thread_t *t) |
112 | { |
112 | { |
113 | cpu_t *cpu; |
113 | cpu_t *cpu; |
114 | runq_t *r; |
114 | runq_t *r; |
115 | pri_t pri; |
115 | ipl_t ipl; |
116 | int i, avg, send_ipi = 0; |
116 | int i, avg, send_ipi = 0; |
117 | 117 | ||
118 | pri = cpu_priority_high(); |
118 | ipl = interrupts_disable(); |
119 | 119 | ||
120 | spinlock_lock(&t->lock); |
120 | spinlock_lock(&t->lock); |
121 | 121 | ||
122 | i = (t->pri < RQ_COUNT -1) ? ++t->pri : t->pri; |
122 | i = (t->priority < RQ_COUNT -1) ? ++t->priority : t->priority; |
123 | 123 | ||
124 | cpu = CPU; |
124 | cpu = CPU; |
125 | if (t->flags & X_WIRED) { |
125 | if (t->flags & X_WIRED) { |
126 | cpu = t->cpu; |
126 | cpu = t->cpu; |
127 | } |
127 | } |
Line 146... | Line 146... | ||
146 | */ |
146 | */ |
147 | ipi_broadcast(VECTOR_WAKEUP_IPI); |
147 | ipi_broadcast(VECTOR_WAKEUP_IPI); |
148 | } |
148 | } |
149 | spinlock_unlock(&cpu->lock); |
149 | spinlock_unlock(&cpu->lock); |
150 | 150 | ||
151 | cpu_priority_restore(pri); |
151 | interrupts_restore(ipl); |
152 | } |
152 | } |
153 | 153 | ||
154 | 154 | ||
155 | /** Create new thread |
155 | /** Create new thread |
156 | * |
156 | * |
Line 169... | Line 169... | ||
169 | thread_t *t; |
169 | thread_t *t; |
170 | __address frame_ks, frame_us = NULL; |
170 | __address frame_ks, frame_us = NULL; |
171 | 171 | ||
172 | t = (thread_t *) malloc(sizeof(thread_t)); |
172 | t = (thread_t *) malloc(sizeof(thread_t)); |
173 | if (t) { |
173 | if (t) { |
174 | pri_t pri; |
174 | ipl_t ipl; |
175 | 175 | ||
176 | spinlock_initialize(&t->lock); |
176 | spinlock_initialize(&t->lock); |
177 | 177 | ||
178 | frame_ks = frame_alloc(FRAME_KA); |
178 | frame_ks = frame_alloc(FRAME_KA); |
179 | if (THREAD_USER_STACK & flags) { |
179 | if (THREAD_USER_STACK & flags) { |
180 | frame_us = frame_alloc(FRAME_KA); |
180 | frame_us = frame_alloc(FRAME_KA); |
181 | } |
181 | } |
182 | 182 | ||
183 | pri = cpu_priority_high(); |
183 | ipl = interrupts_disable(); |
184 | spinlock_lock(&tidlock); |
184 | spinlock_lock(&tidlock); |
185 | t->tid = ++last_tid; |
185 | t->tid = ++last_tid; |
186 | spinlock_unlock(&tidlock); |
186 | spinlock_unlock(&tidlock); |
187 | cpu_priority_restore(pri); |
187 | interrupts_restore(ipl); |
188 | 188 | ||
189 | memsetb(frame_ks, THREAD_STACK_SIZE, 0); |
189 | memsetb(frame_ks, THREAD_STACK_SIZE, 0); |
190 | link_initialize(&t->rq_link); |
190 | link_initialize(&t->rq_link); |
191 | link_initialize(&t->wq_link); |
191 | link_initialize(&t->wq_link); |
192 | link_initialize(&t->th_link); |
192 | link_initialize(&t->th_link); |
Line 197... | Line 197... | ||
197 | context_save(&t->saved_context); |
197 | context_save(&t->saved_context); |
198 | context_set(&t->saved_context, FADDR(cushion), t->kstack, THREAD_STACK_SIZE); |
198 | context_set(&t->saved_context, FADDR(cushion), t->kstack, THREAD_STACK_SIZE); |
199 | 199 | ||
200 | the_initialize((the_t *) t->kstack); |
200 | the_initialize((the_t *) t->kstack); |
201 | 201 | ||
202 | pri = cpu_priority_high(); |
202 | ipl = interrupts_disable(); |
203 | t->saved_context.pri = cpu_priority_read(); |
203 | t->saved_context.ipl = interrupts_read(); |
204 | cpu_priority_restore(pri); |
204 | interrupts_restore(ipl); |
205 | 205 | ||
206 | t->thread_code = func; |
206 | t->thread_code = func; |
207 | t->thread_arg = arg; |
207 | t->thread_arg = arg; |
208 | t->ticks = -1; |
208 | t->ticks = -1; |
209 | t->pri = -1; /* start in rq[0] */ |
209 | t->priority = -1; /* start in rq[0] */ |
210 | t->cpu = NULL; |
210 | t->cpu = NULL; |
211 | t->flags = 0; |
211 | t->flags = 0; |
212 | t->state = Entering; |
212 | t->state = Entering; |
213 | t->call_me = NULL; |
213 | t->call_me = NULL; |
214 | t->call_me_with = NULL; |
214 | t->call_me_with = NULL; |
Line 225... | Line 225... | ||
225 | t->fpu_context_engaged=0; |
225 | t->fpu_context_engaged=0; |
226 | 226 | ||
227 | /* |
227 | /* |
228 | * Register this thread in the system-wide list. |
228 | * Register this thread in the system-wide list. |
229 | */ |
229 | */ |
230 | pri = cpu_priority_high(); |
230 | ipl = interrupts_disable(); |
231 | spinlock_lock(&threads_lock); |
231 | spinlock_lock(&threads_lock); |
232 | list_append(&t->threads_link, &threads_head); |
232 | list_append(&t->threads_link, &threads_head); |
233 | spinlock_unlock(&threads_lock); |
233 | spinlock_unlock(&threads_lock); |
234 | 234 | ||
235 | /* |
235 | /* |
Line 237... | Line 237... | ||
237 | */ |
237 | */ |
238 | spinlock_lock(&task->lock); |
238 | spinlock_lock(&task->lock); |
239 | list_append(&t->th_link, &task->th_head); |
239 | list_append(&t->th_link, &task->th_head); |
240 | spinlock_unlock(&task->lock); |
240 | spinlock_unlock(&task->lock); |
241 | 241 | ||
242 | cpu_priority_restore(pri); |
242 | interrupts_restore(ipl); |
243 | } |
243 | } |
244 | 244 | ||
245 | return t; |
245 | return t; |
246 | } |
246 | } |
247 | 247 | ||
Line 252... | Line 252... | ||
252 | * state. All pending timeouts are executed. |
252 | * state. All pending timeouts are executed. |
253 | * |
253 | * |
254 | */ |
254 | */ |
255 | void thread_exit(void) |
255 | void thread_exit(void) |
256 | { |
256 | { |
257 | pri_t pri; |
257 | ipl_t ipl; |
258 | 258 | ||
259 | restart: |
259 | restart: |
260 | pri = cpu_priority_high(); |
260 | ipl = interrupts_disable(); |
261 | spinlock_lock(&THREAD->lock); |
261 | spinlock_lock(&THREAD->lock); |
262 | if (THREAD->timeout_pending) { /* busy waiting for timeouts in progress */ |
262 | if (THREAD->timeout_pending) { /* busy waiting for timeouts in progress */ |
263 | spinlock_unlock(&THREAD->lock); |
263 | spinlock_unlock(&THREAD->lock); |
264 | cpu_priority_restore(pri); |
264 | interrupts_restore(ipl); |
265 | goto restart; |
265 | goto restart; |
266 | } |
266 | } |
267 | THREAD->state = Exiting; |
267 | THREAD->state = Exiting; |
268 | spinlock_unlock(&THREAD->lock); |
268 | spinlock_unlock(&THREAD->lock); |
269 | scheduler(); |
269 | scheduler(); |
Line 309... | Line 309... | ||
309 | * @param call_me_with Out-of-context function argument. |
309 | * @param call_me_with Out-of-context function argument. |
310 | * |
310 | * |
311 | */ |
311 | */ |
312 | void thread_register_call_me(void (* call_me)(void *), void *call_me_with) |
312 | void thread_register_call_me(void (* call_me)(void *), void *call_me_with) |
313 | { |
313 | { |
314 | pri_t pri; |
314 | ipl_t ipl; |
315 | 315 | ||
316 | pri = cpu_priority_high(); |
316 | ipl = interrupts_disable(); |
317 | spinlock_lock(&THREAD->lock); |
317 | spinlock_lock(&THREAD->lock); |
318 | THREAD->call_me = call_me; |
318 | THREAD->call_me = call_me; |
319 | THREAD->call_me_with = call_me_with; |
319 | THREAD->call_me_with = call_me_with; |
320 | spinlock_unlock(&THREAD->lock); |
320 | spinlock_unlock(&THREAD->lock); |
321 | cpu_priority_restore(pri); |
321 | interrupts_restore(ipl); |
322 | } |
322 | } |