15 typedef void* (*pthread_func_ptr)(
void*);
31 if (min_priority < 0 or max_priority < 0) {
32 Fw::Logger::logMsg(
"[WARNING] Unable to determine min/max priority with error %s. Discarding priority.\n",
reinterpret_cast<POINTER_CAST
>(strerror(errno)));
37 Fw::Logger::logMsg(
"[WARNING] Task priority set and permissions unavailable. Discarding priority.\n");
41 Fw::Logger::logMsg(
"[WARNING] Low task priority of %d being clamped to %d\n", priority, min_priority);
42 priority = min_priority;
45 Fw::Logger::logMsg(
"[WARNING] High task priority of %d being clamped to %d\n", priority, max_priority);
46 priority = max_priority;
50 Fw::Logger::logMsg(
"[WARNING] Stack size %d too small, setting to minimum of %d\n", stack, PTHREAD_STACK_MIN);
51 stack = PTHREAD_STACK_MIN;
55 Fw::Logger::logMsg(
"[WARNING] Cpu affinity set and permissions unavailable. Discarding affinity.\n");
63 I32 stat = pthread_attr_setstacksize(&att, stack);
65 Fw::Logger::logMsg(
"pthread_attr_setstacksize: %s\n",
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
74 I32 stat = pthread_attr_setschedpolicy(&att,
SCHED_POLICY);
76 Fw::Logger::logMsg(
"pthread_attr_setschedpolicy: %s\n",
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
80 stat = pthread_attr_setinheritsched(&att, PTHREAD_EXPLICIT_SCHED);
83 reinterpret_cast<POINTER_CAST
>(strerror(stat)));
87 sched_param schedParam;
88 memset(&schedParam, 0,
sizeof(sched_param));
89 schedParam.sched_priority = priority;
90 stat = pthread_attr_setschedparam(&att, &schedParam);
92 Fw::Logger::logMsg(
"pthread_attr_setschedparam: %s\n",
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
101 #ifdef TGT_OS_TYPE_LINUX
104 CPU_SET(cpuAffinity, &cpuset);
106 I32 stat = pthread_attr_setaffinity_np(&att,
sizeof(cpu_set_t), &cpuset);
109 reinterpret_cast<POINTER_CAST
>(strerror(stat)));
123 memset(&att,0,
sizeof(att));
126 I32 stat = pthread_attr_init(&att);
128 Fw::Logger::logMsg(
"pthread_attr_init: (%d): %s\n", stat,
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
152 const char* message =
NULL;
160 message =
"Invalid thread attributes specified";
164 message =
"Insufficient permissions to create thread. May not set thread priority without permission";
168 message =
"Unable to allocate thread. Increase thread ulimit.";
172 message =
"Unknown error";
176 (void)pthread_attr_destroy(&att);
180 Fw::Logger::logMsg(
"pthread_create: %s. %s\n",
reinterpret_cast<POINTER_CAST
>(message),
reinterpret_cast<POINTER_CAST
>(strerror(stat)));
186 Task::Task() : m_handle(0), m_identifier(0), m_affinity(-1), m_started(false), m_suspendedOnPurpose(false), m_routineWrapper() {
192 this->m_name =
"TP_";
193 this->m_name += name;
194 this->m_identifier = identifier;
196 this->m_routineWrapper.routine = routine;
197 this->m_routineWrapper.arg = arg;
201 TaskStatus status =
create_pthread(priority, stackSize, cpuAffinity, tid, &this->m_routineWrapper,
true);
203 if (status == TASK_ERROR_PERMISSION) {
205 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()));
206 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");
207 Fw::Logger::logMsg(
"[WARNING] Note: future releases of fprime will fail when setting priority/affinity without sufficient permissions \n");
209 status =
create_pthread(priority, stackSize, cpuAffinity, tid, &this->m_routineWrapper,
false);
212 if (status != TASK_OK) {
218 this->m_handle = (POINTER_CAST)tid;
221 if (Task::s_taskRegistry) {
222 Task::s_taskRegistry->addTask(
this);
231 time1.tv_sec = milliseconds/1000;
232 time1.tv_nsec = (milliseconds%1000)*1000000;
238 timespec* sleepTimePtr = &time1;
239 timespec* remTimePtr = &time2;
242 int stat = nanosleep(sleepTimePtr,remTimePtr);
246 if (EINTR == errno) {
247 timespec* temp = remTimePtr;
248 remTimePtr = sleepTimePtr;
252 return TASK_DELAY_ERROR;
261 if (this->m_handle) {
262 delete (pthread_t*)this->m_handle;
265 if (Task::s_taskRegistry) {
266 Task::s_taskRegistry->removeTask(
this);
274 void Task::suspend(
bool onPurpose) {
278 void Task::resume(
void) {
282 bool Task::isSuspended(
void) {
294 if (!(this->m_handle)) {
295 return TASK_JOIN_ERROR;
297 stat = pthread_join(*((pthread_t*) this->m_handle), value_ptr);
300 return TASK_JOIN_ERROR;