1 /* src/threads/threadlist.cpp - thread list
3 Copyright (C) 2008, 2009
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
32 #include "threads/mutex.hpp"
33 #include "threads/threadlist.hpp"
34 #include "threads/thread.hpp"
36 #include "toolbox/list.hpp"
37 #include "toolbox/logging.hpp"
39 #include "vm/jit/stacktrace.hpp"
44 Mutex ThreadList::_mutex; // a mutex for all thread lists
46 List<threadobject*> ThreadList::_active_thread_list; // list of active threads
47 List<threadobject*> ThreadList::_free_thread_list; // list of free threads
48 List<int32_t> ThreadList::_free_index_list; // list of free thread indexes
50 int32_t ThreadList::_number_of_started_java_threads;
51 int32_t ThreadList::_number_of_active_java_threads;
52 int32_t ThreadList::_peak_of_active_java_threads;
53 int32_t ThreadList::_number_of_non_daemon_threads;
55 int32_t ThreadList::_last_index = 0;
59 * Dumps info for all threads running in the VM. This function is
60 * called when SIGQUIT (<ctrl>-\) is sent to the VM.
62 void ThreadList::dump_threads()
64 // XXX we should stop the world here and remove explicit
65 // thread suspension from the loop below.
66 // Lock the thread lists.
69 printf("Full thread dump CACAO "VERSION_FULL":\n");
71 // Iterate over all started threads.
72 threadobject* self = THREADOBJECT;
73 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
74 threadobject* t = *it;
76 // Ignore threads which are in state NEW.
77 if (t->state == THREAD_STATE_NEW)
80 /* Suspend the thread (and ignore return value). */
83 (void) threads_suspend_thread(t, SUSPEND_REASON_DUMP);
85 /* Print thread info. */
91 /* Print trace of thread. */
93 stacktrace_print_of_thread(t);
95 /* Resume the thread (and ignore return value). */
98 (void) threads_resume_thread(t, SUSPEND_REASON_DUMP);
101 // Unlock the thread lists.
107 * Fills the passed list with all currently active threads. Creating a copy
108 * of the thread list here, is the only way to ensure we do not end up in a
109 * dead-lock when iterating over the list.
111 * @param list list class to be filled
113 void ThreadList::get_active_threads(List<threadobject*> &list)
115 // Lock the thread lists.
118 // Use the assignment operator to create a copy of the thread list.
119 list = _active_thread_list;
121 // Unlock the thread lists.
127 * Fills the passed list with all currently active threads which should be
128 * visible to Java. Creating a copy of the thread list here, is the only way
129 * to ensure we do not end up in a dead-lock when iterating over the list.
131 * @param list list class to be filled
133 void ThreadList::get_active_java_threads(List<threadobject*> &list)
135 // Lock the thread lists.
138 // Iterate over all active threads.
139 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
140 threadobject* t = *it;
142 // We skip internal threads.
143 if (t->flags & THREAD_FLAG_INTERNAL)
149 // Unlock the thread lists.
155 * Return a free thread object.
157 * @return free thread object or NULL if none available
159 threadobject* ThreadList::get_free_thread()
161 threadobject* t = NULL;
165 // Do we have free threads in the free-list?
166 if (_free_thread_list.empty() == false) {
167 // Yes, get the index and remove it from the free list.
168 t = _free_thread_list.front();
169 _free_thread_list.remove(t);
179 * Return a free thread index.
181 * @return free thread index
183 int32_t ThreadList::get_free_thread_index()
189 // Do we have free indexes in the free-list?
190 if (_free_index_list.empty() == false) {
191 // Yes, get the index and remove it from the free list.
192 index = _free_index_list.front();
193 _free_index_list.remove(index);
196 // Get a new the thread index.
197 index = ++_last_index;
207 * Return the number of daemon threads visible to Java.
209 * NOTE: This function does a linear-search over the threads list,
210 * because it is only used by the management interface.
212 * @return number of daemon threads
214 int32_t ThreadList::get_number_of_daemon_java_threads(void)
218 // Lock the thread lists.
221 // Iterate over all active threads.
222 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
223 threadobject* t = *it;
225 // We skip internal threads.
226 if (t->flags & THREAD_FLAG_INTERNAL)
229 if (thread_is_daemon(t))
233 // Unlock the thread lists.
241 * Return the number of non-daemon threads.
243 * NOTE: This function does a linear-search over the threads list,
244 * because it is only used for joining the threads.
246 * @return number of non daemon threads
248 int32_t ThreadList::get_number_of_non_daemon_threads(void)
254 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
255 threadobject* t = *it;
257 if (!thread_is_daemon(t))
268 * Return the thread object with the given index.
270 * @return thread object
272 threadobject* ThreadList::get_thread_by_index(int32_t index)
276 List<threadobject*>::iterator it = find_if(_active_thread_list.begin(), _active_thread_list.end(), std::bind2nd(comparator(), index));
279 if (it == _active_thread_list.end()) {
284 threadobject* t = *it;
286 // The thread found is in state new.
287 if (t->state == THREAD_STATE_NEW) {
298 * Return the Java thread object from the given thread object.
300 * @return Java thread object
302 threadobject* ThreadList::get_thread_from_java_object(java_handle_t* h)
304 List<threadobject*>::iterator it;
310 for (it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
313 LLNI_equals(t->object, h, equal);
326 void ThreadList::deactivate_thread(threadobject *t)
328 ThreadListLocker lock;
329 remove_from_active_thread_list(t);
330 threads_impl_clear_heap_pointers(t); // allow it to be garbage collected
334 * Release the thread.
336 * @return free thread index
338 void ThreadList::release_thread(threadobject* t, bool needs_deactivate)
342 if (needs_deactivate)
343 // Move thread from active thread list to free thread list.
344 remove_from_active_thread_list(t);
346 assert(!t->is_in_active_list);
348 add_to_free_thread_list(t);
350 // Add thread index to free index list.
351 add_to_free_index_list(t->index);
357 /* C interface functions ******************************************************/
360 void ThreadList_lock() { ThreadList::lock(); }
361 void ThreadList_unlock() { ThreadList::unlock(); }
362 void ThreadList_dump_threads() { ThreadList::dump_threads(); }
363 threadobject* ThreadList_get_free_thread() { return ThreadList::get_free_thread(); }
364 int32_t ThreadList_get_free_thread_index() { return ThreadList::get_free_thread_index(); }
365 void ThreadList_add_to_active_thread_list(threadobject* t) { ThreadList::add_to_active_thread_list(t); }
366 threadobject* ThreadList_get_thread_by_index(int32_t index) { return ThreadList::get_thread_by_index(index); }
367 threadobject* ThreadList_get_main_thread() { return ThreadList::get_main_thread(); }
368 threadobject* ThreadList_get_thread_from_java_object(java_handle_t* h) { return ThreadList::get_thread_from_java_object(h); }
370 int32_t ThreadList_get_number_of_non_daemon_threads() { return ThreadList::get_number_of_non_daemon_threads(); }
374 * These are local overrides for various environment variables in Emacs.
375 * Please do not remove this and leave it at the end of the file, where
376 * Emacs will automagically detect them.
377 * ---------------------------------------------------------------------
380 * indent-tabs-mode: t
384 * vim:noexpandtab:sw=4:ts=4: