1 /* src/threads/threadlist.cpp - thread list
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 "threads/mutex.hpp"
31 #include "threads/threadlist.hpp"
32 #include "threads/thread.hpp"
34 #include "toolbox/list.hpp"
35 #include "toolbox/logging.h"
40 Mutex ThreadList::_mutex; // a mutex for all thread lists
42 list<threadobject*> ThreadList::_active_thread_list; // list of active threads
43 list<threadobject*> ThreadList::_free_thread_list; // list of free threads
44 list<int32_t> ThreadList::_free_index_list; // list of free thread indexes
46 int32_t ThreadList::_number_of_non_daemon_threads;
50 * Dumps info for all threads running in the VM. This function is
51 * called when SIGQUIT (<ctrl>-\) is sent to the VM.
53 void ThreadList::dump_threads()
55 // XXX we should stop the world here
56 // Lock the thread lists.
59 printf("Full thread dump CACAO "VERSION":\n");
61 // Iterate over all started threads.
62 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
63 threadobject* t = *it;
65 // Ignore threads which are in state NEW.
66 if (t->state == THREAD_STATE_NEW)
69 #if defined(ENABLE_GC_CACAO)
70 /* Suspend the thread. */
71 /* XXX Is the suspend reason correct? */
73 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
74 vm_abort("threads_dump: threads_suspend_thread failed");
77 /* Print thread info. */
83 /* Print trace of thread. */
85 stacktrace_print_of_thread(t);
87 #if defined(ENABLE_GC_CACAO)
88 /* Resume the thread. */
90 if (threads_resume_thread(t) == false)
91 vm_abort("threads_dump: threads_resume_thread failed");
95 // Unlock the thread lists.
101 * Return a free thread object.
103 * @return free thread object or NULL if none available
105 threadobject* ThreadList::get_free_thread()
107 threadobject* t = NULL;
109 // Do we have free threads in the free-list?
110 if (_free_thread_list.empty() == false) {
111 // Yes, get the index and remove it from the free list.
112 threadobject* t = _free_thread_list.front();
113 _free_thread_list.remove(t);
121 * Return a free thread index.
123 * @return free thread index
125 int32_t ThreadList::get_free_thread_index()
129 // Do we have free indexes in the free-list?
130 if (_free_index_list.empty() == false) {
131 // Yes, get the index and remove it from the free list.
132 index = _free_index_list.front();
133 _free_index_list.remove(index);
136 // Get a new the thread index.
137 index = _active_thread_list.size() + 1;
145 * Return the number of non-daemon threads.
147 * NOTE: This function does a linear-search over the threads list,
148 * because it is only used for joining the threads.
150 * @return number of non daemon threads
152 int32_t ThreadList::get_number_of_non_daemon_threads(void)
158 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
159 threadobject* t = *it;
161 if (!thread_is_daemon(t))
172 * Return the thread object with the given index.
174 * @return thread object
176 threadobject* ThreadList::get_thread_by_index(int32_t index)
178 threadobject* t = NULL;
182 for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
185 if (t->state == THREAD_STATE_NEW)
188 if (t->index == index)
199 * Return the Java thread object from the given thread object.
201 * @return Java thread object
203 threadobject* ThreadList::get_thread_from_java_object(java_handle_t* h)
205 List<threadobject*>::iterator it;
211 for (it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
214 LLNI_equals(t->object, h, equal);
229 * Release the thread.
231 * @return free thread index
233 void ThreadList::release_thread(threadobject* t)
237 // Move thread from active thread list to free thread list.
238 remove_from_active_thread_list(t);
239 add_to_free_thread_list(t);
241 // Add thread index to free index list.
242 add_to_free_index_list(t->index);
248 /* C interface functions ******************************************************/
251 void ThreadList_lock() { ThreadList::lock(); }
252 void ThreadList_unlock() { ThreadList::unlock(); }
253 void ThreadList_dump_threads() { ThreadList::dump_threads(); }
254 void ThreadList_release_thread(threadobject* t) { ThreadList::release_thread(t); }
255 threadobject* ThreadList_get_free_thread() { return ThreadList::get_free_thread(); }
256 int32_t ThreadList_get_free_thread_index() { return ThreadList::get_free_thread_index(); }
257 void ThreadList_add_to_active_thread_list(threadobject* t) { ThreadList::add_to_active_thread_list(t); }
258 threadobject* ThreadList_get_thread_by_index(int32_t index) { return ThreadList::get_thread_by_index(index); }
259 threadobject* ThreadList_get_main_thread() { return ThreadList::get_main_thread(); }
260 threadobject* ThreadList_get_thread_from_java_object(java_handle_t* h) { return ThreadList::get_thread_from_java_object(h); }
262 int32_t ThreadList_get_number_of_non_daemon_threads() { return ThreadList::get_number_of_non_daemon_threads(); }
266 * These are local overrides for various environment variables in Emacs.
267 * Please do not remove this and leave it at the end of the file, where
268 * Emacs will automagically detect them.
269 * ---------------------------------------------------------------------
272 * indent-tabs-mode: t
276 * vim:noexpandtab:sw=4:ts=4: