On 29 May 2002, Jay Soffian wrote:
>  "IK" == Ilmari Karonen <[EMAIL PROTECTED]> writes:
> 
> IK> Isn't this rather needlessly complex?
> Nope, not needlessly.

That can be argued.  I still don't think you need to take usleep()
granularity into account -- it's not as if you could do anything to
improve it even if you found it wasn't quite good enough.


>>  use Time::HiRes qw(time sleep);   # optional, for subsecond precision
>>  my $step = 0.1;                   # ten iterations per second
>>
>>  my $t = time;
>>  while (1) {
>>      # do stuff...
>>  } continue {
>>      $t += $step;                  # watch out for rounding errors!
>>      my $delay = $t - time;        # corrected, was: time - $t
>>      sleep $delay if $delay > 0;
>>  }
> 
> I think you meant $t - time;

Oops, so I did.  Teaches me not to post untested code...


> Ah, but I don't want to maintain the average rate in all cases. This
> code was written to limit packets being sent out over the network. If
> the packet sending code falls behind significantly for some reason
> (say because someone paused the process), I don't want the code to run
> through the loop as quickly as possible till it brings the average
> rate back up. Rather, the code gives up if it has fallen too far
> behind and resets the rate (I'll make how far behind it can fall
> configurable).

I don't see how that requires more than one extra line in my code.  To
reset the counter if the execution of the loop took too long, add:

  $t = time if $delay < -$give_up_limit;


Of course, for other purposes different catching-up strategies may be
useful.  For example, if a minimum delay between iterations was desired,
the following line could be used instead:

  $delay = $minimum, $t = time + $delay if $delay < $minimum;

And for applications where maintaining phase is more important than the
average rate, catching up after unexpected delays could be achieved by
replacing the first line of the continue-block with:

  do {$t += $step} while $t < time;

(Note that at least one increment is necessary, otherwise there could be
trouble if sleep() takes too little time.)

-- 
Ilmari Karonen - http://www.sci.fi/~iltzu/
"TIMTOWTDI, but did you have to pick the ugliest way you could find?"
                          -- after Michael Carman in comp.lang.perl.misc

Reply via email to