F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
Task.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title Os/Task.cpp
3// \brief common function implementation for Os::Task
4// ======================================================================
5#include <Os/Task.hpp>
6#include <Fw/Types/Assert.hpp>
7
8namespace Os {
9
11 void * const routine_argument, const FwSizeType priority,
12 const FwSizeType stackSize, const FwSizeType cpuAffinity,
13 const PlatformUIntType identifier) :
14 m_name(name),
15 m_routine(routine),
16 m_routine_argument(routine_argument),
17 m_priority(priority),
18 m_stackSize(stackSize),
19 m_cpuAffinity(cpuAffinity),
20 m_identifier(identifier)
21{
22 FW_ASSERT(routine != nullptr);
23}
24
26
27void Task::TaskRoutineWrapper::run(void* wrapper_pointer) {
28 FW_ASSERT(wrapper_pointer != nullptr);
29 TaskRoutineWrapper& wrapper = *reinterpret_cast<TaskRoutineWrapper*>(wrapper_pointer);
30 FW_ASSERT(wrapper.m_user_function != nullptr);
31
32 wrapper.m_task.m_lock.lock();
33 Task::State state = wrapper.m_task.m_state;
34 wrapper.m_task.m_lock.unlock();
36 // Run once start code
37 if (state == Task::State::STARTING) {
38 wrapper.m_task.m_lock.lock();
39 wrapper.m_task.m_state = Task::State::RUNNING;
40 wrapper.m_task.m_lock.unlock();
41 wrapper.m_task.onStart();
42 }
43
44 // Call user function supplying the user argument
45 wrapper.m_user_function(wrapper.m_user_argument);
46}
47
51
52TaskRegistry* Task::s_taskRegistry = nullptr;
53FwSizeType Task::s_numTasks = 0;
54Mutex Task::s_taskMutex;
55
57 return false;
58}
59
60Task::Task() : m_wrapper(*this), m_handle_storage(), m_delegate(*TaskInterface::getDelegate(m_handle_storage)) {}
61
63 // If a registry has been registered and the task has been started then remove task from the registry
64 if ((Task::s_taskRegistry != nullptr) && this->m_registered) {
65 Task::s_taskRegistry->removeTask(this);
66 }
67 m_delegate.~TaskInterface();
68}
69
73
75 Task::State state;
76 this->m_lock.lock();
77 state = this->m_state;
78 this->m_lock.unlock();
79 return state;
80}
81
82Task::Status Task::start(const Fw::StringBase &name, const taskRoutine routine, void* const arg,
83 const ParamType priority, const ParamType stackSize, const ParamType cpuAffinity,
84 const ParamType identifier) {
85 FW_ASSERT(routine != nullptr);
86 return this->start(Task::Arguments(name, routine, arg,
87 priority,
88 stackSize,
89 cpuAffinity,
90 static_cast<PlatformUIntType>(identifier)));
91}
92
93
95 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
96 FW_ASSERT(arguments.m_routine != nullptr);
97 this->m_name = arguments.m_name;
98 this->m_state = State::STARTING;
99
100 Arguments wrapped_arguments = arguments;
101 // Intercept routine and argument with the local wrapper
102 this->m_wrapper.m_user_function = arguments.m_routine;
103 this->m_wrapper.m_user_argument = arguments.m_routine_argument;
104 wrapped_arguments.m_routine = Task::TaskRoutineWrapper::run;
105 wrapped_arguments.m_routine_argument = &this->m_wrapper;
106
107 Task::Status status = this->m_delegate.start(wrapped_arguments);
108 if (status == Task::Status::OP_OK) {
109 Task::m_lock.lock();
110 this->m_priority = wrapped_arguments.m_priority;
111 Task::m_lock.unlock();
112 Task::s_taskMutex.lock();
113 Task::s_numTasks++;
114 Task::s_taskMutex.unlock();
115
116 // If a registry has been registered, register task to it
117 if (Task::s_taskRegistry) {
118 Task::s_taskRegistry->addTask(this);
119 this->m_registered = true;
120 }
121 }
122 return status;
123}
124
126 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
127 this->m_delegate.onStart();
128}
129
131 this->m_wrapper.invoke();
132}
133
135 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
137 Task::State state = this->getState();
138 if (state == Task::RUNNING || state == STARTING) {
139 status = this->m_delegate.join();
140 this->m_lock.lock();
141 if (status == Task::Status::OP_OK) {
142 this->m_state = Task::State::EXITED;
143 } else {
144 this->m_state = Task::State::UNKNOWN;
145 }
146 this->m_lock.unlock();
147 }
148 return status;
149}
150
152 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
153 this->m_delegate.suspend(suspensionType);
154 this->m_lock.lock();
156 this->m_lock.unlock();
157}
158
160 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
161 this->m_delegate.resume();
162}
163
165 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
166 return this->m_delegate.isCooperative();
167}
168
170 Os::ScopeLock lock(this->m_lock);
171 return this->m_priority;
172}
173
175 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
176 return this->m_delegate.getHandle();
177}
178
180 Task::s_taskMutex.lock();
181 FwSizeType num_tasks = Task::s_numTasks;
182 Task::s_taskMutex.unlock();
183 return num_tasks;
184}
185
187 FW_ASSERT(&this->m_delegate == reinterpret_cast<TaskInterface*>(&this->m_handle_storage[0]));
188 return this->m_delegate._delay(interval);
189}
190
194
196 // Force trigger on the fly singleton setup
197 (void) Task::getSingleton();
198}
199
201 static Task s_singleton;
202 return s_singleton;
203}
204
206 Task::s_taskRegistry = registry;
207}
208}
#define FW_ASSERT(...)
Definition Assert.hpp:14
unsigned int PlatformUIntType
PlatformSizeType FwSizeType
Definition FpConfig.h:35
void unlock()
alias for unLock to meet BasicLockable requirements
Definition Mutex.hpp:63
void lock()
lock the mutex and assert success
Definition Mutex.cpp:34
locks a mutex within the current scope
Definition Mutex.hpp:79
Wrapper for task routine that ensures onStart() is called once the task actually begins.
Definition Task.hpp:199
void invoke()
invoke the run method with "self" as argument
Definition Task.cpp:48
static void run(void *task_pointer)
run the task routine wrapper
Definition Task.cpp:27
void * m_user_argument
Argument to user function.
Definition Task.hpp:215
TaskRoutineWrapper(Task &self)
Definition Task.cpp:25
Task & m_task
Reference to owning task.
Definition Task.hpp:213
taskRoutine m_user_function
User function to run once started.
Definition Task.hpp:214
Task handle representation.
Definition Task.hpp:24
static FwSizeType getNumTasks()
get the current number of tasks
Definition Task.cpp:179
bool isCooperative() override
determine if the task is cooperative multitasking (implementation specific)
Definition Task.cpp:164
static Status delay(Fw::TimeInterval interval)
delay the current task
Definition Task.cpp:191
Task()
default constructor
Definition Task.cpp:60
TaskHandle * getHandle() override
return the underlying task handle (implementation specific)
Definition Task.cpp:174
State getState()
get the task's state
Definition Task.cpp:74
FwSizeType getPriority()
get the task priority
Definition Task.cpp:169
FwSizeType ParamType
backwards-compatible parameter type
Definition Task.hpp:219
static Task & getSingleton()
get a reference to singleton
Definition Task.cpp:200
static void init()
initialize singleton
Definition Task.cpp:195
void resume() override
resume a suspended task
Definition Task.cpp:159
void onStart() override
perform delegate's required task start actions
Definition Task.cpp:125
Status _delay(Fw::TimeInterval interval) override
delay the current task
Definition Task.cpp:186
void invokeRoutine()
invoke the task's routine
Definition Task.cpp:130
void suspend()
suspend the current task
Definition Task.cpp:70
static void registerTaskRegistry(TaskRegistry *registry)
register a task registry to track Threads
Definition Task.cpp:205
Status start(const Arguments &arguments) override
start the task
Definition Task.cpp:82
~Task() final
default virtual destructor
Definition Task.cpp:62
Status join() override
block until the task has ended
Definition Task.cpp:134
Arguments(const Fw::StringBase &name, const taskRoutine routine, void *const routine_argument=nullptr, const FwSizeType priority=TASK_DEFAULT, const FwSizeType stackSize=TASK_DEFAULT, const FwSizeType cpuAffinity=TASK_DEFAULT, const PlatformUIntType identifier=static_cast< PlatformUIntType >(TASK_DEFAULT))
construct a set of arguments to start a task
Definition Task.cpp:10
const Os::TaskString m_name
Definition Task.hpp:83
virtual Status start(const Arguments &arguments)=0
start the task
virtual TaskHandle * getHandle()=0
return the underlying task handle (implementation specific)
virtual void suspend(SuspensionType suspensionType)=0
suspend the task given the suspension type
virtual Status join()=0
block until the task has ended
virtual void resume()=0
resume a suspended task
virtual Status _delay(Fw::TimeInterval interval)=0
delay the currently scheduled task using the given architecture
static TaskInterface * getDelegate(TaskHandleStorage &aligned_placement_new_memory)
provide a pointer to a task delegate object
@ SUSPENDED_INTENTIONALLY
Definition Task.hpp:52
@ SUSPENDED_UNINTENTIONALLY
Definition Task.hpp:53
virtual ~TaskInterface()=default
default virtual destructor
void(* taskRoutine)(void *ptr)
Prototype for task routine started in task context.
Definition Task.hpp:59
virtual void onStart()=0
perform required task start actions
@ INVALID_STATE
Task is in an invalid state for the operation.
Definition Task.hpp:40
@ OP_OK
message sent/received okay
Definition Task.hpp:30
virtual bool isCooperative()
determine if the task requires cooperative multitasking
Definition Task.cpp:56
virtual void addTask(Task *task)=0
add supplied task to the registry
virtual void removeTask(Task *task)=0
remove supplied task to the registry