F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
Task.hpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title Os/Task.hpp
3 // \brief common function definitions for Os::Task
4 // ======================================================================
5 #ifndef Os_Task_hpp_
6 #define Os_Task_hpp_
7 
8 #include <FpConfig.hpp>
9 #include <Fw/Time/Time.hpp>
11 #include <Os/Os.hpp>
12 #include <Os/TaskString.hpp>
13 #include <Os/Mutex.hpp>
14 
15 #include <Fw/Deprecate.hpp>
16 #include <limits>
17 
18 namespace Os {
19 
20  // Forward declarations
21  class TaskRegistry;
22 
24  class TaskHandle {};
25 
26  class TaskInterface {
27  public:
28  static constexpr FwSizeType TASK_DEFAULT = std::numeric_limits<FwSizeType>::max();
29  enum Status {
41  };
42 
46  };
47 
48  enum State {
54  UNKNOWN
55  };
56 
58  typedef void (*taskRoutine)(void* ptr);
59 
60  class Arguments {
61  public:
74  Arguments(const Fw::StringBase& name, const taskRoutine routine,
75  void* const routine_argument = nullptr,
76  const FwSizeType priority = TASK_DEFAULT,
77  const FwSizeType stackSize = TASK_DEFAULT,
78  const FwSizeType cpuAffinity = TASK_DEFAULT,
79  const PlatformUIntType identifier = static_cast<PlatformUIntType>(TASK_DEFAULT));
80 
81  public:
89  };
90 
92  TaskInterface() = default;
93 
95  virtual ~TaskInterface() = default;
96 
98  TaskInterface(const TaskInterface& other) = delete;
99 
101  TaskInterface& operator=(const TaskInterface& other) = delete;
102 
103  // =================
104  // Implementation functions (static) to be supplied by the linker
105  // =================
106 
114  static Status delay(Fw::Time interval);
115 
135  static TaskInterface* getDelegate(HandleStorage& aligned_placement_new_memory);
136 
137  // =================
138  // Implementation functions (instance) to be supplied by the Os::TaskInterface children
139  // =================
140 
142  virtual void onStart() = 0;
143 
150  virtual Status join() = 0;
151 
159  virtual void suspend(SuspensionType suspensionType) = 0;
160 
165  virtual void resume() = 0;
166 
177  virtual bool isCooperative();
178 
181  virtual TaskHandle* getHandle() = 0;
182 
189  virtual Status start(const Arguments& arguments) = 0;
190  };
191 
195  class Task final : public TaskInterface {
196  public:
199  public:
200  explicit TaskRoutineWrapper(Task& self);
201 
207  static void run(void* task_pointer);
208 
210  void invoke();
211 
214  void* m_user_argument = nullptr;
215  };
216 
219 
221  Task();
222 
224  ~Task() final;
225 
227  Task(const Task& other) = delete;
228 
230  Task& operator=(const Task& other) = delete;
231 
236  void suspend();
237 
244  State getState();
245 
260  DEPRECATED(Status start(const Fw::StringBase &name, const taskRoutine routine, void* const arg = nullptr,
261  const ParamType priority = TASK_DEFAULT,
262  const ParamType stackSize = TASK_DEFAULT,
263  const ParamType cpuAffinity = TASK_DEFAULT,
264  const ParamType identifier = TASK_DEFAULT), "Switch to Task::start(Arguments&)");
265 
271  //
276  Status start(const Arguments& arguments) override;
277 
279  void onStart() override;
280 
282  //~
285  void invokeRoutine();
286 
294  DEPRECATED(Status join(void** value_ptr), "Please switch to argument free join.");
295 
302  Status join() override;
303 
311  void suspend(SuspensionType suspensionType) override;
312 
317  void resume() override;
318 
321  bool isCooperative() override;
322 
325  TaskHandle* getHandle() override;
326 
329  static FwSizeType getNumTasks();
330 
333  static void registerTaskRegistry(TaskRegistry* registry);
334 
335  PRIVATE:
336  static TaskRegistry* s_taskRegistry;
337  static FwSizeType s_numTasks;
338  static Mutex s_taskMutex;
339 
340  TaskString m_name;
341  TaskInterface::State m_state = Task::NOT_STARTED;
342  Mutex m_lock;
343  TaskRoutineWrapper m_wrapper;
344 
345  bool m_registered = false;
346 
347  // This section is used to store the implementation-defined file handle. To Os::File and fprime, this type is
348  // opaque and thus normal allocation cannot be done. Instead, we allow the implementor to store then handle in
349  // the byte-array here and set `handle` to that address for storage.
350  //
351  alignas(FW_HANDLE_ALIGNMENT) HandleStorage m_handle_storage;
352  TaskInterface& m_delegate;
353  };
354 
355  class TaskRegistry {
356  public:
358  TaskRegistry() = default;
360  virtual ~TaskRegistry() = default;
364  virtual void addTask(Task* task) = 0;
365 
369  virtual void removeTask(Task* task) = 0;
370  };
371 }
372 
373 #endif
unsigned int PlatformUIntType
#define FW_HANDLE_ALIGNMENT
Alignment of handle storage.
Definition: FpConfig.h:378
PlatformSizeType FwSizeType
Definition: FpConfig.h:30
C++-compatible configuration header for fprime configuration.
U8 HandleStorage[FW_HANDLE_MAX_SIZE]
Storage type for OSAL handles.
Definition: Os.hpp:10
Definition: Time.hpp:9
Wrapper for task routine that ensures onStart() is called once the task actually begins.
Definition: Task.hpp:198
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:214
TaskRoutineWrapper(Task &self)
Definition: Task.cpp:25
Task & m_task
Reference to owning task.
Definition: Task.hpp:212
taskRoutine m_user_function
User function to run once started.
Definition: Task.hpp:213
Task handle representation.
Definition: Task.hpp:24
static FwSizeType getNumTasks()
get the current number of tasks
Definition: Task.cpp:170
bool isCooperative() override
determine if the task is cooperative multitasking (implementation specific)
Definition: Task.cpp:160
DEPRECATED(Status start(const Fw::StringBase &name, const taskRoutine routine, void *const arg=nullptr, const ParamType priority=TASK_DEFAULT, const ParamType stackSize=TASK_DEFAULT, const ParamType cpuAffinity=TASK_DEFAULT, const ParamType identifier=TASK_DEFAULT), "Switch to Task::start(Arguments&)")
start this task
Task()
default constructor
Definition: Task.cpp:60
TaskHandle * getHandle() override
return the underlying task handle (implementation specific)
Definition: Task.cpp:165
State getState()
get the task's state
Definition: Task.cpp:74
FwSizeType ParamType
backwards-compatible parameter type
Definition: Task.hpp:218
void resume() override
resume a suspended task
Definition: Task.cpp:155
void onStart() override
perform delegate's required task start actions
Definition: Task.cpp:121
void invokeRoutine()
invoke the task's routine
Definition: Task.cpp:126
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:177
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:130
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:82
FwSizeType m_cpuAffinity
Definition: Task.hpp:87
PlatformUIntType m_identifier
Definition: Task.hpp:88
virtual TaskHandle * getHandle()=0
return the underlying task handle (implementation specific)
static TaskInterface * getDelegate(HandleStorage &aligned_placement_new_memory)
provide a pointer to a task delegate object
Definition: DefaultTask.cpp:41
virtual Status start(const Arguments &arguments)=0
start the task
TaskInterface(const TaskInterface &other)=delete
copy constructor is forbidden
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
TaskInterface()=default
default constructor
static constexpr FwSizeType TASK_DEFAULT
Definition: Task.hpp:28
@ SUSPENDED_INTENTIONALLY
Definition: Task.hpp:51
@ SUSPENDED_UNINTENTIONALLY
Definition: Task.hpp:52
virtual ~TaskInterface()=default
default virtual destructor
void(* taskRoutine)(void *ptr)
Prototype for task routine started in task context.
Definition: Task.hpp:58
TaskInterface & operator=(const TaskInterface &other)=delete
assignment operator is forbidden
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
@ UNKNOWN_ERROR
unexpected error return value
Definition: Task.hpp:34
@ ERROR_PERMISSION
permissions error setting-up tasks
Definition: Task.hpp:39
@ INVALID_PARAMS
started task with invalid parameters
Definition: Task.hpp:32
@ ERROR_RESOURCES
unable to allocate more tasks
Definition: Task.hpp:38
@ DELAY_ERROR
error trying to delay the task
Definition: Task.hpp:36
@ INVALID_STACK
started with invalid stack size
Definition: Task.hpp:33
@ INVALID_HANDLE
Task handle invalid.
Definition: Task.hpp:31
@ INVALID_AFFINITY
unable to set the task affinity
Definition: Task.hpp:35
@ JOIN_ERROR
error trying to join the task
Definition: Task.hpp:37
virtual bool isCooperative()
determine if the task requires cooperative multitasking
Definition: Task.cpp:56
static Status delay(Fw::Time interval)
delay the current task
Definition: DefaultTask.cpp:11
TaskRegistry()=default
default task registry constructor
virtual void addTask(Task *task)=0
add supplied task to the registry
virtual void removeTask(Task *task)=0
remove supplied task to the registry
virtual ~TaskRegistry()=default
default task registry constructor