summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/c++11/futex.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/src/c++11/futex.cc')
-rw-r--r--libstdc++-v3/src/c++11/futex.cc36
1 files changed, 22 insertions, 14 deletions
diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index c2b2d32e8c4..15959cebee5 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -51,6 +51,8 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ using __gnu_cxx::__int_traits;
+
namespace
{
std::atomic<bool> futex_clock_realtime_unavailable;
@@ -74,10 +76,10 @@ namespace
auto rel_s = abs_s.count() - now_s;
// Avoid overflows
- if (rel_s > __gnu_cxx::__int_traits<time_t>::__max)
- rel_s = __gnu_cxx::__int_traits<time_t>::__max;
- else if (rel_s < __gnu_cxx::__int_traits<time_t>::__min)
- rel_s = __gnu_cxx::__int_traits<time_t>::__min;
+ if (rel_s > __int_traits<time_t>::__max) [[unlikely]]
+ rel_s = __int_traits<time_t>::__max;
+ else if (rel_s < __int_traits<time_t>::__min) [[unlikely]]
+ rel_s = __int_traits<time_t>::__min;
// Convert the absolute timeout value to a relative timeout
rt.tv_sec = rel_s;
@@ -111,14 +113,17 @@ namespace
{
if (!futex_clock_realtime_unavailable.load(std::memory_order_relaxed))
{
- struct timespec rt;
- rt.tv_sec = __s.count();
- rt.tv_nsec = __ns.count();
-
// futex sets errno=EINVAL for absolute timeouts before the epoch.
- if (__builtin_expect(rt.tv_sec < 0, false))
+ if (__s.count() < 0)
return false;
+ struct timespec rt;
+ if (__s.count() > __int_traits<time_t>::__max) [[unlikely]]
+ rt.tv_sec = __int_traits<time_t>::__max;
+ else
+ rt.tv_sec = __s.count();
+ rt.tv_nsec = __ns.count();
+
if (syscall (SYS_futex, __addr,
futex_wait_bitset_op | futex_clock_realtime_flag,
__val, &rt, nullptr, futex_bitset_match_any) == -1)
@@ -184,14 +189,17 @@ namespace
{
if (!futex_clock_monotonic_unavailable.load(std::memory_order_relaxed))
{
- struct timespec rt;
- rt.tv_sec = __s.count();
- rt.tv_nsec = __ns.count();
-
// futex sets errno=EINVAL for absolute timeouts before the epoch.
- if (__builtin_expect(rt.tv_sec < 0, false))
+ if (__s.count() < 0) [[unlikely]]
return false;
+ struct timespec rt;
+ if (__s.count() > __int_traits<time_t>::__max) [[unlikely]]
+ rt.tv_sec = __int_traits<time_t>::__max;
+ else
+ rt.tv_sec = __s.count();
+ rt.tv_nsec = __ns.count();
+
if (syscall (SYS_futex, __addr,
futex_wait_bitset_op | futex_clock_monotonic_flag,
__val, &rt, nullptr, futex_bitset_match_any) == -1)