I'm thinking of using the following code:
auto now = std::chrono::high_resolution_clock::now();
std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
if(lock.try_lock_until(now + std::chrono::milliseconds(15))
// swap some buffer pointers...
However, it's not clear to me from the documentation if
try_lock_until() is implemented as a busy wait or if the thread will yield/sleep in between tries (which is my desired behavior). Is this the best way to query a lock while minimizing thread resource usage?
The CppReference page for
std::unique_lock::try_lock_until indeed only states it "Blocks until specified
timeout_time has been reached or the lock is acquired". This is not just a shortcoming of the website though. The standard (I used the November 2014 working draft) carefully steers clear of specifying whether a
thread has to
yield while blocking on any kind of
mutex, talking only about acquiring ownership.
std::mutex, for instance, section 18.104.22.168.1 states
If one thread owns a
mutexobject, attempts by another thread to acquire ownership of that object will fail (for
try_lock()) or block (for
lock()) until the owning thread has released ownership with a call to unlock().
No mention of scheduling or
yielding is made at all, though.
Furthermore, even if it did mention
yield explicitly, that wouldn't help that much, as
this_thread::yield (section 30.3.2) merely "Offers the implementation the opportunity to reschedule".
CppReference makes this more concrete, stating
The exact behavior of this function depends on the implementation, in particular on the mechanics of the OS scheduler in use and the state of the system. For example, a first-in-first-out realtime scheduler (SCHED_FIFO in Linux) would suspend the current thread and put it on the back of the queue of the same-priority threads that are ready to run (and if there are no other threads at the same priority, yield has no effect).
So I'm afraid the question of how
try_lock_until is implemented in C++ cannot be answered. Perhaps you can ask a new question targeting a specific platform. For your second question ("Is this the best way to query a lock while minimizing thread resource usage?") the answer is yes, the best option your platform offers should be invoked using this API (though, as T.C. commented,
try_lock_for seems like a better fit).