The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Simple implementation of SDL_Events
bazz


Joined: 25 Oct 2010
Posts: 31
Hi, I'm programming an embedded system. Porting the entire SDL library to this system is more than intimidating, but there are certain things I'm used to thinking like SDL_Events and I was wondering if someone with more experience than I have, can offer some tips on how to simply implement a kind of SDL_Event queue.. It's the queue itself I'm not sure about.. Should I just google 'queue C' ?

But the rest I can handle.. like I understand that I would be adding to the queue when certain events happen low level (like a button released), and in the main loop I will check the queue to parse to process the events like I would in SDL...
bazz


Joined: 25 Oct 2010
Posts: 31
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


Joined: 26 Jun 2010
Posts: 620
Is cross compiling not a reasonable option for the platform?  What embedded platform are you targeting? On 25 Mar 2015 06:30, "bazz" wrote:
Quote:
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...


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

bazz


Joined: 25 Oct 2010
Posts: 31
It's not. The platform is undisclosed
Simple implementation of SDL_Events
MrOzBarry


Joined: 26 Jun 2010
Posts: 620
Are you able to disclose the CPU architecture? On 25 Mar 2015 09:02, "bazz" wrote:
Quote:
It's not. The platform is undisclosed


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Simple implementation of SDL_Events
Jonny D


Joined: 12 Sep 2009
Posts: 932
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:
Quote:

Are you able to disclose the CPU architecture? On 25 Mar 2015 09:02, "bazz" <[url=javascript:_e(%7B%7D,'cvml','');][/url]> wrote:
Quote:
It's not. The platform is undisclosed


_______________________________________________
SDL mailing list
[url=javascript:_e(%7B%7D,'cvml','');][/url]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


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:
Quote:
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...


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Simple implementation of SDL_Events
Ryan C. Gordon
Guest

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

(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

Quote:
I don't have statistics on this,

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


Joined: 12 Sep 2009
Posts: 932
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. Wink


Jonny D






On Wed, Mar 25, 2015 at 10:50 AM, bazz wrote:
Quote:
Let's focus on implementing a queue in C. Is it as easy as lemon pie?
I was just going to find a "linked-list" queue implementation and cap the size at run-time.

I wanted to ask, does anyone have recommendations on handling a "queue full" situation?


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

bazz


Joined: 25 Oct 2010
Posts: 31
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


Joined: 25 Oct 2010
Posts: 31
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:
Code:
printf("hi %d", 5); -> hi 5

this won't
Code:
fprintf(stderr, "hi %d", 5); -> hi


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


Joined: 25 Oct 2010
Posts: 31
newlib 2.1.0
bazz


Joined: 25 Oct 2010
Posts: 31
I realize I am asking newlib question on SDL forum. :3 but you are smart guys <3 Very Happy I will consider heading to another forum Smile
Simple implementation of SDL_Events
Ryan C. Gordon
Guest

Quote:
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.

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


Joined: 26 Nov 2011
Posts: 905
2015-03-25 20:53 GMT-03:00, Ryan C. Gordon:
Quote:
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.

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

Quote:
How do you determine this? Especially since the timer subsystem may
not be initialized yet.

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


Joined: 26 Nov 2011
Posts: 905
2015-03-26 3:50 GMT-03:00, Ryan C. Gordon:
Quote:
Oh, I meant check SDL_GetTicks() when messing with the queue, not using
an actual timer event.

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


Joined: 26 Jun 2010
Posts: 620
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:
Quote:
Hi, I'm programming an embedded system. Porting the entire SDL library to this system is more than intimidating, but there are certain things I'm used to thinking like SDL_Events and I was wondering if someone with more experience than I have, can offer some tips on how to simply implement a kind of SDL_Event queue.. It's the queue itself I'm not sure about.. Should I just google 'queue C' ?

But the rest I can handle.. like I understand that I would be adding to the queue when certain events happen low level (like a button released), and in the main loop I will check the queue to parse to process the events like I would in SDL...


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Simple implementation of SDL_Events
Ryan C. Gordon
Guest

Quote:
I thought that also required timers to be initialized (or is that not
the case for this specific function?).

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