QWaitCondition/Unix: do check for pthread_condattr_setclock()
Instead of guessing that Apple systems don't have it. Because of this, we properly split the clockid_t constants in qcore_unix_p.h between what the std::chrono::steady_clock uses and what QWaitCondition will use. The difference is on Apple systems and on QNX. Therefore, amends 5642b999754e75a9db3585b97ffbddac761f21b3. Change-Id: Ibf5439b6cb4c332b0f24fffde43452e8ccd4e9c9 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
b6ca35f653
commit
2a7cacb5e3
@ -446,6 +446,20 @@ int main()
|
||||
}
|
||||
")
|
||||
|
||||
# pthread_condattr_setclock
|
||||
qt_config_compile_test(pthread_condattr_setclock
|
||||
LABEL "pthread_condattr_setclock()"
|
||||
LIBRARIES Threads::Threads
|
||||
CODE
|
||||
"#include <pthread.h>
|
||||
#include <time.h>
|
||||
int main()
|
||||
{
|
||||
pthread_condattr_t condattr;
|
||||
return pthread_condattr_setclock(&condattr, CLOCK_REALTIME);
|
||||
}
|
||||
")
|
||||
|
||||
# pthread_timedjoin
|
||||
qt_config_compile_test(pthread_timedjoin
|
||||
LABEL "pthread_timedjoin()"
|
||||
@ -730,6 +744,11 @@ qt_feature("pthread_clockjoin" PRIVATE
|
||||
AUTODETECT UNIX
|
||||
CONDITION UNIX AND QT_FEATURE_thread AND TEST_pthread_clockjoin
|
||||
)
|
||||
qt_feature("pthread_condattr_setclock" PRIVATE
|
||||
LABEL "pthread_condattr_setclock() function"
|
||||
AUTODETECT UNIX
|
||||
CONDITION UNIX AND QT_FEATURE_thread AND TEST_pthread_condattr_setclock
|
||||
)
|
||||
qt_feature("pthread_timedjoin" PRIVATE
|
||||
LABEL "pthread_timedjoin() function"
|
||||
AUTODETECT UNIX
|
||||
|
@ -75,14 +75,12 @@ static inline constexpr clockid_t SteadyClockClockId =
|
||||
#elif defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_CLOCK_MONOTONIC)
|
||||
// libstdc++ falling back to system_clock
|
||||
CLOCK_REALTIME
|
||||
#elif defined(Q_OS_DARWIN)
|
||||
// Darwin lacks pthread_condattr_setclock()
|
||||
CLOCK_REALTIME
|
||||
#elif defined(Q_OS_QNX)
|
||||
// unknown why
|
||||
CLOCK_REALTIME
|
||||
#elif defined(_LIBCPP_VERSION) && defined(Q_OS_DARWIN)
|
||||
// on Apple systems, libc++ uses CLOCK_MONOTONIC_RAW since LLVM 11
|
||||
// https://github.com/llvm/llvm-project/blob/llvmorg-11.0.0/libcxx/src/chrono.cpp#L117-L129
|
||||
CLOCK_MONOTONIC_RAW
|
||||
#elif defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)
|
||||
// both libstdc++ and libc++ do use CLOCK_MONOTONIC
|
||||
// both libstdc++ and libc++ otherwise use CLOCK_MONOTONIC
|
||||
CLOCK_MONOTONIC
|
||||
#else
|
||||
# warning "Unknown C++ Standard Library implementation - code may be sub-optimal"
|
||||
@ -90,6 +88,21 @@ static inline constexpr clockid_t SteadyClockClockId =
|
||||
#endif
|
||||
;
|
||||
|
||||
static inline constexpr clockid_t QWaitConditionClockId =
|
||||
#if !QT_CONFIG(thread)
|
||||
// bootstrap mode, there are no wait conditions
|
||||
CLOCK_REALTIME
|
||||
#elif !QT_CONFIG(pthread_condattr_setclock)
|
||||
// OSes that lack pthread_condattr_setclock() (e.g., Darwin)
|
||||
CLOCK_REALTIME
|
||||
#elif defined(Q_OS_QNX)
|
||||
// unknown why use of the monotonic clock causes failures
|
||||
CLOCK_REALTIME
|
||||
#else
|
||||
SteadyClockClockId;
|
||||
#endif
|
||||
;
|
||||
|
||||
static constexpr auto OneSecAsNsecs = std::chrono::nanoseconds(std::chrono::seconds{ 1 }).count();
|
||||
|
||||
inline timespec durationToTimespec(std::chrono::nanoseconds timeout) noexcept
|
||||
@ -205,13 +218,14 @@ inline timespec qAbsTimespec(timespec ts)
|
||||
return normalizedTimespec(ts);
|
||||
}
|
||||
|
||||
template <clockid_t ClockId = SteadyClockClockId>
|
||||
inline timespec deadlineToAbstime(QDeadlineTimer deadline)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
using Clock =
|
||||
std::conditional_t<SteadyClockClockId == CLOCK_REALTIME, system_clock, steady_clock>;
|
||||
std::conditional_t<ClockId == CLOCK_REALTIME, system_clock, steady_clock>;
|
||||
auto timePoint = deadline.deadline<Clock>();
|
||||
if (timePoint < Clock::time_point{})
|
||||
if (timePoint < typename Clock::time_point{})
|
||||
return {};
|
||||
return durationToTimespec(timePoint.time_since_epoch());
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ enum { ThreadPriorityResetFlag = 0x80000000 };
|
||||
//
|
||||
// To support this scenario, we start the thread in detached state.
|
||||
static constexpr bool UsingPThreadTimedJoin = QT_CONFIG(pthread_clockjoin)
|
||||
|| (QT_CONFIG(pthread_timedjoin) && SteadyClockClockId == CLOCK_REALTIME);
|
||||
|| (QT_CONFIG(pthread_timedjoin) && QWaitConditionClockId == CLOCK_REALTIME);
|
||||
#if !QT_CONFIG(pthread_clockjoin)
|
||||
int pthread_clockjoin_np(...) { return ENOSYS; } // pretend
|
||||
#endif
|
||||
|
@ -30,14 +30,14 @@ static void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)
|
||||
{
|
||||
pthread_condattr_t *attrp = nullptr;
|
||||
|
||||
#if defined(CLOCK_MONOTONIC) && !defined(Q_OS_DARWIN)
|
||||
#if QT_CONFIG(pthread_condattr_setclock)
|
||||
pthread_condattr_t condattr;
|
||||
attrp = &condattr;
|
||||
|
||||
pthread_condattr_init(&condattr);
|
||||
auto destroy = qScopeGuard([&] { pthread_condattr_destroy(&condattr); });
|
||||
if (SteadyClockClockId != CLOCK_REALTIME)
|
||||
pthread_condattr_setclock(&condattr, SteadyClockClockId);
|
||||
if (QWaitConditionClockId != CLOCK_REALTIME)
|
||||
pthread_condattr_setclock(&condattr, QWaitConditionClockId);
|
||||
#endif
|
||||
|
||||
qt_report_pthread_error(pthread_cond_init(cond, attrp), where, "cv init");
|
||||
@ -53,7 +53,7 @@ public:
|
||||
|
||||
int wait_relative(QDeadlineTimer deadline)
|
||||
{
|
||||
timespec ti = deadlineToAbstime(deadline);
|
||||
timespec ti = deadlineToAbstime<QWaitConditionClockId>(deadline);
|
||||
return pthread_cond_timedwait(&cond, &mutex, &ti);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user