0

This is a very weird issue that is driving me crazy...

I'm using Sleep() function to set my game framerate, I just execute game loop and I wait for some milliseconds at the end to adjust to ~16.6 ms per frame. To do that I created my own waiting function (multiplatform, but issue just happens on _WIN32):

// Wait for some milliseconds (stop program execution)
static void Wait(float ms)
{
//#define USE_BUSY_WAIT_LOOP
#if defined(USE_BUSY_WAIT_LOOP)
    double prevTime = GetTime();
    double nextTime = 0.0;

    // Busy wait loop
    while ((nextTime - prevTime) < ms/1000.0f) nextTime = GetTime();
#else
    #if defined _WIN32
        Sleep((unsigned int)ms);
    #elif defined __linux__
        struct timespec req = { 0 };
        time_t sec = (int)(ms/1000.0f);
        ms -= (sec*1000);
        req.tv_sec = sec;
        req.tv_nsec = ms*1000000L;

        // NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated.
        while (nanosleep(&req, &req) == -1) continue;
    #elif defined __APPLE__
        usleep(ms*1000.0f);
    #endif
#endif
}

To avoid windows.h inclusion, I just defined Sleep() function as:

#if defined(_WIN32)
    void __stdcall Sleep(unsigned long msTimeout);
#endif

The issue: when I compile this code using MinGW32 (GCC 5.3.0), it seems Sleep() takes longer (almost double) than the milliseconds passed to the function, when I compile using MSVC (Visual Studio Community 2015), sometimes it works ok, sometimes not. The most weird thing is that, when it works, if I execute the MinGW32 versions previously not working... then they work ok! Crazy...

Per my understanding, problem should be related to some runtime lib usage, OS dependant (trying on Windows 10 64bit). Noticed that, when working ok, if exploring processes, dwm.exe controls a second thread (wait chain) -not sure what it means- and when fails, that process is not available.

Just for reference in case I missed some detail, that's the function where I use Wait():

// End frame drawing
void EndFrame(void)
{
    SwapBuffers();                  // Copy back buffer to front buffer
    PollInputEvents();              // Poll user events

    // Frame time control system
    currentTime = GetTime();
    drawTime = currentTime - previousTime;
    previousTime = currentTime;

    frameTime = updateTime + drawTime;

    // Wait for some milliseconds...
    if (frameTime < targetTime)
    {
        Wait((targetTime - frameTime)*1000.0f);

        currentTime = GetTime();
        double extraTime = currentTime - previousTime;
        previousTime = currentTime;

        frameTime += extraTime;
    }
}
Ray
  • 123
  • 2
  • 9
  • 4
    MS Sleep() has a granularity of the same order as the interval you are using:( You could try a multimedia timer. – ThingyWotsit Mar 27 '17 at 22:41
  • 2
    You should look at this: http://stackoverflow.com/questions/4128766/how-accurate-is-sleep-or-sleep – Jerry Jeremiah Mar 27 '17 at 22:58
  • Thank you very much for your answers! Thinking about today's computer speeds, I couldn't imagine such a huge granularity... – Ray Mar 28 '17 at 17:08
  • 1
    @Ray Windows is a desktop OS for human users and has had a lengthy life. Windows 3.1 running on a 5MHz 8088 was physically unable to stream video or provide high-framerate gaming. The Sleep() tick interval was chosen on such machines, and backward-compatibiity and inertia issues mean that system calls should not deviate significantly as time went on. Instead, additional functionality, (eg. the multimedia timers), was added as hardware got faster and YouTube/Netflix/whatever became possible. – ThingyWotsit Mar 29 '17 at 15:10

0 Answers0