-
-
Notifications
You must be signed in to change notification settings - Fork 127
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
RingBuffer - is inherently unsafe if either store_char or read_char is called from an interrupt. #195
Comments
The RingBuffer class is not supposed to be threadsafe which is why i.e. |
Quick note: I have a quick and dirty test sketch, that is setup for UNOR4 boards:
And it does not hit the error condition often, but when it does it would then forever be out of sync.
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why: The class has a member variable: _numElems
Which is updated by both of these methods.
For example
unless _numElems-- is atomic, there is the risk that in between the fetch and store, an interrupt happens which calls store_char one or more times, which each of these calls does numElems++. The store operation will then miss these other changes.
Context: - I am currently experimenting with changes the the SerialX objects for the Uno R4 code base, and was seeing that the processing of interrupts either to store away a character received into one Ring Buffer or to fetch the next byte from the write ring buffer to output, was taking more time than I was expecting. More of this in the issue:
arduino/ArduinoCore-renesas#75
Possible solution: In the past I and I know many others have written buffer classes that the store_char method, would only update the _iHead member variable, and the read_char only updates the _iTail member, and when necessary, you compute how many elements are in the buffer, like:
Which is safer. It does not solve the multiple producers or consumers problem.
For those cases you might need something like the SafeRingBuffer code that is in that core. Although I have modified version, which only protects one side. either the Reads or the Writes, where the other side has only the single consumer or producer of the interrupt.
I am testing a version of this now, which appears to be faster.
Should the API version be updated?
The text was updated successfully, but these errors were encountered: