freertos: remove extra tick timeout for 0 length durations

Although meeting the API contract, this removes an unnecessary extra
timeout tick for zero length durations.

This also adds explicit downcasting from int64_t to TickType_t when
invoking native APIs.

Change-Id: I18bd8b81c269a9d1c5227d88993cf293be8f9a75
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/36921
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_sync_freertos/binary_semaphore.cc b/pw_sync_freertos/binary_semaphore.cc
index 16a1fb2..ef32b83 100644
--- a/pw_sync_freertos/binary_semaphore.cc
+++ b/pw_sync_freertos/binary_semaphore.cc
@@ -36,8 +36,8 @@
 bool BinarySemaphore::try_acquire_for(SystemClock::duration for_at_least) {
   PW_DCHECK(!interrupt::InInterruptContext());
 
-  // Use non-blocking try_acquire for negative durations.
-  if (for_at_least < SystemClock::duration::zero()) {
+  // Use non-blocking try_acquire for negative and zero length durations.
+  if (for_at_least <= SystemClock::duration::zero()) {
     return try_acquire();
   }
 
@@ -46,12 +46,16 @@
   constexpr SystemClock::duration kMaxTimeoutMinusOne =
       pw::chrono::freertos::kMaxTimeout - SystemClock::duration(1);
   while (for_at_least > kMaxTimeoutMinusOne) {
-    if (xSemaphoreTake(&native_type_, kMaxTimeoutMinusOne.count()) == pdTRUE) {
+    if (xSemaphoreTake(&native_type_,
+                       static_cast<TickType_t>(kMaxTimeoutMinusOne.count())) ==
+        pdTRUE) {
       return true;
     }
     for_at_least -= kMaxTimeoutMinusOne;
   }
-  return xSemaphoreTake(&native_type_, for_at_least.count() + 1) == pdTRUE;
+  return xSemaphoreTake(&native_type_,
+                        static_cast<TickType_t>(for_at_least.count() + 1)) ==
+         pdTRUE;
 }
 
 }  // namespace pw::sync
diff --git a/pw_sync_freertos/counting_semaphore.cc b/pw_sync_freertos/counting_semaphore.cc
index 501c47d..3b57397 100644
--- a/pw_sync_freertos/counting_semaphore.cc
+++ b/pw_sync_freertos/counting_semaphore.cc
@@ -56,8 +56,8 @@
 bool CountingSemaphore::try_acquire_for(SystemClock::duration for_at_least) {
   PW_DCHECK(!interrupt::InInterruptContext());
 
-  // Use non-blocking try_acquire for negative durations.
-  if (for_at_least < SystemClock::duration::zero()) {
+  // Use non-blocking try_acquire for negative and zero length durations.
+  if (for_at_least <= SystemClock::duration::zero()) {
     return try_acquire();
   }
 
@@ -66,12 +66,16 @@
   constexpr SystemClock::duration kMaxTimeoutMinusOne =
       pw::chrono::freertos::kMaxTimeout - SystemClock::duration(1);
   while (for_at_least > kMaxTimeoutMinusOne) {
-    if (xSemaphoreTake(&native_type_, kMaxTimeoutMinusOne.count()) == pdTRUE) {
+    if (xSemaphoreTake(&native_type_,
+                       static_cast<TickType_t>(kMaxTimeoutMinusOne.count())) ==
+        pdTRUE) {
       return true;
     }
     for_at_least -= kMaxTimeoutMinusOne;
   }
-  return xSemaphoreTake(&native_type_, for_at_least.count() + 1) == pdTRUE;
+  return xSemaphoreTake(&native_type_,
+                        static_cast<TickType_t>(for_at_least.count() + 1)) ==
+         pdTRUE;
 }
 
 }  // namespace pw::sync
diff --git a/pw_sync_freertos/mutex.cc b/pw_sync_freertos/mutex.cc
index e8bb50b..7cdfef5 100644
--- a/pw_sync_freertos/mutex.cc
+++ b/pw_sync_freertos/mutex.cc
@@ -38,8 +38,8 @@
 bool Mutex::try_lock_for(SystemClock::duration for_at_least) {
   PW_DCHECK(!interrupt::InInterruptContext());
 
-  // Use non-blocking try_lock for negative durations.
-  if (for_at_least < SystemClock::duration::zero()) {
+  // Use non-blocking try_acquire for negative and zero length durations.
+  if (for_at_least <= SystemClock::duration::zero()) {
     return try_lock();
   }
 
@@ -48,12 +48,16 @@
   constexpr SystemClock::duration kMaxTimeoutMinusOne =
       pw::chrono::freertos::kMaxTimeout - SystemClock::duration(1);
   while (for_at_least > kMaxTimeoutMinusOne) {
-    if (xSemaphoreTake(&native_type_, kMaxTimeoutMinusOne.count()) == pdTRUE) {
+    if (xSemaphoreTake(&native_type_,
+                       static_cast<TickType_t>(kMaxTimeoutMinusOne.count())) ==
+        pdTRUE) {
       return true;
     }
     for_at_least -= kMaxTimeoutMinusOne;
   }
-  return xSemaphoreTake(&native_type_, for_at_least.count() + 1) == pdTRUE;
+  return xSemaphoreTake(&native_type_,
+                        static_cast<TickType_t>(for_at_least.count() + 1)) ==
+         pdTRUE;
 }
 
 }  // namespace pw::sync
diff --git a/pw_thread_freertos/sleep.cc b/pw_thread_freertos/sleep.cc
index 3f64ce1..0decfa0 100644
--- a/pw_thread_freertos/sleep.cc
+++ b/pw_thread_freertos/sleep.cc
@@ -30,8 +30,8 @@
 void sleep_for(SystemClock::duration for_at_least) {
   PW_DCHECK(get_id() != thread::Id());
 
-  // Yield for negative durations.
-  if (for_at_least < SystemClock::duration::zero()) {
+  // Yield for negative and zero length durations.
+  if (for_at_least <= SystemClock::duration::zero()) {
     taskYIELD();
     return;
   }
@@ -41,10 +41,10 @@
   constexpr SystemClock::duration kMaxTimeoutMinusOne =
       pw::chrono::freertos::kMaxTimeout - SystemClock::duration(1);
   while (for_at_least > kMaxTimeoutMinusOne) {
-    vTaskDelay(kMaxTimeoutMinusOne.count());
+    vTaskDelay(static_cast<TickType_t>(kMaxTimeoutMinusOne.count()));
     for_at_least -= kMaxTimeoutMinusOne;
   }
-  vTaskDelay(for_at_least.count() + 1);
+  vTaskDelay(static_cast<TickType_t>(for_at_least.count() + 1));
 }
 
 }  // namespace pw::this_thread