* src/threads/thread.cpp: Use a finalizer to remove dead threads.
[cacao.git] / src / threads / threadlist.hpp
index 5fb28c54bfc30abced82ec84271ea4f78ec12761..76cd7c5538f5dcc58ad80db775337bdf53e078fb 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/threadlist.hpp - different thread-lists
 
-   Copyright (C) 2008
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #include "toolbox/list.hpp"
 
+#include "vm/global.h"
+
 
 /* ThreadList *****************************************************************/
 
 #ifdef __cplusplus
 
-using std::list;
-
 class ThreadList {
 private:
        static Mutex               _mutex;              // a mutex for all thread lists
 
-       static list<threadobject*> _active_thread_list; // list of active threads
-       static list<threadobject*> _free_thread_list;   // list of free threads
-       static list<int32_t>       _free_index_list;    // list of free thread indexes
+       static List<threadobject*> _active_thread_list; // list of active threads
+       static List<threadobject*> _free_thread_list;   // list of free threads
+       static List<int32_t>       _free_index_list;    // list of free thread indexes
 
+       // Thread counters visible to Java.
+       static int32_t             _number_of_started_java_threads;
+       static int32_t             _number_of_active_java_threads;
+       static int32_t             _peak_of_active_java_threads;
+
+       // Thread counters for internal usage.
        static int32_t             _number_of_non_daemon_threads;
 
-       static inline void          remove_from_active_thread_list(threadobject* t);
-       static inline void          add_to_free_thread_list(threadobject* t);
-       static inline void          add_to_free_index_list(int32_t index);
+       static void                 remove_from_active_thread_list(threadobject* t);
+       static void                 add_to_free_thread_list(threadobject* t);
+       static void                 add_to_free_index_list(int32_t index);
+
+private:
+       // Comparator class.
+       class comparator : public std::binary_function<threadobject*, int32_t, bool> {
+       public:
+               bool operator() (const threadobject* t, const int32_t index) const
+               {
+                       return (t->index == index);
+               }
+       };
 
 public:
-       static inline void          lock()   { _mutex.lock(); }
-       static inline void          unlock() { _mutex.unlock(); }
+       static void                 lock()   { _mutex.lock(); }
+       static void                 unlock() { _mutex.unlock(); }
 
-       // TODO make private
-       static inline void          add_to_active_thread_list(threadobject* t);
+       static void                 add_to_active_thread_list(threadobject* t);
 
-       static void                 dump_threads();
-       static inline threadobject* get_main_thread();
+       // Thread management methods.
+       static threadobject*        get_main_thread();
        static threadobject*        get_free_thread();
        static int32_t              get_free_thread_index();
-       static int32_t              get_number_of_non_daemon_threads();
        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);
+       static void                 get_active_java_threads(List<threadobject*> &list);
+
+       // Thread counting methods visible to Java.
+       static int32_t              get_number_of_started_java_threads();
+       static int32_t              get_number_of_active_java_threads();
+       static int32_t              get_number_of_daemon_java_threads();
+       static int32_t              get_peak_of_active_java_threads();
+       static void                 reset_peak_of_active_java_threads();
+
+       // Thread counting methods for internal use.
+       static int32_t              get_number_of_active_threads();
+       static int32_t              get_number_of_non_daemon_threads();
+
+       // Debugging methods.
+       static void                 dump_threads();
+};
+
+struct ThreadListLocker {
+       ThreadListLocker()  { ThreadList::lock(); }
+       ~ThreadListLocker()  { ThreadList::unlock(); }
 };
 
 
 inline void ThreadList::add_to_active_thread_list(threadobject* t)
 {
+       lock();
        _active_thread_list.push_back(t);
+       t->is_in_active_list = true;
+
+       // Update counter variables.
+       if ((t->flags & THREAD_FLAG_INTERNAL) == 0) {
+               _number_of_started_java_threads++;
+               _number_of_active_java_threads++;
+               _peak_of_active_java_threads = MAX(_peak_of_active_java_threads, _number_of_active_java_threads);
+       }
+       unlock();
 }
 
 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()
+{
+       lock();
+       int32_t size = _active_thread_list.size();
+       unlock();
+       return size;
+}
+
+inline int32_t ThreadList::get_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()
+{
+       lock();
+       int32_t num = _number_of_active_java_threads;
+       unlock();
+       return num;
+}
+
+inline int32_t ThreadList::get_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
@@ -105,7 +207,6 @@ typedef struct ThreadList ThreadList;
 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);