-
Notifications
You must be signed in to change notification settings - Fork 3
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
Make LVGL thread-safe #8
Comments
@edjubuh said:
#define LV_LOCK_TAKE (whatever)
#define LV_LOCK_GIVE (whatever)
|
Theoretically, shouldn't this only occur if someone yields (such as using
|
The configuration we use includes priority-based preemptive scheduling, in which at any given time the currently running task is the highest priority task that isn't blocked. When there are multiple tasks running at the same priority, they are round-robined such that each gets an equal amount of processing time. As I mentioned in the original comment, this has yet to be the obvious cause of any issues, which means in the end you may be right. My original intent though was just to be safer than sorry (especially as the porting guide now recommends this course of action). |
@HotelCalifornia I completely agree—I was just trying to clarify the situation. I've been working on PROS & LVGL bindings for Rust, where thread safety is a big deal (which is why I came across this thread). I'd love to see more thread-safety functionality. |
That said, do you have any opinions regarding how we might go about implementing this? We discussed a couple options above but each have their problems |
It looks like LVGL is not interested in adding their own synchronization calls within their funcions. This leaves either requiring the user to manually lock and unlock with the originally proposed solution, or generating our own API that builds on top of LVGL. However, it's probably not worth the effort to rename every LVGL function symbol, and write our own wrapper over every function (unless you hack something together that uses e.g. clang's parser to do it for you). Realistically, creating our own functions and requiring the user to call them seems to be the best option. I wouldn't prefix them with |
Yeah, I'd looked into function decorators and such in C and determined that there's not really a good way to wrap all the functions without more work than I'm really willing to put in. I also hesitate to throw my lot in with duplicating the lvgl API, as that's just more stuff to maintain. Your mention of the clang parser to generate such an API is intriguing, but I also worry about confusing users. Another possible solution would be to just leave the lvgl C functions as they are, and finally implement a proper C++ abstraction layer that handles thread-safety. I've done a small amount of preliminary work on such a layer, and I believe there is at least one other member of the community who was working on something similar. Beyond that, I guess I find I'm leaning back toward a |
I would probably go with both a C++ abstraction and user mutex. The part of LVGL that I don't like the most aside from the lack of detailed documentation is how destructive
|
It would be nice if this included a |
we're hoping to get all of std::thread working for "free" on our pthread branch |
I think it would not be favourable to make the lib thread save, because then you will run in other trouble. For e.g. then you will ad a widget or something and then after releasing the lock it will start redrawing the stuff also if you are not finished with changing the stuff on block. In my opinion this should be left to the user to make it thread save, like other environments will do (for e.g. QT is also not thread save, you have to follow the same conventions as here). But in the examples the user shall use more callbacks for this type of usage. For e.g. passing a change widget function to the task system with a "future" is a good way to synchronize stuff without the needs for lock but with the benefit to fuse the changes to the objects itself. So for C++ users, this may be a simple lambda if one will write a good adaption. EDIT: I also saw some code which was added to make it save, but it does not make it save. In the lv_task_handler() there is a section
which is not save on a preemptive system, I added the line where the non good stuff may happen, if a schedule will happen there. I saw a lot of code of this kind which is bad. So this code shall better be removed since it is not misleading and will not work every time. Here one needs a TestAndSet strategy to be save. |
Will naturally be done by simplified screen API since it's coupled to the screen mutex, closing to reduce clutter. |
Expected Behavior:
LVGL functions should be thread-safe.
Actual Behavior:
Per lvgl/lvgl#544, we need to mutex guard the call to
lv_task_handler
, and then make the same mutex available to guard the calls to thelv_*
API.Steps to reproduce:
This hasn't yet been the obvious cause of any observed issues.
System information:
Platform: V5
PROS Kernel Version: any
Additional Information
As I'm thinking about it, it seems the best solution will be to add accessor functions:
My first thought was to just have a single function that would just return the mutex itself, but I have since realized that would potentially allow users to delete it, which would not be desirable. As such, I think the above solution is the way to go.
Screenshots/Output Dumps/Stack Traces
N/A
The text was updated successfully, but these errors were encountered: