pw_chrono: add SystemClock::for_at_least helper

Adds a helper function for legibility to SystemClock to invoke
std::chrono::ceil for us where the return type is fixed to a
SystemClock::duration type.

Also migrates the existing uses of std::chrono::ceil to this.

Change-Id: I1234ab3dfaf1d3ec22b0daa9d7666f66e0ce3310
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/37321
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Ewout van Bekkum <ewout@google.com>
diff --git a/pw_chrono/public/pw_chrono/system_clock.h b/pw_chrono/public/pw_chrono/system_clock.h
index 6c42396..3c5be0e 100644
--- a/pw_chrono/public/pw_chrono/system_clock.h
+++ b/pw_chrono/public/pw_chrono/system_clock.h
@@ -105,6 +105,14 @@
   static time_point now() noexcept {
     return time_point(duration(backend::GetSystemClockTickCount()));
   }
+
+  // This is purely a helper, identical to directly using std::chrono::ceil, to
+  // convert a duration type which cannot be implicitly converted where the
+  // result is rounded up.
+  template <class Rep, class Period>
+  static constexpr duration for_at_least(std::chrono::duration<Rep, Period> d) {
+    return std::chrono::ceil<duration>(d);
+  };
 };
 
 // An abstract interface representing a SystemClock.
diff --git a/pw_chrono/simulated_system_clock_test.cc b/pw_chrono/simulated_system_clock_test.cc
index f7d4fe8..7c35617 100644
--- a/pw_chrono/simulated_system_clock_test.cc
+++ b/pw_chrono/simulated_system_clock_test.cc
@@ -23,9 +23,9 @@
 
 // We can't control the SystemClock's period configuration, so just in case
 // 42 hours cannot be accurately expressed in integer ticks, round the
-// duration w/ ceil.
-constexpr auto kRoundedArbitraryDuration =
-    std::chrono::ceil<SystemClock::duration>(42h);
+// duration up.
+constexpr SystemClock::duration kRoundedArbitraryDuration =
+    SystemClock::for_at_least(42h);
 
 TEST(SimulatedSystemClock, InitialTime) {
   SimulatedSystemClock clock;
diff --git a/pw_sync/binary_semaphore_facade_test.cc b/pw_sync/binary_semaphore_facade_test.cc
index d5ad28c..b3d136f 100644
--- a/pw_sync/binary_semaphore_facade_test.cc
+++ b/pw_sync/binary_semaphore_facade_test.cc
@@ -43,9 +43,9 @@
 
 // We can't control the SystemClock's period configuration, so just in case
 // duration cannot be accurately expressed in integer ticks, round the
-// duration w/ ceil.
-constexpr auto kRoundedArbitraryDuration =
-    std::chrono::ceil<SystemClock::duration>(42ms);
+// duration up.
+constexpr SystemClock::duration kRoundedArbitraryDuration =
+    SystemClock::for_at_least(42ms);
 constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
     PW_SYSTEM_CLOCK_MS(42);
 
diff --git a/pw_sync/counting_semaphore_facade_test.cc b/pw_sync/counting_semaphore_facade_test.cc
index b0f1bc8..d086a90 100644
--- a/pw_sync/counting_semaphore_facade_test.cc
+++ b/pw_sync/counting_semaphore_facade_test.cc
@@ -48,9 +48,9 @@
 
 // We can't control the SystemClock's period configuration, so just in case
 // duration cannot be accurately expressed in integer ticks, round the
-// duration w/ ceil.
-constexpr auto kRoundedArbitraryDuration =
-    std::chrono::ceil<SystemClock::duration>(42ms);
+// duration up.
+constexpr SystemClock::duration kRoundedArbitraryDuration =
+    SystemClock::for_at_least(42ms);
 constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
     PW_SYSTEM_CLOCK_MS(42);
 
diff --git a/pw_sync/mutex_facade_test.cc b/pw_sync/mutex_facade_test.cc
index 30cef1f..ca47cfe 100644
--- a/pw_sync/mutex_facade_test.cc
+++ b/pw_sync/mutex_facade_test.cc
@@ -39,9 +39,9 @@
 
 // We can't control the SystemClock's period configuration, so just in case
 // duration cannot be accurately expressed in integer ticks, round the
-// duration w/ ceil.
-constexpr auto kRoundedArbitraryDuration =
-    std::chrono::ceil<SystemClock::duration>(42ms);
+// duration up.
+constexpr SystemClock::duration kRoundedArbitraryDuration =
+    SystemClock::for_at_least(42ms);
 constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
     PW_SYSTEM_CLOCK_MS(42);
 
diff --git a/pw_thread/sleep_facade_test.cc b/pw_thread/sleep_facade_test.cc
index 42548bd..3112b63 100644
--- a/pw_thread/sleep_facade_test.cc
+++ b/pw_thread/sleep_facade_test.cc
@@ -36,9 +36,9 @@
 
 // We can't control the SystemClock's period configuration, so just in case
 // duration cannot be accurately expressed in integer ticks, round the
-// duration w/ ceil.
-constexpr auto kRoundedArbitraryDuration =
-    std::chrono::ceil<SystemClock::duration>(42ms);
+// duration up.
+constexpr SystemClock::duration kRoundedArbitraryDuration =
+    SystemClock::for_at_least(42ms);
 constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
     PW_SYSTEM_CLOCK_MS(42);
 
diff --git a/pw_thread_freertos/dynamic_test_threads.cc b/pw_thread_freertos/dynamic_test_threads.cc
index a9c3f02..f596bab 100644
--- a/pw_thread_freertos/dynamic_test_threads.cc
+++ b/pw_thread_freertos/dynamic_test_threads.cc
@@ -41,8 +41,8 @@
 // the application will on average not be able to starve the heap if they
 // execute this test over and over again.
 void WaitUntilDetachedThreadsCleanedUp() {
-  this_thread::sleep_for(std::chrono::ceil<chrono::SystemClock::duration>(
-      std::chrono::milliseconds(50)));
+  this_thread::sleep_for(
+      chrono::SystemClock::for_at_least(std::chrono::milliseconds(50)));
 }
 
 }  // namespace pw::thread::test
diff --git a/pw_thread_freertos/static_test_threads.cc b/pw_thread_freertos/static_test_threads.cc
index 2684612..fc1884d 100644
--- a/pw_thread_freertos/static_test_threads.cc
+++ b/pw_thread_freertos/static_test_threads.cc
@@ -47,8 +47,8 @@
   // nullptr. However, there's still a race condition that the task has not
   // finished the execution of vTaskDelete. In addition during this time the
   // the task_handle has been cleared meaning we cannot call vTaskDelete.
-  this_thread::sleep_for(std::chrono::ceil<chrono::SystemClock::duration>(
-      std::chrono::milliseconds(50)));
+  this_thread::sleep_for(
+      chrono::SystemClock::for_at_least(std::chrono::milliseconds(50)));
 }
 
 }  // namespace pw::thread::test