Thanks to visit codestin.com
Credit goes to github.com

Skip to content

don't gc_free() ringbuf if no heap; cleanup ringbuf #6214

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 4 commits into from

Conversation

dhalbert
Copy link
Collaborator

@dhalbert dhalbert commented Mar 30, 2022

  • Fixes RP2040: board.UART() giving "Attempted heap allocation when VM not running." on reload #6213.

  • UART deinit might happen when there is no VM, during reset_board_buses(), so check before trying to free a UART ringbuf that is on the heap. This UART deinit possibility was introduced in Allow multiple board buses #5422.

  • There was a lot of inconsistency about how and whether a buffer could be supplied as the UART ringbuf. Make the code consistent across multiple ports.

  • ringbuf_init() should have been used several places where it was not. There is a fine distinction between the ringbuf buffer size in bytes, and its capacity in bytes, which is one less. ringbuf_init() used to take the capacity, but I made it take the actual buffer size, because that was less confusing when passing in an existing buffer, though inconsistent with ringbuf_alloc(), which takes capacity and then allocates a buffer of one extra byte. Some discussion here about this point: Introduced ringbuf_init to perform static buffer initialisation #5813 (comment)

  • (EDIT) Rewrote ringbuf to remove capacity == size -1 limitation. Now the size is the capacity. Code is smaller and I think more readable, at the very small expense of keeping a count of used slots.

I will see if this builds, and test it more tomorrow, to make sure I have the ringbuf fixes right. Draft for now.

@dhalbert dhalbert requested a review from jepler March 30, 2022 03:00
@dhalbert dhalbert force-pushed the uart-deinit-when-no-vm branch from d98faf5 to 8dcbfb3 Compare March 30, 2022 03:10
@dhalbert dhalbert force-pushed the uart-deinit-when-no-vm branch from 8dcbfb3 to b9a4f7b Compare March 30, 2022 14:31
@dhalbert
Copy link
Collaborator Author

I think I am going to make ringbuf not have the idiosyncratic capacity == size - 1 by adding a little bit more state to it.

@dhalbert dhalbert changed the title don't gc_free() ringbuf if no heap; cleanup ringbuf uses don't gc_free() ringbuf if no heap; cleanup ringbuf Mar 30, 2022
@dhalbert dhalbert marked this pull request as ready for review March 30, 2022 21:55
@dhalbert
Copy link
Collaborator Author

@jepler this is ready for review. It will go in the next 7.2.x release.

@dhalbert
Copy link
Collaborator Author

New ringbuf code tested with busio.UART (RP2040 to RP2040), _bleio.PacketBuffer (BLE Heart Rate monitor) and _bleio.CharacteristicBuffer (BLE UART demo).

@jepler
Copy link

jepler commented Mar 30, 2022

Isn't r->heap supposed to track if the ring buffer is heap allocated? can we re-use that flag instead? I wonder if a quick discord video/audio chat tomorrow would be good to get through the review on this PR @dhalbert feel free to ping me after 10 your time or so.

@dhalbert
Copy link
Collaborator Author

dhalbert commented Mar 30, 2022

Isn't r->heap supposed to track if the ring buffer is heap allocated? can we re-use that flag instead? I wonder if a quick discord video/audio chat tomorrow would be good to get through the review on this PR @dhalbert feel free to ping me after 10 your time or so.

We were checking r->heap to only free a heap-allocated before, but there was a new possibility introduced by #5422 that deinit() was getting called after the VM stopped. So if you call gc_free() at that time, it throws an error saying you are using the heap when there is no VM. It's phrased a little badly, because the same error is used for both alloc and free.

The fundamental bug fix here is just this commit:
9ee6ec6

All the rest is fixing some other bugs, some latent, and then, being dissatisfied with ringbuf, I made it simpler. It is the same size: the trinket M0 build before and after was exactly the same size.

Happy to discuss this tomorrow.

@dhalbert dhalbert changed the base branch from 7.2.x to main March 31, 2022 13:30
@dhalbert
Copy link
Collaborator Author

Closing this to make a simpler change just for 7.2.x. Will do additional work for main.

@dhalbert dhalbert closed this Mar 31, 2022
@dhalbert dhalbert reopened this Mar 31, 2022
@dhalbert dhalbert changed the base branch from main to 7.2.x March 31, 2022 14:41
@dhalbert dhalbert closed this Mar 31, 2022
@dhalbert dhalbert deleted the uart-deinit-when-no-vm branch May 19, 2022 03:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RP2040: board.UART() giving "Attempted heap allocation when VM not running." on reload
2 participants