#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
-# if defined(ENABLE_GC_BOEHM)
+
+#if defined(__LINUX__)
+# define GC_LINUX_THREADS
+#elif defined(__IRIX__)
+# define GC_IRIX_THREADS
+#elif defined(__DARWIN__)
+# define GC_DARWIN_THREADS
+#endif
+
+#if defined(ENABLE_GC_BOEHM)
/* We need to include Boehm's gc.h here because it overrides
pthread_create and friends. */
-# include "mm/boehm-gc/include/gc.h"
-# endif
+# include "mm/boehm-gc/include/gc.h"
+#endif
#if defined(ENABLE_JVMTI)
#include "native/jvmti/cacaodbg.h"
t->interrupted = false;
t->signaled = false;
- t->sleeping = false;
t->suspended = false;
t->suspend_reason = 0;
java_handle_t *o;
functionptr function;
+#if defined(ENABLE_GC_BOEHM)
+# if !defined(__DARWIN__)
+ struct GC_stack_base sb;
+ int result;
+# endif
+#endif
+
#if defined(ENABLE_INTRP)
u1 *intrp_thread_stack;
+#endif
+#if defined(ENABLE_INTRP)
/* create interpreter stack */
if (opt_intrp) {
thread_set_current(t);
+#if defined(ENABLE_GC_BOEHM)
+# if defined(__DARWIN__)
+ // This is currently not implemented in Boehm-GC. Just fail silently.
+# else
+ /* Register the thread with Boehm-GC. This must happen before the
+ thread allocates any memory from the GC heap.*/
+
+ result = GC_get_stack_base(&sb);
+
+ if (result != 0)
+ vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
+
+ GC_register_my_thread(&sb);
+# endif
+#endif
+
/* get the java.lang.Thread object for this thread */
object = (java_lang_Thread *) thread_get_object(t);
/* We ignore the return value. */
- (void) threads_detach_thread(t);
+ (void) thread_detach_current_thread();
/* set ThreadMXBean variables */
}
-/* threads_detach_thread *******************************************************
-
- Detaches the passed thread from the VM. Used in JNI.
-
-*******************************************************************************/
-
-bool threads_detach_thread(threadobject *t)
+/**
+ * Detaches the current thread from the VM.
+ *
+ * @return true on success, false otherwise
+ */
+bool thread_detach_current_thread(void)
{
+ threadobject *t;
bool result;
java_lang_Thread *object;
java_handle_t *o;
methodinfo *m;
#endif
+ t = thread_get_current();
+
+ /* Sanity check. */
+
+ assert(t != NULL);
+
/* If the given thread has already been detached, this operation
is a no-op. */
mutex_lock(&t->waitmutex);
- /* mark us as sleeping */
-
- t->sleeping = true;
-
/* wait on waitcond */
if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
}
}
- t->sleeping = false;
-
/* release the waitmutex */
mutex_unlock(&t->waitmutex);
pthread_kill(thread->tid, SIGHUP);
- if (thread->sleeping)
- pthread_cond_signal(&thread->waitcond);
+ pthread_cond_signal(&thread->waitcond);
thread->interrupted = true;
inline static bool thread_is_interrupted(threadobject *t)
{
- return t->interrupted;
+ bool interrupted;
+
+ /* We need the mutex because classpath will call this function when
+ a blocking system call is interrupted. The mutex ensures that it will
+ see the correct value for the interrupted flag. */
+
+ mutex_lock(&t->waitmutex);
+ interrupted = t->interrupted;
+ mutex_unlock(&t->waitmutex);
+
+ return interrupted;
}
bool threads_thread_start_internal(utf *name, functionptr f);
void threads_thread_start(java_handle_t *object);
-bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+bool thread_detach_current_thread(void);
+
+bool thread_detach_current_external_thread(void);
void thread_fprint_name(threadobject *t, FILE *stream);
void thread_print_info(threadobject *t);