* src/threads/posix/thread-posix.cpp (threads_impl_clear_heap_pointers): Added.
* src/threads/thread.hpp: Likewise.
* src/threads/posix/thread-posix.hpp: Added flag is_in_active_list.
* src/threads/threadlist.cpp, src/threads/threadlist.hpp: Take thread list lock
for all thread list operations.
(deactivate_thread): Added.
* src/threads/thread-classpath.cpp: Adapted to lock change.
t->index = 0;
t->flags = 0;
t->state = 0;
+ t->is_in_active_list = false;
t->tid = 0;
#endif
}
+void threads_impl_clear_heap_pointers(threadobject *t)
+{
+ t->object = 0;
+ t->flc_object = 0;
+}
/* threads_impl_preinit ********************************************************
/* src/threads/posix/thread-posix.hpp - POSIX thread functions
- Copyright (C) 1996-2005, 2006, 2007, 2008
+ Copyright (C) 1996-2011
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
s4 index; /* thread index, starting with 1 */
u4 flags; /* flag field */
u4 state; /* state field */
+ bool is_in_active_list; /* for debugging only */
pthread_t tid; /* pthread id */
assert(jlvmt.get_handle() != NULL);
assert(jlvmt.get_vmdata() == NULL);
- ThreadList::lock();
jlvmt.set_vmdata(t);
- ThreadList::unlock();
}
void ThreadRuntimeClasspath::print_thread_name(const java_lang_Thread& jlt, FILE *stream)
#include "vm/jit/builtin.hpp"
#include "vm/class.hpp"
#include "vm/exceptions.hpp"
+#include "vm/finalizer.hpp"
#include "vm/globals.hpp"
#include "vm/javaobjects.hpp"
#include "vm/method.hpp"
thread_set_object(t, NULL);
- /* Release the thread. */
-
- ThreadList::release_thread(t);
+ ThreadList::deactivate_thread(t);
}
*******************************************************************************/
+static void thread_cleanup_finalizer(java_handle_t *h, void *data)
+{
+ threadobject *t = reinterpret_cast<threadobject*>(data);
+ ThreadList::release_thread(t, false);
+}
+
bool threads_thread_start_internal(utf *name, functionptr f)
{
threadobject *t;
/* Create the Java thread object. */
- if (!thread_create_object(t, javastring_new(name), threadgroup_system))
+ if (!thread_create_object(t, javastring_new(name), threadgroup_system)) {
+ ThreadList::release_thread(t, true);
return false;
+ }
+
+ Finalizer::attach_custom_finalizer(thread_get_object(t), thread_cleanup_finalizer, t);
/* Start the thread. */
ThreadRuntime::setup_thread_vmdata(jlt, t);
+ Finalizer::attach_custom_finalizer(thread_get_object(t), thread_cleanup_finalizer, t);
+
/* Start the thread. Don't pass a function pointer (NULL) since
we want Thread.run()V here. */
/* Create the Java thread object. */
- if (!thread_create_object(t, name, group))
+ if (!thread_create_object(t, name, group)) {
+ ThreadList::release_thread(t, true);
return false;
+ }
/* The thread is completely initialized. */
{
/* Set the state inside a lock. */
- ThreadList::lock();
-
thread_set_state(t, THREAD_STATE_TERMINATED);
DEBUGTHREADS("is TERMINATED", t);
-
- ThreadList::unlock();
}
void thread_handle_set_priority(java_handle_t *th, int priority)
{
- ThreadListLocker l;
-
threadobject *t = thread_get_thread(th);
/* For GNU classpath, this should not happen, because both
setPriority() and start() are synchronized. */
bool thread_handle_is_interrupted(java_handle_t *th)
{
- ThreadListLocker l;
-
threadobject *t = thread_get_thread(th);
return t ? thread_is_interrupted(t) : false;
}
void thread_handle_interrupt(java_handle_t *th)
{
- ThreadListLocker l;
-
threadobject *t = thread_get_thread(th);
/* For GNU classpath, this should not happen, because both
interrupt() and start() are synchronized. */
int thread_handle_get_state(java_handle_t *th)
{
- ThreadListLocker l;
-
threadobject *t = thread_get_thread(th);
return t ? cacaothread_get_state(t) : THREAD_STATE_NEW;
}
void threads_impl_thread_clear(threadobject *t);
void threads_impl_thread_reuse(threadobject *t);
+void threads_impl_clear_heap_pointers(threadobject *t);
void threads_impl_thread_start(threadobject *thread, functionptr f);
void threads_yield(void);
/**
- * Return a free thread object. Caller must hold the thread list lock.
+ * Return a free thread object.
*
* @return free thread object or NULL if none available
*/
{
threadobject* t = NULL;
+ lock();
+
// Do we have free threads in the free-list?
if (_free_thread_list.empty() == false) {
// Yes, get the index and remove it from the free list.
_free_thread_list.remove(t);
}
+ unlock();
+
return t;
}
/**
- * Return a free thread index. Caller must hold the thread list lock.
+ * Return a free thread index.
*
* @return free thread index
*/
{
int32_t index;
+ lock();
+
// Do we have free indexes in the free-list?
if (_free_index_list.empty() == false) {
// Yes, get the index and remove it from the free list.
index = _active_thread_list.size() + 1;
}
+ unlock();
+
return index;
}
return NULL;
}
+void ThreadList::deactivate_thread(threadobject *t)
+{
+ ThreadListLocker lock;
+ remove_from_active_thread_list(t);
+ threads_impl_clear_heap_pointers(t); // allow it to be garbage collected
+}
/**
* Release the thread.
*
* @return free thread index
*/
-void ThreadList::release_thread(threadobject* t)
+void ThreadList::release_thread(threadobject* t, bool needs_deactivate)
{
lock();
- // Move thread from active thread list to free thread list.
- remove_from_active_thread_list(t);
+ if (needs_deactivate)
+ // Move thread from active thread list to free thread list.
+ remove_from_active_thread_list(t);
+ else
+ assert(!t->is_in_active_list);
+
add_to_free_thread_list(t);
// Add thread index to free index list.
void ThreadList_lock() { ThreadList::lock(); }
void ThreadList_unlock() { ThreadList::unlock(); }
void ThreadList_dump_threads() { ThreadList::dump_threads(); }
- void ThreadList_release_thread(threadobject* t) { ThreadList::release_thread(t); }
threadobject* ThreadList_get_free_thread() { return ThreadList::get_free_thread(); }
int32_t ThreadList_get_free_thread_index() { return ThreadList::get_free_thread_index(); }
void ThreadList_add_to_active_thread_list(threadobject* t) { ThreadList::add_to_active_thread_list(t); }
static int32_t get_free_thread_index();
static threadobject* get_thread_by_index(int32_t index);
static threadobject* get_thread_from_java_object(java_handle_t* h);
- static void release_thread(threadobject* t);
+ static void release_thread(threadobject* t, bool needs_deactivate);
+ static void deactivate_thread(threadobject *t);
// Thread listing methods.
static void get_active_threads(List<threadobject*> &list);
{
lock();
_active_thread_list.push_back(t);
+ t->is_in_active_list = true;
// Update counter variables.
if ((t->flags & THREAD_FLAG_INTERNAL) == 0) {
inline void ThreadList::remove_from_active_thread_list(threadobject* t)
{
+ lock();
_active_thread_list.remove(t);
+ t->is_in_active_list = false;
// Update counter variables.
if ((t->flags & THREAD_FLAG_INTERNAL) == 0) {
_number_of_active_java_threads--;
}
+ unlock();
}
inline void ThreadList::add_to_free_thread_list(threadobject* t)
{
+ lock();
_free_thread_list.push_back(t);
+ unlock();
}
inline void ThreadList::add_to_free_index_list(int32_t index)
{
+ lock();
_free_index_list.push_back(index);
+ unlock();
}
inline threadobject* ThreadList::get_main_thread()
{
- return _active_thread_list.front();
+ lock();
+ threadobject *r = _active_thread_list.front();
+ unlock();
+ return r;
}
inline int32_t ThreadList::get_number_of_active_threads()
{
- return _active_thread_list.size();
+ lock();
+ int32_t size = _active_thread_list.size();
+ unlock();
+ return size;
}
inline int32_t ThreadList::get_number_of_started_java_threads()
{
- return _number_of_started_java_threads;
+ lock();
+ int32_t num = _number_of_started_java_threads;
+ unlock();
+ return num;
}
inline int32_t ThreadList::get_number_of_active_java_threads()
{
- return _number_of_active_java_threads;
+ lock();
+ int32_t num = _number_of_active_java_threads;
+ unlock();
+ return num;
}
inline int32_t ThreadList::get_peak_of_active_java_threads()
{
- return _peak_of_active_java_threads;
+ lock();
+ int32_t num = _peak_of_active_java_threads;
+ unlock();
+ return num;
}
inline void ThreadList::reset_peak_of_active_java_threads()
{
+ lock();
_peak_of_active_java_threads = _number_of_active_java_threads;
+ unlock();
}
#else
void ThreadList_lock();
void ThreadList_unlock();
void ThreadList_dump_threads();
-void ThreadList_release_thread(threadobject* t);
threadobject* ThreadList_get_free_thread();
int32_t ThreadList_get_free_thread_index();
void ThreadList_add_to_active_thread_list(threadobject* t);