Merge pull request 'Allow creating regular threads' (#140) from allow_creating_regular_threads into develop

Reviewed-on: #140
This commit is contained in:
Robin Müller 2023-03-24 14:15:53 +01:00
commit b814e7198f
10 changed files with 74 additions and 35 deletions

View File

@ -20,16 +20,18 @@ TaskFactory::~TaskFactory() = default;
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
PeriodicTaskIF* TaskFactory::createPeriodicTask( PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskPeriod periodInSeconds_,
TaskDeadlineMissedFunction deadLineMissedFunction_,
void* args) {
return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_, return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_); deadLineMissedFunction_);
} }
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask( FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_, return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_); deadLineMissedFunction_);
} }

View File

@ -7,10 +7,15 @@
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_, FixedTimeslotTask::FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_) TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
PosixThreadArgs* args)
: FixedTimeslotTaskBase(periodSeconds_, dlmFunc_), : FixedTimeslotTaskBase(periodSeconds_, dlmFunc_),
posixThread(name_, priority_, stackSize_), posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
started(false) {} started(false) {
if (args != nullptr) {
posixThread.setSchedPolicy(args->policy);
}
}
void* FixedTimeslotTask::taskEntryPoint(void* arg) { void* FixedTimeslotTask::taskEntryPoint(void* arg) {
// The argument is re-interpreted as PollingTask. // The argument is re-interpreted as PollingTask.

View File

@ -23,7 +23,8 @@ class FixedTimeslotTask : public FixedTimeslotTaskBase {
* @param deadlineMissedFunc_ * @param deadlineMissedFunc_
*/ */
FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_, FixedTimeslotTask(const char* name_, TaskPriority priority_, size_t stackSize_,
TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_); TaskPeriod periodSeconds_, TaskDeadlineMissedFunction dlmFunc_,
PosixThreadArgs* args);
~FixedTimeslotTask() override = default; ~FixedTimeslotTask() override = default;
ReturnValue_t startTask() override; ReturnValue_t startTask() override;

View File

@ -4,10 +4,15 @@
#include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h"
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_) TaskPeriod period_, TaskDeadlineMissedFunction dlmFunc_,
PosixThreadArgs* args)
: PeriodicTaskBase(period_, dlmFunc_), : PeriodicTaskBase(period_, dlmFunc_),
posixThread(name_, priority_, stackSize_), posixThread(name_, SchedulingPolicy::REGULAR, priority_, stackSize_),
started(false) {} started(false) {
if (args != nullptr) {
posixThread.setSchedPolicy(args->policy);
}
}
void* PeriodicPosixTask::taskEntryPoint(void* arg) { void* PeriodicPosixTask::taskEntryPoint(void* arg) {
// The argument is re-interpreted as PollingTask. // The argument is re-interpreted as PollingTask.

View File

@ -24,7 +24,7 @@ class PeriodicPosixTask : public PeriodicTaskBase {
* @param deadlineMissedFunc_ * @param deadlineMissedFunc_
*/ */
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_, PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, TaskPeriod period_,
TaskDeadlineMissedFunction dlmFunc_); TaskDeadlineMissedFunction dlmFunc_, PosixThreadArgs* args);
~PeriodicPosixTask() override = default; ~PeriodicPosixTask() override = default;
/** /**

View File

@ -7,8 +7,9 @@
#include "fsfw/osal/linux/unixUtility.h" #include "fsfw/osal/linux/unixUtility.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_) PosixThread::PosixThread(const char* name_, SchedulingPolicy schedPolciy, int priority_,
: thread(0), priority(priority_), stackSize(stackSize_) { size_t stackSize_)
: thread(0), schedPolicy(schedPolciy), priority(priority_), stackSize(stackSize_) {
name[0] = '\0'; name[0] = '\0';
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1); std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
} }
@ -178,20 +179,30 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
#ifndef FSFW_USE_REALTIME_FOR_LINUX #ifndef FSFW_USE_REALTIME_FOR_LINUX
#error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1" #error "Please define FSFW_USE_REALTIME_FOR_LINUX with either 0 or 1"
#endif #endif
#if FSFW_USE_REALTIME_FOR_LINUX == 1 if (schedPolicy == SchedulingPolicy::RR) {
// RR -> This needs root privileges for the process // RR -> This needs root privileges for the process
#if FSFW_USE_REALTIME_FOR_LINUX == 1
status = pthread_attr_setschedpolicy(&attributes, SCHED_RR); status = pthread_attr_setschedpolicy(&attributes, SCHED_RR);
if (status != 0) { if (status != 0) {
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy"); utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedpolicy");
} }
sched_param scheduleParams; sched_param scheduleParams;
scheduleParams.__sched_priority = priority; scheduleParams.sched_priority = priority;
status = pthread_attr_setschedparam(&attributes, &scheduleParams); status = pthread_attr_setschedparam(&attributes, &scheduleParams);
if (status != 0) { if (status != 0) {
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_setschedparam"); #if FSFW_CPP_OSTREAM_ENABLED == 1
} sif::warning << "PosixThread: Setting priority failed" << std::endl;
#endif #endif
}
#else
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning
<< "Real time priorities are only allowed if FSFW_USE_REALTIME_FOR_LINUX is set to 1"
<< std::endl;
#endif
#endif
}
// Set Signal Mask for suspend until startTask is called // Set Signal Mask for suspend until startTask is called
sigset_t waitSignal; sigset_t waitSignal;
sigemptyset(&waitSignal); sigemptyset(&waitSignal);
@ -243,3 +254,5 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_destroy"); utility::printUnixErrorGeneric(CLASS_NAME, "createTask", "pthread_attr_destroy");
} }
} }
void PosixThread::setSchedPolicy(SchedulingPolicy policy) { this->schedPolicy = policy; }

View File

@ -9,10 +9,15 @@
#include "../../returnvalues/returnvalue.h" #include "../../returnvalues/returnvalue.h"
enum SchedulingPolicy { REGULAR, RR };
struct PosixThreadArgs {
SchedulingPolicy policy = SchedulingPolicy::REGULAR;
};
class PosixThread { class PosixThread {
public: public:
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16; static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
PosixThread(const char* name_, int priority_, size_t stackSize_); PosixThread(const char* name_, SchedulingPolicy schedPolicy, int priority_, size_t stackSize_);
virtual ~PosixThread(); virtual ~PosixThread();
/** /**
* Set the Thread to sleep state * Set the Thread to sleep state
@ -20,6 +25,9 @@ class PosixThread {
* @return Returns Failed if sleep fails * @return Returns Failed if sleep fails
*/ */
static ReturnValue_t sleep(uint64_t ns); static ReturnValue_t sleep(uint64_t ns);
void setSchedPolicy(SchedulingPolicy policy);
/** /**
* @brief Function to suspend the task until SIGUSR1 was received * @brief Function to suspend the task until SIGUSR1 was received
* *
@ -72,6 +80,7 @@ class PosixThread {
private: private:
char name[PTHREAD_MAX_NAMELEN]; char name[PTHREAD_MAX_NAMELEN];
SchedulingPolicy schedPolicy;
int priority; int priority;
size_t stackSize = 0; size_t stackSize = 0;

View File

@ -12,18 +12,20 @@ TaskFactory::~TaskFactory() = default;
TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; }
PeriodicTaskIF* TaskFactory::createPeriodicTask( PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskPeriod periodInSeconds_,
TaskDeadlineMissedFunction deadLineMissedFunction_,
void* args) {
return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_, return new PeriodicPosixTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_); deadLineMissedFunction_, reinterpret_cast<PosixThreadArgs*>(args));
} }
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask( FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(
TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_) { TaskPeriod periodInSeconds_, TaskDeadlineMissedFunction deadLineMissedFunction_, void* args) {
return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_, return new FixedTimeslotTask(name_, taskPriority_, stackSize_, periodInSeconds_,
deadLineMissedFunction_); deadLineMissedFunction_, reinterpret_cast<PosixThreadArgs*>(args));
} }
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {

View File

@ -47,7 +47,8 @@ class TaskFactory {
*/ */
PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_, PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_,
TaskStackSize stackSize_, TaskPeriod periodInSeconds_, TaskStackSize stackSize_, TaskPeriod periodInSeconds_,
TaskDeadlineMissedFunction deadLineMissedFunction_); TaskDeadlineMissedFunction deadLineMissedFunction_,
void* args = nullptr);
/** /**
* The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks. * The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks.
@ -62,7 +63,8 @@ class TaskFactory {
FixedTimeslotTaskIF* createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_, FixedTimeslotTaskIF* createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_,
TaskStackSize stackSize_, TaskStackSize stackSize_,
TaskPeriod periodInSeconds_, TaskPeriod periodInSeconds_,
TaskDeadlineMissedFunction deadLineMissedFunction_); TaskDeadlineMissedFunction deadLineMissedFunction_,
void* args = nullptr);
/** /**
* Function to be called to delete a task * Function to be called to delete a task

View File

@ -69,6 +69,6 @@ void flushTxRxBuf(int fd);
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter); int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
} // namespace uart } // namespace serial
#endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */ #endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */