Yielding until an event occurs
Peter .

I was wondering if it is possible to yield a process using Allegro, until an event occurs (i.e. the press of a key, a timer interrupt, etc.). I have looked through the manual, and have not found anything like this. Calling rest( 0 ); is not what I am trying to achieve, but rather I am trying to achieve the same effect as calling the Windows API function WaitMessage();. If this is not possible with Allegro, then I must ask: why?


Why not:

while (!keypressed () && !mouse_b) {
  poll_keyboard ();
  poll_mouse ();
  rest (0);

About timer interrupt:

volatile int tick = 0;
void timer (void) { tick++; } END_OF_FUNCTION (timer);

void fn (void)
/* Whait for time interrupt. */
  install_int_ex (timer, MSEC_TO_TIMER (5000); /* Five seconds. */
  while (!tick)
    rest (0);
/* Uninstall time interrupt. */
  remove_int (timer);

About the "why" you ask: because Allegro is multi platform library and not all platforms manages events in the same way.

Peter .

The problem there is that it will still eat CPU time, checking Task Manager under Windows shows the Allegro process consuming something like 98% of the CPU time, although all my process keeps doing is going through a loop checking if escape is pressed. I want to know how could I indefinitely put the process to sleep (so that it isn't given execution time at all), until an event occurs? The problem with rest( 0 ); is that the Allegro process is eventually given execution time again, even though no event has occured. Do you see what I'm saying? I don't see how it would hinder portability, a function wait_for_event could exist, which would do the same thing as the Windows API's WaitMessage();, only if the platform of execution was incapable of doing it, it would simply do nothing (an empty function).


Have you tried rest(1);?


I think that actually this is impossible using only Allegro. Remember that Allegro is a Game Library and it isn't multi threaded. May be when Allegro 5.0 becomes released::)...

lennaert van der linden

I haven't tested this, but perhaps you could wait on a semaphore for signals that are sent on a mouse or keyboard event.

You can setup a callback functions that send a signal to the semaphore with mouse_callback and keyboard_lowlevel_callback

Neil Walker

Doesn't anyone ever RTFM ;)

Waits a specified number of milliseconds or yields CPU.
void rest(unsigned int time);
This function waits for the specified number of milliseconds.

Passing 0 as parameter will not wait, but just yield.

Kitty Cat

In 4.2 or earlier, there is no way to truely wait until an event occurs.. all you can do is make a check+rest combo. The loop

while(!keypressed () && !mouse_b)

will wait (and give up most of the CPU) until a key or mouse button is pressed. For just keypresses, you can use readkey(), which will wait and give up the CPU until a key is pressed (by implementing its own loop).

In 4.3, however, there is going to be an event API that'll supposedly do exactly what you want. I've never worked with it myself so I don't know its details, though.


Also note that 4.3 has just begun mainstream development...

Peter .

Oh, I didn't realise that rest can sleep the process, I thought it still ate CPU time while resting. Sure, it's not as efficient and "clean" (because during the resting period an event could occur and the task wouldn't handle it until the period is over) as an event-driven solution to this would be, but that's unimportant, this solution gets the job done fairly well.

Thanks everybody.


4.0's rest doesn't sleep BTW. You need yield_timeslice or something like that.

Tobias Dammers

4.2's rest() however does. 4.0's yielding/resting behaviour is crooked anyway.
You may also want to use a coarser granularity if low resource consumption is more important to you than responsiveness. Just use something like rest(50) in you polling loop; this will only check the input 20 times per second. As long as you program is the foreground app, this is probably not acceptable, but as lomng as you're in pause mode or something like that and waiting for input is your only task, then a 50msec delay between hitting a key and your program responding is not likely to be noticed anyway.


In your main loop, use a rest(1) to reduce your CPU consumption to minimum, whilst still retaining responsiveness.

I highly disagree with using rest(50), it is far too high.

Tobias Dammers

Read my post again; rest(50) should be fine if all you need to do is wait in the background until a key is pressed. In all other cases, rest(50) is absolutely insane of course.


rest(50) would give you considerable delay in response.

rest(1) is suffecient, it gives you both reduced cpu usage, and responsiveness,
(and on Windows, you'll get rest(10) anyway, due to the pathetically defaulted granuality)

Jeff Bernard

it may just be my program, but i dont see much of a difference when implementing readkey() or rest(1). the peak is the same for using both of those and not using any of them, at 98% cpu usage. but the lowest point is achieved when neither is used, which got down to 72%. readkey() and rest(1) were both around 77% for their lowest.


if your app is still at 77%, then you are obviously using 77% of the CPU for doing something.
if your using 77% of your CPU, its time to upgrade.

Tobias Dammers

If you're using 77% of cpu respurces, it's time to profile. If everything is optimized to the max and you're still using 77%, then it's time to upgrade (either OS or CPU or both).

Thread #553251. Printed from Allegro.cc