Add __system_property_wait and return the serial in __system_property_read_callback.

In order to implement android::base::WaitForProperty well, we need a way to
wait not for *any* property to change (__system_property_wait_any), but to
specifically wait for the property represented by a given `prop_info` to
change.

The android::base::WaitForProperty implementation, like attempts to cache
system properties in the past, also needs a way to keep serials and values
in sync, but the existing functions don't provide a cheap way to get a
consistent snapshot. Change the __system_property_read_callback callback's
type to include the serial corresponding to the given value.

Add a test, slightly clean up some of the existing tests (and name them to
include the names of the functions they're testing, in our usual style).

Bug: http://b/35201172
Test: ran tests
Change-Id: Ibc8ebe2e88eef1e333a1bd3dd7f68135f1ba7fb5
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index a62ce14..32d1e31 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -1102,7 +1102,7 @@
   return fsetxattr_failed ? -2 : 0;
 }
 
-unsigned int __system_property_area_serial() {
+uint32_t __system_property_area_serial() {
   prop_area* pa = __system_property_area__;
   if (!pa) {
     return -1;
@@ -1163,8 +1163,10 @@
 }
 
 void __system_property_read_callback(const prop_info* pi,
-                                     void (*callback)(void* cookie, const char* name,
-                                                      const char* value),
+                                     void (*callback)(void* cookie,
+                                                      const char* name,
+                                                      const char* value,
+                                                      uint32_t serial),
                                      void* cookie) {
   while (true) {
     uint32_t serial = __system_property_serial(pi);  // acquire semantics
@@ -1177,7 +1179,7 @@
     // TODO: see todo in __system_property_read function
     atomic_thread_fence(memory_order_acquire);
     if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
-      callback(cookie, pi->name, value_buf);
+      callback(cookie, pi->name, value_buf, serial);
       return;
     }
   }
@@ -1329,30 +1331,34 @@
 }
 
 // Wait for non-locked serial, and retrieve it with acquire semantics.
-unsigned int __system_property_serial(const prop_info* pi) {
+uint32_t __system_property_serial(const prop_info* pi) {
   uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);
   while (SERIAL_DIRTY(serial)) {
-    __futex_wait(const_cast<volatile void*>(reinterpret_cast<const void*>(&pi->serial)), serial,
-                 nullptr);
+    __futex_wait(const_cast<_Atomic(uint_least32_t)*>(&pi->serial), serial, nullptr);
     serial = load_const_atomic(&pi->serial, memory_order_acquire);
   }
   return serial;
 }
 
-unsigned int __system_property_wait_any(unsigned int serial) {
+uint32_t __system_property_wait_any(uint32_t old_serial) {
   prop_area* pa = __system_property_area__;
-  uint32_t my_serial;
+  if (!pa) return 0;
 
-  if (!pa) {
-    return 0;
-  }
-
+  uint32_t new_serial;
   do {
-    __futex_wait(pa->serial(), serial, nullptr);
-    my_serial = atomic_load_explicit(pa->serial(), memory_order_acquire);
-  } while (my_serial == serial);
+    __futex_wait(pa->serial(), old_serial, nullptr);
+    new_serial = atomic_load_explicit(pa->serial(), memory_order_acquire);
+  } while (new_serial == old_serial);
+  return new_serial;
+}
 
-  return my_serial;
+uint32_t __system_property_wait(const prop_info* pi, uint32_t old_serial) {
+  uint32_t new_serial;
+  do {
+    __futex_wait(const_cast<_Atomic(uint_least32_t)*>(&pi->serial), old_serial, nullptr);
+    new_serial = load_const_atomic(&pi->serial, memory_order_acquire);
+  } while (new_serial == old_serial);
+  return new_serial;
 }
 
 const prop_info* __system_property_find_nth(unsigned n) {