summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/os/os_time.c41
-rw-r--r--src/gallium/auxiliary/os/os_time.h26
2 files changed, 67 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c
index bd09452df16..3d2e4167222 100644
--- a/src/gallium/auxiliary/os/os_time.c
+++ b/src/gallium/auxiliary/os/os_time.c
@@ -96,6 +96,26 @@ os_time_sleep(int64_t usecs)
#endif
+int64_t
+os_time_get_absolute_timeout(uint64_t timeout)
+{
+ int64_t time, abs_timeout;
+
+ /* Also check for the type upper bound. */
+ if (timeout == PIPE_TIMEOUT_INFINITE || timeout > INT64_MAX)
+ return PIPE_TIMEOUT_INFINITE;
+
+ time = os_time_get_nano();
+ abs_timeout = time + (int64_t)timeout;
+
+ /* Check for overflow. */
+ if (abs_timeout < time)
+ return PIPE_TIMEOUT_INFINITE;
+
+ return abs_timeout;
+}
+
+
bool
os_wait_until_zero(volatile int *var, uint64_t timeout)
{
@@ -128,3 +148,24 @@ os_wait_until_zero(volatile int *var, uint64_t timeout)
return true;
}
}
+
+
+bool
+os_wait_until_zero_abs_timeout(volatile int *var, int64_t timeout)
+{
+ if (!p_atomic_read(var))
+ return true;
+
+ if (timeout == PIPE_TIMEOUT_INFINITE)
+ return os_wait_until_zero(var, PIPE_TIMEOUT_INFINITE);
+
+ while (p_atomic_read(var)) {
+ if (os_time_get_nano() >= timeout)
+ return false;
+
+#if defined(PIPE_OS_UNIX)
+ sched_yield();
+#endif
+ }
+ return true;
+}
diff --git a/src/gallium/auxiliary/os/os_time.h b/src/gallium/auxiliary/os/os_time.h
index 2989af10fe2..21979a72ac5 100644
--- a/src/gallium/auxiliary/os/os_time.h
+++ b/src/gallium/auxiliary/os/os_time.h
@@ -95,6 +95,17 @@ os_time_timeout(int64_t start,
/**
+ * Convert a relative timeout in nanoseconds into an absolute timeout,
+ * in other words, it returns current time + timeout.
+ * os_time_get_nano() must be monotonic.
+ * PIPE_TIMEOUT_INFINITE is passed through unchanged. If the calculation
+ * overflows, PIPE_TIMEOUT_INFINITE is returned.
+ */
+int64_t
+os_time_get_absolute_timeout(uint64_t timeout);
+
+
+/**
* Wait until the variable at the given memory location is zero.
*
* \param var variable
@@ -105,6 +116,21 @@ os_time_timeout(int64_t start,
bool
os_wait_until_zero(volatile int *var, uint64_t timeout);
+
+/**
+ * Wait until the variable at the given memory location is zero.
+ * The timeout is the absolute time when the waiting should stop. If it is
+ * less than or equal to the current time, it only returns the status and
+ * doesn't wait. PIPE_TIME_INFINITE waits forever. This requires that
+ * os_time_get_nano is monotonic.
+ *
+ * \param var variable
+ * \param timeout the time in ns when the waiting should stop
+ * \return true if the variable is zero
+ */
+bool
+os_wait_until_zero_abs_timeout(volatile int *var, int64_t timeout);
+
#ifdef __cplusplus
}
#endif