Dear Upakul,

if it is not too much of a bother, can you please check if the attached
patch fixes the CPU usage problem?

It is a port of Ingo Molnar's CPU usage fix - we have used that patch in
iperf with great benefit (the CPU usage went down to very modest values).

Regards
Gerrit

Quoting Upakul Barkakaty:
|    Hi Jon,
| 
|    I have upgraded to Iperf-v2.0.4. But unfortunately, even with this version
|    I observed that the Iperf client was consuming all the CPU MIPS even if it
|    was running at 1 Mbps.
| 
|    --
|    Regards,
|    Upakul Barkakaty
| 
|    On 4/23/08, Jon Dugan <[EMAIL PROTECTED]> wrote:
| 
|      Upakul,
| 
|      Which version of Iperf are you using?  This should be resolved in Iperf
|      MailScanner warning: numerical links are often malicious: 2.0.4.
| 
|      Jon
| 
|      Upakul Barkakaty wrote:
| 
|        Hi all,
| 
|        I was using the Iperf UDP client to test the network bandwidth and CPU
|        Utilization. I observed that the Iperf client was consuming all the
|        CPU MIPS even if it was running at 1 Mbps.
| 
|        On investigation, It looks like the delay_loop() function in the file
|        Client.cpp is blocking in the kernel space while adjusting the
|        thoughput speeds. On trying out replacing delay_loop() by usleep()
|        function, Idle MIPS were available.
| 
|        Please can you let me know if this is an intended behaviour keeping in
|        mind some particular purpose?
| 


The University of Aberdeen is a charity registered in Scotland, No SC013683.

[Thread]: Replace thread_rest() with condition variables

This applies the patch by Ingo Molnar from

   http://marc.info/?l=linux-kernel&m=119088670113210&w=2

by reverting previous changes that coincided with changes made by this
patch. Other than that, the patch is the original from the above URL.

Gerrit
---
 compat/Thread.c |    6 ------
 src/Reporter.c  |   37 +++++++++----------------------------
 src/main.cpp    |    2 ++
 3 files changed, 11 insertions(+), 34 deletions(-)

--- a/compat/Thread.c
+++ b/compat/Thread.c
@@ -405,12 +405,6 @@ int thread_numuserthreads( void ) {
 void thread_rest ( void ) {
 #if defined( HAVE_THREAD )
 #if defined( HAVE_POSIX_THREAD )
-#if defined( _POSIX_PRIORITY_SCHEDULING )
-    sched_yield();
-#else
-    usleep( 0 );
-#endif
-
 #else // Win32
     SwitchToThread( );
 #endif
--- a/src/Reporter.c
+++ b/src/Reporter.c
@@ -110,9 +110,8 @@ report_statistics multiple_reports[kRepo
 
 char buffer[64]; // Buffer for printing
 ReportHeader *ReportRoot = NULL;
-int threadWait = 0;
-int threadSleeping = 0;
 extern Condition ReportCond;
+extern Condition ReportDoneCond;
 int reporter_process_report ( ReportHeader *report );
 void process_report ( ReportHeader *report );
 int reporter_handle_packet( ReportHeader *report );
@@ -340,7 +339,7 @@ void ReportPacket( ReportHeader* agent, 
             // item
             while ( index == 0 ) {
                 Condition_Signal( &ReportCond );
-                thread_rest();
+                Condition_Wait( &ReportDoneCond );
                 index = agent->reporterindex;
             }
             agent->agentindex = 0;
@@ -348,11 +347,9 @@ void ReportPacket( ReportHeader* agent, 
         // Need to make sure that reporter is not about to be "lapped"
         while ( index - 1 == agent->agentindex ) {
             Condition_Signal( &ReportCond );
-            thread_rest();
+            Condition_Wait( &ReportDoneCond );
             index = agent->reporterindex;
         }
-	if (threadSleeping)
-           Condition_Signal( &ReportCond );
 
         // Put the information there
         memcpy( agent->data + agent->agentindex, packet, sizeof(ReportStruct) );
@@ -382,9 +379,6 @@ void CloseReport( ReportHeader *agent, R
         packet->packetLen = 0;
         ReportPacket( agent, packet );
         packet->packetID = agent->report.cntDatagrams;
-	if (threadSleeping)
-           Condition_Signal( &ReportCond );
-
     }
 }
 
@@ -396,9 +390,6 @@ void CloseReport( ReportHeader *agent, R
 void EndReport( ReportHeader *agent ) {
     if ( agent != NULL ) {
         int index = agent->reporterindex;
-	if (threadSleeping)
-           Condition_Signal( &ReportCond );
-
         while ( index != -1 ) {
             thread_rest();
             index = agent->reporterindex;
@@ -467,10 +458,6 @@ void ReportSettings( thread_Settings *ag
              * Update the ReportRoot to include this report.
              */
             Condition_Lock( ReportCond );
-	    if ( isUDP(agent) )
-	      threadWait = 0;
-	    else
-	      threadWait = 1;
             reporthdr->next = ReportRoot;
             ReportRoot = reporthdr;
             Condition_Signal( &ReportCond );
@@ -567,6 +554,7 @@ void reporter_spawn( thread_Settings *th
         }
         Condition_Unlock ( ReportCond );
 
+again:
         if ( ReportRoot != NULL ) {
             ReportHeader *temp = ReportRoot;
             //Condition_Unlock ( ReportCond );
@@ -589,19 +577,12 @@ void reporter_spawn( thread_Settings *th
                 // finished with report so free it
                 free( temp );
                 Condition_Unlock ( ReportCond );
+                Condition_Signal( &ReportDoneCond );
+                if (ReportRoot)
+                    goto again;
             }
-            // yield control of CPU is another thread is waiting
-	    // sleep on a condition variable, as it is much cheaper
-	    // on most platforms than issuing schedyield or usleep
-	    // syscalls
-	    Condition_Lock ( ReportCond );
-	    if ( threadWait && ReportRoot != NULL) {
-	      threadSleeping = 1;
-	      Condition_TimedWait (& ReportCond, 1 );
-	      threadSleeping = 0;
-	    }
-	    Condition_Unlock ( ReportCond );
-	    
+            Condition_Signal( &ReportDoneCond );
+            usleep(10000);
         } else {
             //Condition_Unlock ( ReportCond );
         }
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -96,6 +96,7 @@ extern "C" {
     // records being accessed in a report and also to
     // serialize modification of the report list
     Condition ReportCond;
+    Condition ReportDoneCond;
 }
 
 // global variables only accessed within this file
@@ -142,6 +143,7 @@ int main( int argc, char **argv ) {
 
     // Initialize global mutexes and conditions
     Condition_Initialize ( &ReportCond );
+    Condition_Initialize ( &ReportDoneCond );
     Mutex_Initialize( &groupCond );
     Mutex_Initialize( &clients_mutex );
 
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
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

Reply via email to