21 std::atomic<bool> PosixTask::s_permissions_reported(
false);
24 typedef void* (*pthread_func_ptr)(
void*);
33 #if defined(POSIX_THREADS_ENABLE_NAMES) && POSIX_THREADS_ENABLE_NAMES 40 wrapper.
run(&wrapper);
50 long page_size = sysconf(_SC_PAGESIZE);
55 Fw::Logger::log(
"[WARNING] %s could not determine page size %s. Skipping stack-size check.\n",
56 const_cast<CHAR*>(arguments.
m_name.
toChar()), strerror(errno));
57 }
else if ((stack % static_cast<FwSizeType>(page_size)) != 0) {
61 " is not multiple of page size %ld, rounding to %" PRI_FwSizeType "\n",
62 const_cast<CHAR*>(arguments.
m_name.
toChar()), stack, page_size, rounded);
67 if (stack <= static_cast<FwSizeType>(PTHREAD_STACK_MIN)) {
70 const_cast<CHAR*>(arguments.
m_name.
toChar()), stack, static_cast<FwSizeType>(PTHREAD_STACK_MIN));
71 stack =
static_cast<FwSizeType>(PTHREAD_STACK_MIN);
74 FW_ASSERT(stack >= static_cast<FwSizeType>(PTHREAD_STACK_MIN), static_cast<FwAssertArgType>(stack));
75 status = pthread_attr_setstacksize(&attributes, static_cast<size_t>(stack));
85 if (priority < min_priority) {
87 const_cast<CHAR*>(arguments.
m_name.
toChar()), priority, min_priority);
88 priority = min_priority;
91 else if (priority > max_priority) {
93 const_cast<CHAR*>(arguments.
m_name.
toChar()), priority, max_priority);
94 priority = max_priority;
98 FW_ASSERT(priority >= min_priority && priority <= max_priority, static_cast<FwAssertArgType>(priority));
101 status = pthread_attr_setschedpolicy(&attributes,
SCHED_POLICY);
103 status = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED);
106 sched_param schedParam;
107 (void)memset(&schedParam, 0,
sizeof(sched_param));
108 schedParam.sched_priority =
static_cast<int>(priority);
109 status = pthread_attr_setschedparam(&attributes, &schedParam);
119 #if defined(TGT_OS_TYPE_LINUX) && defined(__GLIBC__) && defined(_GNU_SOURCE) 122 FW_ASSERT(affinity < static_cast<FwSizeType>(CPU_SETSIZE), static_cast<FwAssertArgType>(affinity));
125 CPU_SET(static_cast<int>(affinity), &cpu_set);
128 status = pthread_attr_setaffinity_np(&attributes,
sizeof(cpu_set_t), &cpu_set);
131 Fw::Logger::log(
"[WARNING] %s setting CPU affinity is only available with GNU pthreads\n",
143 #if defined(TGT_OS_TYPE_LINUX) && defined(__GLIBC__) && defined(_GNU_SOURCE) && defined(POSIX_THREADS_ENABLE_NAMES) && \ 144 POSIX_THREADS_ENABLE_NAMES 147 status = pthread_setname_np(thread, name);
155 PosixTaskHandle& handle = this->m_handle;
158 pthread_attr_t attributes;
159 (void)memset(&attributes, 0,
sizeof(attributes));
160 pthread_status = pthread_attr_init(&attributes);
173 #if defined(POSIX_THREADS_ENABLE_NAMES) && POSIX_THREADS_ENABLE_NAMES 184 handle.m_is_valid =
true;
187 (void)pthread_attr_destroy(&attributes);
197 Os::Task::Status status = this->create(arguments, PermissionExpectation::EXPECT_PERMISSION);
199 if (status == Os::Task::Status::ERROR_PERMISSION) {
200 if (not PosixTask::s_permissions_reported) {
205 "[NOTE] You have insufficient permissions to create a task with priority and/or cpu affinity.\n");
206 Fw::Logger::log(
"[NOTE] A task without priority and affinity will be created.\n");
209 Fw::Logger::log(
"[NOTE] 1. Use tasks without priority and affinity using parameterless start()\n");
210 Fw::Logger::log(
"[NOTE] 2. Run this executable as a user with task priority permission\n");
211 Fw::Logger::log(
"[NOTE] 3. Grant capability with \"setcap 'cap_sys_nice=eip'\" or equivalent\n");
213 PosixTask::s_permissions_reported =
true;
216 status = this->create(arguments, PermissionExpectation::EXPECT_NO_PERMISSION);
218 Fw::Logger::log(
"[ERROR] Failed to create task with status: %d", static_cast<int>(status));
226 status = Os::Task::Status::INVALID_HANDLE;
235 return &this->m_handle;
250 timespec sleep_interval;
251 sleep_interval.tv_sec = interval.
getSeconds();
252 sleep_interval.tv_nsec = interval.
getUSeconds() * 1000;
254 timespec remaining_interval;
255 remaining_interval.tv_sec = 0;
256 remaining_interval.tv_nsec = 0;
259 int status = nanosleep(&sleep_interval, &remaining_interval);
265 else if (EINTR == errno) {
266 sleep_interval = remaining_interval;
271 task_status = Os::Task::Status::DELAY_ERROR;
Status _delay(const Fw::TimeInterval &interval) override
delay the current task
static constexpr FwSizeType TASK_DEFAULT
TaskHandle * getHandle() override
return the underlying task handle (implementation specific)
Task handle representation.
PlatformSizeType FwSizeType
const char * toChar() const
Convert to a C-style char*.
int set_priority_params(pthread_attr_t &attributes, const Os::Task::Arguments &arguments)
void suspend(SuspensionType suspensionType) override
suspend the task given the suspension type
static void log(const char *format,...)
log a formated string with supplied arguments
static constexpr int SUCCESS
void * m_routine_argument
static constexpr FwTaskPriorityType TASK_PRIORITY_DEFAULT
Task::Status posix_status_to_task_status(int posix_status)
message sent/received okay
bool m_is_valid
Is the above descriptor valid.
PermissionExpectation
Enumeration of permission expectations.
pthread_t m_task_descriptor
Posix task descriptor.
char * string_copy(char *destination, const char *source, FwSizeType num)
copy string with null-termination guaranteed
TaskHandle * getHandle() override
return the underlying task handle (implementation specific)
static void run(void *task_pointer)
run the task routine wrapper
static constexpr FwSizeType PTHREAD_NAME_LENGTH
Length of pthread name.
Wrapper for task routine that ensures onStart() is called once the task actually begins.
Task & m_task
Reference to owning task.
const Os::TaskString m_name
void * pthread_entry_wrapper(void *wrapper_pointer)
int set_stack_size(pthread_attr_t &attributes, const Os::Task::Arguments &arguments)
static const int SCHED_POLICY
Expect that you hold necessary permissions.
Status join() override
block until the task has ended
Status start(const Arguments &arguments) override
start the task
FwTaskPriorityType m_priority
int set_cpu_affinity(pthread_attr_t &attributes, const Os::Task::Arguments &arguments)
void resume() override
resume a suspended task
void onStart() override
perform required task start actions
int set_task_name(pthread_t thread, char *name)