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
parent 6009182731
commit 1f278d9ae4

View file

@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <thrift/concurrency/Mutex.h>
namespace apache
@ -13,31 +15,52 @@ 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 false;
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 nullptr;
return &impl_->lock;
}
} // namespace concurrency
} // namespace thrift