-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Renamings for that esp_yield
is really suspend, replacing delay(0), shimmable suspend-CONT API for async esp_suspend() / esp_schedule()
#7148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4df7186
b64622d
9bb4894
97d59ae
08ed7d0
397408f
0bb470c
971ad28
99ed6fc
cd8d2d3
070eb48
d11be8b
4b92d28
208c4a3
3720ac0
3be70a4
67ced12
62af940
863c482
679ecb1
6199eb9
7cfaeea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,7 +62,7 @@ cont_t* g_pcont __attribute__((section(".noinit"))); | |
static os_event_t s_loop_queue[LOOP_QUEUE_SIZE]; | ||
|
||
/* Used to implement optimistic_yield */ | ||
static uint32_t s_cycles_at_yield_start; | ||
static uint32_t s_cycles_at_resume; | ||
|
||
/* For ets_intr_lock_nest / ets_intr_unlock_nest | ||
* Max nesting seen by SDK so far is 2. | ||
|
@@ -80,6 +80,10 @@ const char* core_release = | |
#else | ||
NULL; | ||
#endif | ||
|
||
static os_timer_t delay_timer; | ||
#define ONCE 0 | ||
#define REPEAT 1 | ||
} // extern "C" | ||
|
||
void initVariant() __attribute__((weak)); | ||
|
@@ -106,32 +110,71 @@ extern "C" void __preloop_update_frequency() { | |
extern "C" void preloop_update_frequency() __attribute__((weak, alias("__preloop_update_frequency"))); | ||
|
||
extern "C" bool can_yield() { | ||
return cont_can_yield(g_pcont); | ||
return cont_can_suspend(g_pcont); | ||
} | ||
|
||
static inline void esp_yield_within_cont() __attribute__((always_inline)); | ||
static void esp_yield_within_cont() { | ||
cont_yield(g_pcont); | ||
s_cycles_at_yield_start = ESP.getCycleCount(); | ||
static inline void esp_suspend_within_cont() __attribute__((always_inline)); | ||
static void esp_suspend_within_cont() { | ||
cont_suspend(g_pcont); | ||
s_cycles_at_resume = ESP.getCycleCount(); | ||
run_scheduled_recurrent_functions(); | ||
} | ||
|
||
extern "C" void __esp_yield() { | ||
if (can_yield()) { | ||
esp_yield_within_cont(); | ||
extern "C" void __esp_suspend() { | ||
if (cont_can_suspend(g_pcont)) { | ||
esp_suspend_within_cont(); | ||
} | ||
} | ||
|
||
extern "C" void esp_yield() __attribute__ ((weak, alias("__esp_yield"))); | ||
extern "C" void esp_suspend() __attribute__ ((weak, alias("__esp_suspend"))); | ||
|
||
extern "C" IRAM_ATTR void esp_schedule() { | ||
ets_post(LOOP_TASK_PRIORITY, 0, 0); | ||
} | ||
|
||
// Replacement for delay(0). In CONT, same as yield(). Whereas yield() panics | ||
// in SYS, esp_yield() is safe to call and only schedules CONT. Use yield() | ||
// whereever only called from CONT, use esp_yield() if code is called from SYS | ||
// or both CONT and SYS. | ||
extern "C" void esp_yield() { | ||
esp_schedule(); | ||
esp_suspend(); | ||
} | ||
|
||
void delay_end(void* arg) { | ||
(void)arg; | ||
esp_schedule(); | ||
} | ||
|
||
extern "C" void __esp_delay(unsigned long ms) { | ||
if (ms) { | ||
os_timer_setfn(&delay_timer, (os_timer_func_t*)&delay_end, 0); | ||
os_timer_arm(&delay_timer, ms, ONCE); | ||
} | ||
else { | ||
esp_schedule(); | ||
} | ||
esp_suspend(); | ||
if (ms) { | ||
os_timer_disarm(&delay_timer); | ||
} | ||
} | ||
|
||
extern "C" void esp_delay(unsigned long ms) __attribute__((weak, alias("__esp_delay"))); | ||
|
||
bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uint32_t intvl_ms) { | ||
uint32_t expired = millis() - start_ms; | ||
if (expired >= timeout_ms) { | ||
return true; | ||
} | ||
esp_delay(std::min((timeout_ms - expired), intvl_ms)); | ||
return false; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about commenting the choice of this name (is it interrupting tasks calling ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what happened, but you must not have available the current sources somehow.
Meaning, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I forgot to disable my previous answer before the last one. Sorry that this confused you. So you propose If the earlier discussion you refer to is that one, it also says:
@devyte maybe you can elaborate on this:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @d-a-v Thanks, one can never look too many times at the code. I'm going to explain next that it's a bit different than you think, but that wasn't helped by me replacing
|
||
extern "C" void __yield() { | ||
if (can_yield()) { | ||
if (cont_can_suspend(g_pcont)) { | ||
esp_schedule(); | ||
esp_yield_within_cont(); | ||
esp_suspend_within_cont(); | ||
} | ||
else { | ||
panic(); | ||
|
@@ -140,14 +183,17 @@ extern "C" void __yield() { | |
|
||
extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); | ||
|
||
// In CONT, actually performs yield() only once the given time interval | ||
// has elapsed since the last time yield() occured. Whereas yield() panics | ||
// in SYS, optimistic_yield() additionally is safe to call and does nothing. | ||
extern "C" void optimistic_yield(uint32_t interval_us) { | ||
const uint32_t intvl_cycles = interval_us * | ||
#if defined(F_CPU) | ||
clockCyclesPerMicrosecond(); | ||
#else | ||
ESP.getCpuFreqMHz(); | ||
#endif | ||
if ((ESP.getCycleCount() - s_cycles_at_yield_start) > intvl_cycles && | ||
if ((ESP.getCycleCount() - s_cycles_at_resume) > intvl_cycles && | ||
can_yield()) | ||
{ | ||
yield(); | ||
|
@@ -207,16 +253,16 @@ static void loop_wrapper() { | |
|
||
static void loop_task(os_event_t *events) { | ||
(void) events; | ||
s_cycles_at_yield_start = ESP.getCycleCount(); | ||
s_cycles_at_resume = ESP.getCycleCount(); | ||
ESP.resetHeap(); | ||
cont_run(g_pcont, &loop_wrapper); | ||
ESP.setDramHeap(); | ||
if (cont_check(g_pcont) != 0) { | ||
panic(); | ||
} | ||
} | ||
extern "C" { | ||
|
||
extern "C" { | ||
struct object { long placeholder[ 10 ]; }; | ||
void __register_frame_info (const void *begin, struct object *ob); | ||
extern char __eh_frame[]; | ||
|
@@ -253,7 +299,6 @@ static void __unhandled_exception_cpp() | |
} | ||
#endif | ||
} | ||
|
||
} | ||
|
||
void init_done() { | ||
|
Uh oh!
There was an error while loading. Please reload this page.