1 /* src/threads/threadlist.c - different thread-lists
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 #include "mm/memory.h"
32 #include "threads/mutex.hpp"
33 #include "threads/threadlist.h"
34 #include "threads/thread.h"
36 #include "toolbox/list.h"
38 #include "vmcore/options.h"
41 /* global variables ***********************************************************/
43 static Mutex* threadlist_mutex; /* global mutex for the thread list */
45 static list_t *list_thread; /* global threads list */
46 static list_t *list_thread_free; /* global free threads list */
47 static list_t *list_thread_index_free;
50 typedef struct thread_index_t {
56 /* threadlist_init *************************************************************
58 Initialize thread-lists.
60 *******************************************************************************/
62 void threadlist_init(void)
64 TRACESUBSYSTEMINITIALIZATION("threadlist_init");
66 /* Initialize the thread list mutex. */
68 threadlist_mutex = Mutex_new();
70 /* Initialize the thread lists. */
72 list_thread = list_create(OFFSET(threadobject, linkage));
73 list_thread_free = list_create(OFFSET(threadobject, linkage_free));
74 list_thread_index_free = list_create(OFFSET(thread_index_t, linkage));
78 /* threadlist_lock *************************************************************
80 Enter the thread list mutex.
82 NOTE: We need this function as we can't use an internal lock for
83 the threads lists because the thread's lock is initialized in
84 threads_table_add (when we have the thread index), but we
85 already need the lock at the entry of the function.
87 *******************************************************************************/
89 void threadlist_lock(void)
91 Mutex_lock(threadlist_mutex);
95 /* threadlist_unlock *********************************************************
97 Leave the thread list mutex.
99 *******************************************************************************/
101 void threadlist_unlock(void)
103 Mutex_unlock(threadlist_mutex);
107 /* threadlist_add **************************************************************
109 Add the given threadobject as last entry to the thread list.
112 t ... threadobject to be added
114 *******************************************************************************/
116 void threadlist_add(threadobject *t)
118 list_add_last(list_thread, t);
122 /* threadlist_remove ***********************************************************
124 Remove the given threadobject from the thread list.
127 t ... threadobject to be removed
129 *******************************************************************************/
131 void threadlist_remove(threadobject *t)
133 list_remove(list_thread, t);
137 /* threadlist_first ************************************************************
139 Return the first entry in the thread list.
142 threadobject of the first entry
144 *******************************************************************************/
146 threadobject *threadlist_first(void)
150 t = list_first(list_thread);
156 /* threadlist_next *************************************************************
158 Return the next entry in the thread list.
161 t ... threadobject to get next thread of
164 threadobject of the next entry
166 *******************************************************************************/
168 threadobject *threadlist_next(threadobject *t)
172 next = list_next(list_thread, t);
178 /* threadlist_free_add *********************************************************
180 Add the given threadobject as last entry to the free thread list.
183 t ... threadobject to be added
185 *******************************************************************************/
187 void threadlist_free_add(threadobject *t)
189 list_add_last(list_thread_free, t);
193 /* threadlist_free_remove ******************************************************
195 Remove the given entry from the free thread list.
198 t ... threadobject to be removed
200 *******************************************************************************/
202 void threadlist_free_remove(threadobject *t)
204 list_remove(list_thread_free, t);
208 /* threadlist_free_first *******************************************************
210 Return the first entry in the free thread list.
213 threadobject of the first free entry
215 *******************************************************************************/
217 threadobject *threadlist_free_first(void)
221 t = list_first(list_thread_free);
227 /* threadlist_get_non_daemons **************************************************
229 Return the number of non-daemon threads.
231 NOTE: This function does a linear-search over the threads list,
232 because it's only used for joining the threads.
234 *******************************************************************************/
236 int threadlist_get_non_daemons(void)
241 /* Lock the thread lists. */
247 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
248 if (!thread_is_daemon(t))
252 /* Unlock the thread lists. */
260 /* threadlist_index_first ******************************************************
262 Return the first entry in the thread-index list.
265 thread-index structure
267 *******************************************************************************/
269 static inline thread_index_t *threadlist_index_first(void)
273 ti = list_first(list_thread_index_free);
279 /* threadlist_index_add ********************************************************
281 Add the given thread-index to the thread-index free list.
286 *******************************************************************************/
288 void threadlist_index_add(int index)
292 ti = NEW(thread_index_t);
294 #if defined(ENABLE_STATISTICS)
296 size_thread_index_t += sizeof(thread_index_t);
299 /* Set the index in the structure. */
303 list_add_last(list_thread_index_free, ti);
307 /* threadlist_index_remove *****************************************************
309 Remove the given thread-index from the thread-index list and free
310 the thread-index structure.
313 ti ... thread-index structure
315 *******************************************************************************/
317 static inline void threadlist_index_remove(thread_index_t *ti)
319 list_remove(list_thread_index_free, ti);
321 FREE(ti, thread_index_t);
323 #if defined(ENABLE_STATISTICS)
325 size_thread_index_t -= sizeof(thread_index_t);
330 /* threadlist_get_free_index ***************************************************
332 Return a free thread index.
337 *******************************************************************************/
339 int threadlist_get_free_index(void)
344 /* Try to get a thread index from the free-list. */
346 ti = threadlist_index_first();
348 /* Is a free thread index available? */
351 /* Yes, get the index and remove it from the free list. */
355 threadlist_index_remove(ti);
358 /* Get a new the thread index. */
360 index = list_thread->size + 1;
368 * These are local overrides for various environment variables in Emacs.
369 * Please do not remove this and leave it at the end of the file, where
370 * Emacs will automagically detect them.
371 * ---------------------------------------------------------------------
374 * indent-tabs-mode: t
378 * vim:noexpandtab:sw=4:ts=4: