skullc-peripherals/Threads/Src/threads_primitivethread.cpp
Erki 6f7756e1cb
All checks were successful
continuous-integration/drone/push Build is passing
Threads refactor
Split thread into two different entities.
Add exclusive signal.
2021-06-19 19:34:28 +03:00

121 lines
2.8 KiB
C++

/*
* threads_primitivethread.cpp
*
* Created on: Jun 11, 2021
* Author: erki
*/
#include "threads_primitivethread.hpp"
#include "peripherals_utility.hpp"
#ifdef INCLUDE_xTaskGetCurrentTaskHandle
# define ASSERT_IS_CURRENT() \
assert(Threads::PrimitiveThread::getCurrentThread().taskHandle() == this->taskHandle())
#else
# define ASSERT_IS_CURRENT()
#endif
#ifdef INCLUDE_xTaskGetCurrentTaskHandle
# define ASSERT_IS_NOT_CURRENT() \
assert(Threads::PrimitiveThread::getCurrentThread().taskHandle() != this->taskHandle())
#else
# define ASSERT_IS_NOT_CURRENT()
#endif
namespace Threads
{
#ifdef INCLUDE_xTaskGetCurrentTaskHandle
PrimitiveThread PrimitiveThread::getCurrentThread()
{
return PrimitiveThread(xTaskGetCurrentTaskHandle());
}
#endif
BaseType_t PrimitiveThread::notify(const long value, const eNotifyAction action)
{
ASSERT_IS_NOT_CURRENT();
return xTaskNotify(taskHandle(), value, action);
}
std::pair<BaseType_t, BaseType_t> PrimitiveThread::notifyFromIsr(const long value, const eNotifyAction action)
{
BaseType_t was_notified = pdFALSE;
const BaseType_t rval = xTaskNotifyFromISR(taskHandle(), value, action, &was_notified);
return {rval, was_notified};
}
void PrimitiveThread::yield()
{
ASSERT_IS_CURRENT();
osThreadYield();
}
void PrimitiveThread::sleep(const unsigned long delay)
{
ASSERT_IS_CURRENT();
osDelay(delay);
}
void PrimitiveThread::sleepUntil(const unsigned long deadline)
{
ASSERT_IS_CURRENT();
osDelayUntil(deadline);
}
[[nodiscard]] bool PrimitiveThread::notifyWait(const TickType_t delay) const
{
ASSERT_IS_CURRENT();
return xTaskNotifyWait(0, std::numeric_limits<unsigned long>::max(), nullptr, delay);
}
[[nodiscard]] std::pair<bool, unsigned long> PrimitiveThread::notifyWait(const TickType_t delay, const unsigned long set_on_entry, const unsigned long set_on_exit) const
{
ASSERT_IS_CURRENT();
unsigned long notification_value = 0;
const bool rval = xTaskNotifyWait(set_on_entry, set_on_exit, &notification_value, delay);
return {rval, notification_value};
}
PrimitiveThread::PrimitiveThread(osThreadFunc_t function, const osThreadAttr_t& attrs)
: thread_id(nullptr)
, attributes(attrs)
{
assert(function);
thread_id = osThreadNew(function, this, &attributes);
assert(thread_id != nullptr);
}
PrimitiveThread::PrimitiveThread(TaskHandle_t threadHandle)
: thread_id(static_cast<osThreadId_t>(threadHandle))
, attributes(Peripherals::zeroInitialized<osThreadAttr_t>())
{
assert(thread_id != nullptr);
}
osThreadAttr_t PrimitiveThread::constructThreadAttrs_(const char* name, const osPriority_t priority, const std::uint32_t stack_size)
{
auto attrs = Peripherals::zeroInitialized<osThreadAttr_t>();
attrs.name = name;
attrs.priority = priority;
attrs.stack_size = stack_size;
return attrs;
}
}