8000 WIP: py: Implement mp_sched_vm_abort() to force a return to the very top level by dpgeorge · Pull Request #10241 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

WIP: py: Implement mp_sched_vm_abort() to force a return to the very top level #10241

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

Closed
wants to merge 6 commits into from

Conversation

dpgeorge
Copy link
Member

This is an alternative to #9949 which does a "very long jump" to force the VM to stop and return up to the very top level of code control (usually pyexec).

The idea is for the top level to mark its nlr_buf as the special one to return to. Then a call to mp_sched_vm_abort() will schedule (indicate to) the VM that it should stop immediately. The VM (actually mp_handle_pending() the next time it is run) will then jump to this special nlr_buf (bypassing all those nlr bufs in between).

This approach should work with multiple threads. Only the main thread handles the abort.

@dpgeorge dpgeorge added the py-core Relates to py/ directory in source label Dec 16, 2022
@github-actions
Copy link
github-actions bot commented Dec 16, 2022

Code size report:

   bare-arm:    +4 +0.007% 
minimal x86:    +0 +0.000% 

@jimmo
Copy link
Member
jimmo commented Dec 16, 2022

Further to #9949 (comment) -- the original intent was that setting the pending exception would also set MP_SCHED_PENDING, but this won't happen (in mp_sched_exception) when the scheduler is locked.

One way to solve this without adding an extra check in the VM might be to rework the two state variables...

Currently we have:
sched_state: Serves as both the lock count (< 0), idle (0), or pending-or-exception (1)
mp_pending_exception: Either NULL, SENTINEL (abort), or exception.

Instead we could do:
sched_lock_depth: Only the lock depth (0 or positive). (Exactly like gc_lock_depth)
mp_pending_exception: Either NULL, SENTINEL (abort OR scheduler pending), or exception.

This would mean that the VM only ever checks mp_pending_exception. In threading builds, it has to check the pending exception on both the current thread and the main thread (but in this scenario there's currently two checks anyway). (See #8838 (comment) for why we support per-thread pending exceptions).

Here's an attempt at implementing that (also it comes out at -48 bytes code size):
jimmo@6980fee

@dpgeorge
Copy link
Member Author
dpgeorge commented Dec 23, 2022

It might be possible to also catch hard IRQs by using nlr_set_abort() in the hard IRQ (and restoring the previous one on exit from the hard IRQ), then rescheduling the VM abort to propagate it out (if it was raised).

@dpgeorge
Copy link
Member Author

I've now incorporated the commit mentioned by @jimmo above.

Also made it so abort can now abort a scheduled function, as well as the possibility to abort hard IRQ handlers (and an example is given for stm32 pin IRQs).

jimmo and others added 6 commits January 25, 2023 17:31
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
@codecov-commenter
Copy link
codecov-commenter commented Jan 25, 2023

Codecov Report

Merging #10241 (4ad904c) into master (67fac4e) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master   #10241   +/-   ##
=======================================
  Coverage   98.50%   98.50%           
=======================================
  Files         155      155           
  Lines       20540    20543    +3     
=======================================
+ Hits        20232    20236    +4     
+ Misses        308      307    -1     
Impacted Files Coverage Δ
py/nlr.c 100.00% <ø> (ø)
py/runtime.h 100.00% <ø> (ø)
py/runtime.c 98.89% <100.00%> (+<0.01%) ⬆️
py/scheduler.c 98.41% <100.00%> (+1.63%) ⬆️
py/vm.c 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@dlech
Copy link
Contributor
dlech commented Jan 25, 2023

These changes are quite difficult to follow when just looking at the code. Can we add more comments in the code to explain what is going on?

@dpgeorge
Copy link
Member Author

It should be easier to follow if you look at each commit separately (the first one is effectively a refactoring and does most of the work here).

But yes I'll also add comments.

@dpgeorge dpgeorge changed the title py: Implement mp_sched_vm_abort() to force a return to the very top level WIP: py: Implement mp_sched_vm_abort() to force a return to the very top level Feb 1, 2023
@dpgeorge dpgeorge marked this pull request as draft February 1, 2023 12:40
@dpgeorge
Copy link
Member Author
dpgeorge commented Feb 1, 2023

I've now incorporated the commit mentioned by @jimmo above.

Upon closer inspection of this commit, it introduces a problem: pending exceptions (eg a keyboard interrupt) can now be caught by scheduled functions. In practice this means that a ctrl-C could be caught by, eg, a soft interrupt handler, and that handler would terminate early but the ctrl-C would not propagate out any further, and so the main application keeps running.

This is a tricky/complex situation. Maybe we do want ctrl-C to stop a scheduled function (because that function may be in an infinite loop), but we'd definitely then want that ctrl-C to propagate out and also terminate the main code. But that's really getting out of scope of this PR.

@dpgeorge
Copy link
Member Author

Closing in favour of #10971.

@dpgeorge dpgeorge closed this Mar 10, 2023
@dpgeorge dpgeorge deleted the py-sched-vm-abort branch March 10, 2023 11:18
tannewt added a commit to tannewt/circuitpython that referenced this pull request May 9, 2025
This fixes an issue where a terminal can't be started after being
stopped (when tilegrid_tiles is freed and set to NULL.)

Fixes micropython#10241
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0