From fd3a0a143509a829f1e5ace9322d035406517991 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Fri, 20 May 2022 14:09:37 -0500 Subject: [PATCH] c/multi: Fix condition var waiting for wait thread. Spurious wakeups happen, have to actually have a condition to check in a loop with the cond var wait. --- src/xrt/compositor/multi/comp_multi_compositor.c | 10 ++++++++-- src/xrt/compositor/multi/comp_multi_private.h | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/xrt/compositor/multi/comp_multi_compositor.c b/src/xrt/compositor/multi/comp_multi_compositor.c index 6794e8949..4cecb016c 100644 --- a/src/xrt/compositor/multi/comp_multi_compositor.c +++ b/src/xrt/compositor/multi/comp_multi_compositor.c @@ -226,6 +226,7 @@ run_func(void *ptr) while (os_thread_helper_is_running_locked(&mc->wait_thread.oth)) { if (mc->wait_thread.xcsem == NULL && mc->wait_thread.xcf == NULL) { + //! @todo what condition should we spin on here to handle spurious wakeups? os_thread_helper_wait_locked(&mc->wait_thread.oth); // Fall through here on stopping to clean up and outstanding waits. } @@ -274,6 +275,8 @@ run_func(void *ptr) mc->wait_thread.waiting = false; if (mc->wait_thread.blocked) { + // Release one thread + mc->wait_thread.blocked = false; os_thread_helper_signal_locked(&mc->wait_thread.oth); } } @@ -289,9 +292,12 @@ wait_for_wait_thread_locked(struct multi_compositor *mc) // Should we wait for the last frame. if (mc->wait_thread.waiting) { COMP_TRACE_IDENT(blocked); + + // OK, wait until the wait thread releases us by setting blocked to false mc->wait_thread.blocked = true; - os_thread_helper_wait_locked(&mc->wait_thread.oth); - mc->wait_thread.blocked = false; + while (mc->wait_thread.blocked) { + os_thread_helper_wait_locked(&mc->wait_thread.oth); + } } } diff --git a/src/xrt/compositor/multi/comp_multi_private.h b/src/xrt/compositor/multi/comp_multi_private.h index 2a07cb47d..a974f3c32 100644 --- a/src/xrt/compositor/multi/comp_multi_private.h +++ b/src/xrt/compositor/multi/comp_multi_private.h @@ -146,7 +146,12 @@ struct multi_compositor //! Is the thread waiting, if so the client should block. bool waiting; - //! Is the client thread blocked, if so it should be woken up. + /*! + * Is the client thread blocked? + * + * Set to true by the client thread, + * cleared by the wait thread to release the client thread. + */ bool blocked; } wait_thread;