1 |
/* Threads. |
/* Threads. |
2 |
Copyright 1999, 2000, 2001, 2002 Johan Rydberg, jrydberg@opencores.org. |
Copyright 1999, 2000, 2001, 2002 Johan Rydberg, jrydberg@rtmk.org. |
3 |
|
|
4 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
5 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
23 |
#include "trace.h" |
#include "trace.h" |
24 |
#include "libkern.h" |
#include "libkern.h" |
25 |
#include "queue.h" |
#include "queue.h" |
26 |
|
#include "ipc-tqueue.h" |
27 |
|
|
28 |
bool thread_system_running = false; |
bool thread_system_running = false; |
29 |
|
|
150 |
spin_lock_init (&thread->lock); |
spin_lock_init (&thread->lock); |
151 |
|
|
152 |
thread->task = task; |
thread->task = task; |
153 |
|
task_reference (task); |
154 |
|
|
155 |
thread->ref_cnt = 1; |
thread->ref_cnt = 1; |
156 |
thread->suspend_cnt = 1; |
thread->suspend_cnt = 1; |
186 |
spin_lock (&thread_list_lock); |
spin_lock (&thread_list_lock); |
187 |
queue_enter (&thread_list, thread, struct thread *, allq); |
queue_enter (&thread_list, thread, struct thread *, allq); |
188 |
spin_unlock (&thread_list_lock); |
spin_unlock (&thread_list_lock); |
189 |
|
|
190 |
|
queue_enter (&task->thread_list, thread, struct thread *, taskq); |
191 |
SPLON (spl); |
SPLON (spl); |
192 |
|
|
193 |
trace_count (n_threads++); |
trace_count (n_threads++); |
225 |
/* ??? release other resources. */ |
/* ??? release other resources. */ |
226 |
|
|
227 |
/* Remove thread from thread list. */ |
/* Remove thread from thread list. */ |
|
|
|
228 |
spl = SPLOFF (); |
spl = SPLOFF (); |
229 |
spin_lock (&thread_list_lock); |
spin_lock (&thread_list_lock); |
230 |
queue_remove (&thread_list, thread, struct thread *, allq); |
queue_remove (&thread_list, thread, struct thread *, allq); |
231 |
spin_unlock (&thread_list_lock); |
spin_unlock (&thread_list_lock); |
232 |
|
|
233 |
|
/* Remove thread from task list -- and release task reference. */ |
234 |
|
queue_remove (&thread->task->thread_list, thread, struct thread *, taskq); |
235 |
|
task_deallocate (thread->task); |
236 |
|
|
237 |
SPLON (spl); |
SPLON (spl); |
238 |
|
|
239 |
kmem_cache_free (thread_cache, thread); |
kmem_cache_free (thread_cache, thread); |
255 |
|
|
256 |
spl = SPLOFF (); |
spl = SPLOFF (); |
257 |
thread_lock (thread); |
thread_lock (thread); |
258 |
|
|
259 |
|
/* Before we do anything else we mark the thread as a zombie. */ |
260 |
|
thread->sched_state |= THREAD_STATE_ZOMBIE; |
261 |
|
|
262 |
#if 0 /* NCPUS > 1 */ |
#if 0 /* NCPUS > 1 */ |
263 |
/* Check if thread is running on some other processor. If it does, |
/* Check if thread is running on some other processor. If it does, |
273 |
} |
} |
274 |
#endif |
#endif |
275 |
|
|
276 |
|
/* If this thread is waiting for a message on part we'll have to |
277 |
|
remove it from that port (otherwise: crash and burn!!!) */ |
278 |
|
if (thread->ipc_blocked_port) |
279 |
|
{ |
280 |
|
struct ipc_port *port = thread->ipc_blocked_port; |
281 |
|
ipc_tqueue_remove (&port->waiting_threads, thread); |
282 |
|
|
283 |
|
thread->ipc_blocked_port = 0; |
284 |
|
} |
285 |
|
|
286 |
/* Thread is not running on any processor -> it is either waiting or |
/* Thread is not running on any processor -> it is either waiting or |
287 |
on some run queue. Remove thread from queue and kill it. */ |
on some run queue. Remove thread from queue and kill it. */ |
|
|
|
288 |
if (thread->sched_state & THREAD_STATE_WAIT) |
if (thread->sched_state & THREAD_STATE_WAIT) |
289 |
{ |
{ |
290 |
int event; |
int event; |
312 |
else /* on runq */ |
else /* on runq */ |
313 |
(*thread->sched_sp->ops->remove_fn) (thread->sched_sp, thread); |
(*thread->sched_sp->ops->remove_fn) (thread->sched_sp, thread); |
314 |
|
|
315 |
|
|
316 |
|
|
317 |
/* Add thread to reaper daemon zombie list. Since we no longer will |
/* Add thread to reaper daemon zombie list. Since we no longer will |
318 |
use the RUNQ chain in thread we use that as reaper chain link. */ |
use the RUNQ chain in thread we use that as reaper chain link. */ |
|
|
|
319 |
thread_unlock (thread); |
thread_unlock (thread); |
320 |
spin_lock (&reaper_lock); |
spin_lock (&reaper_lock); |
321 |
thread_lock (thread); |
thread_lock (thread); |