-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
examples/usercmodule: Add finaliser to cexample. #13011
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
e45023b
to
d7ba712
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #13011 +/- ##
==========================================
+ Coverage 98.39% 98.43% +0.03%
==========================================
Files 161 158 -3
Lines 21200 20978 -222
==========================================
- Hits 20860 20649 -211
+ Misses 340 329 -11 ☔ View full report in Codecov by Sentry. |
|
||
#if ENABLE_DEINIT_FUNCTION && !MICROPY_ENABLE_FINALISER | ||
#error example deinit requires: MICROPY_ENABLE_FINALISER | ||
#endif |
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 remove this ENABLE_DEINIT_FUNCTION
option and unconditionally have the finaliser there.
@@ -24,6 +32,9 @@ typedef struct _example_Timer_obj_t { | |||
// cannot be accessed by MicroPython code directly. In this example we | |||
// store the time at which the object was created. | |||
mp_uint_t start_time; | |||
#if ENABLE_DEINIT_FUNCTION | |||
bool init; |
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.
Adjust the comment just above to mention the use of this new member.
example_Timer_obj_t *self = MP_OBJ_TO_PTR(self_in); | ||
if (self->init) { | ||
self->init = false; | ||
mp_printf(MICROPY_ERROR_PRINTER, "de-init cexample resources.\n"); |
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.
Please use MP_PYTHON_PRINTER, and I suggest no full-stop at the end of the sentence.
This is an automated heads-up that we've just merged a Pull Request See #13763 A search suggests this PR might apply the STATIC macro to some C code. If it Although this is an automated message, feel free to @-reply to me directly if |
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
d7ba712
to
c846071
Compare
This PR has been rebased and the comments addressed. Ready for re-review thanks! |
Signed-off-by: Andrew Leech <andrew@alelec.net>
50caf27
to
d0528fe
Compare
@dpgeorge there's something strange going on with running the finalizer, or not. This PR adds the print statement in This test is failing however, never seeing that new printout. I've added two new smaller tests to explicitly trigger the collect, which are both passing here in CI now. However in my home computer one of them fails. This works:
This fails to run the finalizer
Adding a time.sleep_ms(100) instead of |
Could try to |
Yeah I did try that earlier, tried to trim the repros down to the minimum. Just running it twice didn't seem to fix it. I also had cases like:
where the collect would run the finalizer in the final two instances (verified with extra print(self) in C code) but the one for the original instance never gets run. |
It can be finicky.. E.g. I have this somewhere to force TheThing to be collected:
silly thing is that back when I wrote it I spent some time figuring out on the gc level why exactly that extra code was needed but didn't write it down :( |
That's really interesting, I got the impression that the number of allocations before and after was key here. More importantly, I need to test whether it's always reliability run on soft-reboot; the point of this example / usage pattern is to use a finalizer to deinit hardware resources or similar, if that's not run when needed then it's nota usable pattern. |
That certainly is possible, I don't think the allocation size really matters, rather 'poking' gc and/or stack; note my particular example here was written a long time ago (about 10 years I think) so things might have been a bit different then, and I haven't tried to minimize it, on the contrary: it started off a lot simpler but then I got failures on unix/windows ports depending on where they'd run (locally vs Travis vs newer compiler versions etc) and just added more statements to make the failures go away.. |
Yeah that sounds like what I was doing with these examples, adding more/less to them until the worked/didn't work. As a more important test I just added the example C module to a pyboard-d build and ran it;
The deinit string is shown on soft reset - that's the actual requirement for this kind of automatic deinit and it worked. So this example is still relevant and ready for review. I'll need to figure out how I want to clean up the unit test though. Trying to prompt gc to collect it at runtime should be less important; if user runtime deinit is needed a separate function should be exposed to do so. |
FWIW I think this will usually come down to stray pointers being left on the memory used for the stack, if a particular stack frame doesn't rewrite every word. It's hard to avoid this, and calling extra functions or evaluating additional Python code should cause them to be rewritten eventually. There was a bug where this happened very reliably for some addresses - #14136 - but looks like the fix was included in the most recent rebase so probably this is unrelated if you're still seeing some "zombie" objects. |
This PR still needs some work to get the tests running under CI. But I'm not sure what the best way is to do that. Maybe put the creation of the Also, making the |
Preferred approach now in #16063 |
There are a number of situations in user C modules where hardware or static C variables should be reset or de-init when the module is no longer being used, or particularly over a soft-reset.
This PR adds usage of the gc finaliser to the existing cexample module to demonstrate how this can be achieved.
Inspired by discussion in #12803 and https://ptb.discord.com/channels/574275045187125269/1012726673709469818/1173760875539206225