There are no timers in there, just one thread, and no busy-waiting.
But does it hog the CPU?
It does, unless the video driver implements retrace sync’ed flips, as
they do on DirectX/Win32. On Linux (except in OpenGL mode with some
drivers), it will just run as fast as it can.
If it does, then that solution is no better
than what I have. Note that my problem isn’t that the emulator can’t
render the frames, just that its wasting CPU during the idle times.
There’s not much to do about this. I can only think of two ways to reduce
the amount of CPU hogging:
1) Keep track of your average effective rendering + "flipping"
time, and subtract that from the total 60 Hz period, to get
an approximate "delay time". If that's greater than 10 ms,
SDL_Delay(10) - if not, busy-wait... Of course, it's quite
likely that you'll actually be sleeping for more than 10 ms
every time you call SDL_Delay(10). :-/
2) Throw a pthread_yield() into the busy-waiting loop, to give
the scheduler the impression that you're not a *real* CPU
hog. This should improve your chances of actually being
allowed to use the CPU when you need it. (Hogging lowers
your priority, so that *any* other thread that decides to
do something can take the CPU away from you for several
(BTW, IMHO, it would be nice if SDL_Delay(0) would concistently perform
the operation corresponding to pthread_yield() on all platforms where
it’s relevant and possible.)
The good news is that I think I’ve figured out a relatively nice
(non-busy-waiting) way of implementing retrace sync on Linux, and other
Un*x like systems that might need it. You’ll get a daemon that runs a PLL
in sync with the retrace (a very low priority thread that should
basically replacy the kernel idle thread), and a shared library with
calls that implement “were is the raster beam now?” and blocking retrace
sync. There will be no polling, and it can be implemented on anything
that supports testing for retrace - no interrupts needed.
Hopefully, this will improve the chances of Linux eventually being able
to achieve the same animation quality as DirectX has provided ever since
it was introduced.
I’m just checking SDL_GetTicks() once per rendered frame, to see how
many “logic” frames I should run to catch up with the time
corresponding to the next frame to render. (This may be anything from
0 times and up.)
The fact that the logic code doesn’t really run once every 30 ms
doesn’t matter, as it communicates with the outside world only once
per rendered frame. (On low end machines, one could consider
increasing the user input testing rate, but the same principles still
Yes, but in the emulator, you do a call to the emulator core every
frame (mediaSource->update()) and then put that to the screen. The
real Atari ran at 60 fps, or more to the point, it did this update 60
times per second. So the reason I want to run at 60 fps is because the
logic has to be updated 60 times per second.
Maybe I should have been more clear. The fact that the framerate is 60
fps is indirectly related to the fact that the logic has to be
updated 60 times per second.
Of course, but that’s not what I’m talking about. There’s a very big
difference between running something exactly once every 60th of a
second, and running it at an average rate of 60 Hz.
The point is that you only need to hit the right video frame - not the
right microsecond, or even the right millisecond. Big difference when
you’re on a normal “general purpose” OS without high resolution timers.
If you can show me a way of doing both of these and not hog the CPU,
then I will be extremely happy
So I can change the question slightly. How do I call logic code 60
times a second and not make it busywait until the next time the logic
code should be called?
Either retrace sync or “yield looping” will do the trick, or it’s simply
not possible without high resolution timers - and Linux do not have any.
All right, there is the RTC device. Unfortunately, you’ll have to be
root to set it any higher than 64 Hz or so - and it supports only
power-of-two frequencies, so you’d have to use something higher for
sufficient accuracy… (Another problem that my retrace sync daemon would
"hide", as you won’t have to touch the RTC directly.)
//David Olofson — Programmer, Reologica Instruments AB
.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Thursday 14 March 2002 23:09, Stephen Anthony wrote: