diff --git a/AUTHORS b/AUTHORS index f61f99d..924e5dd 100644 --- a/AUTHORS +++ b/AUTHORS @@ -31,3 +31,6 @@ Stephen Hemminger Nathan Jones * patch for underflow when value specified in -n is not a multiple of -l + +Gerrit Renker + * replace costly gettimeofday() with nanonsleep() diff --git a/ChangeLog b/ChangeLog index 12d9c95..ca26911 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-05-09 Gerrit Renker + +* replace costly gettimeofday() with nanonsleep() See: +https://sourceforge.net/tracker/index.php?func=detail&aid=1940009&group_id=128336&atid=711373 + +2008-05-09 Jon Dugan + +* change currLen to unsigned to squelch warning generated by Nathan's patch + 2008-05-09 Nathan Jones * prevent underflow when the amount of data to be transmitted (-n) is not a diff --git a/compat/delay.cpp b/compat/delay.cpp index 9fc69c6..c1f41b5 100644 --- a/compat/delay.cpp +++ b/compat/delay.cpp @@ -51,24 +51,26 @@ * ------------------------------------------------------------------- */ #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 using POSIX nanosleep(). This allows a + * higher timing resolution (under Linux e.g. it uses hrtimers), does not + * affect any signals, and will use up remaining time when interrupted. * ------------------------------------------------------------------- */ +void delay_loop(unsigned long usec) +{ + struct timespec requested, remaining; -void delay_loop( unsigned long usec ) { - Timestamp end; - end.add( usec * 1e-6 ); + requested.tv_sec = 0; + requested.tv_nsec = usec * 1000L; - Timestamp now; - while ( now.before( end ) ) { - now.setnow(); - } + while (nanosleep(&requested, &remaining) == -1) + if (errno == EINTR) + requested = remaining; + else { + WARN_errno(1, "nanosleep"); + break; + } } diff --git a/include/Timestamp.hpp b/include/Timestamp.hpp index ae05f85..d98bcfc 100644 --- a/include/Timestamp.hpp +++ b/include/Timestamp.hpp @@ -151,6 +151,16 @@ public: (mTime.tv_usec - right.tv_usec); } + /* ------------------------------------------------------------------- + * 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. @@ -199,15 +209,6 @@ public: mTime.tv_usec < kMillion ); } - /* ------------------------------------------------------------------- - * 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. * ------------------------------------------------------------------- */ @@ -216,15 +217,17 @@ public: (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 diff --git a/src/Client.cpp b/src/Client.cpp index c089ab0..e2ee366 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -116,7 +116,7 @@ const double kSecs_to_usecs = 1e6; const int kBytes_to_Bits = 8; void Client::RunTCP( void ) { - long currLen = 0; + unsigned long currLen = 0; struct itimerval it; max_size_t totLen = 0; @@ -203,7 +203,7 @@ void Client::RunTCP( void ) { void Client::Run( void ) { struct UDP_datagram* mBuf_UDP = (struct UDP_datagram*) mBuf; - long currLen = 0; + unsigned long currLen = 0; int delay_target = 0; int delay = 0;