-
Notifications
You must be signed in to change notification settings - Fork 73
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
Dropping Screen
s and associated memory leaks
#111
Comments
Thinking about it, we can also modify the API so as to require a reference to the |
This seems to be the case for any Widget created, unfortunately my understanding of Rust FFI isn't yet good enough to help with this :-( |
Some thoughts on lifecycle management for LVGL resources in rustThe problemLVGL is a Some LVGL resources hold pointers to other LVGL resource, e.g. a When binding to LVGL as a rust FFI library, then the binding needs to Errors to mitigate include:
Usage patterns for resources in LVGLLVGL has a number of different ways in which resources are used. Global lifespanThe most common usage pattern in an embedded systems context is to Where this patten is usable, it does not require free-ing of certain Dynamic lifespanIn this usage pattern, which may be required either to low ram Mixed lifespanThis mode is a combination of the Global and Dynamic lifespans in Resource ownershipIn LVGL, a widget is (with one exception) always parented by another For styles, there is a many-to-many relationship as a Widget may Images may be either dynamically allocated or stored in ROM. Thread safetyAFAIK, LVGL is not thread safe. All mutation of LVGL resources Potential approachesWhen binding an FFI resource to a rust library, it is common to wrap When a rust struct is associated with an FFI pointer, then the Rust programmers should expect to be aware of the lifetime management In the case of LVGL, there are two additional considerations. The The current implementation of
Note that:
In order to address the issues noted above, it is proposed that an Implementing destructor for ObjIt is proposed that the destructor be implemented as follows:
Side effects of this proposal include:
|
Hey @cydergoth, thank you so much for the detailed writeup! It definitely echoes some concerns I've had also. I mostly agree that we need to tackle dropping somehow and it's been a big headscratcher for me; I considered something tangentially related in #107 (specifically, this) which vaguely correlates. On I do like the idea of keeping a global list of live objects, though we are burdened by the fact that - as you pointed out - we don't have an allocator by default except for LVGL's (which has access to very little memory). I'm unsure thus if it's possible to implement it for all cases (i.e. without I do think there's a happy compromise possible to allow dropping and also not tax resources or performance too much. Rust's lifetimes do allow us to automatically invalidate a lot of things; changing e.g. This doesn't address threading though, so I am curious what can be done there (current approach being "nothing, just don't touch LVGL-space from multiple threads"). There's also the issue of "what do we do if something manifests an object pointer out of thin air" which can occur (see the animation PR I recently merged, where via witchcraft I need to turn a Honestly I'm not sure what to do, but I worry about the cost involved in dynamic checking of anything. Though if you want to, I would be curious to see benchmarks. |
So the performance of rendering should be mostly on the The mutex would need to be locked during rendering, then any events would have to wait for rendering to complete, but it would stop one thread like an event thread trying to update the LVGL model whilst another thread is deleting that object 😀 If you take a look at my repo, you'll see it uses an unsafe impl Send and async to update the UI. I don't think I could do that without async, unless I move completely to a command model and have the render thread poll a command queue for mutation requests - which whilst possible seems a little clunky as async effectively does the poll |
|
Do you think prototyping with Arc would be valuable to determine precisely what the tradeoffs are? |
Sure. Though if there is any noticeable impact on memory use or speed, we will probably need this as an explicit opt-in |
Yes, it definitely needs a feature gate, as it will need alloc and maybe
mutex too.
…On Mon, Jun 19, 2023, 12:54 PM Nia ***@***.***> wrote:
Sure. Though if there is *any* noticeable impact on memory use or speed,
we will probably need this as an explicit opt-in
—
Reply to this email directly, view it on GitHub
<#111 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABPWAWVGQOVYMRTYAGPYC5TXMCG5BANCNFSM6AAAAAAXYFHNEY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Would you be interested in working on this with me? I can ask that you be added as a collaborator |
I'm a little busy with my actual job rn, but I'm hoping to get a chance to
look at the weekend
…On Tue, Jun 20, 2023, 7:03 AM Nia ***@***.***> wrote:
Would you be interested in working on this with me? I can ask that you be
added as a collaborator
—
Reply to this email directly, view it on GitHub
<#111 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABPWAWXUQJ55Y2OJ6TNKHWDXMGGSFANCNFSM6AAAAAAXYFHNEY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
That's fair. This probably won't be getting merged "soon", but I'll open a dedicated issue for threading and we can discuss it there. |
See #140. I'll get started on trying to figure things out, but it's probably going to be a while before it works. But in case you want to help out with code - @kisvegabor can you give @cydergoth write perms on branches? I can't manage access for people w/ my current perms. |
@nia-e I've added Admin rights for you. Now you should be able to invite people and change permissions. |
Thanks! :D |
Currently we provide no way to delete a
Screen
after it's been instantiated. Having the user manually call a deletion function also feels... un-rusty and generally unwise as it would be easy to forget. Also, making the screen be deleted onDrop
carries the risk of e.g. a user callingget_scr_act()
multiple times and double-deleting a screen -> a double free -> undefined behaviour. I'm honestly kind of stumped as to what to do here; we can't store some kind ofis_active: bool
field either as every call toget_scr_act()
returns a differentScreen
and there's no way to dynamically check on drop if there are otherScreen
s pointing to the same underlying object.The other option is to have the
Display
store a copy of a pointer to the lastScreen
it returned and simply refuse to return multiple identicalScreen
s thus allowing us to delete on drop, but this does make things slightly more inconvenient (and can be trivially circumvented by changing theScreen
and then going back, unless we store a collection).Also, how do we prevent accessing child objects of a
Screen
(or any object) and thus a use-after-free post-deletion?The text was updated successfully, but these errors were encountered: