Jump to content

Simple timing problem


Recommended Posts

I have some processes where I need to time an external device and issue a timeout if that device fails to respond in a certain amount of time. These timeouts can be in seconds or minutes or even longer in some rare cases.

I have accomplished this in the past by getting a time stamp outside the loop that monitors the external device and then in each iteration of the loop I get another time stamp, subtract the original time stamp and then take action on the result if it exceeds the limit.

I have used the time stamp instead of the tick counter because I am concerned that the tick counter can roll over and cause a problem with my elapsed time calculation.

The problem is, once in a while, the clock on my machine is 'adjusted' by the network time service to bring it back in line. If this happens while the loop is running, the time stamp calculation will be thrown off and my code will think the external device has not responded in the allotted time when in reality it still has more time left to finish. When this happens, I issue a timeout condition that is not real.

So, anyone have a suggestion for how to solve this or at least make it more reliable? Our IT guys are not willing to disable the NTP service on my machine to prevent these adjustments so I need to find another way.

-John

Link to comment

I have some processes where I need to time an external device and issue a timeout if that device fails to respond in a certain amount of time. These timeouts can be in seconds or minutes or even longer in some rare cases.

I have accomplished this in the past by getting a time stamp outside the loop that monitors the external device and then in each iteration of the loop I get another time stamp, subtract the original time stamp and then take action on the result if it exceeds the limit.

I have used the time stamp instead of the tick counter because I am concerned that the tick counter can roll over and cause a problem with my elapsed time calculation.

The problem is, once in a while, the clock on my machine is 'adjusted' by the network time service to bring it back in line. If this happens while the loop is running, the time stamp calculation will be thrown off and my code will think the external device has not responded in the allotted time when in reality it still has more time left to finish. When this happens, I issue a timeout condition that is not real.

So, anyone have a suggestion for how to solve this or at least make it more reliable? Our IT guys are not willing to disable the NTP service on my machine to prevent these adjustments so I need to find another way.

-John

If the following correct attribute it ti Rolf because I think it was him that posted to Info-LabVIEW the following. If its wrong blame me.

THe tick count is a U32 so as long as you keep it as U32 the math will still work out, even durring the roll-over.

Ben

Link to comment

Here's a really simple example of how I usually solve problems similar to this. Note this is quick and dirty, I don't clean up my refs, you might want two way synchronization for a cancel operation, etc, but it gets the point across...

post-11742-126902356821_thumb.png

Basic idea is I let some kind of synchronization object handle the timeout for me. Of course if you need a timeout exceeding 2^31 milliseconds (~25 days), you'll need to consider something else...

Timeout.vi

Edited by mje
Link to comment

No, the tick counter in my example was just to simulate a "Long Task" running for some period of time, it doesn't even consider a rollover (you'd normally have some other code in the while loop). It's the event structure that does the timeout check.

The idea is this: The bottom task, (or Watchdog task) creates some kind of synch object, in this case an event. It then launches a worker task (Long Task) which takes a long time for some reason. The Watchdog task then immediately blocks on the synch object with a timeout. In this case, it's an event structure, which has a maximum timeout of 2^31 milliseconds (the maximum value for an I32). The task will not return until either the original task is complete, or the specified timeout has happened.

That's a really basic example which should not be used as-is, there is a possible race conditions in it. But it does gets the point across, I hope.

By using a pair of synch objects (one for an "I'm finished!" signal, and another for a "Abort!" signal), you can achieve a logic that incorporates a timeout, and does absolutely no polling.

I can try to elaborate later if no one else fills in...

Link to comment

Ok. I see where you are going with this. I am not sure this would fit into my application. In my case, I have a consumer loop that is monitoring a feed from a producer that enqueues data from an external source. The consumer will issue an exit condition in the following cases:

  • The external source reports it is done.
  • There is an error (of any kind).
  • The user presses abort in the UI.
  • The maximum time is exceeded.

The consumer loop executes at least once a second to check the time. It will execute faster if there is data to process from the producer.

So, I actually want some polling of the time. IF I implement some sort of external event structure, I imagine I would want to simply let it run until timeout and then assert some sort of signal that the consumer could monitor. I would then also need the event structure to have a user event that allows the consumer to abort it if a different exit condition occurs.

This does seem a lot more complex than a simple polling style timeout check. But if it is the only way to make this more reliable I may have to try it.

Link to comment

Ben is correct - as long as the math is all U32 and you take the difference of the two the rollover won't matter - to prove it to yourself, create a couple of u32's and set one to 2^32-1 and then subtract that from one set to 1. The answer is 2 - exactly what you need for an elapsed time counter that rolled over (the 1 would be the counter that had rolled over and the 2^32-1 is the start tick count).

Mark

  • Like 1
Link to comment

Yeah, I think you got it.

It's definitely more complex, but I despise polling variables. I've implemented a few things which are "wait until done or X amount of time" and usually end up using a synchronization based implementation rather than time polling. Sync objects also scale nicely, you can signal multiple tasks off the same occurrence, for example. Useful for the "wait until done or I say so" scenarios.

post-11742-126902744703_thumb.png

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.