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;
57 * Dumps info for all threads running in the VM. This function is
58 * called when SIGQUIT (<ctrl>-\) is sent to the VM.
60 void ThreadList::dump_threads()
62 // XXX we should stop the world here and remove explicit
63 // thread suspension from the loop below.
64 // Lock the thread lists.
67 printf("Full thread dump CACAO "VERSION_FULL":\n");
69 // Iterate over all started threads.
70 threadobject* self = THREADOBJECT;
71 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
72 threadobject* t = *it;
74 // Ignore threads which are in state NEW.
75 if (t->state == THREAD_STATE_NEW)
78 /* Suspend the thread (and ignore return value). */
81 (void) threads_suspend_thread(t, SUSPEND_REASON_DUMP);
83 /* Print thread info. */
89 /* Print trace of thread. */
91 stacktrace_print_of_thread(t);
93 /* Resume the thread (and ignore return value). */
96 (void) threads_resume_thread(t, SUSPEND_REASON_DUMP);
99 // Unlock the thread lists.
105 * Fills the passed list with all currently active threads. Creating a copy
106 * of the thread list here, is the only way to ensure we do not end up in a
107 * dead-lock when iterating over the list.
109 * @param list list class to be filled
111 void ThreadList::get_active_threads(List<threadobject*> &list)
113 // Lock the thread lists.
116 // Use the assignment operator to create a copy of the thread list.
117 list = _active_thread_list;
119 // Unlock the thread lists.
125 * Fills the passed list with all currently active threads which should be
126 * visible to Java. Creating a copy of the thread list here, is the only way
127 * to ensure we do not end up in a dead-lock when iterating over the list.
129 * @param list list class to be filled
131 void ThreadList::get_active_java_threads(List<threadobject*> &list)
133 // Lock the thread lists.
136 // Iterate over all active threads.
137 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
138 threadobject* t = *it;
140 // We skip internal threads.
141 if (t->flags & THREAD_FLAG_INTERNAL)
147 // Unlock the thread lists.
153 * Return a free thread object.
155 * @return free thread object or NULL if none available
157 threadobject* ThreadList::get_free_thread()
159 threadobject* t = NULL;
163 // Do we have free threads in the free-list?
164 if (_free_thread_list.empty() == false) {
165 // Yes, get the index and remove it from the free list.
166 t = _free_thread_list.front();
167 _free_thread_list.remove(t);
177 * Return a free thread index.
179 * @return free thread index
181 int32_t ThreadList::get_free_thread_index()
187 // Do we have free indexes in the free-list?
188 if (_free_index_list.empty() == false) {
189 // Yes, get the index and remove it from the free list.
190 index = _free_index_list.front();
191 _free_index_list.remove(index);
194 // Get a new the thread index.
195 index = _active_thread_list.size() + 1;
205 * Return the number of daemon threads visible to Java.
207 * NOTE: This function does a linear-search over the threads list,
208 * because it is only used by the management interface.
210 * @return number of daemon threads
212 int32_t ThreadList::get_number_of_daemon_java_threads(void)
216 // Lock the thread lists.
219 // Iterate over all active threads.
220 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
221 threadobject* t = *it;
223 // We skip internal threads.
224 if (t->flags & THREAD_FLAG_INTERNAL)
227 if (thread_is_daemon(t))
231 // Unlock the thread lists.
239 * Return the number of non-daemon threads.
241 * NOTE: This function does a linear-search over the threads list,
242 * because it is only used for joining the threads.
244 * @return number of non daemon threads
246 int32_t ThreadList::get_number_of_non_daemon_threads(void)
252 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
253 threadobject* t = *it;
255 if (!thread_is_daemon(t))
266 * Return the thread object with the given index.
268 * @return thread object
270 threadobject* ThreadList::get_thread_by_index(int32_t index)
274 List<threadobject*>::iterator it = find_if(_active_thread_list.begin(), _active_thread_list.end(), std::bind2nd(comparator(), index));
277 if (it == _active_thread_list.end()) {
282 threadobject* t = *it;
284 // The thread found is in state new.
285 if (t->state == THREAD_STATE_NEW) {
296 * Return the Java thread object from the given thread object.
298 * @return Java thread object
300 threadobject* ThreadList::get_thread_from_java_object(java_handle_t* h)
302 List<threadobject*>::iterator it;
308 for (it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
311 LLNI_equals(t->object, h, equal);
324 void ThreadList::deactivate_thread(threadobject *t)
326 ThreadListLocker lock;
327 remove_from_active_thread_list(t);
328 threads_impl_clear_heap_pointers(t); // allow it to be garbage collected
332 * Release the thread.
334 * @return free thread index
336 void ThreadList::release_thread(threadobject* t, bool needs_deactivate)
340 if (needs_deactivate)
341 // Move thread from active thread list to free thread list.
342 remove_from_active_thread_list(t);
344 assert(!t->is_in_active_list);
346 add_to_free_thread_list(t);
348 // Add thread index to free index list.
349 add_to_free_index_list(t->index);
355 /* C interface functions ******************************************************/
358 void ThreadList_lock() { ThreadList::lock(); }
359 void ThreadList_unlock() { ThreadList::unlock(); }
360 void ThreadList_dump_threads() { ThreadList::dump_threads(); }
361 threadobject* ThreadList_get_free_thread() { return ThreadList::get_free_thread(); }
362 int32_t ThreadList_get_free_thread_index() { return ThreadList::get_free_thread_index(); }
363 void ThreadList_add_to_active_thread_list(threadobject* t) { ThreadList::add_to_active_thread_list(t); }
364 threadobject* ThreadList_get_thread_by_index(int32_t index) { return ThreadList::get_thread_by_index(index); }
365 threadobject* ThreadList_get_main_thread() { return ThreadList::get_main_thread(); }
366 threadobject* ThreadList_get_thread_from_java_object(java_handle_t* h) { return ThreadList::get_thread_from_java_object(h); }
368 int32_t ThreadList_get_number_of_non_daemon_threads() { return ThreadList::get_number_of_non_daemon_threads(); }
372 * These are local overrides for various environment variables in Emacs.
373 * Please do not remove this and leave it at the end of the file, where
374 * Emacs will automagically detect them.
375 * ---------------------------------------------------------------------
378 * indent-tabs-mode: t
382 * vim:noexpandtab:sw=4:ts=4: