Simple implementation of SDL_Events |
bazz
|
After some thought, I think my bigger issue comes from the fact that a lot of influence on me that malloc() is not good to utilize in bare metal embedded applications, and not using malloc() would cause me to have to limit my queue size to a statically declared size in the code.. That bothers me.. Bite the bullet and start using malloc() ?? .... My issue is not amount of RAM, this system has 32MB RAM.. I'll figure it out...
|
|||||||||||
|
Simple implementation of SDL_Events |
MrOzBarry
|
Is cross compiling not a reasonable option for the platform? What embedded platform are you targeting? On 25 Mar 2015 06:30, "bazz" wrote:
|
|||||||||||||
|
bazz
|
It's not. The platform is undisclosed
|
|||||||||||
|
Simple implementation of SDL_Events |
MrOzBarry
|
Are you able to disclose the CPU architecture? On 25 Mar 2015 09:02, "bazz" wrote:
|
|||||||||||||
|
Simple implementation of SDL_Events |
Jonny D
|
As I understand it, the SDL event queue is not dynamically sized. You would be alright with a static buffer as long as it is big enough (see SDL source).
Jonny D On Wednesday, March 25, 2015, Alex Barry wrote:
|
|||||||||||||||
|
Simple implementation of SDL_Events |
Jonas Kulla
Guest
|
FWIW, SDL's event queue used to be statically allocated for the longest time, but Sam
changed it to a dynamically allocated linked list some time after he joined Valve (supposedly they were hitting cases of dropped events). 2015-03-25 11:30 GMT+01:00 bazz:
|
|||||||||||||
|
Simple implementation of SDL_Events |
Ryan C. Gordon
Guest
|
On 3/25/15 6:30 AM, bazz wrote:
(Even on embedded systems, malloc() isn't as bad as you think, in my opinion. Some times you need it! You have to have more discipline than on a desktop machine, and you have to be smart about what and when you allocate. Bonus points for letting allocators isolate to a block of memory that you can remove wholesale when you finish a piece of work, to prevent fragmentation across the whole address space, but that can add a lot of complexity. As always, it depends on your needs.) Here's what SDL does. You might be surprised. SDL 2.0 uses a doubly-linked list for the event queue, and keeps a pool of SDL_Event objects for reuse. That is, every time we need to add an event to the queue, we look for an event that's not in use and reuse it, and if there aren't any available, we malloc() a new one. When the event is processed, it isn't freed, but rather put in the reuse pool for the next event to come through. Basically once they are malloc()'d, they just move back and forth between two linked lists (the event queue and the queue of free events). In practice, we have a small pile of allocations near the start of the program, and then never again. We _do_ have an upper bound of 64k events, to stop a massive spamming of events on an app that isn't reading the event queue in a timely manner (or at all). If we have that many events and another is added, we drop it immediately. This is a failsafe; I don't have statistics on this, but I can't imagine any reasonable app uses more than a few dozen events at once. SDL_AddEvent() is pretty illustrative of the details: https://hg.libsdl.org/SDL/file/0af69dab9bb6/src/events/SDL_events.c#l180 ...the whole file is only 650 lines of C code, and somewhat self-contained, so you could write this from scratch, or probably just modify it for your project, without much drama. SDL 1.2 was much simpler: it was a static array of 128 events, and if it filled up, we dropped any further events until you drained some from the queue. I never saw this event queue overflow, even on high-end, complex games. In practice, I bet you could get away with an array of 32 events. Measure and sprinkle some assert() calls around and see what you can get away with. If you ignore the SYSWMEVENT special case, the 1.2 version of SDL_AddEvent() is 10 lines of C code. https://hg.libsdl.org/SDL/file/c238763e1228/src/events/SDL_events.c#l264 For a really tiny system like you describe, the 1.2 way is probably more than sufficient for your needs, dirt-simple to implement, and doesn't take much memory and needs no malloc at all. I'd aim for that. --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Simple implementation of SDL_Events |
Ryan C. Gordon
Guest
|
Now I do! The latest in revision control will track the maximum events in-flight at a time (so if you have 5 events in the queue, drain it, and later have 7 events before you drain, and later 3, at the end of the program, this number is seven). To use it, export an enviroment variable: SDL_EVENT_QUEUE_STATISTICS=1 ./testsprite2 And when you call SDL_Quit(), you'll get a line that looks something like this to stdout: 2015-03-25 10:18:11.413 testsprite2[77754:507] INFO: SDL EVENT QUEUE: Maximum events in-flight: 4 4 was about as high as I could get testsprite2 to go; I'm sure other things go higher, especially if you're pounding on the keyboard of a game that's blocking to load game data. Feel free to try it and see what sort of queue usage your app uses. --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Simple implementation of SDL_Events |
Jonny D
|
Well, Ryan has the definitive suggestion for when the queue is full. You might as well mimic SDL's behavior in this case and just drop new events.
Implementing a simple linked list queue is much easier than lemon pie. Jonny D On Wed, Mar 25, 2015 at 10:50 AM, bazz wrote:
|
|||||||||||||
|
bazz
|
I deleted my last post given I just read Ryan C. Gordon's excellent first post answer. It's golden. Thank you.
The bonus points for malloc() avoidance of defragmentation sounds awesome but I have enough on my plate already. See you in at least 4 months to discuss that. heheh. I had some desires to learn whether SDL2 would ever free from its pool of malloc'd events over time if the volume of active events was reduced substantially. But if you're not interested in answering, don't bother, I really do have enough on my plate. hehe Thanks for the answer and the confidence and all the good vibes |
|||||||||||
|
bazz
|
Man.. I just spent the past couple hours just getting assert() to work!! I had to learn how to override the _write() syscall in newlib. It's probably time to confess I am coding for an ARM processor. hehe that's all I'll say.
but oddly enough, I could only get assert() to work if it was set to stdout, rather than stderr.. If I use stderr, the format string doesn't get interpreted.. so think of it as printing a raw format string.. for instance : while this works:
this won't
I did some backtracing in GDB and I noticed that the call in regular printf (or an fprintf call with stdout ) reaches the final _write() call with the string formatted "hi 5" as expected, while stderr version shows the string coming into _write as "hi %d" -- I couldn't tell for the life of me why this is happening.. My newlib implementation is otherwise pretty stock.. Meaning I'm not getting the bang for my buck out of it.. I'm doing a lot of things the hard way.. but temporarily as far as assert() goes, I set it to use stdout.. but I would really like to know if anyone has a clue what's going on here so that stderr does not remain broken... I'm not including my _write() routine since it was proven to NOT be the problem. Thanks! |
|||||||||||||||
|
bazz
|
newlib 2.1.0
|
|||||||||||
|
bazz
|
I realize I am asking newlib question on SDL forum. :3 but you are smart guys <3 I will consider heading to another forum
|
|||||||||||
|
Simple implementation of SDL_Events |
Ryan C. Gordon
Guest
|
SDL doesn't do this at the moment, but we could probably do something like: if X frames (or milliseconds) have passed with Y events being unused, free up to Z events per frame. --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Simple implementation of SDL_Events |
Sik
|
2015-03-25 20:53 GMT-03:00, Ryan C. Gordon:
How do you determine this? Especially since the timer subsystem may not be initialized yet. Maybe it's better to do the check only when already messing with the event list (e.g. when removing an event from the list, check if the list had gone too empty for many events or something). _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Simple implementation of SDL_Events |
Ryan C. Gordon
Guest
|
Oh, I meant check SDL_GetTicks() when messing with the queue, not using an actual timer event. --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Simple implementation of SDL_Events |
Sik
|
2015-03-26 3:50 GMT-03:00, Ryan C. Gordon:
I thought that also required timers to be initialized (or is that not the case for this specific function?). _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Simple implementation of SDL_Events |
MrOzBarry
|
Sorry I misinterpretted what you were trying to do, oops. Good luck with the project, though!
On Wed, Mar 25, 2015 at 6:12 AM, bazz wrote:
|
|||||||||||||
|
Simple implementation of SDL_Events |
Ryan C. Gordon
Guest
|
SDL_TicksInit() happens before SDL_StartEventLoop()... https://hg.libsdl.org/SDL/file/d0865e9f674a/src/SDL.c#l107 ...and even if it didn't, SDL_GetTicks() will explicitly call it if necessary: https://hg.libsdl.org/SDL/file/d0865e9f674a/src/timer/unix/SDL_systimer.c#l93 --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|