arduino-audio-tools
Loading...
Searching...
No Matches
Task.h
Go to the documentation of this file.
1// Linux Task implementation using std::thread to mimic FreeRTOS Task API
2#pragma once
3#ifdef USE_CPP_TASK
4
5#include <atomic>
6#include <chrono>
7#include <condition_variable>
8#include <functional>
9#include <mutex>
10#include <thread>
12
13namespace audio_tools {
14
21class Task : public ITask {
22 public:
23 Task(const char *name, int stackSize, int priority = 1, int core = -1) {
24 (void)name;
27 (void)core; // parameters unused
28 }
29 Task() = default;
30 ~Task() { remove(); }
31
32 bool create(const char *name, int stackSize, int priority = 1,
33 int core = -1) {
34 (void)name;
37 (void)core; // parameters unused
38 return true;
39 }
40
41 bool begin(std::function<void()> process) {
42 if (running_thread.joinable()) return false; // already running
43 loop_code = process;
44 terminate_flag = false;
45 // start suspended similar to FreeRTOS create+suspend pattern
46 paused = false;
47 running_thread = std::thread([this] { this->thread_loop(); });
48 return true;
49 }
50
51 void end() { remove(); }
52
53 void remove() {
54 terminate_flag = true;
55 resume(); // wake if paused
56 if (running_thread.joinable()) {
57 if (std::this_thread::get_id() == running_thread.get_id()) {
58 // Avoid deadlock: cannot join the current thread; detach instead
59 running_thread.detach();
60 } else {
61 running_thread.join();
62 }
63 }
64 }
65
66 void suspend() {
67 std::lock_guard<std::mutex> lk(mtx);
68 paused = true;
69 }
70
71 void resume() {
72 {
73 std::lock_guard<std::mutex> lk(mtx);
74 paused = false;
75 }
76 cv.notify_all();
77 }
78
79 // API compatibility – return thread id reference surrogate
80 std::thread::id &getTaskHandle() { return thread_id; }
81
82 void setReference(void *r) { ref = r; }
83 void *getReference() { return ref; }
84
85 protected:
86 std::thread running_thread;
87 std::thread::id thread_id{};
88 std::function<void()> loop_code = nop;
89 void *ref = nullptr;
90 std::atomic<bool> terminate_flag{false};
91 std::mutex mtx;
92 std::condition_variable cv;
93 bool paused = false;
94
95 static void nop() {
96 std::this_thread::sleep_for(std::chrono::milliseconds(100));
97 }
98
99 void thread_loop() {
100 thread_id = std::this_thread::get_id();
101 while (!terminate_flag.load()) {
102 // wait while paused
103 {
104 std::unique_lock<std::mutex> lk(mtx);
105 cv.wait(lk, [this] { return !paused || terminate_flag.load(); });
106 }
107 if (terminate_flag.load()) break;
108 if (loop_code)
109 loop_code();
110 else
111 nop();
112 }
113 }
114};
115
116} // namespace audio_tools
117
118#endif // __linux__
void * getReference()
Definition Task.h:83
bool create(const char *name, int stackSize, int priority=1, int core=-1)
If you used the empty constructor, you need to call create!
Definition Task.h:36
void * ref
Definition Task.h:96
~Task()
Definition Task.h:33
TaskHandle_t & getTaskHandle()
Definition Task.h:75
void remove()
deletes the FreeRTOS task
Definition Task.h:53
void suspend()
Definition Task.h:71
void resume()
Definition Task.h:73
static void nop()
Definition Task.h:98
void end()
suspends the task
Definition Task.h:69
std::function< void()> loop_code
Definition Task.h:95
bool begin(std::function< void()> process)
Definition Task.h:61
void setReference(void *r)
Definition Task.h:79
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
TaskZephyr Task
Compatibility typedef for RTOS-based task naming.
Definition Task.h:128
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508