Dear Jon,
further to earlier email discussion, I am now in the process
of updating the DCCP patches from
http://www.erg.abdn.ac.uk/users/gerrit/dccp/apps/#iperf
to match the current SVN revision (#37). I have copied this
to the iperf-users list -- can you please advise re submission
format and to whom to copy?
I will be sending the other patches shortly. The first patch
in the series has been omitted (replacing sched_yield() with
condition variables), since per announcement this is in the
works anyway.
Gerrit
The attached patch:
------------------
* replaces delay_loop() with nanosleep
- this has advantages over the gettimeofday() spin-loop
since among other things it blocks signals and was found
to be more accurate over the long term than the current
implementation
- if people feel they would like a different delay_loop,
the old implementation has been kept via #ifdefs
* implements several timer utilities
- a "timer-stop" delta_usec() time measurement method
- an overloaded form of "before()"
- a corresponding "after()"
The University of Aberdeen is a charity registered in Scotland, No SC013683.
Timer Utilities
===============
Apart from extending the Timestamp class (support for measuring elapsed
time and an `after' test), the main point of this patch is to update
the delay_loop() function.
The present implementation used a tight loop of continually calling
gettimeofday(2) until the specified amount of time has passed. This
is resource-intensive. In addition, while the loop worked reasonably
in many cases, it sometimes caused unwanted delays of 50 milliseconds
or more (process preempted?).
This has been replaced with nanosleep(2) as default now. The advantage
of nanosleep over the old solution is that signals are blocked and it
seems a much more robust solution.
Also, nanosleep uses the hrtimers interface internally
(/usr/src/davem-2.6/Documentation/hrtimers/hrtimers.txt).
For people who would like to keep the old behaviour, #ifdefs with
alternatives have been added.
Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
---
compat/delay.cpp | 38 ++++++++++++++++++++++++++++++--------
include/Timestamp.hpp | 29 ++++++++++++++++-------------
2 files changed, 46 insertions(+), 21 deletions(-)
--- a/compat/delay.cpp
+++ b/compat/delay.cpp
@@ -51,19 +51,31 @@
* ------------------------------------------------------------------- */
#include "Timestamp.hpp"
-
+#include "util.h"
#include "delay.hpp"
/* -------------------------------------------------------------------
- * A micro-second delay function. This uses gettimeofday (underneith
- * the Timestamp) which has a resolution of upto microseconds. I've
- * found it's good to within about 10 usecs.
- * I used to do calibration, but iperf automatically adjusts itself
- * so that isn't necesary, and it causes some problems if the
- * calibration adjustment is larger than your sleep time.
+ * A micro-second delay function.
* ------------------------------------------------------------------- */
+void delay_loop(unsigned long usec)
+{
+#ifdef SLEEP_VIA_SELECT
+ // This is a hack but works apparently quite well
+ // I found that it sometimes under-estimates the timeout
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = usec;
-void delay_loop( unsigned long usec ) {
+ select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv);
+#elif defined(SLEEP_OLD_METHOD)
+ /* Tis uses gettimeofday (underneath the Timestamp), which has a
+ * resolution of upto microseconds. I've found it's good to within
+ * about 10 usecs. I used to do calibration, but iperf automatically
+ * adjusts itself so that isn't necesary, and it causes some problems
+ * if the calibration adjustment is larger than your sleep time.
+ * Note: I found this has problems - if the loop gets interrupted,
+ * long sleeps can result. I found up to 50..60msec. -- Gerrit */
Timestamp end;
end.add( usec * 1e-6 );
@@ -71,4 +83,14 @@ void delay_loop( unsigned long usec ) {
while ( now.before( end ) ) {
now.setnow();
}
+#else
+ // This is preferred; it is even better than usleep (see manpage).
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = usec * 1000L;
+
+ if (nanosleep(&ts, NULL) < 0)
+ WARN_errno(1, "nanosleep");
+#endif
}
--- a/include/Timestamp.hpp
+++ b/include/Timestamp.hpp
@@ -152,6 +152,16 @@ public:
}
/* -------------------------------------------------------------------
+ * Return the number of microseconds from now to last time of setting.
+ * ------------------------------------------------------------------- */
+ long delta_usec(void) {
+ struct timeval previous = mTime;
+
+ setnow();
+ return subUsec(previous);
+ }
+
+ /* -------------------------------------------------------------------
* subtract the right timestamp from my timestamp.
* return the difference in seconds as a floating point.
* ------------------------------------------------------------------- */
@@ -202,29 +212,22 @@ public:
/* -------------------------------------------------------------------
* return true if my timestamp is before the right timestamp.
* ------------------------------------------------------------------- */
- bool before( Timestamp right ) {
- return mTime.tv_sec < right.mTime.tv_sec ||
- (mTime.tv_sec == right.mTime.tv_sec &&
- mTime.tv_usec < right.mTime.tv_usec);
- }
-
- /* -------------------------------------------------------------------
- * return true if my timestamp is before the right timestamp.
- * ------------------------------------------------------------------- */
bool before( timeval right ) {
return mTime.tv_sec < right.tv_sec ||
(mTime.tv_sec == right.tv_sec &&
mTime.tv_usec < right.tv_usec);
}
+ bool before( Timestamp right ) { return before(right.mTime); }
/* -------------------------------------------------------------------
* return true if my timestamp is after the right timestamp.
* ------------------------------------------------------------------- */
- bool after( Timestamp right ) {
- return mTime.tv_sec > right.mTime.tv_sec ||
- (mTime.tv_sec == right.mTime.tv_sec &&
- mTime.tv_usec > right.mTime.tv_usec);
+ bool after( timeval right ) {
+ return mTime.tv_sec > right.tv_sec ||
+ (mTime.tv_sec == right.tv_sec &&
+ mTime.tv_usec > right.tv_usec);
}
+ bool after( Timestamp right ) { return after(right.mTime); }
/**
* This function returns the fraction of time elapsed after the beginning
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Register now and save $200. Hurry, offer ends at 11:59 p.m.,
Monday, April 7! Use priority code J8TLD2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Iperf-users mailing list
Iperf-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/iperf-users