pw_chrono: simplify RTOS SystemClock backends

Simplifies the SystemClock backends for FreeRTOS, ThreadX, and
embOS using the updated pw::sync::SpinLock facade which has a
constexpr constructor which removes the need for special early
boot handling.

Change-Id: I9d69a4e0c34ab7b3a1488dce6693cbc642b282bb
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/36581
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
diff --git a/pw_chrono_embos/system_clock.cc b/pw_chrono_embos/system_clock.cc
index 8de700e..4506172 100644
--- a/pw_chrono_embos/system_clock.cc
+++ b/pw_chrono_embos/system_clock.cc
@@ -25,25 +25,7 @@
 namespace pw::chrono::backend {
 namespace {
 
-// Extension wrapping pw::SpinLock to allow an atomic to be used to determine
-// whether it has been constructed and is ready to be used.
-class ConstructionSignalingSpinLock : public sync::SpinLock {
- public:
-  ConstructionSignalingSpinLock(std::atomic<bool>& constructed_signal)
-      : sync::SpinLock() {
-    // Note that the memory order is relaxed because C++ global static
-    // construction is a single threaded environment.
-    constructed_signal.store(true, std::memory_order_relaxed);
-  };
-};
-
-// This is POD, meaning this atomic is available before static C++ global
-// constructors are run.
-std::atomic<bool> system_clock_spin_lock_constructed = {false};
-
-ConstructionSignalingSpinLock system_clock_spin_lock(
-    system_clock_spin_lock_constructed);
-
+sync::SpinLock system_clock_spin_lock;
 int64_t overflow_tick_count = 0;
 uint32_t native_tick_count = 0;
 static_assert(!SystemClock::is_nmi_safe,
@@ -66,12 +48,6 @@
 }  // namespace
 
 int64_t GetSystemClockTickCount() {
-  // Note that the memory order is relaxed because C++ global static
-  // construction is a single threaded environment.
-  if (!system_clock_spin_lock_constructed.load(std::memory_order_relaxed)) {
-    return GetUint32TickCount();
-  }
-
   std::lock_guard lock(system_clock_spin_lock);
   const uint32_t new_native_tick_count = GetUint32TickCount();
   // WARNING: This must be called more than once per overflow period!
diff --git a/pw_chrono_freertos/system_clock.cc b/pw_chrono_freertos/system_clock.cc
index 17c42b3..84f2e43 100644
--- a/pw_chrono_freertos/system_clock.cc
+++ b/pw_chrono_freertos/system_clock.cc
@@ -27,25 +27,7 @@
 namespace pw::chrono::backend {
 namespace {
 
-// Extension wrapping pw::SpinLock to allow an atomic to be used to determine
-// whether it has been constructed and is ready to be used.
-class ConstructionSignalingSpinLock : public sync::SpinLock {
- public:
-  ConstructionSignalingSpinLock(std::atomic<bool>& constructed_signal)
-      : sync::SpinLock() {
-    // Note that the memory order is relaxed because C++ global static
-    // construction is a single threaded environment.
-    constructed_signal.store(true, std::memory_order_relaxed);
-  };
-};
-
-// This is POD, meaning this atomic is available before static C++ global
-// constructors are run.
-std::atomic<bool> system_clock_spin_lock_constructed = {false};
-
-ConstructionSignalingSpinLock system_clock_spin_lock(
-    system_clock_spin_lock_constructed);
-
+sync::SpinLock system_clock_spin_lock;
 int64_t overflow_tick_count = 0;
 TickType_t native_tick_count = 0;
 static_assert(!SystemClock::is_nmi_safe,
@@ -58,13 +40,6 @@
 }  // namespace
 
 int64_t GetSystemClockTickCount() {
-  // Note that the memory order is relaxed because C++ global static
-  // construction is a single threaded environment.
-  if (!system_clock_spin_lock_constructed.load(std::memory_order_relaxed)) {
-    return interrupt::InInterruptContext() ? xTaskGetTickCountFromISR()
-                                           : xTaskGetTickCount();
-  }
-
   std::lock_guard lock(system_clock_spin_lock);
   const TickType_t new_native_tick_count = interrupt::InInterruptContext()
                                                ? xTaskGetTickCountFromISR()
diff --git a/pw_chrono_threadx/system_clock.cc b/pw_chrono_threadx/system_clock.cc
index 972fc29..3017c33 100644
--- a/pw_chrono_threadx/system_clock.cc
+++ b/pw_chrono_threadx/system_clock.cc
@@ -29,25 +29,7 @@
 #error "This backend is not compatible with TX_NO_TIMER"
 #endif  // defined(TX_NO_TIMER) && TX_NO_TIMER
 
-// Extension wrapping pw::SpinLock to allow an atomic to be used to determine
-// whether it has been constructed and is ready to be used.
-class ConstructionSignalingSpinLock : public sync::SpinLock {
- public:
-  ConstructionSignalingSpinLock(std::atomic<bool>& constructed_signal)
-      : sync::SpinLock() {
-    // Note that the memory order is relaxed because C++ global static
-    // construction is a single threaded environment.
-    constructed_signal.store(true, std::memory_order_relaxed);
-  };
-};
-
-// This is POD, meaning this atomic is available before static C++ global
-// constructors are run.
-std::atomic<bool> system_clock_spin_lock_constructed = {false};
-
-ConstructionSignalingSpinLock system_clock_spin_lock(
-    system_clock_spin_lock_constructed);
-
+sync::SpinLock system_clock_spin_lock;
 int64_t overflow_tick_count = 0;
 ULONG native_tick_count = 0;
 static_assert(!SystemClock::is_nmi_safe,
@@ -60,12 +42,6 @@
 }  // namespace
 
 int64_t GetSystemClockTickCount() {
-  // Note that the memory order is relaxed because C++ global static
-  // construction is a single threaded environment.
-  if (!system_clock_spin_lock_constructed.load(std::memory_order_relaxed)) {
-    return tx_time_get();
-  }
-
   std::lock_guard lock(system_clock_spin_lock);
   const ULONG new_native_tick_count = tx_time_get();
   // WARNING: This must be called more than once per overflow period!