bionic: fix pthread_mutex_timedlock for PI mutexes
FUTEX_LOCK_PI uses CLOCK_REALTIME so adjust clock timebase
accordingly.
FUTEX_WAIT_BITSET, FUTEX_WAIT_REQUEUE_PI, FUTEX_LOCK_PI2
are updated to check the presence of FUTEX_CLOCK_REALTIME flag.
Test: atest bionic-unit-tests
Bug: 312787238
Bug: 315897315
Change-Id: I2d93286cf22d3b3d9f3757d49b46f7ee9ea5490c
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 749d687..1a882be 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -2398,6 +2398,20 @@
ts.tv_sec = -1;
ASSERT_EQ(ETIMEDOUT, lock_function(&m, &ts));
+ // check we wait long enough for the lock.
+ ASSERT_EQ(0, clock_gettime(clock, &ts));
+ const int64_t start_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
+
+ // add a second to get deadline.
+ ts.tv_sec += 1;
+
+ ASSERT_EQ(ETIMEDOUT, lock_function(&m, &ts));
+
+ // The timedlock must have waited at least 1 second before returning.
+ clock_gettime(clock, &ts);
+ const int64_t end_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
+ ASSERT_GT(end_ns - start_ns, NS_PER_S);
+
// If the mutex is unlocked, pthread_mutex_timedlock should succeed.
ASSERT_EQ(0, pthread_mutex_unlock(&m));
@@ -2443,7 +2457,11 @@
timespec ts;
clock_gettime(clock, &ts);
+ const int64_t start_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
+
+ // add a second to get deadline.
ts.tv_sec += 1;
+
ASSERT_EQ(0, lock_function(&m.lock, &ts));
struct ThreadArgs {
@@ -2472,6 +2490,12 @@
void* result;
ASSERT_EQ(0, pthread_join(thread, &result));
ASSERT_EQ(ETIMEDOUT, reinterpret_cast<intptr_t>(result));
+
+ // The timedlock must have waited at least 1 second before returning.
+ clock_gettime(clock, &ts);
+ const int64_t end_ns = ts.tv_sec * NS_PER_S + ts.tv_nsec;
+ ASSERT_GT(end_ns - start_ns, NS_PER_S);
+
ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
}