CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 32
  1. #1
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Thread sleep time resolution

    I'm writing some platform independent code - the eventual target is an RTOS Linux flavour. However, at the moment due to portability issues with code I am dependent on, the demo target is Windows XP. I believe the problem that I am having is a problem of me trying to impose real-time requirements on a non-real-time OS.

    So, here is the background. I need to make a thread sleep for around 5 ms, the sleep time cannot exceed 8 ms. The call that I'm making is boost::this_thread::sleep and on Windows this eventually unfortunately seems to call Sleep. On linux this boost call wouldn't be a problem, since the underlying OS call can cope with an approximate 5 ms resolution. However, on Windows XP, as far as I am aware, Sleep cannot make a thread sleep for less than 50 ms accurateley and the actual sleep time for a request of 5 ms, could inconsistantly vary anything between 15 ms and 50 ms.

    Does anyone know how I can make a thread on Windows XP sleep consistantly for around 5ms?

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Thread sleep time resolution

    I'm not sure it could help you but have a look at Multimedia Timers
    Victor Nijegorodov

  3. #3
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Thread sleep time resolution

    given that you know the machine on which your demo will run, you could try something like

    Code:
    for( int c=0; c<counts; ++c )
    {
    	::SwitchToThread();
    }
    where you determine counts from some external test time measurement. Note that SwitchToThread returns a BOOL indicating if the switch actually happened; therefore, you could use two counts, one for busy and one for unbusy state. ( I never tried the code above, just curious to see if it works )

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Thread sleep time resolution

    Windows is not an RTOS, you cannot make it "sleep" and at the same time expect to be woken up at a precise interval. There's even restrictions on expecting your thread to get scheduled for CPU time.

    You aren't saying what you want, but it is very well possible Windows will not be suitable for this project if you indeed need precise out times.

    You can use a multimediatimer for a more accurate timer than the regular UI timer, but it still has it's issues, among others severe restrictions on what you can do inside the timer proc.

    Windows can be used successfully for many RTOS type projects, but you need to be very aware of how the windows scheduler works and it may require a closed box solution. Since you mention you're making a portable project, that typically means it's a no go. Since you typically have to work around the scheduler, and that's against the common practices when you're writing your portable code with an RTOS in mind.

  5. #5
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Thread sleep time resolution

    Quote Originally Posted by superbonzo View Post
    given that you know the machine on which your demo will run, you could try something like

    Code:
    for( int c=0; c<counts; ++c )
    {
    	::SwitchToThread();
    }
    where you determine counts from some external test time measurement. Note that SwitchToThread returns a BOOL indicating if the switch actually happened; therefore, you could use two counts, one for busy and one for unbusy state. ( I never tried the code above, just curious to see if it works )
    Sorry, but that's just horrible.

    Not only does it eat all the CPU time for no reason.
    It also doens't provide accurate timing at all.

    Tricks like this may have worked on single CPU machines with predictable CPU execution times, but this hasn't been the case on PC's for many years.
    Branch prediction, CPU look ahead buffers, L1 & L2 cache, various types of procesors, memory architecture, instruction rescheduling and all the other tricks CPU makers come up with to make their CPU's perform that bit better are all going to mess up any attempt at this.

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Thread sleep time resolution

    Sleep (or any of the other WaitFor... functions) aren't reliable at all.

    On a system that doesn't have higher priority threads running, they're close.

    However, since higher priority threads get execution precedent over lower priority threads, lower priority threads can get starved out (even without using sleep).

  7. #7
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Thread sleep time resolution

    Quote Originally Posted by OReubens View Post
    Tricks like this may have worked on single CPU machines with predictable CPU execution times, but this hasn't been the case on PC's for many years.
    in fact I started my post with "given that you know the machine on which your demo will run" which means that you can do extensive tests in a controlled and repetitive fashion; the OP explicitly said this would be a temporary workaround for a temporary platform used for demoing purpose only.

    Obviously, the OP already knows what are the limits of a non RT OS; he's simply seeking a workaround to make a thread sleep for at least 5 ms but no more then 8 ms on a specific machine running XP.

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Thread sleep time resolution

    Quote Originally Posted by superbonzo View Post
    in fact I started my post with "given that you know the machine on which your demo will run" which means that you can do extensive tests in a controlled and repetitive fashion; the OP explicitly said this would be a temporary workaround for a temporary platform used for demoing purpose only.

    Obviously, the OP already knows what are the limits of a non RT OS; he's simply seeking a workaround to make a thread sleep for at least 5 ms but no more then 8 ms on a specific machine running XP.
    there is no PC anywhere in the world capable of running windows XP that would satisfy the requirements for such a loop to provide any kind of reliable timing. THe fact he's talking about windows kinda excludes any of the 'simple' machines where you can actually reliably time via a loop.


    and like I said, it depends what he wants...
    a reliable wait isn't going to happen on windows. it's just not part of how windows is designed.
    making a service thread that needs to proces an event within 5-8ms of the event happening... very well doable 99.99% of the time, but not guaranteed. if you can tightly control the box hard- and software wise, then you can get this to guarantee level (been there, done it at even lower timing needs).

    but without knowing more of what is needed... not much to say...

  9. #9
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Thread sleep time resolution

    Thanks for your replies... I forgot to mention that I was going on holiday after writing the last post. But I'm back now.

    Effectively what I was trying to do was wrap a call back mechanism into a blocking function call. For example, the libpcap/winpcap interface allows you to you pass it a call back function so that it can call you back every time it receives some new data off the wire. This effectly sets your program up an event driven kind of way. That is not what I want (by the way, the API I am dealing with is not pcap, but I'm using this an an example). I basically want to wrap a blocking call around the callback:

    Code:
    struct some_hardware_api
    {
      template <typename T>
      void read(image<T>& destination)
      {
        bool new_data(false);
    
          while(!new_data)
        {
          //Reduce scope of lock
          {
            boost::mutex::scoped_lock lock(io_mutex_);
            if(new_image_data_) new_data = true;
          }
    
            if(new_data)
          {
            //get data into image...
          }
          else 
          {
            boost::this_thread::sleep(boost::posix_time::milliseconds(5));
          }
        }
      }
    
        static void callback(const char* data, size)
      {
        //handle data
        //...
    
          boost::thread::scoped_lock(io_mutex_);
        new_image_data_ = true;
      }
    
    private: 
      //private members .... 
    };
    Effectively the blocking function call makes the client code far simpler.

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Thread sleep time resolution

    Quote Originally Posted by PredicateNormative View Post
    Effectively the blocking function call makes the client code far simpler.
    That may seemingly be the case, but it's a strange way to go about things as most of the time writing proper threaded code is about AVOIDING this sort of blocking calls because they... well... duh... block.

    And blocking, especially in a RTOS is bad.

    Blocking means you're negating part of the purpose of even making your program multithreaded. Which is to increase throughput, remain responsive, and avoid wasting CPU cycles in do-nothing loops (although the OS will usually solve this by making Sleep()'s yield the remaining timeslice).

    It may seem simpler from a code development p.o.v., but you're going to cause a variety of issues and subtle bugs by doing things this way.

  11. #11
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Thread sleep time resolution

    Actually the whole point is that the consuming thread needs to be blocked while there is no new frame data, or else the application needs to be driven by the source. If it's to be driven by the source then the code the call back calls needs to be in a different thread anyway since the thread that is constructing the frame data cannot be stalled else data will be lost.

    Effectively in this part of the code I have two threads, a frame construction thread that cannot be interrupted (in a loose sense of the term interrupted) and a consuming thread. I need to be able to get the consuming thread to consume data only when a new frame is available. If I don't block the consuming thread while there is no data, then I am not sure how to synchronise the consuming thread with the frame construction thread such that the consuming thread only does work when new frame data is available without stalling the frame construction thread. There is also a possibility that the frame construction thread can provide data faster than the consuming thread can consume it - if that happens the frame construction thread must throw the oldest unconsumed frame away. Putting in multiple consuming threads would violate the detailed software requirements, for reasons that I cannot go in to, so that is not an option.

    I am well aware of the impact and rationale of blocking, but with regards to your comment "And blocking, especially in a RTOS is bad." I would have to say "one shoe doesn't fit all". It depends on the detailed software requirements for that section of code. Therefore I would disagree that blocking is bad where there is a legitimate case for it. Remember, my code is behaving itself perfectly on the RTOS O/S, but not on Windows. I'm beginning to think that there is no 'fix' that I can apply to the Windows build. Perhaps I can do something funny with mutexes rather than use a sleep call - at the moment I don't like this idea because of the potential of getting it wrong, but I can't think of any other way round the problem at the moment.

    EDIT:

    OReubens, just thought I would add, that despite me disagreeing with some of your post, I appreciate your comments, so if you have any more, keep them rolling.
    Last edited by PredicateNormative; April 13th, 2010 at 03:22 AM.

  12. #12
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Thread sleep time resolution

    There is nothing wroing with blocking if it's as you've described. If a thread has no work, it generally needs to block until signalled there is more work available to do.

    On Windows, there are a few system threads that run at high priority (like in csrss.exe and winlogon.exe). Most of the time these high priority threads don't have anything to do and are effectively blocked. If they weren't, then lower priority threads wouldn't get to run.

  13. #13
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Thread sleep time resolution

    Thanks for the insight Arjay. Do you know how Windows copes with mutexes? What I mean is, if thread A applies a lock on a particular section of code and thread B attempts to get a lock on the same section (with an infinite timeout), thread B will need to wait until thread A unlocks the section. Now lets say thread A unlocks the section, do you know if there is any timing guarantee that thread B will aquire a lock within so many milliseconds of thread A releasing its lock?

  14. #14
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Thread sleep time resolution

    Windows schedules threads in a round robin fashion where higher priority threads get executed before lower priority threads. Because of this, there is no guarantee.

    To illustrate, consider the following: thread A gets a lock, while thread B waits to obtain the lock. Thread A finishes and releases the lock. However, before thread B can obtain the lock, a high priority thread wakes up to do some work. The OS scheduler will give thread slices to the high priority thread until it's finished its work. Only then will thread B get scheduled.

    This is the behavior that is guaranteed. On the other hand, the practical behavior can be something that is reliable but not guaranteed. If you have a controlled system (dedicated to the operations you wish to do rather than a general purpose machine), and threads running at rt or high priority then you can expect a response within a reasonable timeframe. I don't know what the response time would be for your hardware, but I would expect something less than a ms.

  15. #15
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Thread sleep time resolution

    Thank you very much for your input. I'm going to see if I can control the blocking nature of the read function call using thread locks instead of a call to sleep.

    Once I've figured out a way to do it, I'll post my solution for criticism.

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured