Always use CLOCK_MONOTONIC for pthreads and semaphores

pthread's and semaphore's default behavior is to use CLOCK_REALTIME,
however this behavior is essentially never intended, as that clock is
prone to change discontinuously.

What users really intend is to use CLOCK_MONOTONIC, however only
pthread_cond_timedwait() provides this as an option and even there, a
large amount of existing code does not opt into CLOCK_MONOTONIC.

We have seen numerous bugs directly attributable to this difference.
Therefore, we provide this general workaround to always use
CLOCK_MONOTONIC for waiting, regardless of what the input timespec
is.

Specifically this impacts the below APIs:
pthread_mutex_timedlock()
pthread_cond_timedwait()
pthread_rwlock_timedrdlock()
pthread_rwlock_timedwrlock()
sem_timedwait()

Test: boot bullhead, boot sailfish
Test: bionic pthread/semaphore unit tests
Test: check that pthread_cond_timedwait() timeouts are uneffected by
      CLOCK_REALTIME time changes

Bug: 64694413
Bug: 64623895
Bug: 35756266
Bug: 35678943
Change-Id: Ibba98f5d88be1c306d14e9b9366302ecbef6d534
diff --git a/libc/private/bionic_futex.h b/libc/private/bionic_futex.h
index 946d9dd..9b89131 100644
--- a/libc/private/bionic_futex.h
+++ b/libc/private/bionic_futex.h
@@ -36,13 +36,10 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
-__BEGIN_DECLS
-
 struct timespec;
 
 static inline __always_inline int __futex(volatile void* ftx, int op, int value,
-                                          const struct timespec* timeout,
-                                          int bitset) {
+                                          const timespec* timeout, int bitset) {
   // Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
   int saved_errno = errno;
   int result = syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset);
@@ -61,17 +58,16 @@
   return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL, 0);
 }
 
-static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
+static inline int __futex_wait(volatile void* ftx, int value, const timespec* timeout) {
   return __futex(ftx, FUTEX_WAIT, value, timeout, 0);
 }
 
-static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value,
-                                  bool use_realtime_clock, const struct timespec* abs_timeout) {
-  return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE) |
-                 (use_realtime_clock ? FUTEX_CLOCK_REALTIME : 0), value, abs_timeout,
+static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value) {
+  return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE), value, nullptr,
                  FUTEX_BITSET_MATCH_ANY);
 }
 
-__END_DECLS
+__LIBC_HIDDEN__ int __futex_wait_ex(volatile void* ftx, bool shared, int value,
+                                    bool use_realtime_clock, const timespec* abs_timeout);
 
 #endif /* _BIONIC_FUTEX_H */
diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h
index 3dbafe0..b389247 100644
--- a/libc/private/bionic_lock.h
+++ b/libc/private/bionic_lock.h
@@ -64,7 +64,7 @@
     }
     while (atomic_exchange_explicit(&state, LockedWithWaiter, memory_order_acquire) != Unlocked) {
       // TODO: As the critical section is brief, it is a better choice to spin a few times befor sleeping.
-      __futex_wait_ex(&state, process_shared, LockedWithWaiter, false, nullptr);
+      __futex_wait_ex(&state, process_shared, LockedWithWaiter);
     }
     return;
   }
diff --git a/libc/private/bionic_time_conversions.h b/libc/private/bionic_time_conversions.h
index b9eaad2..fb049f2 100644
--- a/libc/private/bionic_time_conversions.h
+++ b/libc/private/bionic_time_conversions.h
@@ -42,6 +42,9 @@
 
 __LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts);
 
+__LIBC_HIDDEN__ void monotonic_time_from_realtime_time(timespec& monotonic_time,
+                                                       const timespec& realtime_time);
+
 __END_DECLS
 
 static inline int check_timespec(const timespec* ts, bool null_allowed) {