Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Migrating to 3.0: What to use instead of glfwSleep?

Using GLFW
2013-06-13
2013-10-31
  • David Bregman
    David Bregman
    2013-06-13

    So with glfwSleep removed, what should I be using instead?

    The translation guide says something about C11 and C++11 threads, but I'm using C on visual studio which only has C90 support or something like that.

     
  • Cameron King
    Cameron King
    2013-06-15

    include unistd.h

    usleep(1000000); // = 1 second.

     
    Last edit: Cameron King 2013-06-15
  • Camilla Löwy
    Camilla Löwy
    2013-06-16

    Read the entire paragraph. There are links to software that works with Visual Studio.

     
  • David Bregman
    David Bregman
    2013-06-16

    Cameron: thanks, but usleep doesn't exist on all GLFW's supported platforms.

    Camilla: So your suggestion is to install a multi-threading library so I can call sleep in my single-threaded program? What guarantee is there that the threading library's sleep function even works together with my default/main thread which is not created via that library? Even if that is always the case in practice, this seems quite inelegant compared to a simple glfwSleep call. Could you explain why this situation is preferable to the GLFW 2.x way?

     
  • Camilla Löwy
    Camilla Löwy
    2013-06-16

    Those libraries use native OS threads, of which the main thread is one, so it is guaranteed. You can also pluck out the implementation of sleep from one of them and use only that.

    Proper, per-thread sleep is in the domain of a threading API, not of a window and context creation one. Even if your application is single-threaded, frameworks you are using directly or indirectly may be using worker threads that shouldn't be put to sleep by a naive, process-wide sleep function.

     
  • David Bregman
    David Bregman
    2013-06-16

    You can also pluck out the implementation of sleep from one of them and use only that.

    That's what I thought :( I am just going to end up copying and pasting the code for the glfwSleep function (or the one from the thread lib, same thing) into my code, because it doesn't make any sense to require a threading library to sleep when I am not doing any threading. The end result is my code is less portable, has more ugly #ifdefs, more maintenance burden and more frustration. I don't expect my experience here will be unique either.

    Proper, per-thread sleep is in the domain of a threading API, not of a window and context creation one. Even if your application is single-threaded, frameworks you are using directly or indirectly may be using worker threads that shouldn't be put to sleep by a naive, process-wide sleep function.

    If I am not doing anything whatsoever with threads, then I shouldn't have to worry about any of this. Single threaded programs still need to be able to sleep, so with that function gone we are in trouble.

    What I would suggest is either (a) bring back glfwSleep or (b) make a version of glfwWaitEvents which takes a timeout parameter. Either would be sufficient for implementing cpu throttling / FPS limiting type things.

     
    • Marcel Metz
      Marcel Metz
      2013-06-17

      If I am not doing anything whatsoever with threads.[…]
      But you do, you put the calling thread of your process to sleep. If your application only uses one thread that's your design decision.

       
  • If I am not doing anything whatsoever with threads, then I shouldn't have to worry about any of this. Single threaded programs still need to be able to sleep, so with that function gone we are in trouble.
    What I would suggest is either (a) bring back glfwSleep or (b) make a version of glfwWaitEvents which takes a timeout parameter. Either would be sufficient for implementing cpu throttling / FPS limiting type things.

    I think, GLFW3 "strives" to be focused, minimalistic and clean. And this philosophy is one of the reasons many of us love GLFW. While glfwSleep() is occasionally useful, it is (in my opinion) not useful enough to justify including it in GLFW, it's really in domain of threading and out of focus of GLFW. For the same reason we don't have in GLFW3 many other things, such as limited image loading, text drawing, config files parsing or sound routines etc. It's just not the focus of GLFW and there are mature, complete and featureful solutions for such things. Do we really need limited and "overlapping" functionality in GLFW? Rationale for API cleanup and all deprecations presented perfectly in "2 to 3" transition guide.
    And in most cases (i don't know about yours) sleep is just no good for fps limiting, because of granularity issues and sleep time upper bound guaranties. Usually, best tool for this job is vsync. What we really need is to polish glfwSwapInterval (mostly under win, desktop composition check currently blocks any control over swap interval).

     
    Last edit: Vittorio Lassini 2013-06-17
  • David Bregman
    David Bregman
    2013-06-17

    Vsync is not good for fps limiting either (in general) because a lot of drivers implement it with a busy wait, resulting in 100% cpu use. Nvidia on windows does this even on the latest drivers (May 23, 2013). Of course, advanced programs will offer multiple options for fps limiting.

    Without a sleep function, GLFW3 has no ability to write a proper main loop to control CPU use or FPS rate. In my opinion, it is completely insane to require 3rd party libraries to write a proper event loop. The cross platform event loop is the absolute core of what GLFW is supposed to provide, it is not tangential functionality like image loading or text drawing.

     
  • Vsync is not good for fps limiting either (in general) because a lot of drivers implement it with a busy wait, resulting in 100% cpu use. Nvidia on windows does this even on the latest drivers (May 23, 2013).

    It is simply the best that you can get. With sleep-based solutions you'll get tearing, your fps will likely be lower than you expect and there will be jitter. It's a cure worse than disease. Vsync issues are only driver issues and drivers get better, but sleep solution is fundamentally broken.
    I have win7, 560Ti with latest drivers and there is no 100% cpu usage in my GLFW3 applications with vsync. Can you give more details about your system and your application? Do you use glFinish() in your code? What is the status of "Threaded optimization" and "Vertical sync" in your Nvidia Control Panel?

    Of course, advanced programs will offer multiple options for fps limiting.

    Most commercial games have just vsync switch in options.

    Without a sleep function, GLFW3 has no ability to write a proper main loop to control CPU use or FPS rate.

    You don't need sleep in main loop in the first place. For example, you can look at Doom 3 source code. There is no sleeping for fps limiting.
    Sleeping in main loop is rare and questionable. For those rare cases you just use some threading solution, it's not that difficult.

     
    Last edit: Vittorio Lassini 2013-06-17
  • David Bregman
    David Bregman
    2013-06-17

    I am sorry but you are just misinformed here. It is not "questionable" or a "rare case". Every main loop needs to have some kind of yield call in it, unless it is acceptable for the application to consume the entire CPU. Vsync cannot be relied on, and even if it could be relied on, you don't always want to run at the refresh rate. Mostly fullscreen games will consume 100% CPU, but these days even games are becoming more aware of power efficiency issues, the need to not excessively drain the battery on laptops or tablet devices.

    Secondly, Vsync off does not imply tearing. For example on modern windows systems, the entire desktop surface is always vsynced when compositing is enabled.

    Thirdly, sleep-based solutions can work just fine. I am not speculating about stuff I haven't tried in real life here.

    I don't want to get into specific details my system since it is orthogonal to the point I am attempting to make here. I will say that I do a lot of tech support for graphics issues for the product I maintain, and I have seen vsync causing 100% cpu on many different setups. Please google "vsync 100 cpu" if you don't believe me.

     
  • Every main loop needs to have some kind of yield call in it, unless it is acceptable for the application to consume the entire CPU.

    It's just that you don't need sleep in your main loop. And commercial games don't do that.

    Vsync cannot be relied on

    Of course you can rely on vsync, because you simple don't have another sensible options for most cases. You can't rely on sleep because on desktop OSes you don't have any guaranties about sleep time upper bound. Sleep(10) basically means that you'll get no less then 10 time units of sleep. And there is problem with granularity (for example, to achieve low granularity on win you need to mess with timeBeginPeriod()/timeBeginPeriod(), which globally affects scheduler resulting in lower performance and decreasing chances for cpu to use power-saving modes).
    In fact, i never experienced vsync busy-waiting on large range of hardware, so i wonder how much this is a problem at all.

    even if it could be relied on, you don't always want to run at the refresh rate.

    Yes, and most of such cases can be described with words "render as fast as you can".

    but these days even games are becoming more aware of power efficiency issues, the need to not excessively drain the battery on laptops or tablet devices.

    Properly implemented vsync to the rescue.

    Secondly, Vsync off does not imply tearing.

    Yet i see tearing all the time with vsync off.

    Thirdly, sleep-based solutions can work just fine. I am not speculating about stuff I haven't tried in real life here.

    Vsync can definitely work just fine. Can you list some of sleep-based commercial games for reference?
    If you really need sleep, just use some threading solution.

     
    Last edit: Vittorio Lassini 2013-06-17
  • David Bregman
    David Bregman
    2013-06-17

    It's just that you don't need sleep in your main loop. And commercial games don't do that.

    What function do you call to yield CPU then? *nix sched_yield() is equivalent to what glfwSleep(0) does in 2.x.

    Of course you can rely on vsync.

    No. See previous post. It is not always reliable, and even if it was reliable, it isn't always the desired behavior.

    You can't rely on sleep

    Sure, you can't rely on it to sleep for exactly the amount of time requested, but it works well most of the time in practice. There's also no alternative that I am aware of.

    Yes, and most of such cases can be described with words "render as fast as you can".

    No. There are more possibilities than "refresh rate" and "as fast as you can". Examples would be playing an animation at its native rate, or limiting FPS to a specific maximum.

    Yet i see tearing all the time with vsync off.

    I said implies. In other words, vsync off does not guarantee tearing. On modern windows for example, you typically only get tearing when compositing is off, or when in fullscreen/exclusive mode with vsync off.

    Can you list some of sleep-based commercial games for reference?

    Any game with a MaxFPS option. World of Warcraft for example.

     
  • What function do you call to yield CPU then?

    I'm just using vsync. If i'll be in need of explicit yielding, sleeping or other threading-related things, then i'll use some portable threading solution.

    No. See previous post. It is not always reliable

    Nothing is always reliable. But (in my opinion) need for workaround for some problem of some hardware/software configurations is poor reason to include some "unrelated" functionality to the library.

    even if it was reliable, it isn't always the desired behavior.

    I'm not denying that. I'm just saying that the other cases are pretty rare.

    Sure, you can't rely on it to sleep for exactly the amount of time requested, but it works well most of the time in practice.

    Vsync works well most of the time in practice too. In my practice, at least. But i cannot say anything good about sleep-based methods (especially for active, high fps games).

    No. There are more possibilities than "refresh rate" and "as fast as you can". Examples would be playing an animation at its native rate, or limiting FPS to a specific maximum.

    Yes, there are more possibilities. But this two used much more frequently then the other. And that reflected in commercial games. Do we need rarely used "out-of-focus" features in glfw? Besides, just adding glfwSleep() is not enough. You must add some means for controlling granularity.

    typically only get tearing when compositing is off, or when in fullscreen/exclusive mode with vsync off

    I feel this "only" happens much more frequently than busy-waiting vsync problems..

    Any game with a MaxFPS option. World of Warcraft for example.

    It's a good example, but most games i played were without such option.

     
    Last edit: Vittorio Lassini 2013-06-17
  • David Bregman
    David Bregman
    2013-06-17

    So what you are telling me is that the ability to control the frame rate and CPU use of my application is an advanced feature which is outside the scope of GLFW? I find that rather incredible.

     
  • So what you are telling me is that the ability to control the frame rate and CPU use of my application is an advanced feature which is outside the scope of GLFW?

    I think that the ability to control the frame rate and CPU use through sleep calls is outside the scope of GLFW.

     
  • David Bregman
    David Bregman
    2013-06-17

    I just don't know how to get through to you. I believe I presented a strong argument in my previous posts, if you don't get it then I guess we will have to agree to disagree. For me, if I need more than one library to write my basic event loop, then GLFW has failed its job. That simple. Removing glfwSleep will help no one, but it will waste people's time as it has wasted mine. If your way of thinking about this issue represents the maintainer's views, I think it is very sad for GLFW.

     
  • David, i've just stated my personal view as a random glfw user and i really have nothing to add. Of course you are free to disagree.
    This proposal is seen from my eyes like that:
    Let's return glfwSleep() because there are some people that
    - want to control framerate through sleep calls
    - want to write single-thread application
    - refuse to use some threading solution

     
  • David Bregman
    David Bregman
    2013-06-17

    want to control framerate through sleep calls

    I wasn't going to reply again, but you keep saying "through sleep calls" like you are implying there is some other way to accomplish these things other than with sleep calls. Is there? What is it?

    refuse to use some threading solution

    I must I do whatever it takes to make my program work correctly, otherwise my users will be in trouble. But I am saddened when an elegant library like GLFW is suffering poor design decisions and going backwards, forcing me to add ugly hacks to my code to accomplish my job. Like requiring an entirely different library just to write my freaking main loop (seems like a bad joke).

     
  • you are implying there is some other way to accomplish these things other than with sleep calls. Is there? What is it?

    It is vsync (again). It limits your fps (to monitor refresh rate) and cpu use (with proper implementation, and personally i don't experienced "improper implementation" in years). And i have a feeling (i don't have hard numbers to support that claim, but neither are you, it seems) that most people are happy with just that (many if not most commercial games don't use sleep-based system). I'm personally one of such people.
    If you need fps limits other than monitor refresh rate then vsync is not for you. But i'm not convinced that your needs are common. And even with your needs it's no big deal to just use threading library.

    forcing me to add ugly hacks to my code to accomplish my job

    There is no need for any hacks. You just need additional dependency. It's not that painful.

    Okay, lets stop at this and just wait for opinions from other users or Camilla.

     
    Last edit: Vittorio Lassini 2013-06-17
  • David Bregman
    David Bregman
    2013-06-17

    Let's remove glfwGetTime and glfwSetTime too. What has time got to do with opening an OpenGL context? GLFW strives to be "minimalistic" and clean. If you need them just use a time library. It's not that painful.

    Clipboard handling? WTF has clipboard handling to do with GLFW? Most commercial games don't use the clipboard either. Better junk it ASAP as the clipboard code is introducing unacceptable maintenance burden on the GLFW developers.

    Joysticks? Not many commercial games actually use joysticks. At least not many I've played. I'm not convinced that your need for joystick input is common, so let's get rid of it too. Use a library if you need it.

    Repeat ad nauseam until no one uses GLFW.

     
  • If you need them just use a time library

    Do you know any mature, lightweight, popular and maintained portable high-precision timing library?

    Clipboard handling? WTF has clipboard handling to do with GLFW? Most commercial games don't use the clipboard either

    Actually, many commercial games do use clipboard handling (for example, in chat or login screens). It's really useful for GUI's. And there is no "clipboard library", so without this functionality you must write all the platform-specific code yourself. This is not the case with sleeping, because there is many mature, lightweight and maintained threading libraries (and with newer standards of c/c++ you don't even need any threading library).

    Joysticks? Not many commercial games actually use joysticks.

    In this day and age of console gaming and multiplatform games there are literally TONS of games that use (or even "optimized for") joysticks. Again, do you know good joystick library?

     
    Last edit: Vittorio Lassini 2013-06-17
  • David Bregman
    David Bregman
    2013-06-17

    You didn't get it again. I was attempting to demonstrate your way of thinking extended to its absurd conclusion.
    The point is, even if there were libraries for those things, they still shouldn't be removed from GLFW. Just like sleep shouldn't have been removed. If those libraries exist in the future will you recommend GLFW remove that functionality then? This is nonsense.

    and BTW, the whole "commercial games" thing is kind of a red herring anyways as (1) this isn't the only target use case for GLFW and (2) I'm pretty sure most commercial games (at least AAA games) would never use GLFW anyways as it is not full featured enough. (Lack of a sleep function doesn't help here)

     
  • You didn't get it again. I was attempting to demonstrate your way of thinking extended to its absurd conclusion.

    And i'm demonstrated that my way of thinking don't really extends to any "absurd conclusion", but to current state of things.

    If those libraries exist in the future will you recommend GLFW remove that functionality then?

    If there will be a really good timing library in the future, then i will not object deprecating current timing functions in some very-very distant, backwards-incompatible version of GLFW. I will not recommend this deprecation (because i use timing all the time), but it will not hurt me.
    GLFW3 was designed not in vacuum with only some "way of thinking". It was designed (as backwards-incompatible, cleaned up API) with existing software and typical use cases in mind, i believe.

    and BTW, the whole "commercial games" thing is kind of a red herring anyways as (1) this isn't the only target use case for GLFW and (2) I'm pretty sure most commercial games (at least AAA games) would never use GLFW anyways as it is not full featured enough. (Lack of a sleep function doesn't help here)

    The whole "commercial games" thing is not about GLFW, but about frame rate limiting with sleep. It is only to show on what grounds i think that your needs are not common. To reiterate, i think that including some "out-of-focus, overlapped" functionality is only justified when there is sufficiently high demand for such functionality and you can't get that functionality elsewhere without much pain. I believe that glfwSleep() not meets such conditions.
    David, i understand your position fully. It's just i cannot agree with it.

    This is going nowhere, so i'm done.

     
    Last edit: Vittorio Lassini 2013-06-17
  • Camilla Löwy
    Camilla Löwy
    2013-06-17

    The suggested library is a single source file with a single header file, requiring no special configuration. It would have taken a fraction of the time that was spent creating this thread to integrate into a project. It's bundled with GLFW 3 and used in its tests, so if you have the source tree available you can see this for yourself.

    I currently have no plans to reintroduce a sleep function and this thread isn't convincing anyone of anything. If anyone wants to change those plans, file a feature request and make a good argument for it.

    That's all I'm going to say here.

     
  • David Bregman
    David Bregman
    2013-06-17

    The suggested library is a single source file with a single header file, requiring no special configuration. It would have taken a fraction of the time that was spent creating this thread to integrate into a project.

    Clearly, but I've been arguing this thread on principle for a while now. You know what would have taken even less time? Not removing core functionality on a whim, for zero benefit.

    I currently have no plans to reintroduce a sleep function and this thread isn't convincing anyone of anything. If anyone wants to change those plans, file a feature request and make a good argument for it.

    In other words, please direct all complaints to the trash bin. Gotcha.

    BTW: for anyone else affected by this debacle, here's what I'm using:

    void MySleep(double time) {
    #ifdef WIN32
        Sleep((DWORD)(time*1000));
    #else
        if(time == 0.0) {
            sched_yield(); // sched.h
        } else {
            usleep((useconds_t)(time*1000000)); // unistd.h
        }
    #endif
    }
    

    Will work on Windows and 'nix until I can complete migrating my code to SDL 2.0.

     
  • mariojmartin
    mariojmartin
    2013-10-04

    I am using the following code to limit the framerate

    clock_t star_clock = clock();
    ...
    display()
    ...
    clock_t end_clock = clock();
    clock_t sleep_time = MAX_FRAMERATE_MILISECONDS
        + ((start_clock - end_clock)* 1000)/CLOCKS_PER_SEC;
    
    if (sleep_time > 0){
        std::this_thread::sleep_for
            ( std::chrono::milliseconds( sleep_time ));
    }
    
     
    Last edit: mariojmartin 2013-10-04
  • I know that this is an old thread by now (I missed it), but I'll give it a shot anyway. Perhaps it can clear up some things about the design philosophies in GLFW (old and new).

    First of all, David, I'm sorry that you feel that way.

    I guess I'm the one to blame for bringing the threading functionality into the 2.x line of GLFW in the first place, but here's my reasoning (and I honestly don't think that it's insane)...

    While threading support, including glfwSleep(), was an attempt att bringing cross-platform threading to the OpenGL development community back in the days when such solutions were not commonplace, I totally agree with the decision of dropping it in 3.x.

    GLFW 3.x is, as has been told over and over, a move for simplification and re-adjustment to the current state and trends in the software & OpenGL development community, over a decade after GLFW first saw the light of day.

    In particular, C11 and C++11 has finally brought proper, standardized threading libraries to us C & C++ developers, so there is really little point in keeping that in GLFW anymore.

    If you look closely at those specifications, you'll find that the Sleep functionality is part of the threading libraries: thrd_sleep() in <threads.h> (C11) and std::this_thread::sleep_for() in <thread> (C++11).

    Now, since C11 and C++11 support was lacking a couple of years ago, I created TinyCThread and TinyThread++ for developers to use during the transitional period until compilers have caught up (because in my mind, the only sane way is to use standard libraries - and if you're compiler is flawed, change compilers or work around it by using replacement libraries until it gets fixed).

    I think that your particular problem is that you're using the dreadful combination Visual Studio + C, which (as I understand it) has very poor support from Microsoft. They don't seem to be interested in supporting anything newer than C90, other than subsets from newer C++ standards, which in my book reads "C is pretty low priority to us".

    My suggestion to anyone finding themselves in this unfortunate situation, rather than blaming GLFW for Microsofts poor C11 support, is to do some combination of the following:

    A) If you want to stay with Visual Studio, perhaps move to C++ and reap the benefits of its C++11 support (yes, you can do std::this_thread::sleep_for() in VS 2012 and later).

    B) If you want to stay with Visual Studio AND stay with its dated C support, start using TinyCThread and adopt the new standard way of doing threads in C11 (and no matter what you say - sleep() IS a threading function).

    C) Nag on Microsoft to add support for C11 threads in Visual Studio (according to [1] I assume it's only a matter of time, but they could probably do with some constructive user feedback).

    [1] http://herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99/