Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixes per review
  • Loading branch information
d-a-v committed Jan 14, 2023
commit 4d17f1b8084d87144b362ec9796507adb888ed08
10 changes: 6 additions & 4 deletions cores/esp8266/Schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include <assert.h>
#include <numeric>

#include "Schedule.h"
#include "PolledTimeout.h"
Expand All @@ -34,8 +35,7 @@ static scheduled_fn_t* sFirst = nullptr;
static scheduled_fn_t* sLast = nullptr;
static scheduled_fn_t* sUnused = nullptr;
static int sCount = 0;

uint32_t recurrent_max_grain_mS = 0;
static uint32_t recurrent_max_grain_mS = 0;

typedef std::function<bool(void)> mRecFuncT;
struct recurrent_fn_t
Expand Down Expand Up @@ -138,15 +138,15 @@ bool schedule_recurrent_function_us(const std::function<bool(void)>& fn,
return true;
}

void update_recurrent_grain ()
uint32_t compute_recurrent_grain ()
{
if (recurrent_max_grain_mS == 0)
{
if (rFirst)
{
uint32_t recurrent_max_grain_uS = rFirst->callNow.getTimeout();
for (auto it = rFirst->mNext; it; it = it->mNext)
recurrent_max_grain_uS = compute_gcd(recurrent_max_grain_uS, it->callNow.getTimeout());
recurrent_max_grain_uS = std::gcd(recurrent_max_grain_uS, it->callNow.getTimeout());
if (recurrent_max_grain_uS)
// round to the upper millis
recurrent_max_grain_mS = recurrent_max_grain_uS <= 1000? 1: (recurrent_max_grain_uS + 999) / 1000;
Expand All @@ -161,6 +161,8 @@ void update_recurrent_grain ()
}
#endif
}

return recurrent_max_grain_mS;
}

void run_scheduled_functions()
Expand Down
10 changes: 4 additions & 6 deletions cores/esp8266/Schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,10 @@
// scheduled function happen more often: every yield() (vs every loop()),
// and time resolution is microsecond (vs millisecond). Details are below.

// recurrent_max_grain_mS is used by delay() to let a chance to all
// recurrent functions to accomplish their duty per their timing
// requirement.
// When it is 0, update_recurrent_grain() can be called to recalculate it.
extern uint32_t recurrent_max_grain_mS;
void update_recurrent_grain ();
// compute_recurrent_grain() is used by delay() to give a chance to all
// recurrent functions to run per their timing requirement.

uint32_t compute_recurrent_grain ();

// scheduled functions called once:
//
Expand Down
14 changes: 8 additions & 6 deletions cores/esp8266/core_esp8266_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

//This may be used to change user task stack size:
//#define CONT_STACKSIZE 4096

#include <numeric>

#include <Arduino.h>
#include "Schedule.h"
extern "C" {
Expand Down Expand Up @@ -168,14 +171,13 @@ bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uin
return true; // expired
}

// possibly recompute recurrent scheduled functions common timing grain
update_recurrent_grain();

// update intvl_ms according to this grain
uint32_t ms = compute_gcd(intvl_ms, recurrent_max_grain_mS);
// compute greatest chunked delay with respect to scheduled recurrent functions
uint32_t grain_ms = std::gcd(intvl_ms, compute_recurrent_grain());

// recurrent scheduled functions will be called from esp_delay()->esp_suspend()
esp_delay(ms? std::min((timeout_ms - expired), ms): (timeout_ms - expired));
esp_delay(grain_ms > 0 ?
std::min((timeout_ms - expired), grain_ms):
(timeout_ms - expired));

return false; // expiration must be checked again
}
Expand Down
14 changes: 0 additions & 14 deletions cores/esp8266/coredecls.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,4 @@ inline void esp_delay(const uint32_t timeout_ms, T&& blocked) {
esp_delay(timeout_ms, std::forward<T>(blocked), timeout_ms);
}

// Greatest Common Divisor Euclidian algorithm
// one entry may be 0, the other is returned
template <typename T>
auto compute_gcd (T a, T b)
{
while (b)
{
auto t = b;
b = a % b;
a = t;
}
return a;
}

#endif // __cplusplus
5 changes: 2 additions & 3 deletions libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,7 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) {
//tasks to wait correctly.
constexpr unsigned int timeoutValue = 1000; //1 second
if(can_yield()) {
// The final argument, intvl_ms, to esp_delay determines at least
// how frequently wifi_get_opmode() is checked
// check opmode every 100ms or give up after timeout
esp_delay(timeoutValue, [m]() { return wifi_get_opmode() != m; }, 100);

//if at this point mode still hasn't been reached, give up
Expand Down Expand Up @@ -642,7 +641,7 @@ static int hostByNameImpl(const char* aHostname, IPAddress& aResult, uint32_t ti
// We need to wait for c/b to fire *or* we exit on our own timeout
// (which also requires us to notify the c/b that it is supposed to delete the pending obj)
case ERR_INPROGRESS:
// esp_delay will be interrupted by found callback
// sleep until dns_found_callback is called or timeout is reached
esp_delay(timeout_ms, [&]() { return !pending->done; });

if (pending->done) {
Expand Down