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>
This commit is contained in:
Christopher Friedt 2023-07-28 08:04:42 -04:00 committed by Anas Nashif
commit 1f278d9ae4

View file

@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <zephyr/kernel.h>
#include <thrift/concurrency/Mutex.h> #include <thrift/concurrency/Mutex.h>
namespace apache namespace apache
@ -13,31 +15,52 @@ namespace thrift
namespace concurrency namespace concurrency
{ {
class Mutex::impl
{
public:
k_spinlock_key_t key;
struct k_spinlock lock;
};
Mutex::Mutex() Mutex::Mutex()
{ {
impl_ = std::make_shared<Mutex::impl>();
} }
void Mutex::lock() const void Mutex::lock() const
{ {
while (!trylock()) {
k_msleep(1);
}
} }
bool Mutex::trylock() const bool Mutex::trylock() const
{ {
return false; return k_spin_trylock(&impl_->lock, &impl_->key) == 0;
} }
bool Mutex::timedlock(int64_t milliseconds) const 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; return false;
} }
void Mutex::unlock() const void Mutex::unlock() const
{ {
k_spin_unlock(&impl_->lock, impl_->key);
} }
void *Mutex::getUnderlyingImpl() const void *Mutex::getUnderlyingImpl() const
{ {
return nullptr; return &impl_->lock;
} }
} // namespace concurrency } // namespace concurrency
} // namespace thrift } // namespace thrift