zephyr/modules/thrift/src/thrift/concurrency/Mutex.cpp
Christopher Friedt 1f278d9ae4 thrift: add temporary Mutex implementation
The Thrift library has its own abstraction for mutexes, which
normally just a wrapper around `std::mutex` using the PIMPL
idiom (pointer-to-impl).

Since Zephyr does not yet support `std::mutex`, a workaround
was added in Zephyr that was essentially no-op, and actually
the PIMPL idiom made it quite easy to do that. However,
pretending there is no synchronization requirement is not a
solution for it.

We can't yet just use a `struct k_mutex` yet, because we
don't yet support userspace, but for now we can fake a mutex
interface with a spinlock.

We hope to eventually drop this workaround entirely and just
support `std::mutex`.

Signed-off-by: Christopher Friedt <cfriedt@meta.com>
2023-07-29 10:26:56 -04:00

68 lines
948 B
C++

/*
* Copyright 2022 Meta
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <thrift/concurrency/Mutex.h>
namespace apache
{
namespace thrift
{
namespace concurrency
{
class Mutex::impl
{
public:
k_spinlock_key_t key;
struct k_spinlock lock;
};
Mutex::Mutex()
{
impl_ = std::make_shared<Mutex::impl>();
}
void Mutex::lock() const
{
while (!trylock()) {
k_msleep(1);
}
}
bool Mutex::trylock() const
{
return k_spin_trylock(&impl_->lock, &impl_->key) == 0;
}
bool Mutex::timedlock(int64_t milliseconds) const
{
k_timepoint_t end = sys_timepoint_calc(K_MSEC(milliseconds));
do {
if (trylock()) {
return true;
}
k_msleep(5);
} while(!sys_timepoint_expired(end));
return false;
}
void Mutex::unlock() const
{
k_spin_unlock(&impl_->lock, impl_->key);
}
void *Mutex::getUnderlyingImpl() const
{
return &impl_->lock;
}
} // namespace concurrency
} // namespace thrift
} // namespace apache