Skip to content

Commit

Permalink
iox-eclipse-iceoryx#2301 Add SpinLockMutex
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Jul 24, 2024
1 parent b4f99bb commit 8736de4
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,105 @@
#ifndef IOX_POSH_POPO_BUILDING_BLOCKS_LOCKING_POLICY_HPP
#define IOX_POSH_POPO_BUILDING_BLOCKS_LOCKING_POLICY_HPP

#include "iox/detail/adaptive_wait.hpp"
#include "iox/mutex.hpp"

namespace iox
{
namespace popo
{
class SpinlockMutex
{
public:
SpinlockMutex()
: m_flag(ATOMIC_FLAG_INIT)
, m_recursive{Recursive{0, 0}}
{
}

expected<void, MutexLockError> lock() noexcept
{
pid_t tid = gettid();

auto recursive = m_recursive.load();

if (recursive.tid == tid)
{
recursive.count += 1;
m_recursive.store(recursive);

return ok();
}

detail::adaptive_wait spinner;
spinner.wait_loop([this] { return this->m_flag.test_and_set(std::memory_order_acquire); });

m_recursive.store(Recursive{tid, 1});

return ok();
}

expected<void, MutexUnlockError> unlock() noexcept
{
pid_t tid = gettid();

auto recursive = m_recursive.load();

if (recursive.tid == tid)
{
recursive.count -= 1;

if (recursive.count == 0)
{
recursive.tid = 0;
m_recursive.store(recursive);
m_flag.clear(std::memory_order_release);
}
else
{
m_recursive.store(recursive);
}

return ok();
}


return err(MutexUnlockError::UNKNOWN_ERROR);
}

expected<MutexTryLock, MutexTryLockError> try_lock() noexcept
{
pid_t tid = gettid();

auto recursive = m_recursive.load();

if (recursive.tid == tid)
{
recursive.count += 1;
m_recursive.store(recursive);
return ok(MutexTryLock::LOCK_SUCCEEDED);
}

if (!m_flag.test_and_set(std::memory_order_acquire))
{
m_recursive.store(Recursive{tid, 1});

return ok(MutexTryLock::LOCK_SUCCEEDED);
}
return ok(MutexTryLock::FAILED_TO_ACQUIRE_LOCK);
}

struct Recursive
{
pid_t tid;
uint32_t count;
};

private:
std::atomic_flag m_flag;
std::atomic<Recursive> m_recursive;
};

class ThreadSafePolicy
{
public:
Expand All @@ -33,7 +126,7 @@ class ThreadSafePolicy
bool tryLock() const noexcept;

private:
mutable optional<mutex> m_mutex;
mutable optional<SpinlockMutex> m_mutex;
};

class SingleThreadedPolicy
Expand Down
12 changes: 7 additions & 5 deletions iceoryx_posh/source/popo/building_blocks/locking_policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ namespace popo
{
ThreadSafePolicy::ThreadSafePolicy() noexcept
{
MutexBuilder()
.isInterProcessCapable(true)
.mutexType(MutexType::RECURSIVE)
.create(m_mutex)
.expect("Failed to create Mutex");
/// @todo iox-#2301 fix this with a proper spin-lock implementation
// MutexBuilder()
// .isInterProcessCapable(true)
// .mutexType(MutexType::RECURSIVE)
// .create(m_mutex)
// .expect("Failed to create Mutex");
m_mutex.emplace();
}

void ThreadSafePolicy::lock() const noexcept
Expand Down

0 comments on commit 8736de4

Please sign in to comment.