Added parked/timed_parked states.
[cacao.git] / src / threads / posix / thread-posix.cpp
index 6db5dfdab5e7d79f6b3ade281e7675469e8ce54c..9629b004ef99a50225ed4982ed3f64bde589fd04 100644 (file)
 # include "mm/cacao-gc/gc.h"
 #endif
 
-#include "native/jni.h"
 #include "native/llni.h"
-#include "native/native.h"
+#include "native/native.hpp"
 
 #include "threads/condition.hpp"
-#include "threads/lock-common.h"
+#include "threads/lock.hpp"
 #include "threads/mutex.hpp"
-#include "threads/threadlist.h"
+#include "threads/threadlist.hpp"
 #include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
-#include "vm/builtin.h"
+#include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/options.h"
 #include "vm/signallocal.h"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
 
-#include "vm/jit/asmpart.h"
-
-#include "vmcore/globals.hpp"
-#include "vmcore/javaobjects.hpp"
-#include "vmcore/options.h"
-
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
+#include "vm/jit/asmpart.h"
+
 #if !defined(__DARWIN__)
 # include <semaphore.h>
 #endif
 #endif
 
 
-// FIXME For now we export everything as C functions.
-extern "C" {
-
 #if defined(__DARWIN__)
 /* Darwin has no working semaphore implementation.  This one is taken
    from Boehm-GC. */
@@ -434,33 +429,6 @@ void threads_startworld(void)
 #endif
 
 
-/* threads_impl_thread_init ****************************************************
-
-   Initialize OS-level locking constructs in threadobject.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-void threads_impl_thread_init(threadobject *t)
-{
-       /* initialize the mutex and the condition */
-
-       t->flc_lock = new Mutex();
-       t->flc_cond = new Condition();
-
-       t->waitmutex = new Mutex();
-       t->waitcond = new Condition();
-
-       t->suspendmutex = new Mutex();
-       t->suspendcond = new Condition();
-
-#if defined(ENABLE_TLH)
-       tlh_init(&(t->tlh));
-#endif
-}
-
 /* threads_impl_thread_clear ***************************************************
 
    Clears all fields in threadobject the way an MZERO would have
@@ -511,7 +479,7 @@ void threads_impl_thread_clear(threadobject *t)
        t->es = NULL;
 #endif
 
-       MZERO(&t->dumpinfo, dumpinfo_t, 1);
+       // Simply reuse the existing dump memory.
 }
 
 /* threads_impl_thread_reuse ***************************************************
@@ -1324,7 +1292,7 @@ void threads_join_all_threads(void)
           compare against 1 because the current (main thread) is also a
           non-daemon thread. */
 
-       while (threadlist_get_non_daemons() > 1)
+       while (ThreadList::get_number_of_non_daemon_threads() > 1)
                cond_join->wait(mutex_join);
 
        /* leave join mutex */
@@ -1401,7 +1369,7 @@ static bool threads_current_time_is_earlier_than(const struct timespec *tv)
 
 *******************************************************************************/
 
-static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
+static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
 {
        // Acquire the waitmutex.
        t->waitmutex->lock();
@@ -1410,10 +1378,13 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi
 
        if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
                /* with timeout */
-               while (!t->interrupted && !t->signaled
+               while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
                           && threads_current_time_is_earlier_than(wakeupTime))
                {
-                       thread_set_state_timed_waiting(t);
+                       if (parking)
+                               thread_set_state_timed_parked(t);
+                       else
+                               thread_set_state_timed_waiting(t);
 
                        t->waitcond->timedwait(t->waitmutex, wakeupTime);
 
@@ -1422,8 +1393,11 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi
        }
        else {
                /* no timeout */
-               while (!t->interrupted && !t->signaled) {
-                       thread_set_state_waiting(t);
+               while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
+                       if (parking)
+                               thread_set_state_parked(t);
+                       else
+                               thread_set_state_waiting(t);
 
                        t->waitcond->wait(t->waitmutex);
 
@@ -1431,6 +1405,9 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi
                }
        }
 
+       if (parking)
+               t->park_permit = false;
+
        // Release the waitmutex.
        t->waitmutex->unlock();
 }
@@ -1459,7 +1436,7 @@ void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
 
        /* wait */
 
-       threads_wait_with_timeout(thread, &wakeupTime);
+       threads_wait_with_timeout(thread, &wakeupTime, false);
 }
 
 
@@ -1570,7 +1547,7 @@ void threads_sleep(int64_t millis, int32_t nanos)
        else {
                threads_calc_absolute_time(&wakeupTime, millis, nanos);
 
-               threads_wait_with_timeout(t, &wakeupTime);
+               threads_wait_with_timeout(t, &wakeupTime, false);
 
                interrupted = thread_is_interrupted(t);
 
@@ -1585,6 +1562,47 @@ void threads_sleep(int64_t millis, int32_t nanos)
        }
 }
 
+/**
+ * Park the current thread for the specified amount of time or until a
+ * specified deadline.
+ *
+ * @param absolute Is the time in nanos a deadline or a duration?
+ * @param nanos    Nanoseconds to park (absolute=false)
+ *                 or deadline in milliseconds (absolute=true)
+ */
+void threads_park(bool absolute, int64_t nanos)
+{
+       threadobject    *t;
+       struct timespec  wakeupTime;
+
+       t = thread_get_current();
+
+       if (absolute) {
+               wakeupTime.tv_nsec = 0;
+               wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
+       }
+       else
+               threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
+
+       threads_wait_with_timeout(t, &wakeupTime, true);
+}
+
+/**
+ * Unpark the specified thread.
+ *
+ * @param t The thread to unpark.
+ */
+void threads_unpark(threadobject *t)
+{
+       t->waitmutex->lock();
+
+       t->waitcond->signal();
+
+       t->park_permit = true;
+
+       t->waitmutex->unlock();
+}
+
 
 /* threads_yield ***************************************************************
 
@@ -1609,8 +1627,6 @@ void threads_tlh_remove_frame() {
 
 #endif
 
-} // extern "C"
-
 
 /*
  * These are local overrides for various environment variables in Emacs.