hide internal threads from Java. Also added some comments.
* src/threads/threadlist.cpp (ThreadList::get_active_java_threads): Implemented.
(ThreadList::get_number_of_daemon_java_threads): Likewise.
* src/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.cpp:
Adapted to above changes.
* src/native/vm/openjdk/jvm.cpp (JVM_GetAllThreads): Likewise.
* src/threads/posix/thread-posix.cpp: Removed obsolete counting code.
* src/threads/thread.cpp (thread_new): Counting via threadlist requires that
flags are set during threadobject creation.
* src/vm/global.h (MAX): Defined as macro.
* src/vm/vm.cpp (VM::VM): Remember VM initialization time.
* src/vm/vm.hpp (VM::get_inittime): Returns above time.
# include "native/vm/include/gnu_java_lang_management_VMThreadMXBeanImpl.h"
#endif
+#include "threads/threadlist.hpp"
+
#include "toolbox/logging.hpp"
#include "vm/classcache.hpp"
*/
JNIEXPORT jint JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getPeakThreadCount(JNIEnv *env, jclass clazz)
{
-/* return _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount; */
-#warning Move to C++
- log_println("Java_gnu_java_lang_management_ThreadMXBean_getPeakThreadCount: MOVE TO C++!");
- return 0;
+ return ThreadList::get_peak_of_active_java_threads();
}
*/
JNIEXPORT jlong JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getTotalStartedThreadCount(JNIEnv *env, jclass clazz)
{
-/* return _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount; */
-#warning Move to C++
- log_println("Java_gnu_java_lang_management_ThreadMXBean_getTotalStartedThreadCount: MOVE TO C++!");
- return 0;
+ return ThreadList::get_number_of_started_java_threads();
}
*/
JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_resetPeakThreadCount(JNIEnv *env, jclass clazz)
{
-/* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
-#warning Move to C++
- log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_resetPeakThreadCount: MOVE TO C++!");
+ return ThreadList::reset_peak_of_active_java_threads();
}
} // extern "C"
{
// Get a list of all active threads.
List<threadobject*> active_threads;
- ThreadList::get_active_threads(active_threads);
+ ThreadList::get_active_java_threads(active_threads);
// Allocate array to hold the java.lang.Thread objects.
int32_t length = active_threads.size();
if (m == NULL)
vm_abort("threads_startup_thread: run() method not found in class");
- /* set ThreadMXBean variables */
-
-/* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
-
-/* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
-#warning Move to C++
-
#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
// We need to start the run method of java.lang.VMThread.
(void) vm_call_method(m, h);
}
else {
- /* set ThreadMXBean variables */
-
-/* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
-
-/* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
-/* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
-#warning Move to C++
-
/* call passed function, e.g. finalizer_thread */
(function)();
(void) thread_detach_current_thread();
- /* set ThreadMXBean variables */
-
-/* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--; */
-#warning Move to C++
-
return NULL;
}
static void thread_create_initial_threadgroups(void);
static void thread_create_initial_thread(void);
-static threadobject *thread_new(void);
+static threadobject *thread_new(int32_t flags);
/* threads_preinit *************************************************************
/* Create internal thread data-structure for the main thread. */
- mainthread = thread_new();
+ mainthread = thread_new(THREAD_FLAG_JAVA);
/* The main thread should always have index 1. */
vm_abort("threads_preinit: main thread index not 1: %d != 1",
mainthread->index);
- /* thread is a Java thread and running */
+ /* Thread is already running. */
- mainthread->flags |= THREAD_FLAG_JAVA;
mainthread->state = THREAD_STATE_RUNNABLE;
/* Store the internal thread data-structure in the TSD. */
*******************************************************************************/
-static threadobject *thread_new(void)
+static threadobject *thread_new(int32_t flags)
{
int32_t index;
threadobject *t;
t->index = index;
t->thinlock = Lockword::pre_compute_thinlock(t->index);
- t->flags = 0;
+ t->flags = flags;
t->state = THREAD_STATE_NEW;
#if defined(ENABLE_GC_CACAO)
/* Create internal thread data-structure. */
- t = thread_new();
-
- t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
+ t = thread_new(THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON);
/* The thread is flagged as (non-)daemon thread, we can leave the
mutex. */
/* Create internal thread data-structure. */
- threadobject* t = thread_new();
-
- /* this is a normal Java thread */
-
- t->flags |= THREAD_FLAG_JAVA;
+ threadobject* t = thread_new(THREAD_FLAG_JAVA);
#if defined(ENABLE_JAVASE)
/* Is this a daemon thread? */
/* Create internal thread data structure. */
- t = thread_new();
-
- /* Thread is a Java thread and running. */
-
- t->flags = THREAD_FLAG_JAVA;
+ t = thread_new(THREAD_FLAG_JAVA);
if (isdaemon)
t->flags |= THREAD_FLAG_DAEMON;
/* src/threads/threadlist.cpp - thread list
- Copyright (C) 2008
+ Copyright (C) 2008, 2009
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
List<threadobject*> ThreadList::_free_thread_list; // list of free threads
List<int32_t> ThreadList::_free_index_list; // list of free thread indexes
+int32_t ThreadList::_number_of_started_java_threads;
+int32_t ThreadList::_number_of_active_java_threads;
+int32_t ThreadList::_peak_of_active_java_threads;
int32_t ThreadList::_number_of_non_daemon_threads;
}
+/**
+ * Fills the passed list with all currently active threads which should be
+ * visible to Java. Creating a copy of the thread list here, is the only way
+ * to ensure we do not end up in a dead-lock when iterating over the list.
+ *
+ * @param list list class to be filled
+ */
+void ThreadList::get_active_java_threads(List<threadobject*> &list)
+{
+ // Lock the thread lists.
+ lock();
+
+ // Iterate over all active threads.
+ for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
+ threadobject* t = *it;
+
+ // We skip internal threads.
+ if (t->flags & THREAD_FLAG_INTERNAL)
+ continue;
+
+ list.push_back(t);
+ }
+
+ // Unlock the thread lists.
+ unlock();
+}
+
+
/**
* Return a free thread object.
*
}
+/**
+ * Return the number of daemon threads visible to Java.
+ *
+ * NOTE: This function does a linear-search over the threads list,
+ * because it is only used by the management interface.
+ *
+ * @return number of daemon threads
+ */
+int32_t ThreadList::get_number_of_daemon_java_threads(void)
+{
+ int number = 0;
+
+ // Lock the thread lists.
+ lock();
+
+ // Iterate over all active threads.
+ for (List<threadobject*>::iterator it = _active_thread_list.begin(); it != _active_thread_list.end(); it++) {
+ threadobject* t = *it;
+
+ // We skip internal threads.
+ if (t->flags & THREAD_FLAG_INTERNAL)
+ continue;
+
+ if (thread_is_daemon(t))
+ number++;
+ }
+
+ // Unlock the thread lists.
+ unlock();
+
+ return number;
+}
+
+
/**
* Return the number of non-daemon threads.
*
/* src/threads/threadlist.hpp - different thread-lists
- Copyright (C) 2008
+ Copyright (C) 2008, 2009
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "toolbox/list.hpp"
+#include "vm/global.h"
+
/* ThreadList *****************************************************************/
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 void remove_from_active_thread_list(threadobject* t);
// TODO make private
static void add_to_active_thread_list(threadobject* t);
- static void dump_threads();
- static void get_active_threads(List<threadobject*> &list);
+ // 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);
+
+ // 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 {
inline void ThreadList::add_to_active_thread_list(threadobject* t)
{
_active_thread_list.push_back(t);
+
+ // 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);
+ }
}
inline void ThreadList::remove_from_active_thread_list(threadobject* t)
{
_active_thread_list.remove(t);
+
+ // Update counter variables.
+ if ((t->flags & THREAD_FLAG_INTERNAL) == 0) {
+ _number_of_active_java_threads--;
+ }
}
inline void ThreadList::add_to_free_thread_list(threadobject* t)
return _active_thread_list.front();
}
+inline int32_t ThreadList::get_number_of_active_threads()
+{
+ return _active_thread_list.size();
+}
+
+inline int32_t ThreadList::get_number_of_started_java_threads()
+{
+ return _number_of_started_java_threads;
+}
+
+inline int32_t ThreadList::get_number_of_active_java_threads()
+{
+ return _number_of_active_java_threads;
+}
+
+inline int32_t ThreadList::get_peak_of_active_java_threads()
+{
+ return _peak_of_active_java_threads;
+}
+
+inline void ThreadList::reset_peak_of_active_java_threads()
+{
+ _peak_of_active_java_threads = _number_of_active_java_threads;
+}
+
#else
typedef struct ThreadList ThreadList;
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
+#ifndef MAX
+# define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
/* forward typedefs ***********************************************************/
// Initialization is done, VM is created.
_created = true;
_initializing = false;
-
+
+ // Set the VM inittime.
+ _inittime = builtin_currenttimemillis();
+
// Print the run-time VM configuration after all stuff is set and
// the VM is initialized.
if (opt_PrintConfig)
typeinfo_test();
#endif
- /* set ThreadMXBean variables */
-
-// _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
-// _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
-
-// if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
-// _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
-// _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
-// _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
-#warning Move to C++
-
/* start the main thread */
(void) vm_call_method(m, NULL, oa.get_handle());
bool _created;
bool _exiting;
int64_t _starttime;
+ int64_t _inittime;
// Subsystems.
Properties _properties; ///< Commandline properties.
bool is_created() { return _created; }
bool is_exiting() { return _exiting; }
int64_t get_starttime() { return _starttime; }
+ int64_t get_inittime() { return _inittime; }
Properties& get_properties () { return _properties; }
Recompiler& get_recompiler () { return _recompiler; } // REMOVEME