• R.Flowers (cs)

    Welcome Mr. Chen.

     You can always tell a guy's first day on the job. This WTF is in early!

     

     

  • Puckdropper (unregistered) in reply to R.Flowers

    He's very punctual too.  Every day at 7:00 AM exactly, his time, there's a new blog post. ; - )

  • ModemRat (unregistered)

    Alex must be Sleep()ing in right now.

     

  • ammoQ (cs)

    Since Alex is on vacation this week, the main forum is fed by an auto-pilot script. Stay tuned, folks, we'll see contributions from a lot of very interesting guest authors this week.

  • qbolec (cs)

    ...wait a minute....

  • JC (unregistered)

    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? :-)


     

  • merreborn (unregistered) in reply to JC

    Classic WTF: reinventing the wheel in the stupidest way possible.

  • Platypus (unregistered)

    Actually this idiom is neither uncommon nor invalid on platforms that lack a directly-coded sleep() equivalent, and I'll bet the programmer came from such an environment.  That's no excuse for doing absolutely nothing in the error cases, though, and having it exit the thread is just WTF, but the basic idea isn't crazy.

  • Anonymous (unregistered) 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!

    Programmer/Developer I would basically be a guy with less experience who handles the less complex tasks, and a P/D IV would be akin to a senior developer or technical lead in my opinion -- the go-to guy with the knowledge, experience, and (usually) can help you if you're having a problem.  That is, those that don't end up on TDWTF themselves.

  • Paula Bean (unregistered)

    This isn't the dumb way to do it!  Why, it looks positively Enterprisey(TM)(R)(WTF)!

     Far more impressive than some stupid call to a boring function like sleep().
     

  • CDarklock (cs) in reply to JC

    Anonymous:
    can anyone tell me the difference between a "Programmer/Developer I" and a "Programmer/Developer IV"

    Generally 3-5 years of experience at each level, so if you have 9-10 years of experience, you're either at the high end of II or the low end of III.

    Lead software developers are usually directly responsible for the success of one project, and chief software developers for several simultaneously.

    I think the purpose of the survey is to see if they should do job postings here.

  • Colin McGuigan (cs)

    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. 

  • AJ (unregistered)

    Maybe he needed a more accuracy than the 10ms resolution Sleep() provides?

  • themagni (cs) in reply to Colin McGuigan
    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. 

    Yes! I've seen this many, many times. I've tried to explain that this makes the code unstable. It's like talking to a really dumb rock. (In all fairness, sometimes you don't have "sleep".) It just inserts a race condition. How do you know if it's always going to be 6 seconds?

    Will you pause for long enough?

    Will you crash?

    Will your compiler optimise out the loop that has nothing in it? 

    Who knows? It works now; ship that mofo!

  • kipthegreat (cs) in reply to Colin McGuigan
    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?
  • JoeBloggs (unregistered) in reply to Colin McGuigan
    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 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.
  • Manni (cs) in reply to kipthegreat
    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.

  • Bryan K (unregistered)

    Uhh, I guess someone forgot about maybe doing this

     Thread.Sleep()     
     

  • CornedBee (cs)

    I can't believe no one has yet pointed out that the code leaks the waitable timer if it succeeds!

  • englebert (unregistered) in reply to themagni

    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.

  • Well, perhaos the SetWaitableTimer is more acurate than Sleep() (unregistered)

    Maybe they want 60 seconds to the exact microsecond. hmm no.

    This is bad code though because it sounds as if the 60 seconds has been selected because it avoids some contention problem.

    The handle is only closed if the handle failed to open - there is no cleanup (even though the exitthread is likely to take care of it).

     

  • Grimoire (cs)

    The real WTF here isn't the lack of using Sleep, nor the bug where the hTimer handle isn't closed.  The problem is that this function exists at all.  Why would you want to wait for 60 seconds, and then exit the thread?!  This stinks of a hack to fix an exit race condition.  They probably weren't synchronizing the threads properly, and during the shutdown of the app, objects were being destroyed in the wrong order (because threads were exiting in the wrong order).  So, what to do?  I know, sleep the main thread for 60 seconds and THEN exit!  That should be plenty of time for the child threads to exit...

     Yes, Sleep(60000) followed by ExitThread(0) is definitely better, but I suspect that this function shouldn't exist in the first place.  No matter how you code this function, it is still a WTF.
  • merreborn (unregistered) 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.

     

    Wow.  I'm pretty sure the system clock stopping would break a *lot* of code...

     

    Captcha: craptastic. It's like the captcha can read my mind!

  • Bus Raker (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? :-)

     The difference is about $50 -$100 K a year.

    If you're under $50K, you're a 'I'.  If you're over $100K, you're a 'IV'

    Is it just me, or is Foosball girl looking extra perky today?

  • joe bruin (unregistered) in reply to merreborn

    Finally, a real code WTF.

    On Unix systems, it's not uncommon to see the select(2) system call as a portable version of sleep() (it even works on Windows).  Not so common nowadays as way back in the day.

    But the real WTF (you didn't think you would get away that easily?) here is that the thread needs a time delay before exiting.  If you're writing multithreaded code that depends on timeouts to make sure things are working correctly, your code is already a WTF.  This is the kind of code that breaks when the system is under heavy load, or when someone tries it on an SMP machine.  If the thread was not ready to exit, it should not exit.  If it doesn't know whether it can safely exit or not, waiting a certain amount of time will not make a difference.

  • Grimoire (cs) in reply to joe bruin
    Anonymous:

    But the real WTF (you didn't think you would get away that easily?) here is that the thread needs a time delay before exiting.  If you're writing multithreaded code that depends on timeouts to make sure things are working correctly, your code is already a WTF.  This is the kind of code that breaks when the system is under heavy load, or when someone tries it on an SMP machine.  If the thread was not ready to exit, it should not exit.  If it doesn't know whether it can safely exit or not, waiting a certain amount of time will not make a difference.

    Sorry, beat you to it my half an hour.  But I'm glad that we are in agreement! 

  • snoofle (unregistered) in reply to kipthegreat
    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?

    What happens in 2038 when end < now ?

  • kbiel (unregistered) in reply to JoeBloggs

    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. 

  • Erlando (unregistered) in reply to snoofle
    Anonymous:

    What happens in 2038 when end < now ?

    Then we wait...... 

  • TheMuuj (cs) in reply to snoofle

    That sounds like a *nix problem to me.  Well, some Windows programs will have that problem, too, but .NET  programs shouldn't (but I don't put anything past people who went to WTFU).

    DateTime won't overflow until 10,000, and the abstraction makes it possible to extend the range without breaking a lot of code (it would lead to a lot of serialization/parsing problems, though).

  • themagni (cs) in reply to Grimoire
    Grimoire:
    Anonymous:

    But the real WTF (you didn't think you would get away that easily?) here is that the thread needs a time delay before exiting.  If you're writing multithreaded code that depends on timeouts to make sure things are working correctly, your code is already a WTF.  This is the kind of code that breaks when the system is under heavy load, or when someone tries it on an SMP machine.  If the thread was not ready to exit, it should not exit.  If it doesn't know whether it can safely exit or not, waiting a certain amount of time will not make a difference.

    Sorry, beat you to it my half an hour.  But I'm glad that we are in agreement! 

    And I beat you by an hour. ;)

    We all agree that the code is bad - not by design, but by existence - then we're all thinking the right thing. If this was a perfect implementation, it would still be a WTF. Delays don't fix problems. They hide them. (Yes, there are valid reasons for waiting. This is not one of them.)

     

  • skington (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. 
    You can have a timer without a real-time clock. The BBC B had a timer, but it wasn't battery-backed, so it told you the number of seconds since the last restart. 
  • Grimoire (cs) in reply to themagni
    themagni:
    Grimoire:
    Anonymous:

    But the real WTF (you didn't think you would get away that easily?) here is that the thread needs a time delay before exiting.  If you're writing multithreaded code that depends on timeouts to make sure things are working correctly, your code is already a WTF.  This is the kind of code that breaks when the system is under heavy load, or when someone tries it on an SMP machine.  If the thread was not ready to exit, it should not exit.  If it doesn't know whether it can safely exit or not, waiting a certain amount of time will not make a difference.

    Sorry, beat you to it my half an hour.  But I'm glad that we are in agreement! 

    And I beat you by an hour. ;)

    We all agree that the code is bad - not by design, but by existence - then we're all thinking the right thing. If this was a perfect implementation, it would still be a WTF. Delays don't fix problems. They hide them. (Yes, there are valid reasons for waiting. This is not one of them.)

    I feel the shame... :)

    This is why people who don't know proper threading techniques shouldn't code in a multithreaded environment.  Its kind of funny how most people say things like "OMG!  Just use sleep!!!!" or "Haha!  He's not cleaning up the timer handle".  Those aren't the WTFs here.  Yeah, they are silly, or a bug, but not really WTFs.

  • verisimilidude (unregistered) 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.

    On a C64 it was OK to use a busy loop to do timing.  There was no threading, other than what you implemented, so the processor had nothing else to do.  Interrupts were minimally supported so possibly you could have used the sound device.  That was handled by a special purpose chip so you could play music while the 6502 processor did something else. 

     

  • SomeCoder (unregistered) in reply to Grimoire

    This is a great WTF.  First of all, you get the little WTFs of him not cleaning up the handles and such.  Then you get the slightly larger WTF of him reinventing the wheel when you could just call sleep().  Then you get the ultimate WTF of him trying to fix a race condition, by sleep()ing.

    This WTF is indeed, Brillant ;)

  • gfhjgfukygukgkhjfgh (unregistered) 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. 

    It did have a timer - it started ticking from when you turned on the computer.
    No clock though.
  • AbominousCoward (unregistered) in reply to joe bruin

    Besides which select() has better resolution than sleep() on many systems (which is a WTF in and of itself).  Don't ask how I know - I spend to much time in !sleep() state

     Captcha quality (oxymoron wtf?)
     

  • WWWWolf (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.

    Commodore 64 *does* have a real time clock. It doesn't record date, though, and it's not battery-backed-up.

    You can pull its value from BASIC variable TI$. I have no idea how to read it via machine language, but I seem to remember there was a KERNAL call for that. (I wonder what RDTIM does, maybe it does something related. =)

    And in case you're curious: If your system doesn't have a RTC, you probably have other sources of constantly-updating things. If C64 didn't have a RTC, I'd probably hook something to the raster interrupt (Just update your second counter every 25th screen update, or something... I've done a raster interrupt thing only once so I can't remember when or how the stuff works) or via some other clock chip (C64 has CIA chips, which have programmable timer interrupts, I think).

     

  • WWWWolf (cs) in reply to gfhjgfukygukgkhjfgh

    Anonymous:
    No clock though.

    Oh yeah?

    PRINT TI$
    000018

    READY.
    TI$="232729"

    READY.
    PRINT TI$
    232735

    READY.

     

  • joe bruin (unregistered) in reply to Grimoire
    Grimoire:
    themagni:
    Grimoire:
    joe_bruin:

    But the real WTF (you didn't think you would get away that easily?) here is that the thread needs a time delay before exiting.  If you're writing multithreaded code that depends on timeouts to make sure things are working correctly, your code is already a WTF.  This is the kind of code that breaks when the system is under heavy load, or when someone tries it on an SMP machine.  If the thread was not ready to exit, it should not exit.  If it doesn't know whether it can safely exit or not, waiting a certain amount of time will not make a difference.

    Sorry, beat you to it my half an hour.  But I'm glad that we are in agreement! 

    And I beat you by an hour. ;)

    We all agree that the code is bad - not by design, but by existence - then we're all thinking the right thing. If this was a perfect implementation, it would still be a WTF. Delays don't fix problems. They hide them. (Yes, there are valid reasons for waiting. This is not one of them.)

    I feel the shame... :)

    This is why people who don't know proper threading techniques shouldn't code in a multithreaded environment.  Its kind of funny how most people say things like "OMG!  Just use sleep!!!!" or "Haha!  He's not cleaning up the timer handle".  Those aren't the WTFs here.  Yeah, they are silly, or a bug, but not really WTFs.

    Wow, this may be the first time that two or more programmer have agreed about a non-trivial issue on this site.  And I totally missed both of your posts.  It's nice to see a good WTF bringing people together against its creator.

  • ParkinT (cs) in reply to qbolec

    qbolec:
    ...wait a minute....

    Now THAT is funny!

    :-)

  • Alexis de Torquemada (cs)
    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;
      }
    }
    
  • Anonymous Coward (unregistered) 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"...

    The latter is fed intravenously.

  • triso (cs) in reply to ammoQ
    ammoQ:
    Since Alex is on vacation this week, the main forum is fed by an auto-pilot script. Stay tuned, folks, we'll see contributions from a lot of very interesting guest authors this week.
    Does anyone know where Alex went for vacation?  I hope they don't sell sparklers there....
  • Jon (unregistered) in reply to snoofle
    Anonymous:

    What happens in 2038 when end < now ?

    .NET's DateTime goes up to the end of year 9999. Even Microsoft can make a patch in that timeframe. :-)
  • Duh (unregistered) in reply to Jon
    Anonymous:
    Anonymous:

    What happens in 2038 when end < now ?

    .NET's DateTime goes up to the end of year 9999. Even Microsoft can make a patch in that timeframe. :-)

    And in the BASIC code which made the form so popular, the $TIME or $TI was a measure of clock ticks since start up, so anyone who turned their computer off each night or for any other reason restarted on a near-daily basis, that wouldn't be a problem. 

  • Stephen Jones (unregistered) in reply to 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.

     Even worse, when waiting for a thread it will cause the other thread to run slower thus requiring an even larger time out. And yes, I've seen this done in production code.  I wonder if the reasons for avoiding sleep in this case was the same as then, i.e. MS decided that web scripts shouldn't be able to sleep as they are interactive and might receive a signal.

  • RyuO (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? :-)

    The roman numerals sound like what the government contractors use for slots. What it really means is pay grade, i.e., how much salary you can command. In the real world, hiring managers and recruiters invariably use shorthand terms called "Junior", "Midlevel" and "Senior" for how good you actually are. The precise definitions vary, but I use the definitions an old management mentor taught me:

    Junior: The Boss tells you what to do and how to do it.

    Midlevel: The Boss tells you what to do and you figure out how to do it.

    Senior: You tell the Boss what needs to be done.

    So, if  I hire a junior programmer, it does not mean I want a bad one, it means I want someone who can follow precise instructions. Naturally, someone that can handle a higher degree of autonomy will tend to make more money. Having greater technical skill generally means you are more autonomous, but there are plenty of exceptions. Lots of people with mediocre skills can manage themselves, and they are usually more valuable to an employer than an ace who needs to be watched.

  • Mugga (unregistered) in reply to Colin McGuigan
    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. 

     Why the inner for loop ?  Works just as good, and holds on a single line.

    while(end < DateTime.now) { } 

     
    Maybe you worked with the same motorolla compiler we used, at my previous job, that "optimized" every empty loops by jumping over them.  I remember seeing code with inlined assembler "NOP" instructions inside empty loops to make them work right...
     

  • Michael Snyder (unregistered) in reply to themagni

    Delays don't just hide problems, they create insidious new problems.

    I once spent a few weeks helping a developer figure out why our application was running slower on multi-processor machines than it was on single processor machines.

     It turned out that there were two threads in the bowels of the application that were designed by a previous developer. The consumer would empty the queue and then go to sleep for 20 milliseconds.  The producer would put x objects in the queue and then it too would go to sleep for 20 milliseconds.

    On a single processor box, each thread did some work in the 20 millisecond sleep of the other thread.

    On a dual processor box, the threads were sleeping more than they were working.

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

Log In or post as a guest

Replying to comment #:

« Return to Article