util: Move os_misc to util
[mesa.git] / src / util / u_queue.h
index dfe2153281754dd3398ab8b41edfa08258475608..4e63a76aab2f5255d3a45ee42b7fca64502d8b17 100644 (file)
@@ -38,6 +38,7 @@
 #include "util/futex.h"
 #include "util/list.h"
 #include "util/macros.h"
+#include "util/os_time.h"
 #include "util/u_atomic.h"
 #include "util/u_thread.h"
 
@@ -47,8 +48,9 @@ extern "C" {
 
 #define UTIL_QUEUE_INIT_USE_MINIMUM_PRIORITY      (1 << 0)
 #define UTIL_QUEUE_INIT_RESIZE_IF_FULL            (1 << 1)
+#define UTIL_QUEUE_INIT_SET_FULL_THREAD_AFFINITY  (1 << 2)
 
-#if defined(__GNUC__) && defined(HAVE_FUTEX)
+#if defined(__GNUC__) && defined(HAVE_LINUX_FUTEX_H)
 #define UTIL_QUEUE_FENCE_FUTEX
 #else
 #define UTIL_QUEUE_FENCE_STANDARD
@@ -80,26 +82,6 @@ util_queue_fence_destroy(struct util_queue_fence *fence)
    /* no-op */
 }
 
-static inline void
-util_queue_fence_wait(struct util_queue_fence *fence)
-{
-   uint32_t v = fence->val;
-
-   if (likely(v == 0))
-      return;
-
-   do {
-      if (v != 2) {
-         v = p_atomic_cmpxchg(&fence->val, 1, 2);
-         if (v == 0)
-            return;
-      }
-
-      futex_wait(&fence->val, 2);
-      v = fence->val;
-   } while(v != 0);
-}
-
 static inline void
 util_queue_fence_signal(struct util_queue_fence *fence)
 {
@@ -147,7 +129,6 @@ struct util_queue_fence {
 
 void util_queue_fence_init(struct util_queue_fence *fence);
 void util_queue_fence_destroy(struct util_queue_fence *fence);
-void util_queue_fence_wait(struct util_queue_fence *fence);
 void util_queue_fence_signal(struct util_queue_fence *fence);
 
 /**
@@ -170,6 +151,44 @@ util_queue_fence_is_signalled(struct util_queue_fence *fence)
 }
 #endif
 
+void
+_util_queue_fence_wait(struct util_queue_fence *fence);
+
+static inline void
+util_queue_fence_wait(struct util_queue_fence *fence)
+{
+   if (unlikely(!util_queue_fence_is_signalled(fence)))
+      _util_queue_fence_wait(fence);
+}
+
+bool
+_util_queue_fence_wait_timeout(struct util_queue_fence *fence,
+                               int64_t abs_timeout);
+
+/**
+ * Wait for the fence to be signaled with a timeout.
+ *
+ * \param fence the fence
+ * \param abs_timeout the absolute timeout in nanoseconds, relative to the
+ *                    clock provided by os_time_get_nano.
+ *
+ * \return true if the fence was signaled, false if the timeout occurred.
+ */
+static inline bool
+util_queue_fence_wait_timeout(struct util_queue_fence *fence,
+                              int64_t abs_timeout)
+{
+   if (util_queue_fence_is_signalled(fence))
+      return true;
+
+   if (abs_timeout == (int64_t)OS_TIMEOUT_INFINITE) {
+      _util_queue_fence_wait(fence);
+      return true;
+   }
+
+   return _util_queue_fence_wait_timeout(fence, abs_timeout);
+}
+
 typedef void (*util_queue_execute_func)(void *job, int thread_index);
 
 struct util_queue_job {
@@ -181,7 +200,8 @@ struct util_queue_job {
 
 /* Put this into your context. */
 struct util_queue {
-   const char *name;
+   char name[14]; /* 13 characters = the thread name without the index */
+   mtx_t finish_lock; /* only for util_queue_finish */
    mtx_t lock;
    cnd_t has_queued_cond;
    cnd_t has_space_cond;
@@ -214,6 +234,8 @@ void util_queue_add_job(struct util_queue *queue,
 void util_queue_drop_job(struct util_queue *queue,
                          struct util_queue_fence *fence);
 
+void util_queue_finish(struct util_queue *queue);
+
 int64_t util_queue_get_thread_time_nano(struct util_queue *queue,
                                         unsigned thread_index);