mirror of
https://git.intern.spaceteamaachen.de/ALPAKA/rtos2-utils.git
synced 2025-08-07 03:27:33 +00:00
Added barrier pattern, thread yield and updated event API
This commit is contained in:
@@ -9,6 +9,10 @@
|
|||||||
#include <cmsis_os2.h>
|
#include <cmsis_os2.h>
|
||||||
#include <sta/event.hpp>
|
#include <sta/event.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#define STA_EVENT_FLAGS_ALL 0xFFFFFFFFU
|
||||||
|
|
||||||
|
|
||||||
namespace sta
|
namespace sta
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -25,12 +29,12 @@ namespace sta
|
|||||||
/**
|
/**
|
||||||
* @brief Set given flags for the event.
|
* @brief Set given flags for the event.
|
||||||
*/
|
*/
|
||||||
void set(uint32_t flags) override;
|
void set(uint32_t flags = STA_EVENT_FLAGS_ALL) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clear given flags for the event.
|
* @brief Clear given flags for the event.
|
||||||
*/
|
*/
|
||||||
void clear(uint32_t flags) override;
|
void clear(uint32_t flags = STA_EVENT_FLAGS_ALL) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get current flags for the event.
|
* @brief Get current flags for the event.
|
||||||
@@ -46,11 +50,11 @@ namespace sta
|
|||||||
* @param timeout Timeout in milliseconds.
|
* @param timeout Timeout in milliseconds.
|
||||||
* @return Event flags before clearing or error code if highest bit set.
|
* @return Event flags before clearing or error code if highest bit set.
|
||||||
*/
|
*/
|
||||||
uint32_t wait(uint32_t flags, uint32_t timeout = osWaitForever) override;
|
uint32_t wait(uint32_t flags = STA_EVENT_FLAGS_ALL, uint32_t timeout = osWaitForever) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
osEventFlagsId_t event_id; /**< CMSIS RTOS2 Event Flag */
|
osEventFlagsId_t event_id; /**< CMSIS RTOS2 Event Flag */
|
||||||
};
|
};
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
|
||||||
#endif // STA_RTOS_EVENT_HPP
|
#endif // STA_RTOS_EVENT_HPP
|
||||||
|
31
include/sta/rtos/patterns/barrier.hpp
Normal file
31
include/sta/rtos/patterns/barrier.hpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* barrier.hpp
|
||||||
|
*
|
||||||
|
* Created on: Mar 16, 2024
|
||||||
|
* Author: Dario
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTOS2_UTILS_STA_PATTERNS_BARRIER_HPP
|
||||||
|
#define RTOS2_UTILS_STA_PATTERNS_BARRIER_HPP
|
||||||
|
|
||||||
|
#include <sta/rtos/mutex.hpp>
|
||||||
|
#include <sta/rtos/event.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sta
|
||||||
|
{
|
||||||
|
class Barrier {
|
||||||
|
public:
|
||||||
|
Barrier(const char* name, uint8_t n_threads);
|
||||||
|
|
||||||
|
void wait();
|
||||||
|
private:
|
||||||
|
RtosMutex mutex_;
|
||||||
|
RtosEvent flag_;
|
||||||
|
const uint8_t n_threads_;
|
||||||
|
uint8_t n_entered_;
|
||||||
|
uint8_t n_left_;
|
||||||
|
};
|
||||||
|
} // namespace sta
|
||||||
|
|
||||||
|
#endif /* RTOS2_UTILS_STA_PATTERNS_BARRIER_HPP_ */
|
@@ -107,6 +107,12 @@ namespace sta
|
|||||||
*/
|
*/
|
||||||
void sleep(uint32_t ticks);
|
void sleep(uint32_t ticks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Makes the currently running thread pass control to the next thread.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void yield();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send user notification flags to thread.
|
* @brief Send user notification flags to thread.
|
||||||
*
|
*
|
||||||
|
@@ -10,11 +10,11 @@ namespace sta {
|
|||||||
osEventFlagsDelete(event_id);
|
osEventFlagsDelete(event_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtosEvent::set(uint32_t flags) {
|
void RtosEvent::set(uint32_t flags /* = STA_EVENT_FLAGS_ALL */) {
|
||||||
osEventFlagsSet(event_id, flags);
|
osEventFlagsSet(event_id, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtosEvent::clear(uint32_t flags) {
|
void RtosEvent::clear(uint32_t flags /* = STA_EVENT_FLAGS_ALL */) {
|
||||||
osEventFlagsClear(event_id, flags);
|
osEventFlagsClear(event_id, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@ namespace sta {
|
|||||||
return osEventFlagsGet(event_id);
|
return osEventFlagsGet(event_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RtosEvent::wait(uint32_t flags, uint32_t timeout) {
|
uint32_t RtosEvent::wait(uint32_t flags /* = STA_EVENT_FLAGS_ALL */, uint32_t timeout /* = osWaitForever */) {
|
||||||
return osEventFlagsWait(event_id, flags, osFlagsWaitAny, timeout);
|
return osEventFlagsWait(event_id, flags, osFlagsWaitAny, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sta
|
} // namespace sta
|
||||||
|
83
src/patterns/barrier.cpp
Normal file
83
src/patterns/barrier.cpp
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* barrier.cpp
|
||||||
|
*
|
||||||
|
* Created on: Mar 16, 2024
|
||||||
|
* Author: Dario
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sta/rtos/patterns/barrier.hpp>
|
||||||
|
#include <sta/debug/assert.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sta
|
||||||
|
{
|
||||||
|
Barrier::Barrier(const char* name, uint8_t n_threads)
|
||||||
|
: mutex_{name},
|
||||||
|
flag_{},
|
||||||
|
n_threads_{n_threads},
|
||||||
|
n_entered_{0},
|
||||||
|
n_left_{n_threads}
|
||||||
|
{
|
||||||
|
STA_ASSERT(name != nullptr);
|
||||||
|
STA_ASSERT(n_threads >= 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Barrier::wait()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Taken from: https://en.wikipedia.org/wiki/Barrier_(computer_science)#Implementation
|
||||||
|
*/
|
||||||
|
mutex_.acquire();
|
||||||
|
|
||||||
|
if (n_entered_ == 0)
|
||||||
|
{
|
||||||
|
if (n_left_ == n_threads_)
|
||||||
|
{
|
||||||
|
// First thread to arrive clears the flag.
|
||||||
|
flag_.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This branch covers the case where a thread enters this barrier while others are still leaving.
|
||||||
|
// This can happen when a thread is much faster than the others.
|
||||||
|
mutex_.release();
|
||||||
|
|
||||||
|
// Busy waiting until the last thread leaves.
|
||||||
|
while (n_left_ != n_threads_)
|
||||||
|
{
|
||||||
|
osThreadYield();
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_.acquire();
|
||||||
|
|
||||||
|
// Clear the flag to make sure that entering threads cannot pass.
|
||||||
|
flag_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register this thread entering the barrier.
|
||||||
|
++n_entered_;
|
||||||
|
mutex_.release();
|
||||||
|
|
||||||
|
if (n_entered_ == n_threads_)
|
||||||
|
{
|
||||||
|
// If all threads are waiting in the barrier, set the flag allowing threads to leave.
|
||||||
|
n_entered_ = 0;
|
||||||
|
n_left_ = 1;
|
||||||
|
|
||||||
|
flag_.set();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Wait in the barrier until the flag is set.
|
||||||
|
flag_.wait();
|
||||||
|
|
||||||
|
// Register this thread leaving the barrier.
|
||||||
|
mutex_.acquire();
|
||||||
|
n_left_++;
|
||||||
|
mutex_.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace sta
|
||||||
|
|
||||||
|
|
@@ -51,6 +51,15 @@ namespace sta
|
|||||||
osDelay(ticks);
|
osDelay(ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtosThread::yield()
|
||||||
|
{
|
||||||
|
// Make sure that the calling thread is this thread. If not, the
|
||||||
|
// developer very likely has made a mistake.
|
||||||
|
STA_ASSERT(osThreadGetId() == instance_);
|
||||||
|
|
||||||
|
osThreadYield();
|
||||||
|
}
|
||||||
|
|
||||||
void RtosThread::notify(uint32_t flags)
|
void RtosThread::notify(uint32_t flags)
|
||||||
{
|
{
|
||||||
STA_ASSERT(instance_ != NULL);
|
STA_ASSERT(instance_ != NULL);
|
||||||
|
Reference in New Issue
Block a user