17 typedef void* (*pthread_func_ptr)(
void*);
33 if (min_priority < 0 or max_priority < 0) {
34 Fw::Logger::logMsg(
"[WARNING] Unable to determine min/max priority with error %s. Discarding priority.\n",
reinterpret_cast<POINTER_CAST
>(strerror(errno)));
39 Fw::Logger::logMsg(
"[WARNING] Task priority set and permissions unavailable. Discarding priority.\n");
43 Fw::Logger::logMsg(
"[WARNING] Low task priority of %d being clamped to %d\n", priority, min_priority);
44 priority = min_priority;
47 Fw::Logger::logMsg(
"[WARNING] High task priority of %d being clamped to %d\n", priority, max_priority);
48 priority = max_priority;
52 Fw::Logger::logMsg(
"[WARNING] Stack size %d too small, setting to minimum of %d\n", stack, PTHREAD_STACK_MIN);
53 stack = PTHREAD_STACK_MIN;
57 Fw::Logger::logMsg(
"[WARNING] Cpu affinity set and permissions unavailable. Discarding affinity.\n");
65 I32 stat = pthread_attr_setstacksize(&att, stack);
67 Fw::Logger::logMsg(
"pthread_attr_setstacksize: %s\n",
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
76 I32 stat = pthread_attr_setschedpolicy(&att,
SCHED_POLICY);
78 Fw::Logger::logMsg(
"pthread_attr_setschedpolicy: %s\n",
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
82 stat = pthread_attr_setinheritsched(&att, PTHREAD_EXPLICIT_SCHED);
85 reinterpret_cast<POINTER_CAST
>(strerror(stat)));
89 sched_param schedParam;
90 memset(&schedParam, 0,
sizeof(sched_param));
91 schedParam.sched_priority = priority;
92 stat = pthread_attr_setschedparam(&att, &schedParam);
94 Fw::Logger::logMsg(
"pthread_attr_setschedparam: %s\n",
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
103 #ifdef TGT_OS_TYPE_LINUX
106 CPU_SET(cpuAffinity, &cpuset);
108 I32 stat = pthread_attr_setaffinity_np(&att,
sizeof(cpu_set_t), &cpuset);
111 reinterpret_cast<POINTER_CAST
>(strerror(stat)));
125 memset(&att,0,
sizeof(att));
128 I32 stat = pthread_attr_init(&att);
130 Fw::Logger::logMsg(
"pthread_attr_init: (%d): %s\n", stat,
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
154 const char* message =
nullptr;
162 message =
"Invalid thread attributes specified";
166 message =
"Insufficient permissions to create thread. May not set thread priority without permission";
170 message =
"Unable to allocate thread. Increase thread ulimit.";
174 message =
"Unknown error";
178 (void)pthread_attr_destroy(&att);
180 (void)pthread_join(*tid,
nullptr);
183 Fw::Logger::logMsg(
"pthread_create: %s. %s\n",
reinterpret_cast<POINTER_CAST
>(message),
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
189 Task::Task() : m_handle(reinterpret_cast<POINTER_CAST>(nullptr)), m_identifier(0), m_affinity(-1), m_started(false), m_suspendedOnPurpose(false), m_routineWrapper() {
195 this->m_name =
"TP_";
196 this->m_name += name;
197 this->m_identifier = identifier;
199 this->m_routineWrapper.routine = routine;
200 this->m_routineWrapper.arg = arg;
204 TaskStatus status =
create_pthread(priority, stackSize, cpuAffinity, tid, &this->m_routineWrapper,
true);
206 if (status == TASK_ERROR_PERMISSION) {
208 Fw::Logger::logMsg(
"[WARNING] Insufficient permissions to set task priority or set task CPU affinity on task %s. Creating task without priority nor affinity.\n",
reinterpret_cast<POINTER_CAST
>(m_name.toChar()));
209 Fw::Logger::logMsg(
"[WARNING] Please use no-argument <component>.start() calls, set priority/affinity to TASK_DEFAULT or ensure user has correct permissions for operating system.\n");
210 Fw::Logger::logMsg(
"[WARNING] Note: future releases of fprime will fail when setting priority/affinity without sufficient permissions \n");
212 status =
create_pthread(priority, stackSize, cpuAffinity, tid, &this->m_routineWrapper,
false);
215 if (status != TASK_OK) {
221 this->m_handle =
reinterpret_cast<POINTER_CAST
>(tid);
224 if (Task::s_taskRegistry) {
225 Task::s_taskRegistry->addTask(
this);
234 time1.tv_sec = milliseconds/1000;
235 time1.tv_nsec = (milliseconds%1000)*1000000;
241 timespec* sleepTimePtr = &time1;
242 timespec* remTimePtr = &time2;
245 int stat = nanosleep(sleepTimePtr,remTimePtr);
249 if (EINTR == errno) {
250 timespec* temp = remTimePtr;
251 remTimePtr = sleepTimePtr;
255 return TASK_DELAY_ERROR;
264 if (this->m_handle) {
265 delete reinterpret_cast<pthread_t*
>(this->m_handle);
268 if (Task::s_taskRegistry) {
269 Task::s_taskRegistry->removeTask(
this);
277 void Task::suspend(
bool onPurpose) {
281 void Task::resume() {
285 bool Task::isSuspended() {
297 if (!(this->m_handle)) {
298 return TASK_JOIN_ERROR;
300 stat = pthread_join(*
reinterpret_cast<pthread_t*
>(this->m_handle), value_ptr);
303 return TASK_JOIN_ERROR;