Re: Iperf 2.0.3 released
On Tue, 18 Mar 2008 21:44:25 -0700
Jon Dugan <jdugan --at-- x1024.net> wrote:
> I have just posted the Iperf 2.0.3 release on SourceForge. You can find it at:
>
> http://sourceforge.net/project/showfiles.php?group_id=128336
>
> Iperf 2.0.3 addresses several issues with Iperf. This release is a bug fix
> release and does not add any significant new functionality.
>
> Bugs fixed in 2.0.3:
>
> * Compilation issues on several platforms, notably Mac OS X and Solaris
> * Excessive usage of CPU due to updating stats for every TCP packet received
> * several minor nits, see the ChangeLog for details.
>
> These changes come primarily from user patches and have only been lightly
> tested. Special thanks to Andrew Gallatin for his work on making the current
> threading model better.
>
> Jon
>
You ignored several earlier patches for Linux to avoid eating lots of CPU.
Also, the new option to choose congestion control.
Any new redesign should work to eliminate all usage of usleep()/yield() etc,
and just use proper condition variables.
Use sched_yield() rather than usleep(0) to reschedule thread.
On later versions of Linux usleep(0) is actually a nop so the
current thread will use 100% of CPU.
--- a/compat/Thread.c 2008-03-18 22:20:33.000000000 -0700
+++ b/compat/Thread.c 2008-03-18 22:21:30.000000000 -0700
@@ -405,9 +405,12 @@ int thread_numuserthreads( void ) {
void thread_rest ( void ) {
#if defined( HAVE_THREAD )
#if defined( HAVE_POSIX_THREAD )
- // TODO add checks for sched_yield or pthread_yield and call that
- // if available
+#if defined( _POSIX_PRIORITY_SCHEDULING )
+ sched_yield();
+#else
usleep( 0 );
+#endif
+
#else // Win32
SwitchToThread( );
#endif
Add new option to allow selecting the sender congestion control
algorithm. This is a Linux specific extension useful for testing
other congestion control algorithms.
---
include/Settings.hpp | 5 +++++
src/Locale.c | 1 +
src/PerfSocket.cpp | 15 +++++++++++++++
src/Settings.cpp | 14 +++++++++++++-
4 files changed, 34 insertions(+), 1 deletion(-)
--- a/include/Settings.hpp 2008-03-18 22:17:53.000000000 -0700
+++ b/include/Settings.hpp 2008-03-18 22:17:58.000000000 -0700
@@ -170,6 +170,7 @@ typedef struct thread_Settings {
iperf_sockaddr local;
Socklen_t size_local;
nthread_t mTID;
+ char* mCongestion;
#if defined( HAVE_WIN32_THREAD )
HANDLE mHandle;
#endif
@@ -208,6 +209,7 @@ typedef struct thread_Settings {
#define FLAG_NOMULTREPORT 0x00080000
#define FLAG_SINGLECLIENT 0x00100000
#define FLAG_SINGLEUDP 0x00200000
+#define FLAG_CONGESTION 0x00400000
#define isBuflenSet(settings) ((settings->flags & FLAG_BUFLENSET) != 0)
#define isCompat(settings) ((settings->flags & FLAG_COMPAT) != 0)
@@ -233,6 +235,7 @@ typedef struct thread_Settings {
// end Active Low
#define isSingleClient(settings) ((settings->flags & FLAG_SINGLECLIENT) != 0)
#define isSingleUDP(settings) ((settings->flags & FLAG_SINGLEUDP) != 0)
+#define isCongestionControl(settings) ((settings->flags & FLAG_CONGESTION) != 0)
#define setBuflenSet(settings) settings->flags |= FLAG_BUFLENSET
#define setCompat(settings) settings->flags |= FLAG_COMPAT
@@ -256,6 +259,7 @@ typedef struct thread_Settings {
#define setNoMultReport(settings) settings->flags |= FLAG_NOMULTREPORT
#define setSingleClient(settings) settings->flags |= FLAG_SINGLECLIENT
#define setSingleUDP(settings) settings->flags |= FLAG_SINGLEUDP
+#define setCongestionControl(settings) settings->flags |= FLAG_CONGESTION
#define unsetBuflenSet(settings) settings->flags &= ~FLAG_BUFLENSET
#define unsetCompat(settings) settings->flags &= ~FLAG_COMPAT
@@ -279,6 +283,7 @@ typedef struct thread_Settings {
#define unsetNoMultReport(settings) settings->flags &= ~FLAG_NOMULTREPORT
#define unsetSingleClient(settings) settings->flags &= ~FLAG_SINGLECLIENT
#define unsetSingleUDP(settings) settings->flags &= ~FLAG_SINGLEUDP
+#define unsetCongestionControl(settings) settings->flags &= ~FLAG_CONGESTION
#define HEADER_VERSION1 0x80000000
--- a/src/Locale.c 2008-03-18 22:17:53.000000000 -0700
+++ b/src/Locale.c 2008-03-18 22:17:58.000000000 -0700
@@ -162,6 +162,7 @@ Client specific:\n\
-L, --listenport # port to recieve bidirectional tests back on\n\
-P, --parallel # number of parallel client threads to run\n\
-T, --ttl # time-to-live, for multicast (default 1)\n\
+ -Z, --congestion <algo> set TCP congestion control algorithm\n\
\n\
Miscellaneous:\n\
-h, --help print this message and quit\n\
--- a/src/PerfSocket.cpp 2008-03-18 22:17:53.000000000 -0700
+++ b/src/PerfSocket.cpp 2008-03-18 22:17:58.000000000 -0700
@@ -90,6 +90,21 @@ void SetSocketOptions( thread_Settings *
setsock_tcp_windowsize( inSettings->mSock, inSettings->mTCPWin,
(inSettings->mThreadMode == kMode_Client ? 1 : 0) );
+ if ( isCongestionControl( inSettings ) ) {
+#ifdef TCP_CONGESTION
+ Socklen_t len = strlen( inSettings->mCongestion ) + 1;
+ int rc = setsockopt( inSettings->mSock, IPPROTO_TCP, TCP_CONGESTION,
+ inSettings->mCongestion, len);
+ if (rc == SOCKET_ERROR ) {
+ fprintf(stderr, "Attempt to set '%s' congestion control failed: %s\n",
+ inSettings->mCongestion, strerror(errno));
+ exit(1);
+ }
+#else
+ fprintf( stderr, "The -Z option is not available on this operating system\n");
+#endif
+ }
+
// check if we're sending multicast, and set TTL
if ( isMulticast( inSettings ) && ( inSettings->mTTL > 0 ) ) {
int val = inSettings->mTTL;
--- a/src/Settings.cpp 2008-03-18 22:17:53.000000000 -0700
+++ b/src/Settings.cpp 2008-03-18 22:17:58.000000000 -0700
@@ -120,6 +120,7 @@ const struct option long_options[] =
{"single_udp", no_argument, NULL, 'U'},
{"ipv6_domian", no_argument, NULL, 'V'},
{"suggest_win_size", no_argument, NULL, 'W'},
+{"congestion", required_argument, NULL, 'Z'},
{0, 0, 0, 0}
};
@@ -162,12 +163,13 @@ const struct option env_options[] =
{"IPERF_SINGLE_UDP", no_argument, NULL, 'U'},
{"IPERF_IPV6_DOMAIN", no_argument, NULL, 'V'},
{"IPERF_SUGGEST_WIN_SIZE", required_argument, NULL, 'W'},
+{"IPERF_CONGESTION_CONTROL", required_argument, NULL, 'Z'},
{0, 0, 0, 0}
};
#define SHORT_OPTIONS()
-const char short_options[] = "1b:c:df:hi:l:mn:o:p:rst:uvw:x:y:B:CDF:IL:M:NP:RS:T:UVW";
+const char short_options[] = "1b:c:df:hi:l:mn:o:p:rst:uvw:x:y:B:CDF:IL:M:NP:RS:T:UVWZ:";
/* -------------------------------------------------------------------
* defaults
@@ -664,6 +666,17 @@ void Settings_Interpret( char option, co
fprintf( stderr, "The -W option is not available in this release\n");
break;
+ case 'Z':
+#ifdef TCP_CONGESTION
+ setCongestionControl( mExtSettings );
+ mExtSettings->mCongestion = new char[strlen(optarg)+1];
+ strcpy( mExtSettings->mCongestion, optarg);
+#else
+#error fix includes
+ fprintf( stderr, "The -Z option is not available on this operating system\n");
+#endif
+ break;
+
default: // ignore unknown
break;
}