Re: [AD] Timer patch

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Sun, 2008-02-03 at 03:45 -0800, Ryan Dickie wrote:

> I struggled a bit tonight but i got the new 2.6.24 kernel compiled
> with the tickless scheduling. It is damned accurate (no more periodic
> os interupt). Calling al_rest 1000 times for 1 ms sleeps gave the
> following results. 
> 
> 1000x 1ms delays
> Time Slept 1.065
> Cummulative error 0.064732
> Error per sleep 0.000065
> 
> The error in the periodic timer. This is just the error of the timer
> thread itself. The event wakeup itself should add some error as well.
> I'm too tired to code that up just now ;)
> Error:-0.000012
> Percentage: 0.012000 (100 * -error / delay time )
> 
> The error with the old ticking kernel is about 1.5ms (sometimes peaked
> as high as 2.5). This is now a factor of 10x more accurate than the
> windows ones which themselves are only 200us off.
> 

I made a stupid test as well (attached). The max - min reading shows
around 15 us for most seconds here, which sounds good to me :) (2.6.24
here, but I think unlike al_rest this is not affected by the tickless
scheduler, so should be the same with 2.6.23)

-- 
Elias Pschernig <elias@xxxxxxxxxx>
/* An example demonstrating different blending modes.
 */
#include <allegro5/allegro5.h>
#include <allegro5/a5_font.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>

/* A structure holding all variables of our example program. */
struct Example
{
   A5FONT_FONT *myfont; /* Our font. */
   ALLEGRO_EVENT_QUEUE *queue; /* Our events queue. */
   
   double FPS; /* How often to update per second. */
   
   int x[4];
   
   bool first_tick;
   double this_time, prev_time, accum_time;
   double min_diff, max_diff, second_spread;
   double second;
   double timer_events;
} ex;

/* Print some text. */
static void print(int x, int y, char const *format, ...)
{
   va_list list;
   va_start(list, format);
   char message[1024];
   uvszprintf(message, sizeof message, format, list);
   va_end(list);

   ALLEGRO_COLOR color;
   color = al_map_rgb(0, 0, 0);
   al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, color);
   a5font_textout(ex.myfont, message, x, y);
}

/* Draw our example scene. */
static void draw(void)
{
   int h = a5font_text_height(ex.myfont);
   al_clear(al_map_rgb_f(1, 1, 1));
   print(0, 0, "%.9f target for 50 Hz Timer", 0.02);
   print(0, h, "%.9f now", ex.this_time - ex.prev_time);
   print(0, 2 * h, "%.9f accum over one second",
      ex.accum_time / ex.timer_events);
   print(0, 3 * h, "%.9f min", ex.min_diff);
   print(0, 4 * h, "%.9f max", ex.max_diff);
   print(300, 3.5 * h, "%.9f (max - min)", ex.second_spread);

   int y = 240, i;
   for (i = 0; i < 4; i++)
      al_draw_rectangle(ex.x[i], y + i * 60, ex.x[i] + (1 << i),
         y + i * 60 + 60, al_map_rgb(1, 0, 0), ALLEGRO_FILLED);
}

/* Called a fixed amount of times per second. */
static void tick(void)
{
   ex.this_time = al_current_time();

   if (ex.first_tick)
      ex.first_tick = false;
   else {
      if (ex.this_time - ex.second >= 1) {
         ex.second = ex.this_time;
         ex.accum_time = 0;
         ex.timer_events = 0;
         ex.second_spread = ex.max_diff - ex.min_diff;
         ex.max_diff = 0;
         ex.min_diff = 1;
      }
      double duration = ex.this_time - ex.prev_time;
      if (duration < ex.min_diff) ex.min_diff = duration;
      if (duration > ex.max_diff) ex.max_diff = duration;
      ex.accum_time += duration;
      ex.timer_events++;
   }

   draw();
   al_flip_display();
   
   int i;
   for (i = 0; i < 4; i++) {
      ex.x[i] += 1 << i;
      ex.x[i] %= 640;
   }

   ex.prev_time = ex.this_time;
}

/* Run our test. */
static void run(void)
{
   float x, y;
   ALLEGRO_EVENT event;
   while (1) {
      al_wait_for_event(ex.queue, &event, ALLEGRO_WAIT_FOREVER);
      switch (event.type) {
         /* Was the X button on the window pressed? */
         case ALLEGRO_EVENT_DISPLAY_CLOSE:
            return;

         /* Was a key pressed? */
         case ALLEGRO_EVENT_KEY_DOWN:
            if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
               return;
            break;

         /* Is it time for the next timer tick? */
         case ALLEGRO_EVENT_TIMER:
            tick();
            break;
      }
   }
}

/* Initialize the example. */
static void init(void)
{
   ex.FPS = 50;
   ex.first_tick = true;

   ex.myfont = a5font_load_font("font.tga", 0);
   if (!ex.myfont) {
   	allegro_message("font.tga not found");
	exit(1);
   }
}

int main(void)
{
   ALLEGRO_DISPLAY *display;

   al_init();
   al_install_keyboard();
   al_install_mouse();
   display = al_create_display(640, 480);
   al_show_mouse_cursor();

   init();

   ALLEGRO_TIMER *timer = al_install_timer(1.000 / ex.FPS);

   ex.queue = al_create_event_queue();
   al_register_event_source(ex.queue, (void *)al_get_keyboard());
   al_register_event_source(ex.queue, (void *)al_get_mouse());
   al_register_event_source(ex.queue, (void *)display);
   al_register_event_source(ex.queue, (void *)timer);

   al_start_timer(timer);
   run();

   al_destroy_event_queue(ex.queue);  

   return 0;
}
END_OF_MAIN()


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/