# include "native/include/java_lang_ThreadGroup.h"
#endif
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
# include "native/include/java_lang_VMThread.h"
#endif
#endif
#if !defined(__DARWIN__)
+# include <semaphore.h>
+#endif
# if defined(__LINUX__)
# define GC_LINUX_THREADS
# elif defined(__IRIX__)
# define GC_IRIX_THREADS
+# elif defined(__DARWIN__)
+# define GC_DARWIN_THREADS
# endif
-# include <semaphore.h>
# if defined(ENABLE_GC_BOEHM)
# include "mm/boehm-gc/include/gc.h"
# endif
-#endif
#if defined(ENABLE_JVMTI)
#include "native/jvmti/cacaodbg.h"
sem->value = value;
- mutex_init(&sem->mutex, NULL)
+ mutex_init(&sem->mutex);
if (pthread_cond_init(&sem->cond, NULL) < 0)
return -1;
static int sem_post(sem_t *sem)
{
- mutex_lock(&sem->mutex)
+ mutex_lock(&sem->mutex);
sem->value++;
return -1;
}
- mutex_unlock(&sem->mutex)
+ mutex_unlock(&sem->mutex);
return 0;
}
static int sem_wait(sem_t *sem)
{
- mutex_lock(&sem->mutex)
+ mutex_lock(&sem->mutex);
while (sem->value == 0) {
pthread_cond_wait(&sem->cond, &sem->mutex);
sem->value--;
- mutex_unlock(&sem->mutex)
+ mutex_unlock(&sem->mutex);
return 0;
}
if (pthread_cond_destroy(&sem->cond) < 0)
return -1;
- mutex_destroy(&sem->mutex)
+ mutex_destroy(&sem->mutex);
return 0;
}
static mutex_t mutex_join;
static pthread_cond_t cond_join;
-/* XXX We disable that whole bunch of code until we have the exact-GC
- running. */
-
-#if 1
-
/* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
/* being stopped */
static volatile int stopworldwhere;
+#if defined(ENABLE_GC_CACAO)
+
/* semaphore used for acknowleding thread suspension */
static sem_t suspend_ack;
#if defined(__IRIX__)
static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
#endif
-#endif /* 0 */
+#endif /* ENABLE_GC_CACAO */
/* mutexes used by the fake atomic instructions */
#if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
}
/* XXX We disable that whole bunch of code until we have the exact-GC
- running. */
+ running. Some of it may only be needed by the old Boehm-based
+ suspension handling. */
#if 0
}
#endif
-#endif
-
/* threads_stopworld ***********************************************************
*******************************************************************************/
-#if !defined(DISABLE_GC)
void threads_stopworld(void)
{
#if !defined(__DARWIN__) && !defined(__CYGWIN__)
non-signaled NEW threads can't change their state and execute
code. */
}
-#endif /* !defined(DISABLE_GC) */
/* threads_startworld **********************************************************
*******************************************************************************/
-#if !defined(DISABLE_GC)
void threads_startworld(void)
{
#if !defined(__DARWIN__) && !defined(__CYGWIN__)
unlock_stopworld();
}
+
#endif
vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
#if defined(ENABLE_GC_CACAO)
- /* initialize the GC mutext */
+ /* initialize the GC mutex & suspend semaphore */
mutex_init(&mutex_gc);
+ threads_sem_init(&suspend_ack, 0, 0);
#endif
#if !defined(HAVE___THREAD)
if (result != 0)
vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
#endif
-
- threads_sem_init(&suspend_ack, 0, 0);
}
static void *threads_startup_thread(void *arg)
{
startupinfo *startup;
- threadobject *thread;
+ threadobject *t;
java_lang_Thread *object;
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
java_lang_VMThread *vmt;
#endif
sem_t *psem;
startup = arg;
- thread = startup->thread;
+ t = startup->thread;
function = startup->function;
psem = startup->psem;
threads_sem_wait(startup->psem_first);
#if defined(__DARWIN__)
- thread->mach_thread = mach_thread_self();
+ t->mach_thread = mach_thread_self();
#endif
- /* Store the internal thread data-structure in the TSD. */
+ /* Now that we are in the new thread, we can store the internal
+ thread data-structure in the TSD. */
- thread_set_current(thread);
+ thread_set_current(t);
/* get the java.lang.Thread object for this thread */
- object = (java_lang_Thread *) thread_get_object(thread);
+ object = (java_lang_Thread *) thread_get_object(t);
/* set our priority */
- threads_set_thread_priority(thread->tid, LLNI_field_direct(object, priority));
+ threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
- /* thread is completely initialized */
+ /* Thread is completely initialized. */
- threads_thread_state_runnable(thread);
+ thread_set_state_runnable(t);
/* tell threads_startup_thread that we registered ourselves */
/* CAUTION: *startup becomes invalid with this! */
jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
#endif
- DEBUGTHREADS("starting", thread);
+ DEBUGTHREADS("starting", t);
/* find and run the Thread.run()V method if no other function was passed */
if (function == NULL) {
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
/* We need to start the run method of
java.lang.VMThread. Since this is a final class, we can use
the class object directly. */
c = class_java_lang_VMThread;
-#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
LLNI_class_get(object, c);
#else
# error unknown classpath configuration
_Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
/* we need to start the run method of java.lang.VMThread */
LLNI_field_get_ref(object, vmThread, vmt);
- o = (java_handle_t *) vmt;
+ o = (java_handle_t *) vmt;
-#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
- o = (java_handle_t *) object;
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+ o = (java_handle_t *) object;
#else
# error unknown classpath configuration
#endif
- /* run the thread */
+ /* Run the thread. */
(void) vm_call_method(m, o);
}
(function)();
}
- DEBUGTHREADS("stopping", thread);
+ DEBUGTHREADS("stopping", t);
#if defined(ENABLE_JVMTI)
/* fire thread end event */
/* We ignore the return value. */
- (void) threads_detach_thread(thread);
+ (void) threads_detach_thread(t);
/* set ThreadMXBean variables */
to build the java_lang_Thread_UncaughtExceptionHandler
header file with cacaoh. */
-# if defined(WITH_CLASSPATH_GNU)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
LLNI_field_get_ref(object, exceptionHandler, handler);
-# elif defined(WITH_CLASSPATH_SUN)
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
# endif
if (group != NULL) {
LLNI_class_get(group, c);
-# if defined(WITH_CLASSPATH_GNU)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
m = class_resolveclassmethod(c,
utf_removeThread,
utf_java_lang_Thread__V,
class_java_lang_ThreadGroup,
true);
-# elif defined(WITH_CLASSPATH_SUN)
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
m = class_resolveclassmethod(c,
utf_remove,
utf_java_lang_Thread__V,
if (exceptions_get_exception())
return false;
+
+ /* Reset the threadgroup in the Java thread object (Mauve
+ test: gnu/testlet/java/lang/Thread/getThreadGroup). */
+
+ LLNI_field_set_ref(object, group, NULL);
}
#endif
/* Thread has terminated. */
- threads_thread_state_terminated(t);
+ thread_set_state_terminated(t);
/* Notify all threads waiting on this thread. These are joining
this thread. */
}
+#if defined(ENABLE_GC_CACAO)
+
/* threads_suspend_thread ******************************************************
Suspend the passed thread. Execution stops until the thread
/* TODO: remember dump memory size */
-#if defined(ENABLE_GC_CACAO)
/* inform the GC about the suspension */
if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
}
}
-#endif
/* mark this thread as suspended and remember the PC */
thread->pc = pc;
return true;
}
+#endif
/* threads_join_all_threads ****************************************************
t = THREADOBJECT;
- /* this thread is waiting for all non-daemon threads to exit */
+ /* This thread is waiting for all non-daemon threads to exit. */
- threads_thread_state_waiting(t);
+ thread_set_state_waiting(t);
/* enter join mutex */
while (!t->interrupted && !t->signaled
&& threads_current_time_is_earlier_than(wakeupTime))
{
- threads_thread_state_timed_waiting(t);
+ thread_set_state_timed_waiting(t);
pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
wakeupTime);
- threads_thread_state_runnable(t);
+ thread_set_state_runnable(t);
}
}
else {
/* no timeout */
while (!t->interrupted && !t->signaled) {
- threads_thread_state_waiting(t);
+ thread_set_state_waiting(t);
pthread_cond_wait(&t->waitcond, &t->waitmutex);
- threads_thread_state_runnable(t);
+ thread_set_state_runnable(t);
}
}
}
-/* threads_check_if_interrupted_and_reset **************************************
-
- Check if the current thread has been interrupted and reset the
- interruption flag.
+/* threads_sleep ***************************************************************
- RETURN VALUE:
- true, if the current thread had been interrupted
+ Sleep the current thread for the specified amount of time.
*******************************************************************************/
-bool threads_check_if_interrupted_and_reset(void)
+void threads_sleep(int64_t millis, int32_t nanos)
{
- threadobject *thread;
- bool intr;
-
- thread = THREADOBJECT;
-
- mutex_lock(&thread->waitmutex);
-
- /* get interrupted flag */
-
- intr = thread->interrupted;
-
- /* reset interrupted flag */
-
- thread->interrupted = false;
-
- mutex_unlock(&thread->waitmutex);
-
- return intr;
-}
-
-
-/* threads_thread_has_been_interrupted *****************************************
-
- Check if the given thread has been interrupted
-
- IN:
- t............the thread to check
-
- RETURN VALUE:
- true, if the given thread had been interrupted
-
-*******************************************************************************/
+ threadobject *t;
+ struct timespec wakeupTime;
+ bool interrupted;
-bool threads_thread_has_been_interrupted(threadobject *thread)
-{
- return thread->interrupted;
-}
+ if (millis < 0) {
+/* exceptions_throw_illegalargumentexception("timeout value is negative"); */
+ exceptions_throw_illegalargumentexception();
+ return;
+ }
+ t = thread_get_current();
-/* threads_sleep ***************************************************************
+ if (thread_is_interrupted(t) && !exceptions_get_exception()) {
+ /* Clear interrupted flag (Mauve test:
+ gnu/testlet/java/lang/Thread/interrupt). */
- Sleep the current thread for the specified amount of time.
+ thread_set_interrupted(t, false);
-*******************************************************************************/
+/* exceptions_throw_interruptedexception("sleep interrupted"); */
+ exceptions_throw_interruptedexception();
+ return;
+ }
-void threads_sleep(s8 millis, s4 nanos)
-{
- threadobject *thread;
- struct timespec wakeupTime;
- bool wasinterrupted;
+ threads_calc_absolute_time(&wakeupTime, millis, nanos);
- thread = THREADOBJECT;
+ threads_wait_with_timeout(t, &wakeupTime);
- threads_calc_absolute_time(&wakeupTime, millis, nanos);
+ interrupted = thread_is_interrupted(t);
- threads_wait_with_timeout(thread, &wakeupTime);
+ if (interrupted) {
+ thread_set_interrupted(t, false);
- wasinterrupted = threads_check_if_interrupted_and_reset();
+ /* An other exception could have been thrown
+ (e.g. ThreadDeathException). */
- if (wasinterrupted)
- exceptions_throw_interruptedexception();
+ if (!exceptions_get_exception())
+ exceptions_throw_interruptedexception();
+ }
}