I'm working on a very simple game, and one of the project goals is to minimise the use of libraries.

I'm drawing every frame into a buffer, which is then displayed using XPutImage (see the code of the main loop). This simple code is used to limit FPS:

// Limit FPS
  u64 current_timestamp = LinuxGetWallClock();
  u64 ns_elapsed = LinuxGetWallClock() - last_timestamp;

  if (ns_elapsed < target_nspf) {
    struct timespec ts;
    ts.tv_sec = 0;
    ts.tv_nsec = target_nspf - ns_elapsed;  // time to sleep
    clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);

    while (ns_elapsed < target_nspf) {
      ns_elapsed = LinuxGetWallClock() - last_timestamp;
  } else {
    // printf("Frame missed\n");

  last_timestamp = LinuxGetWallClock();

Everything works fine and as expected, but every now and then the image stutters, as if the X server has buffered up a few frames' worth of images and then flushed them all in a single go. This happens irrespective of frame misses.

Note: I'm not talking about image tearing here.

I realise that the code above is not supposed to provide a stable frame rate, and occasionally one frame might be displayed for too long, and another frame might get lost and never displayed, but I don't see how that thing alone can cause the terrible occasional stuttering.

My only guess would be that clock_nanosleep may sleep for longer than I asked for.


  • Is my guess above correct?
  • If not, what might be the reason?
  • Are there any ways to address this problem without having to use OpenGL to wait on vblank?


  • \$\begingroup\$ Hi there. I'm pretty sure this isn't a solution to your issue, but have you tried using CLOCK_MONOTONIC_RAW in your clock_gettime() call? If you look at the manpage for clock_gettime(), it states the following for CLOCK_MONOTONIC_RAW: Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time that is not subject to NTP adjustments or the incremental adjustments performed by adjtime(3). So it could cause slight issues with your times, but it's probably very unlikely. But it would be nice to try in order to rule that out. \$\endgroup\$ Aug 20, 2017 at 8:08
  • \$\begingroup\$ Hi. Thanks for your comment. Just tried that, it didn't help, as you expected \$\endgroup\$ Aug 20, 2017 at 17:24


You must log in to answer this question.

Browse other questions tagged .