arduino / reference-en

Editable source for the Arduino Reference
https://www.arduino.cc/reference/en/
Other
163 stars 733 forks source link

documentation about delay() in std::thread (and other multithreading) environments #783

Open dsyleixa opened 5 years ago

dsyleixa commented 5 years ago

In the documentation about delay() https://www.arduino.cc/reference/en/language/functions/time/delay/ there is no statement about blocking in C++ std::thread environments, vs. std::this_thread::sleep_for();

can you please add them?

Perhaps also hints about additional pros and cons, e.g. to thread safety or perhaps race conditions would be appreciated, e.g. see this discussion:

https://github.com/espressif/arduino-esp32/issues/2814#issuecomment-495616606

atanisoft commented 5 years ago

The arduino-esp32 project has no control over what is documented on www.arduino.cc, you would need to open an issue against the https://github.com/arduino/Arduino project instead likely.

dsyleixa commented 5 years ago

isn't this then at this place here already the right place though? https://github.com/arduino/Arduino/issues/8911

atanisoft commented 5 years ago

Sorry missed that :)

per1234 commented 5 years ago

I'm not knowledgeable on this topic, so I have some questions:

Wouldn't this be obvious already to someone advanced enough to use std::thread?

You say in https://github.com/arduino/Arduino/issues/8720#issuecomment-495528077 that it doesn't even compile for Arduino boards. So why should we add beginner-unfriendly information to our documentation for something that isn't even supported on our platforms?

dsyleixa commented 5 years ago

hello, some attempts to answer your questions:

per1234 commented 5 years ago

Arduino already supports ESP32 and other 3rd party boards, and that is actually just the original Arduino IDE idea: 1 IDE with 1 API that fits many different boards, even those which are are not selled by Aduino.cc itself.

We don't host and maintain documentation specific to 3rd party boards. That is the responsibility of the 3rd parties.

dsyleixa commented 5 years ago

my question is not about the documentation to 3rd party boards, but about how delay() works in C++, e.g. compared to sleep/sleep_for() but I see that the topic can be expanded to delay also with respect to Scheduler and RTOS and other Arduino MT environments. OTOH, it's not even clear what delay() actually does and how it works in single-thread environments.

matthijskooijman commented 5 years ago

The documentation does have a warning already (I pasted just the first bit, there's more):

While it is easy to create a blinking LED with the delay() function, and many sketches use short delays for such tasks as switch debouncing, the use of delay() in a sketch has significant drawbacks. No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function, so in effect, it brings most other activity to a halt.

This could be taken to mean that all other activity (e.g. other threads) will stop working. Also, I believe that if std::thread is implemented in the way that it was intended (which is, AFAICS, to start OS-threads), using delay() would work fine (it would be inefficient since it busy-waits the CPU, but other threads could preempt the delaying thread normally). I suspect the ESP implementation uses a cooperative model instead, where blocking a thread is actually problematic, but that is probably better documented on esp-side instead of here.

Regardless, improving the documentation about how delay works could be beneficial, if we can do it in a way that:

Given that, do you perhaps have a specific suggestion for what to add to the documentation or how to modify it? That might make further discussion more directed as well :-)

dsyleixa commented 5 years ago

@matthijskooijman: yes, I gladly will contribute, if I once will know solid facts and details about delay and threads. BTW, your statement/suspect about cooperative threads used by esp32 is actually puzzling me - all I can see are std::thread from which are supposed to be C++ compatible, i.g. preemptive (CMIIW). Can you please comment on this more detailed? Do you have a suggestion how that might be tested? Perhaps we can also continue this std::thread discussion in https://github.com/arduino/Arduino/issues/8720#issuecomment-495528077 if you wish!

matthijskooijman commented 5 years ago

BTW, your statement/suspect about cooperative threads used by esp32 is actually puzzling me - all I can see are std::thread from which are supposed to be C++ compatible, i.g. preemptive (CMIIW).

I might be wrong here, but I've understood your initial post here to mean that using delay() inside a std::thread causes breakage (e.g. causes the system to lock up during the delay). However, if std::thread is preemptive, then a blocking delay could cause performance issues (one thread that takes up CPU time doing nothing), but the delay should be preempted normally and other threads should still work (though, depending on scheduling choices, this might mean that the delay value is less accurate than using the C++ thread delay functions, since then the scheduler can make more informed decisions in the latter case).

It might very well be that I've jumped to a conclusion about preemptive vs cooperative, though I think it does not really influence the discussion about documentation much (other that showing that it might be even more complicated to document details about interaction with std::thread if there are implementation differences between different cores/architectures.

dsyleixa commented 5 years ago

thank you, I see.

[OT]Nonetheless, I'll try to check that preemptive/cooperative thing additionally somewhere else. [/OT]

dsyleixa commented 5 years ago

update: esp32 std::thread is truely preemptive, just tested by my own sketch: https://github.com/arduino/Arduino/issues/8720#issuecomment-495911059

PaulStoffregen commented 5 years ago

Might be worth considering that the vast majority of hardware-accessing libraries for Arduino are not thread safe for a preemptive multithreading system.

dsyleixa commented 5 years ago

that is not important actually, 1st of all that is no difference to the esp32 implementation (using FreeRTOS?) , and OTOH one may use mutexes. Additionally I suspect that for TeensyThread that is also similar.

PaulStoffregen commented 5 years ago

Yes, similar situation with TeensyThreads.

Adding C++ STL syntax documentation on Arduino's website (which is a complex syntax very much not the sort of thing Arduino promotes) for 1 function isn't going to make any substantial difference for a problem which is really a large ecosystem not designed to be used with preemptive multithreading.

dsyleixa commented 5 years ago

I didn't say it was a work in the park ;)

PaulStoffregen commented 5 years ago

Arduino has a long tradition of not showing STL and C++ template syntax on their website, in examples, or anywhere else ordinary Arduino users look. Much of Arduino's success is attributed to keeping their API and examples and documentation simple & clean & free of syntax which intimidates beginners.

Arduino also has a very long history of rejecting proposals to adopt traditional or "standard" syntax, like printf, cout redirect, and C++ STL. Many, many people have come before you, arguing that this stuff is "standard" and must be documented, made available as APIs, and even used in examples. As you can see from the website, software and examples, they've stayed true to their decisions to keep the syntax simple.

dsyleixa commented 5 years ago

that is an unreasonable manslaughter argument

Instead, a documentation about what a function actually does, by which restrctions, is inevitable to understand program behaviour and to write reasonable prgramming code.