• (cs)

    This is one of the best ones in a while.

  • (cs) in reply to JC
    Anonymous:

    Regarding "The Daily WTF Reader Survey (tm)", can anyone tell me the difference between a "Programmer/Developer I" and a "Programmer/Developer IV"... just so I can decide which I am!

    Oh, and assuming this survey is being used to decide what types of advertising we get on the site, what do people reckon I should choose to get more table football/beanbag girl type ad's? :-)

    A "Programmer/Developer I" would write
      sleep(60);
    They don't know any other way. 
    A "Programmer/Developer II or III" would write:
      void ExitThreadAfterDelay()
      {
       HANDLE hTimer = CreateWaitableTimer(0, FALSE, 0);
       if (hTimer) {
        LARGE_INTEGER SixtySeconds;
        SixtySeconds.QuadPart = -600000000L;
        if (SetWaitableTimer(hTimer, &SixtySeconds, 0, NULL, NULL, FALSE)) {
         if (WaitForSingleObject(hTimer, INFINITE) == WAIT_OBJECT_0) {
          ExitThread(0);
         }
        }
        CloseHandle(hTimer);
       }
      }
    They are clever.
    
    A "Programmer/Developer IV" would write
      sleep(60);
    They know better. 
  • anonymous (unregistered) in reply to JoeBloggs
    Anonymous:
    I did a lot of that in my early programming.  In my defense, I was programming on a Commodore 64, which had neither a sleep() function nor any concept of multitasking.

    Yea. You can use "for" delays on machines you know always use the same clock speed (0.980 Mhz on the C64). This mean also on old videogame consoles, Nintendo, Atari, etc. But I dont think is a good idea on modern ones, because the 100% CPU useage and because modern consoles sould have already proper lenguajes to code (C, C++, etc)

     Just for fun, can be interesting to check how sleep is implemented on a compiler...

     

  • (cs) in reply to anonymous

    Unless your app is something like "Watching Paint Dry 2.0" I can't think of any reason you would make your users stare at a static screen while your for loop maxes out the CPU especially on a C64.

    The trick on the C64 was to implement your own thread switching by hooking the timer interrupt (from memory).  That way your little guy's legs could still dance around, or the star field could twinkle, even when nothing else was happening.

    Ahhh, mutexes in 6502 assembler, those were the days...

  • Dwonis (unregistered)

    What happens if a timezone change happens, or something else causes the system clock to change?  Perhaps this function behaves better than Sleep() does (or is thread-safe when Sleep() isn't---sorry, I'm not a Windows programmer.)

  • (cs) in reply to Some Idiot
    Some Idiot:
    Anonymous:

    Regarding "The Daily WTF Reader Survey (tm)", can anyone tell me the difference between a "Programmer/Developer I" and a "Programmer/Developer IV"... just so I can decide which I am!

    Oh, and assuming this survey is being used to decide what types of advertising we get on the site, what do people reckon I should choose to get more table football/beanbag girl type ad's? :-)

    A "Programmer/Developer I" would write
      sleep(60);
    They don't know any other way. 
    A "Programmer/Developer II or III" would write:
      void ExitThreadAfterDelay()
      {
       HANDLE hTimer = CreateWaitableTimer(0, FALSE, 0);
       if (hTimer) {
        LARGE_INTEGER SixtySeconds;
        SixtySeconds.QuadPart = -600000000L;
        if (SetWaitableTimer(hTimer, &SixtySeconds, 0, NULL, NULL, FALSE)) {
         if (WaitForSingleObject(hTimer, INFINITE) == WAIT_OBJECT_0) {
          ExitThread(0);
         }
        }
        CloseHandle(hTimer);
       }
      }
    They are clever.
    
    A "Programmer/Developer IV" would write
      sleep(60);
    They know better. 


    <font face="tahoma,arial,helvetica,sans-serif">A "Project Manager (contractor/consultant)" would write</font>

    <font face="courier new,courier">// Get Current Interactive User's Permissions for
    //  InitializeSleep, ExecuteSleep,
    //  and FinalizeSleep
    boolean hasPermissionsRequiredToInitializeSleep =
    currentInteractiveUser.HasSpecificPermission
    (
    SpecificApplicationPermissions.InitializeSleep
    );

    boolean hasPermissionsRequiredToExecuteSleep =
    currentInteractiveUser.HasSpecificPermission
    (
    SpecificApplicationPermissions.ExecuteSleep
    );

    boolean hasPermissionsRequiredToFinalizeSleep =
    currentInteractiveUser.HasSpecificPermission
    (
    SpecificApplicationPermissions.FinalizeSleep
    );

    // Determine if Current Interactive User is authorized
    // for the Sleep Action, which requires that
    </font><font face="courier new,courier">// the user has InitializeSleep, ExecuteSleep,
    //  and FinalizeSleep
    boolean hasPermissionsRequiredToSleep = 
    hasPermissionsRequiredToInitializeSleep
    && hasPermissionsRequiredToExecuteSleep
    && hasPermissionsRequiredToFinalizeSleep;

    if(hasPermissionsRequiredToSleep) Sleep(60);</font>

    <font face="tahoma,arial,helvetica,sans-serif">They can.



    </font>

  • ajk (unregistered)

    actually sleep() is not a good choice in a windows program as obviously the posted code is written for although it does give an implication like the tip of an iceberg how the rest of the design is...

     

  • PS (unregistered)

    Please correct me if I'm wrong (hobby programmer with rather theoretical experience in threading here) but doesn't sleep actually freeze the whole process instead of just one thread?

  • (cs)

    Well looking up:

    DWORD WaitForSingleObject(
        HANDLE hHandle,    // handle of object to wait for
        DWORD dwMilliseconds     // time-out interval in milliseconds 
       );

    MHO would be that he didn't need to create a timer at all... if he specified the second param to 60 secs (the long equ of 60secs) 

  • Jens (unregistered)

    (Without having read all comments) Could it be that sleep() applies to the whole process, while this WaitableTimer only halts execution of a single thread?
    The function is called ExitThreadAfterDelay after all.
     

  • anonymous (unregistered) in reply to woodle
    woodle:
    Unless your app is something like "Watching Paint Dry 2.0" I can't think of any reason you would make your users stare at a static screen while your for loop maxes out the CPU especially on a C64.

    The trick on the C64 was to implement your own thread switching by hooking the timer interrupt (from memory).  That way your little guy's legs could still dance around, or the star field could twinkle, even when nothing else was happening.

    Ahhh, mutexes in 6502 assembler, those were the days...

    yea, with interruptions you can even emulate 80 columns with his 40 colums hardware. Absolutelly mad how much you can do with interrrupts. With good timing, you can mix graphics mode and text mode. Can a PC do that?

    --Tei 

  • Wd-40 (unregistered) in reply to merreborn

    The clock does not stop, it does a rollover after 24 days (ticks getting bigger than max)

    Thought you all ought to know.

     

    Captcha: shizzle 

  • Tony68k (unregistered) in reply to verisimilidude

    C64 interupts were probably the best out of the old 8 bit machines.  You also had a couple of hardware timers you could use, or simply hooking a counter onto the raster interupt would give you sec/50 resolution.

  • dave (unregistered)

    Apart from all the silliness around not using Sleep(), I'm pretty impressed by the failure modes.

     

    If the thread DOES manage to exit, it leaks a handle.

     

    More interestingly, under some circumstances, the function named ExitThreadAfterDelay() may not, in fact, exit the thread at all. It will just return (but at least it closes the handle).

     

    Any bets on whether the caller of ExitThreadAfterDelay is expecting to receive control back after the call?

     

    Captcha - "paula",  Brillant!

     

     

     

  • anonymous (unregistered) in reply to Jens
    Anonymous:

    (Without having read all comments) Could it be that sleep() applies to the whole process, while this WaitableTimer only halts execution of a single thread?
    The function is called ExitThreadAfterDelay after all.
     

     

    No.

  • (cs) in reply to Jens
    Anonymous:

    (Without having read all comments) Could it be that sleep() applies to the whole process, while this WaitableTimer only halts execution of a single thread?
    The function is called ExitThreadAfterDelay after all.
     

    Straight from the horses mouth:

     The Sleep function suspends the execution of the current thread for a specified interval.

    VOID Sleep(
        DWORD dwMilliseconds     // sleep time in milliseconds
       );

     

  • (cs) in reply to PS
    Anonymous:
    Please correct me if I'm wrong (hobby programmer with rather theoretical experience in threading here) but doesn't sleep actually freeze the whole process instead of just one thread?


    Sleep() (note the capital S) only suspends the current thread.
  • (cs) in reply to triso

    triso:
    Does anyone know where Alex went for vacation?  I hope they don't sell sparklers there....
    [I'd give an arm to be ambidextrous!]

    ... or anything even bigger that might cost you an arm...

  • (cs) in reply to englebert
    Anonymous:

    The real danger here is that if you are running on a Xell 2600 without a BIOS patch (must be a MS problem<-> must be a Xell problem), and the system clock stops advancing while you are in this loop, you will burn 100% of the CPU for a long time.

    Homework:  Devise a "health check" that can determine if the system clock has stopped.

    Hint: Have an external system provide a hearbeat.

    Note: We switched back to HP servers.

    Fun. Even more fun, judging from this post, it sounds like the fix (or possibly some other fix - not clear) may have broken timekeeping on Linux. (Wouldn't suprise me).
     

  • Ed (unregistered) in reply to kbiel

    Just like old vga dos games, you can sync your app to the vblank (or even scanline) from the VIC chip. Assuming 60(30?) Hz video refresh rate and 525 scanlines on a NTSC display, you should be able to work out the math pretty easily for relative time between two events. There is no such thing as time of day on such a machine, and it's been a couple of years since I've played with this, but that's the basic (no pun intended) idea I've used.

  • (cs) in reply to kbiel
    Anonymous:

    Um, what is the Now() equivalent on a C64?  Just curious because I always found it hard to work up such timers on a system that had no concept of time structures nor even possessed a real time clock.

     

    CAPTCHA: truthiness - Perfect for this comment. 


    The C64 has a timer that counts seconds since power-on.  I can't remember how to access it or what the precision was, but I used it when I needed seconds-granularity timing.  For more precise timing, I used a delay loop.
  • (cs) in reply to Some Idiot
    Some Idiot:
    Anonymous:

    Regarding "The Daily WTF Reader Survey (tm)", can anyone tell me the difference between a "Programmer/Developer I" and a "Programmer/Developer IV"... just so I can decide which I am!

    Oh, and assuming this survey is being used to decide what types of advertising we get on the site, what do people reckon I should choose to get more table football/beanbag girl type ad's? :-)

    A "Programmer/Developer I" would write
    sleep(60);
    They don't know any other way. 
    A "Programmer/Developer II or III" would write:
    void ExitThreadAfterDelay()
    {
    HANDLE hTimer = CreateWaitableTimer(0, FALSE, 0);
    if (hTimer) {
    LARGE_INTEGER SixtySeconds;
    SixtySeconds.QuadPart = -600000000L;
    if (SetWaitableTimer(hTimer, &SixtySeconds, 0, NULL, NULL, FALSE)) {
    if (WaitForSingleObject(hTimer, INFINITE) == WAIT_OBJECT_0) {
    ExitThread(0);
    }
    }
    CloseHandle(hTimer);
    }
    }

    They are clever.
    A "Programmer/Developer IV" would write
    sleep(60);
    They know better. 

    If there were a "Programmer/Developer V" designation, they would write

      delay(60.0);

    ...but, alas, there are no "Programmer/Developer V" jobs any more. 


  • Worf (unregistered) in reply to RyuO

    Hrm. The alternative would be to say, create an event object, pass it into WaitForSingleObject with *gasp*, a 60,000 msec timeout! Then CloseHandle() the event object...

    (You can't pass in NULL for a handle into WaitForSingleObject or WaitForMultipleObjects - it returns with WAIT_FAILED). 

     

  • (cs) in reply to joe bruin

    Actually, there are valid reasons to delay a thread before closing. Especially if you are controlling stuff in teh real world (machines etc) there will be a lot of times you will have to wait some minimum before you can go on. If the 'go on' trigger is the exiting of your thread, then you might need this function in certain cases

    The way it's done is really 'WTF" tho. And in in this case the need to wait is probably a WTF as well since this programmer seems to be new to the whole threading/syncing/kernel handles field :)

  • Vek (unregistered) in reply to Stephen Jones

    Definitely could be worse.  I wrote a high performance app (Game) and tried to use sleep to time the frames.  Turns out that sleep(1) will wait anywhere between 0 and 20 ms even if you tell windows to increase the accuracy.   Just like 'timeGetTime()' will return the same value for many calls in a row, and then suddenly return a new value thats skipped a whole bunch.

    Didn't solve it with waitable timers though.  Just took the lazy way out - created a signal handle and then waited for n milliseconds timeout, without ever signalling it (letting it time out).  Veeeryy accurate.

  • anonny (unregistered) in reply to Alexis de Torquemada
    Alexis de Torquemada:
    for (int i = 0; i <= 10; ++i) {
      switch (i) {
    case 0:
    putchar('O');
    break;
    case 1:
    putchar('h');
    break;
    case 2:
    case 5:
    putchar(' ');
    break;
    case 3:
    putchar('m');
    break;
    case 4:
    putchar('y');
    break;
    case 6:
    putchar('G');
    break;
    case 7:
    putchar('o');
    break;
    case 8:
    putchar('d');
    break;
    case 9:
    putchar('!');
    break;
    case 10:
    putchar(10);
    break;
    }
    }
    Picture a system that doesn't have "data" memory, just totally seperate code and RAM.  The closest you can get to an array is a jump table pointing to a bunch of "return(x)" equivalents.  To make strings, constructs like the above are necessary.

    Now imagine a C compiler designed for it.

    I imagine SDCC will autogenerate some beautiful WTF's in the future. 

  • steve (unregistered) in reply to Manni
    Manni:
    kipthegreat:
    Colin McGuigan:

    Could be worse; I've seen more than one programmer who, when tasked to do something like "wait 5 seconds", writes this code or similar:

     DateTime end = DateTime.Now.AddSeconds(5);

    while(end < DateTime.Now) {

       for (int ii = 0; ii < 100000; ii++) { }

    }
     

    It has all the beauty of ignoring something like Sleep, *and* will spike the CPU to 100% for however long it's waiting for. 

    I have to confess that I did almost exactly this, when I first learned VB.  I was in high school at the time, if that makes it more acceptable..

    Although, shouldn't it be "while(DateTime.Now < end) {"  instead?

    Good pull kip.

    And my favorite implementation of this so far was where the program would execute some external program (I think it might have been a batch file) and wait for the external dude to finish before resuming the program. The external program would basically sleep for 5 seconds, and then exit. Well...not always.

    I've used that trick before in batch files, for example:

      :loop
      (command that needs to be run every 10 seconds)
      ping -n 10 127.0.0.1 > nul
      goto loop
  • (cs) in reply to woodle
    woodle:
    The trick on the C64 was to implement your own thread switching by hooking the timer interrupt (from memory).  That way your little guy's legs could still dance around, or the star field could twinkle, even when nothing else was happening.

    Ahhh, mutexes in 6502 assembler, those were the days...

    Wouldn't it have been easier to use a central event loop?

    Anonymous:
    With good timing, you can mix graphics mode and text mode. Can a PC do that?

    I don't know whether all the C64's tricks were possible, but a good many were. I had several books which described a few of these graphical effects and included floppy disks with example code. I think one of the effects was to switch the character map after every n-th HSYNC (the timing could be obtained through the video adapter's DAC registers) such that the text mode looks like a graphical mode. Another effect was to produce colored horizontal bars as previously seen in C64 games. With VGA came the possibility to use double buffering and wait for a VSYNC before switching buffers, this would entirely eliminate flicker. Obviously, many of these tricks won't work with a TFT display any more. :-)

Leave a comment on “Raymond Chen on Sleep() Deprivation ”

Log In or post as a guest

Replying to comment #:

« Return to Article