(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.On 3/25/15 6:30 AM, bazz wrote:
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…