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? */
assert(jlvmt.get_handle() != NULL);
assert(jlvmt.get_vmdata() == NULL);
+ ThreadList::lock();
jlvmt.set_vmdata(t);
+ ThreadList::unlock();
#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
/* 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;
void thread_set_state_runnable(threadobject *t)
{
- /* Set the state inside a lock. */
-
- ThreadList::lock();
-
if (t->state != THREAD_STATE_TERMINATED) {
thread_set_state(t, THREAD_STATE_RUNNABLE);
DEBUGTHREADS("is RUNNABLE", t);
}
-
- ThreadList::unlock();
}
void thread_set_state_waiting(threadobject *t)
{
- /* Set the state inside a lock. */
-
- ThreadList::lock();
-
if (t->state != THREAD_STATE_TERMINATED) {
thread_set_state(t, THREAD_STATE_WAITING);
DEBUGTHREADS("is WAITING", t);
}
-
- ThreadList::unlock();
}
void thread_set_state_timed_waiting(threadobject *t)
{
- /* Set the state inside a lock. */
-
- ThreadList::lock();
-
if (t->state != THREAD_STATE_TERMINATED) {
thread_set_state(t, THREAD_STATE_TIMED_WAITING);
DEBUGTHREADS("is TIMED_WAITING", t);
}
-
- ThreadList::unlock();
}
void thread_set_state_parked(threadobject *t)
{
- /* Set the state inside a lock. */
-
- ThreadList::lock();
-
if (t->state != THREAD_STATE_TERMINATED) {
thread_set_state(t, THREAD_STATE_PARKED);
DEBUGTHREADS("is PARKED", t);
}
-
- ThreadList::unlock();
}
void thread_set_state_timed_parked(threadobject *t)
{
- /* Set the state inside a lock. */
-
- ThreadList::lock();
-
if (t->state != THREAD_STATE_TERMINATED) {
thread_set_state(t, THREAD_STATE_TIMED_PARKED);
DEBUGTHREADS("is TIMED_PARKED", t);
}
-
- ThreadList::unlock();
}
RETURN VALUE:
the thread object
+ NOTE:
+ Usage of this function without the thread list lock held is
+ almost certainly a bug.
+
*******************************************************************************/
threadobject *thread_get_thread(java_handle_t *h)
return false;
}
+/* thread_is_interrupted *******************************************************
+
+ Check if the given thread has been interrupted.
+
+ ARGUMENTS:
+ t ... the thread to check
+
+ RETURN VALUE:
+ true, if the given thread had been interrupted
+
+*******************************************************************************/
+
+bool thread_is_interrupted(threadobject *t)
+{
+ /* 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. */
+
+ t->waitmutex->lock();
+ bool interrupted = t->interrupted;
+ t->waitmutex->unlock();
+
+ return interrupted;
+}
+
+
+/* thread_set_interrupted ******************************************************
+
+ Set the interrupted flag to the given value.
+
+ ARGUMENTS:
+ interrupted ... value to set
+
+*******************************************************************************/
+
+void thread_set_interrupted(threadobject *t, bool interrupted)
+{
+ t->waitmutex->lock();
+ t->interrupted = interrupted;
+ t->waitmutex->unlock();
+}
+
+/* thread_handle_set_priority **************************************************
+
+ Calls threads_set_thread_priority for the threadobject associated
+ with the thread indicated by handle th, while holding the thread
+ list lock.
+
+*******************************************************************************/
+
+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. */
+ assert(t != 0);
+ threads_set_thread_priority(t->tid, priority);
+}
+
+/* thread_handle_is_interrupted ************************************************
+
+ Calls thread_is_interrupted for the threadobject associated with
+ the thread indicated by handle th, while holding the thread list
+ lock.
+
+*******************************************************************************/
+
+bool thread_handle_is_interrupted(java_handle_t *th)
+{
+ ThreadListLocker l;
+
+ threadobject *t = thread_get_thread(th);
+ return t ? thread_is_interrupted(t) : false;
+}
+
+/* thread_handle_interrupt *****************************************************
+
+ Calls threads_thread_interrupt for the threadobject associated with
+ the thread indicated by handle th, while holding the thread list
+ lock.
+
+*******************************************************************************/
+
+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. */
+ assert(t != 0);
+ threads_thread_interrupt(t);
+}
+
+/* thread_handle_get_state *****************************************************
+
+ Calls cacaothread_get_state for the threadobject associated with
+ the thread indicated by handle th, while holding the thread list
+ lock.
+
+*******************************************************************************/
+
+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;
+}
+
/*
* These are local overrides for various environment variables in Emacs.