Skip to content

Commit

Permalink
iox-eclipse-iceoryx#2301 Add SpinLockSemaphore
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Jul 24, 2024
1 parent 8736de4 commit f70f1b5
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
#define IOX_POSH_POPO_BUILDING_BLOCKS_CONDITION_VARIABLE_DATA_HPP

#include "iceoryx_posh/iceoryx_posh_types.hpp"
#include "iceoryx_posh/internal/popo/building_blocks/locking_policy.hpp"
#include "iceoryx_posh/internal/posh_error_reporting.hpp"
#include "iox/deadline_timer.hpp"
#include "iox/detail/adaptive_wait.hpp"
#include "iox/unnamed_semaphore.hpp"

#include <atomic>
Expand All @@ -27,6 +30,72 @@ namespace iox
{
namespace popo
{
class SpinLockSemaphore : public detail::SemaphoreInterface<SpinLockSemaphore>
{
public:
SpinLockSemaphore()
: m_count(0)
{
}

~SpinLockSemaphore()
{
m_to_be_destroyed = true;
}

expected<void, SemaphoreError> post()
{
std::lock_guard<SpinlockMutex> lock(spinlock);
++m_count;
return ok();
}

expected<void, SemaphoreError> wait()
{
detail::adaptive_wait spinner;
spinner.wait_loop([this] { return !this->tryWait(); });
return ok();
}

expected<bool, SemaphoreError> tryWait()
{
std::lock_guard<SpinlockMutex> lock(spinlock);
if (m_to_be_destroyed == true)
{
return ok(true);
}
if (m_count > 0)
{
--m_count;
return ok(true);
}
return ok(false);
}

expected<SemaphoreWaitState, SemaphoreError> timedWait(const units::Duration& timeout)
{
iox::deadline_timer deadline_timer(timeout);
detail::adaptive_wait spinner;

auto ret_val = SemaphoreWaitState::TIMEOUT;
spinner.wait_loop([this, &deadline_timer, &ret_val] {
if (this->tryWait())
{
ret_val = SemaphoreWaitState::NO_TIMEOUT;
return false;
}
return !deadline_timer.hasExpired();
});

return ok(ret_val);
}

private:
std::atomic<int32_t> m_count{0};
std::atomic<bool> m_to_be_destroyed{false};
SpinlockMutex spinlock;
};

struct ConditionVariableData
{
ConditionVariableData() noexcept;
Expand All @@ -38,7 +107,7 @@ struct ConditionVariableData
ConditionVariableData& operator=(ConditionVariableData&& rhs) = delete;
~ConditionVariableData() noexcept = default;

optional<UnnamedSemaphore> m_semaphore;
optional<SpinLockSemaphore> m_semaphore;
RuntimeName_t m_runtimeName;
std::atomic_bool m_toBeDestroyed{false};
std::atomic_bool m_activeNotifications[MAX_NUMBER_OF_NOTIFIERS];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ ConditionVariableData::ConditionVariableData() noexcept
ConditionVariableData::ConditionVariableData(const RuntimeName_t& runtimeName) noexcept
: m_runtimeName(runtimeName)
{
UnnamedSemaphoreBuilder().initialValue(0U).isInterProcessCapable(true).create(m_semaphore).or_else([](auto) {
IOX_REPORT_FATAL(PoshError::POPO__CONDITION_VARIABLE_DATA_FAILED_TO_CREATE_SEMAPHORE);
});
/// @todo iox-#2301 fix this with a proper spin-lock implementation
// UnnamedSemaphoreBuilder().initialValue(0U).isInterProcessCapable(true).create(m_semaphore).or_else([](auto) {
// IOX_REPORT_FATAL(PoshError::POPO__CONDITION_VARIABLE_DATA_FAILED_TO_CREATE_SEMAPHORE);
// });
m_semaphore.emplace();

for (auto& id : m_activeNotifications)
{
Expand Down

0 comments on commit f70f1b5

Please sign in to comment.