summaryrefslogtreecommitdiff
path: root/src/vulkan
diff options
context:
space:
mode:
authorFaith Ekstrand <faith.ekstrand@collabora.com>2024-06-26 15:39:41 -0500
committerMarge Bot <emma+marge@anholt.net>2024-07-08 22:09:06 +0000
commit4f89af37234026003520d40fee4568788050eb05 (patch)
tree9171aac253c92e62b5a03b3122daea2e6d6d4004 /src/vulkan
parent6aaf6d090c25b436cbd983549a871f48733b1d97 (diff)
vulkan: Use u_cnd_monotonic for vk_sync_timeline
The code we had for handling this with c11 cnd_t was gross. Let's use a primitive that actually works. Reviewed-by: Derek Foreman <derek.foreman@collabora.com> Reviewed-by: Tatsuyuki Ishi <ishitatsuyuki@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29924>
Diffstat (limited to 'src/vulkan')
-rw-r--r--src/vulkan/runtime/vk_sync_timeline.c46
-rw-r--r--src/vulkan/runtime/vk_sync_timeline.h2
2 files changed, 12 insertions, 36 deletions
diff --git a/src/vulkan/runtime/vk_sync_timeline.c b/src/vulkan/runtime/vk_sync_timeline.c
index d2d712daa84..831aeaa6d5b 100644
--- a/src/vulkan/runtime/vk_sync_timeline.c
+++ b/src/vulkan/runtime/vk_sync_timeline.c
@@ -69,7 +69,7 @@ vk_sync_timeline_init(struct vk_device *device,
if (ret != thrd_success)
return vk_errorf(device, VK_ERROR_UNKNOWN, "mtx_init failed");
- ret = cnd_init(&timeline->cond);
+ ret = u_cnd_monotonic_init(&timeline->cond);
if (ret != thrd_success) {
mtx_destroy(&timeline->mutex);
return vk_errorf(device, VK_ERROR_UNKNOWN, "cnd_init failed");
@@ -102,7 +102,7 @@ vk_sync_timeline_finish(struct vk_device *device,
vk_free(&device->alloc, point);
}
- cnd_destroy(&timeline->cond);
+ u_cnd_monotonic_destroy(&timeline->cond);
mtx_destroy(&timeline->mutex);
}
@@ -304,7 +304,7 @@ vk_sync_timeline_point_install(struct vk_device *device,
point->pending = true;
list_addtail(&point->link, &timeline->pending_points);
- int ret = cnd_broadcast(&timeline->cond);
+ int ret = u_cnd_monotonic_broadcast(&timeline->cond);
mtx_unlock(&timeline->mutex);
@@ -381,7 +381,7 @@ vk_sync_timeline_signal_locked(struct vk_device *device,
assert(timeline->highest_pending == timeline->highest_past);
timeline->highest_pending = timeline->highest_past = value;
- int ret = cnd_broadcast(&timeline->cond);
+ int ret = u_cnd_monotonic_broadcast(&timeline->cond);
if (ret == thrd_error)
return vk_errorf(device, VK_ERROR_UNKNOWN, "cnd_broadcast failed");
@@ -428,44 +428,20 @@ vk_sync_timeline_wait_locked(struct vk_device *device,
enum vk_sync_wait_flags wait_flags,
uint64_t abs_timeout_ns)
{
+ struct timespec abs_timeout_ts;
+ timespec_from_nsec(&abs_timeout_ts, abs_timeout_ns);
+
/* Wait on the queue_submit condition variable until the timeline has a
* time point pending that's at least as high as wait_value.
*/
- uint64_t now_ns = os_time_get_nano();
while (timeline->highest_pending < wait_value) {
- if (now_ns >= abs_timeout_ns)
+ int ret = u_cnd_monotonic_timedwait(&timeline->cond, &timeline->mutex,
+ &abs_timeout_ts);
+ if (ret == thrd_timedout)
return VK_TIMEOUT;
- int ret;
- if (abs_timeout_ns >= INT64_MAX) {
- /* Common infinite wait case */
- ret = cnd_wait(&timeline->cond, &timeline->mutex);
- } else {
- /* This is really annoying. The C11 threads API uses CLOCK_REALTIME
- * while all our absolute timeouts are in CLOCK_MONOTONIC. Best
- * thing we can do is to convert and hope the system admin doesn't
- * change the time out from under us.
- */
- uint64_t rel_timeout_ns = abs_timeout_ns - now_ns;
-
- struct timespec now_ts, abs_timeout_ts;
- timespec_get(&now_ts, TIME_UTC);
- if (timespec_add_nsec(&abs_timeout_ts, &now_ts, rel_timeout_ns)) {
- /* Overflowed; may as well be infinite */
- ret = cnd_wait(&timeline->cond, &timeline->mutex);
- } else {
- ret = cnd_timedwait(&timeline->cond, &timeline->mutex,
- &abs_timeout_ts);
- }
- }
- if (ret == thrd_error)
+ if (ret != thrd_success)
return vk_errorf(device, VK_ERROR_UNKNOWN, "cnd_timedwait failed");
-
- /* We don't trust the timeout condition on cnd_timedwait() because of
- * the potential clock issues caused by using CLOCK_REALTIME. Instead,
- * update now_ns, go back to the top of the loop, and re-check.
- */
- now_ns = os_time_get_nano();
}
if (wait_flags & VK_SYNC_WAIT_PENDING)
diff --git a/src/vulkan/runtime/vk_sync_timeline.h b/src/vulkan/runtime/vk_sync_timeline.h
index 5604b9cfcfc..d4692249827 100644
--- a/src/vulkan/runtime/vk_sync_timeline.h
+++ b/src/vulkan/runtime/vk_sync_timeline.h
@@ -80,7 +80,7 @@ struct vk_sync_timeline {
struct vk_sync sync;
mtx_t mutex;
- cnd_t cond;
+ struct u_cnd_monotonic cond;
uint64_t highest_past;
uint64_t highest_pending;