X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fthreads%2Fthread.cpp;h=7fd0205e2a0efc69aea69e789d8109bc9a745bbe;hb=642883f832867bf2fcb70aa702a68ba825c7118d;hp=1579fd4e1ed42269625109f877913ef3f1a9e67e;hpb=8c6bb03b79a31fcdb02e2331a91a928d558c2845;p=cacao.git diff --git a/src/threads/thread.cpp b/src/threads/thread.cpp index 1579fd4e1..7fd0205e2 100644 --- a/src/threads/thread.cpp +++ b/src/threads/thread.cpp @@ -80,7 +80,7 @@ bool threads_pthreads_implementation_nptl; 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 ************************************************************* @@ -138,7 +138,7 @@ void threads_preinit(void) /* 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. */ @@ -146,9 +146,8 @@ void threads_preinit(void) 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. */ @@ -440,7 +439,7 @@ static void thread_create_initial_thread(void) *******************************************************************************/ -static threadobject *thread_new(void) +static threadobject *thread_new(int32_t flags) { int32_t index; threadobject *t; @@ -509,7 +508,7 @@ static threadobject *thread_new(void) 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) @@ -578,9 +577,7 @@ bool threads_thread_start_internal(utf *name, functionptr f) /* 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. */ @@ -624,11 +621,7 @@ void threads_thread_start(java_handle_t *object) /* 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? */ @@ -654,7 +647,9 @@ void threads_thread_start(java_handle_t *object) 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) @@ -708,11 +703,7 @@ bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon) /* 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; @@ -1018,17 +1009,11 @@ static inline void thread_set_state(threadobject *t, int state) 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(); } @@ -1043,17 +1028,11 @@ void thread_set_state_runnable(threadobject *t) 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(); } @@ -1069,17 +1048,11 @@ void thread_set_state_waiting(threadobject *t) 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(); } @@ -1094,17 +1067,11 @@ void thread_set_state_timed_waiting(threadobject *t) 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(); } @@ -1119,17 +1086,11 @@ void thread_set_state_parked(threadobject *t) 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(); } @@ -1164,6 +1125,10 @@ void thread_set_state_terminated(threadobject *t) 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) @@ -1225,6 +1190,118 @@ bool threads_thread_is_alive(threadobject *t) 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.