FastLED 3.9.15
Loading...
Searching...
No Matches

◆ run()

void fl::task::run ( fl::u32 microseconds = 1000,
ExecFlags flags = ExecFlags::ALL )

Run selected task subsystems.

Pumps the requested subsystems and yields for up to microseconds.

Usage:

  • run() — pump ALL + yield for 1ms (default)
  • run(0) — pump ALL, no yield
  • run(250, ExecFlags::SYSTEM) — OS yield only (for DMA wait loops)
  • run(1000, ExecFlags::TASKS | ExecFlags::COROUTINES) — skip OS yield
Parameters
microsecondsBudget in microseconds (default 1000 = 1ms)
flagsWhich subsystems to pump (default ALL)

Definition at line 75 of file executor.cpp.hpp.

75 {
76 // Re-entrancy guard: detect if run is called from within run
78 if (running) {
79 FL_WARN_ONCE("task::run re-entrancy detected, skipping nested call");
80 return;
81 }
82 running = true;
83 auto guard = fl::make_scope_exit([&running]() { running = false; });
84
85 const bool do_tasks = flags & ExecFlags::TASKS;
86 const bool do_coroutines = flags & ExecFlags::COROUTINES;
87 const bool do_system = flags & ExecFlags::SYSTEM;
88
89 // Calculate start time with rollover protection
90 fl::u32 begin_time = fl::micros();
91
92 // Lambda to get elapsed time (rollover-safe)
93 auto elapsed = [begin_time]() {
94 return fl::micros() - begin_time;
95 };
96
97 // Lambda to get remaining time until deadline expires
98 auto remaining = [elapsed, microseconds]() -> fl::u32 {
99 fl::u32 e = elapsed();
100 if (e >= microseconds) {
101 return 0;
102 }
103 return microseconds - e;
104 };
105
106 // Lambda to check if deadline has expired
107 auto expired = [remaining]() {
108 return remaining() == 0;
109 };
110
111 do {
112 // TASKS: Scheduler (fl::task timers) + Executor (fetch, HTTP server, audio)
113 if (do_tasks) {
116 }
117
118 // SYSTEM: OS-level yield.
119 //
120 // When the caller provided a non-zero microseconds budget we treat
121 // this as an explicit spin-wait on hardware (typical DMA / driver
122 // wait loops). In that case we MUST use a deep yield (>= 1 FreeRTOS
123 // tick on ESP32) so that lower-priority network tasks — WiFi,
124 // Ethernet lwIP, etc. — actually get CPU time. Previously this
125 // path was gated on an active WiFi mode check, which missed
126 // Ethernet-only deployments and also the pre-connection window
127 // where `esp_wifi_get_mode` still returns WIFI_MODE_NULL. That
128 // regression manifested as the ESP32-S3 I2S-vs-websockets
129 // starvation reported in https://github.com/FastLED/FastLED/issues/2254
130 // (Issue 1).
131 //
132 // When microseconds == 0 the caller wants the cheapest possible
133 // yield (we are between other pumped subsystems and will loop
134 // again immediately), so we keep the lightweight fl::yield() path.
135 if (do_system) {
136 if (microseconds > 0) {
137 fl::platforms::ICoroutineRuntime::instance().pumpCoroutines(1000);
138 } else {
139 fl::yield();
140 }
141 }
142
143 // COROUTINES: Platform cooperative coroutines (pumpCoroutines)
144 if (do_coroutines) {
145 auto time_left = remaining();
146 if (time_left) {
147 fl::u32 sleep_us = fl::min(1000u, time_left);
148 fl::platforms::ICoroutineRuntime::instance().pumpCoroutines(sleep_us);
149 }
150 }
151 } while (!expired());
152}
static T & instance() FL_NOEXCEPT
Definition singleton.h:133
void update_all()
Update all registered runners.
static Executor & instance()
static Scheduler & instance()
#define FL_WARN_ONCE(X)
Definition log.h:278
duration< fl::i64, fl::micro > microseconds
Microseconds - duration with period of 1/1,000,000 seconds.
Definition chrono.h:100
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
Definition math.h:71
scope_exit< decay_t< EF > > make_scope_exit(EF &&f)
Factory for C++11/14 (no CTAD).
Definition scope_exit.h:48
fl::u32 micros()
Universal microsecond timer - returns microseconds since system startup.
void yield()
Yield to the platform scheduler.
Definition yield.cpp.hpp:31

References COROUTINES, FL_WARN_ONCE, fl::SingletonThreadLocal< T, N >::instance(), fl::task::Executor::instance(), fl::task::Scheduler::instance(), fl::make_scope_exit(), fl::micros(), fl::min(), SYSTEM, TASKS, fl::task::Scheduler::update(), fl::task::Executor::update_all(), and fl::yield().

Referenced by await_top_level(), fl::detail::delay_impl(), fl::net::http::fetch_update(), loop(), fl::net::http::FetchEngineListener::onEndFrame(), CFastLED::show(), CFastLED::showColor(), fl::ChannelManager::waitForCondition(), and fl::IChannelDriver::waitForCondition().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: