Add _monotonic_np versions of timed wait functions

As a follow up to Ibba98f5d88be1c306d14e9b9366302ecbef6d534, where we
added a work around to convert the CLOCK_REALTIME timeouts to
CLOCK_MONOTONIC for pthread and semaphore timed wait functions, we're
introducing a set of _monotonic_np versions of each of these functions
that wait on CLOCK_MONOTONIC directly.

The primary motivation here is that while the above work around helps
for 3rd party code, it creates a dilemma when implementing new code
that would use these functions: either one implements code with these
functions knowing there is a race condition possible or one avoids
these functions and reinvent their own waiting/signaling mechanisms.
Neither are satisfactory, so we create a third option to use these
Android specific _monotonic_np functions that completely remove the
race condition while keeping the rest of the interface.

Specifically this adds the below functions:
pthread_mutex_timedlock_monotonic_np()
pthread_cond_timedwait_monotonic_np()
pthread_rwlock_timedrdlock_monotonic_np()
pthread_rwlock_timedwrlock_monotonic_np()
sem_timedwait_monotonic_np()

Note that pthread_cond_timedwait_monotonic_np() previously existed and
was removed since it's possible to initialize a condition variable to
use CLOCK_MONOTONIC.  It is added back for a mix of reasons,
1) Symmetry with the rest of the functions we're adding
2) libc++ cannot easily take advantage of the new initializer, but
   will be able to use this function in order to wait on
   std::steady_clock
3) Frankly, it's a better API to specify the clock in the waiter function
   than to specify the clock when the condition variable is
   initialized.

Bug: 73951740
Test: new unit tests
Change-Id: I23aa5c204e36a194237d41e064c5c8ccaa4204e3
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index b216ec9..607e37f 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -101,37 +101,51 @@
   }
 }
 
-TEST(semaphore, sem_timedwait) {
+static void sem_timedwait_helper(clockid_t clock,
+                                 int (*wait_function)(sem_t* __sem, const timespec* __ts)) {
   sem_t s;
   ASSERT_EQ(0, sem_init(&s, 0, 0));
 
   timespec ts;
-  ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts));
+  ASSERT_EQ(0, clock_gettime(clock, &ts));
   timespec_add_ms(ts, 100);
 
   errno = 0;
-  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
+  ASSERT_EQ(-1, wait_function(&s, &ts));
   ASSERT_EQ(ETIMEDOUT, errno);
 
   // A negative timeout is an error.
   errno = 0;
   ts.tv_nsec = -1;
-  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
+  ASSERT_EQ(-1, wait_function(&s, &ts));
   ASSERT_EQ(EINVAL, errno);
   errno = 0;
   ts.tv_nsec = NS_PER_S;
-  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
+  ASSERT_EQ(-1, wait_function(&s, &ts));
   ASSERT_EQ(EINVAL, errno);
 
   errno = 0;
   ts.tv_nsec = NS_PER_S - 1;
   ts.tv_sec = -1;
-  ASSERT_EQ(-1, sem_timedwait(&s, &ts));
+  ASSERT_EQ(-1, wait_function(&s, &ts));
   ASSERT_EQ(ETIMEDOUT, errno);
 
   ASSERT_EQ(0, sem_destroy(&s));
 }
 
+TEST(semaphore, sem_timedwait) {
+  sem_timedwait_helper(CLOCK_REALTIME, sem_timedwait);
+}
+
+TEST(semaphore, sem_timedwait_monotonic_np) {
+#if defined(__BIONIC__)
+  sem_timedwait_helper(CLOCK_MONOTONIC, sem_timedwait_monotonic_np);
+#else   // __BIONIC__
+  GTEST_LOG_(INFO)
+      << "This test does nothing since sem_timedwait_monotonic_np is only supported on bionic";
+#endif  // __BIONIC__
+}
+
 TEST(semaphore_DeathTest, sem_timedwait_null_timeout) {
   sem_t s;
   ASSERT_EQ(0, sem_init(&s, 0, 0));