-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Docs: Detail issue with hard ISRs and globals. #10620
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
Conversation
I don't normally ping, but I think there is a significant issue here. It concerns professional applications where reliability is paramount. Knowing that small int access is atomic, the programmer might think a global provides a safe way to return data from a hard ISR. I was surprised to learn from @jimmo that this is not guaranteed. Is there a safe way to return a small int from a hard ISR short of using (e.g) a threadsafe queue? |
Sorry I missed this in January @peterhinch . I think this is a good improvement, and is a lot better than what was there before. You are of course correct, we really need to nail down the semantics of what is and isn't defined behavior in the face of hard IRQs, and now that we're supporting GIL-less multithreading on the rp2 the same applies there too (but with a lot more scope for problems!).
My understanding is that your updated wording is correct. It is safe to write a small int to a global variable (or a class attribute *) as long as there is no chance the underlying dictionary can be in the middle of a re-hash when the IRQ fires.
a = 0
b = SomeClass()
def on_irq(p):
a = 1 # bad,
b.attr = 2 # also bad
def main():
...
if something:
c = True # c global is created in the middle of the program's execution, might cause rehash which makes access to `a` and `b` invalid in ISR. class Ok:
def __init__(self):
def on_irq(p):
self.attr = 1 # safe as long as this instance's dict isn't changing, doesn't matter what's going on with globals (So, for example, ThreadSafeFlag is safe). I'm fairly sure a closure around a local would be safe to. @dpgeorge would need to confirm. def main():
a = 0
def on_irq(p):
a = 1
Specifically for the case of returning a small int, it should always be possible to find some shared scope to put the small int on. Maybe I'm misunderstanding the question though? i.e. if you explicitly want to be able to queue up multiple interrupts worth of values to application code that consumes them asynchronously? Even if you had some sort of ISR-safe queue, you still need a way to access the queue. (As you say in the new wording in this PR, accessing a global for read from an ISR is still a problem). It's implementing an ISR-safe queue that's the hard part! |
Thank you. I think for most applications the aim should be to define all globals (including class instances) before initiating hard IRQ's - and never to delete globals. You might want to comment on #9458 - a possible ISR-safe queue. |
I agree this is an issue that needs clarifying. But maybe we can improve the situation so it "just works". See #11604 for an attempt at that, which makes rehashing atomic wrt IRQ handlers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should merge this, it's an important and useful clarification. The style is maybe a bit inaccessible, it could be presented as a list of "safe" and "unsafe" code samples - but the style is already there in the existing doc so this is still an improvement.
If we make the ISR-safety of objects better in the future then we'll need to update the docs again then, anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let's merge this.
Signed-off-by: Damien George <damien@micropython.org>
This comes out of discussions with @jimmo: there seems to be a hazard which may be little known.
I am unclear about the status of user classes which have bound variables. Are these implemented as a
dict
?