mirror of git://gcc.gnu.org/git/gcc.git
libstdc++: Add std::recursive_timed_mutex tests for negative timeouts [PR116586]
Add tests to show that std::recursive_timed_mutex::try_lock_until and std::recursive_timed_mutex::try_lock_for correctly handle negative timeouts. libstdc++-v3/ChangeLog: PR libstdc++/116586 * testsuite/30_threads/recursive_timed_mutex/try_lock_until/116586.cc: New test. Signed-off-by: Mike Crowe <mac@mcrowe.com>
This commit is contained in:
parent
bb96099a8d
commit
9a3ff39d6b
|
@ -0,0 +1,72 @@
|
|||
// { dg-do run { target c++11 } }
|
||||
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <initializer_list>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
namespace chrono = std::chrono;
|
||||
|
||||
// thread.timedmutex.requirements.general:
|
||||
// If abs_time has already passed, the function attempts to obtain
|
||||
// ownership without blocking (as if by calling try_lock()).
|
||||
|
||||
template <typename Clock>
|
||||
void
|
||||
test_absolute(chrono::nanoseconds offset)
|
||||
{
|
||||
std::recursive_timed_mutex mtx;
|
||||
chrono::time_point<Clock> tp(offset);
|
||||
VERIFY(mtx.try_lock_until(tp));
|
||||
|
||||
{
|
||||
// To test failing to lock a recursive mutex we need to try to lock on a
|
||||
// different thread.
|
||||
auto t = std::async(std::launch::async, [&mtx, tp]() {
|
||||
VERIFY(!mtx.try_lock_until(tp));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// The type of clock used for the actual wait depends on whether
|
||||
// _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK is defined. We might as well just test
|
||||
// both steady_clock and system_clock.
|
||||
template <typename Clock>
|
||||
void
|
||||
test_relative(chrono::nanoseconds offset)
|
||||
{
|
||||
std::recursive_timed_mutex mtx;
|
||||
const auto d = -Clock::now().time_since_epoch() + offset;
|
||||
VERIFY(mtx.try_lock_for(d));
|
||||
|
||||
{
|
||||
// To test failing to lock a recursive mutex we need to try to lock on a
|
||||
// different thread.
|
||||
auto t = std::async(std::launch::async, [&mtx, d]() {
|
||||
VERIFY(!mtx.try_lock_for(d));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Try once with an offset that ought to result in tv_sec == 0, tv_nsec < 0
|
||||
// and one with an offset that ought to result in tv_sec < 0, tv_nsec == 0
|
||||
// for the absolute calls at least. It's not really possible to arrange for
|
||||
// the relative calls to have tv_nsec == 0 due to time advancing.
|
||||
for (const chrono::nanoseconds offset : {
|
||||
// tv_sec == 0, tv_nsec == 0
|
||||
chrono::nanoseconds{0},
|
||||
// tv_sec == 0, tv_nsec < 0
|
||||
chrono::duration_cast<chrono::nanoseconds>(chrono::milliseconds{-10}),
|
||||
// tv_sec < 0
|
||||
chrono::duration_cast<chrono::nanoseconds>(chrono::seconds{-10})
|
||||
}) {
|
||||
test_absolute<chrono::system_clock>(offset);
|
||||
test_relative<chrono::system_clock>(offset);
|
||||
|
||||
test_absolute<chrono::steady_clock>(offset);
|
||||
test_relative<chrono::steady_clock>(offset);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue