std::this_thread::yield()

ESP_igrr
Posts: 2067
Joined: Tue Dec 01, 2015 8:37 am

Re: std::this_thread::yield()

Postby ESP_igrr » Mon Aug 06, 2018 9:26 am

permal wrote:needs to continually check them for readable/writable status (via select()) while at the same time handling events from other parts of the system
This may not necessarily be a solution in your case, but one quite common way to solve this problem is to open a loopback socket and have other events (or at least, wakeup signals corresponding to events) delivered through that socket. Then the thread can perform select (with non-zero timeout) on actual network sockets plus the "control" socket, avoiding the busy waiting.

In IDF, this pattern is used in the http server: https://github.com/espressif/esp-idf/tr ... r/src/util.

permal
Posts: 384
Joined: Sun May 14, 2017 5:36 pm

Re: std::this_thread::yield()

Postby permal » Mon Aug 06, 2018 10:34 am

Not easily, no. It is a nice trick though.

I'll go with the sleep_for-solution now. In practice it means that there is at maximum 1ms delay in (dis)connecting a socket and I can live with that. I'll likely revisit this at a later time.

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: std::this_thread::yield()

Postby ESP_Angus » Mon Aug 06, 2018 11:35 pm

permal wrote: So I see no other option than to do a std::this_thread::sleep_for instead of the yield(). However, times less than 1 ms result in the same behavior as the yield() call as I also wrote above. I take it this is due to the scheduler never getting around to starting the lower priority tasks?

Is there a way that I can calculate the minimum time a high priority task must sleep to guarantee lower priority tasks gets a chance to run, preferably at compile time? There's the setting for the tick frequency in FreeRTOS (CONFIG_FREERTOS_HZ). It's currently set att 1000Hz, so 1ms ticks - coincidence? Also, it is currently limited to max 1000Hz, is there a reason for that or could it be increased further?
You're right this is not a coincidence. The scheduler works in ticks as its timebase, so when a task is delayed it must be for an integer number of ticks.

Delaying for less than the tick length rounds down to delaying for zero ticks and becomes the same as a yield.

The tick length is limited to 1000Hz for two reasons:
  • A lot of code converts (integer) milliseconds to ticks by dividing by "ms per tick", which doesn't cleanly work for fractional values of ticks per ms.
  • Scheduler tick interrupts take some amount of CPU time to process, and having more than 1000 of them per second starts to get up to a sizeable overhead just processing ticks.
Would second Ivan's recommendation of a loopback "event" socket, if you're able to refactor to use one. Or you might be interested in the asio C++ library, for which support was recently added on the IDF master branch.

Who is online

Users browsing this forum: No registered users and 115 guests