mirror of
https://fuchsia.googlesource.com/third_party/pigweed.googlesource.com/pigweed/pigweed
synced 2024-09-20 13:51:05 +00:00
86c25478ba
Fixes the embOS backends for pw::sync::Mutex, pw::sync::BinarySemaphore, pw::sync::CountingSemaphore, and pw::this_thread::sleep_for to add one tick when invoking the native API to comply with the for_at_least contract as we do not know how far we are into the current tick. Note this is not observable without the use of an independent clock. This also adds explicit downcasting from int64_t to OS_TIME ticks when invoking native APIs. Change-Id: I113cbdfc1a88795df87223117e65a763ae050772 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/37280 Reviewed-by: Wyatt Hepler <hepler@google.com> Commit-Queue: Ewout van Bekkum <ewout@google.com>
50 lines
1.6 KiB
C++
50 lines
1.6 KiB
C++
// Copyright 2021 The Pigweed Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
// use this file except in compliance with the License. You may obtain a copy of
|
|
// the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations under
|
|
// the License.
|
|
|
|
#include "pw_thread/sleep.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include "RTOS.h"
|
|
#include "pw_assert/assert.h"
|
|
#include "pw_chrono/system_clock.h"
|
|
#include "pw_chrono_embos/system_clock_constants.h"
|
|
#include "pw_thread/id.h"
|
|
|
|
using pw::chrono::SystemClock;
|
|
|
|
namespace pw::this_thread {
|
|
|
|
void sleep_for(chrono::SystemClock::duration for_at_least) {
|
|
PW_DCHECK(get_id() != thread::Id());
|
|
|
|
// Yield for negative and zero length durations.
|
|
if (for_at_least <= SystemClock::duration::zero()) {
|
|
OS_Yield();
|
|
return;
|
|
}
|
|
|
|
// On a tick based kernel we cannot tell how far along we are on the current
|
|
// tick, ergo we add one whole tick to the final duration.
|
|
constexpr SystemClock::duration kMaxTimeoutMinusOne =
|
|
pw::chrono::embos::kMaxTimeout - SystemClock::duration(1);
|
|
while (for_at_least > kMaxTimeoutMinusOne) {
|
|
OS_Delay(static_cast<OS_TIME>(kMaxTimeoutMinusOne.count()));
|
|
for_at_least -= kMaxTimeoutMinusOne;
|
|
}
|
|
OS_Delay(static_cast<OS_TIME>(for_at_least.count()));
|
|
}
|
|
|
|
} // namespace pw::this_thread
|