2020-08-13 20:53:35 +02:00
|
|
|
#include "../../tasks/ExecutableObjectIF.h"
|
|
|
|
#include "../../serviceinterface/ServiceInterfaceStream.h"
|
2018-07-13 18:28:26 +02:00
|
|
|
#include <errno.h>
|
2020-08-13 20:53:35 +02:00
|
|
|
#include "PeriodicPosixTask.h"
|
2018-07-13 18:28:26 +02:00
|
|
|
|
2020-06-06 15:47:33 +02:00
|
|
|
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_,
|
|
|
|
size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):
|
2020-09-04 14:49:59 +02:00
|
|
|
PosixThread(name_, priority_, stackSize_), objectList(), started(false),
|
|
|
|
periodMs(period_), deadlineMissedFunc(deadlineMissedFunc_) {
|
2018-07-13 18:28:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PeriodicPosixTask::~PeriodicPosixTask() {
|
|
|
|
//Not Implemented
|
|
|
|
}
|
|
|
|
|
|
|
|
void* PeriodicPosixTask::taskEntryPoint(void* arg) {
|
|
|
|
//The argument is re-interpreted as PollingTask.
|
|
|
|
PeriodicPosixTask *originalTask(reinterpret_cast<PeriodicPosixTask*>(arg));
|
|
|
|
//The task's functionality is called.
|
|
|
|
originalTask->taskFunctionality();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-08-04 15:19:31 +02:00
|
|
|
ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) {
|
2018-07-13 18:28:26 +02:00
|
|
|
ExecutableObjectIF* newObject = objectManager->get<ExecutableObjectIF>(
|
|
|
|
object);
|
2020-06-23 01:14:28 +02:00
|
|
|
if (newObject == nullptr) {
|
2020-09-04 14:49:59 +02:00
|
|
|
sif::error << "PeriodicTask::addComponent: Invalid object. Make sure"
|
|
|
|
<< " it implements ExecutableObjectIF!" << std::endl;
|
2018-07-13 18:28:26 +02:00
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
}
|
|
|
|
objectList.push_back(newObject);
|
2020-08-04 15:19:31 +02:00
|
|
|
newObject->setTaskIF(this);
|
2020-06-23 01:14:28 +02:00
|
|
|
|
2018-07-13 18:28:26 +02:00
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
|
|
|
|
return PosixThread::sleep((uint64_t)ms*1000000);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-04 14:49:59 +02:00
|
|
|
ReturnValue_t PeriodicPosixTask::startTask(void) {
|
2018-07-13 18:28:26 +02:00
|
|
|
started = true;
|
2020-06-06 15:47:33 +02:00
|
|
|
//sif::info << stackSize << std::endl;
|
|
|
|
PosixThread::createTask(&taskEntryPoint,this);
|
2018-07-13 18:28:26 +02:00
|
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
|
|
}
|
|
|
|
|
2020-09-04 14:49:59 +02:00
|
|
|
void PeriodicPosixTask::taskFunctionality(void) {
|
|
|
|
if(not started) {
|
2018-07-13 18:28:26 +02:00
|
|
|
suspend();
|
|
|
|
}
|
2020-09-04 14:43:53 +02:00
|
|
|
|
|
|
|
for (auto const &object: objectList) {
|
|
|
|
object->initializeAfterTaskCreation();
|
|
|
|
}
|
|
|
|
|
2018-07-13 18:28:26 +02:00
|
|
|
uint64_t lastWakeTime = getCurrentMonotonicTimeMs();
|
|
|
|
//The task's "infinite" inner loop is entered.
|
|
|
|
while (1) {
|
2020-09-04 14:43:53 +02:00
|
|
|
for (auto const &object: objectList) {
|
|
|
|
object->performOperation();
|
2018-07-13 18:28:26 +02:00
|
|
|
}
|
2020-09-04 14:43:53 +02:00
|
|
|
|
|
|
|
if(not PosixThread::delayUntil(&lastWakeTime, periodMs)){
|
2018-07-13 18:28:26 +02:00
|
|
|
char name[20] = {0};
|
2020-09-04 14:43:53 +02:00
|
|
|
int status = pthread_getname_np(pthread_self(), name, sizeof(name));
|
|
|
|
if(status == 0) {
|
2020-06-06 15:47:33 +02:00
|
|
|
sif::error << "PeriodicPosixTask " << name << ": Deadline "
|
|
|
|
"missed." << std::endl;
|
2020-09-04 14:43:53 +02:00
|
|
|
}
|
|
|
|
else {
|
2020-06-06 15:47:33 +02:00
|
|
|
sif::error << "PeriodicPosixTask X: Deadline missed. " <<
|
|
|
|
status << std::endl;
|
2018-07-13 18:28:26 +02:00
|
|
|
}
|
2020-09-04 14:43:53 +02:00
|
|
|
if (this->deadlineMissedFunc != nullptr) {
|
2018-07-13 18:28:26 +02:00
|
|
|
this->deadlineMissedFunc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t PeriodicPosixTask::getPeriodMs() const {
|
|
|
|
return periodMs;
|
|
|
|
}
|