arduino-audio-tools
Loading...
Searching...
No Matches
Task.h
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>
11
12namespace audio_tools {
13
18class Task {
19 public:
20 Task(const char *name, int stackSize, int priority = 1, int core = -1) {
21 (void)name;
22 (void)stackSize;
23 (void)priority;
24 (void)core; // parameters unused
25 }
26 Task() = default;
27 ~Task() { remove(); }
28
29 bool create(const char *name, int stackSize, int priority = 1,
30 int core = -1) {
31 (void)name;
32 (void)stackSize;
33 (void)priority;
34 (void)core; // parameters unused
35 return true;
36 }
37
38 bool begin(std::function<void()> process) {
39 if (running_thread.joinable()) return false; // already running
40 loop_code = process;
41 terminate_flag = false;
42 // start suspended similar to FreeRTOS create+suspend pattern
43 paused = false;
44 running_thread = std::thread([this] { this->thread_loop(); });
45 return true;
46 }
47
48 void end() { remove(); }
49
50 void remove() {
51 terminate_flag = true;
52 resume(); // wake if paused
53 if (running_thread.joinable()) {
54 if (std::this_thread::get_id() == running_thread.get_id()) {
55 // Avoid deadlock: cannot join the current thread; detach instead
56 running_thread.detach();
57 } else {
58 running_thread.join();
59 }
60 }
61 }
62
63 void suspend() {
64 std::lock_guard<std::mutex> lk(mtx);
65 paused = true;
66 }
67
68 void resume() {
69 {
70 std::lock_guard<std::mutex> lk(mtx);
71 paused = false;
72 }
73 cv.notify_all();
74 }
75
76 // API compatibility – return thread id reference surrogate
77 std::thread::id &getTaskHandle() { return thread_id; }
78
79 void setReference(void *r) { ref = r; }
80 void *getReference() { return ref; }
81
82 protected:
83 std::thread running_thread;
84 std::thread::id thread_id{};
85 std::function<void()> loop_code = nop;
86 void *ref = nullptr;
87 std::atomic<bool> terminate_flag{false};
88 std::mutex mtx;
89 std::condition_variable cv;
90 bool paused = false;
91
92 static void nop() {
93 std::this_thread::sleep_for(std::chrono::milliseconds(100));
94 }
95
96 void thread_loop() {
97 thread_id = std::this_thread::get_id();
98 while (!terminate_flag.load()) {
99 // wait while paused
100 {
101 std::unique_lock<std::mutex> lk(mtx);
102 cv.wait(lk, [this] { return !paused || terminate_flag.load(); });
103 }
104 if (terminate_flag.load()) break;
105 if (loop_code)
106 loop_code();
107 else
108 nop();
109 }
110 }
111};
112
113} // namespace audio_tools
114
115#endif // __linux__
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:32
void remove()
deletes the FreeRTOS task
Definition Task.h:49
Task(const char *name, int stackSize, int priority=1, int core=-1)
Defines and creates a FreeRTOS task.
Definition Task.h:24
void end()
suspends the task
Definition Task.h:65
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10