diff --git a/Source/Common/CommonBase.cpp b/Source/Common/CommonBase.cpp index 2e7e8ec5..194f2325 100644 --- a/Source/Common/CommonBase.cpp +++ b/Source/Common/CommonBase.cpp @@ -98,15 +98,26 @@ void CommonBase::MPISpinner() int MSGBUFSIZ = 1024; // Individual incoming message buffer char * MSGBUF = new char[MSGBUFSIZ]; // Pull it off the heap + +const int MAX_PROBE_IDLE_BACKOFF_US=100000; // Maximum is 100,000us, i.e. 10hz +int probe_idle_backoff_us=0; for (;;) { // See if there are any MPI packets coming down the pipe MPI_Status status; // Note the multi-threaded MPI probe int flag; MPI_Iprobe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&flag,&status); if (flag==0) { // Nothing there.... - OnIdle(); // Guess + if(HaveIdleWork()){ + OnIdle(); // Guess + }else{ + probe_idle_backoff_us=std::min(MAX_PROBE_IDLE_BACKOFF_US, std::max(10, (probe_idle_backoff_us*5)/4)); + OSFixes::sleep( probe_idle_backoff_us / 1000 ); + } continue; // And try again } + + probe_idle_backoff_us=0; + int count; MPI_Get_count(&status,MPI_CHAR,&count); if (count > MSGBUFSIZ) { // Ensure we have the space for it @@ -142,6 +153,13 @@ void CommonBase::OnIdle() //------------------------------------------------------------------------------ +bool CommonBase::HaveIdleWork() +{ + return true; // For compatibility with existing users of OnIdle +} + +//------------------------------------------------------------------------------ + unsigned CommonBase::OnPmap(PMsg_p * Z) { pPmap->Register(Z); diff --git a/Source/Common/CommonBase.h b/Source/Common/CommonBase.h index 8a26a4fa..30b83ebb 100644 --- a/Source/Common/CommonBase.h +++ b/Source/Common/CommonBase.h @@ -31,6 +31,7 @@ virtual unsigned Decode(PMsg_p *) = 0; void Dump(unsigned = 0,FILE * = stdout); unsigned OnExit(PMsg_p *); virtual void OnIdle(); +virtual bool HaveIdleWork(); // Return false if there is something we want to do in OnIdle unsigned OnPmap(PMsg_p *); unsigned OnSystPingAck(PMsg_p *); unsigned OnSystPingReq(PMsg_p *); diff --git a/Source/LogServer/LogServer.cpp b/Source/LogServer/LogServer.cpp index fedfeec8..3d75b89e 100644 --- a/Source/LogServer/LogServer.cpp +++ b/Source/LogServer/LogServer.cpp @@ -155,14 +155,27 @@ while (recd!=0) { // Walk the records in the section //------------------------------------------------------------------------------ +// DT10 : This was previously a static within LogServer::OnIdle. A static +// global here seems as problematic as there, so moved it out. It looked +// like a hack anyway. +static bool OnIdle_flag0 = false; // All the processes registered? + +bool LogServer::HaveIdleWork() +{ + if(logfp==0) return false; + if((OnIdle_flag0==false)&&(pPmap->vPmap.size()>=unsigned(Usize))){ + return true; + } + return false; +} + void LogServer::OnIdle() { if (logfp==0) return; // May not yet have an output channel -static bool flag0 = false; // All the processes registered? -if ((flag0==false)&&(pPmap->vPmap.size()>=unsigned(Usize))) { +if ((OnIdle_flag0==false)&&(pPmap->vPmap.size()>=unsigned(Usize))) { if (pPmap->vPmap.size()>unsigned(Usize))Post(113); pPmap->Show(logfp); - flag0 = true; // Make sure we just do this once + OnIdle_flag0 = true; // Make sure we just do this once } CommonBase::OnIdle(); // Any base actions? } diff --git a/Source/LogServer/LogServer.h b/Source/LogServer/LogServer.h index 1412daee..193976e3 100644 --- a/Source/LogServer/LogServer.h +++ b/Source/LogServer/LogServer.h @@ -22,6 +22,7 @@ string Assemble(int,vector &); void Dump(unsigned = 0,FILE * = stdout); void InitFile(); void LoadMessages(string); +bool HaveIdleWork(); void OnIdle(); unsigned OnLoad(PMsg_p *); unsigned OnLogP(PMsg_p *); diff --git a/Source/OrchBase/Handlers/CmCall.cpp b/Source/OrchBase/Handlers/CmCall.cpp index 8f191896..a25db5c5 100644 --- a/Source/OrchBase/Handlers/CmCall.cpp +++ b/Source/OrchBase/Handlers/CmCall.cpp @@ -121,6 +121,13 @@ fflush(fp); //------------------------------------------------------------------------------ +bool CmCall::IsEmpty() +{ + return Equeue.empty(); +} + +//------------------------------------------------------------------------------ + Cli CmCall::Front() // Provides a valid Cm object: if there was one in the Q, it gets popped off // the front; otherwise an empty one is returned. diff --git a/Source/OrchBase/Handlers/CmCall.h b/Source/OrchBase/Handlers/CmCall.h index f47b8ad1..9bc68233 100644 --- a/Source/OrchBase/Handlers/CmCall.h +++ b/Source/OrchBase/Handlers/CmCall.h @@ -20,6 +20,7 @@ void CaEcho(Cli::Cl_t); void CaFile(Cli::Cl_t); void Dump(unsigned = 0,FILE * = stdout); Cli Front(); +bool IsEmpty(); void Show(FILE * = stdout); unsigned operator()(Cli *); diff --git a/Source/RTCL/RTCL.cpp b/Source/RTCL/RTCL.cpp index 51fe4192..dac98b0f 100644 --- a/Source/RTCL/RTCL.cpp +++ b/Source/RTCL/RTCL.cpp @@ -106,6 +106,12 @@ fprintf(fp,"%sRTCL dump ------------------------------------------------\n",os); fflush(stdout); } +bool RTCL::HaveIdleWork() +{ + // We don't have OnIdle, so must never have work. + return false; +} + //------------------------------------------------------------------------------ unsigned RTCL::OnExit(PMsg_p * Z) diff --git a/Source/RTCL/RTCL.h b/Source/RTCL/RTCL.h index d3d2d9ed..f46ac27c 100644 --- a/Source/RTCL/RTCL.h +++ b/Source/RTCL/RTCL.h @@ -23,6 +23,8 @@ void Dump(unsigned = 0,FILE * = stdout); unsigned OnExit(PMsg_p *); unsigned OnRTCL(PMsg_p *); +bool HaveIdleWork(); + public: struct comms_t { RTCL * pthis; diff --git a/Source/Root/Root.cpp b/Source/Root/Root.cpp index 82ab7753..cbec1a57 100644 --- a/Source/Root/Root.cpp +++ b/Source/Root/Root.cpp @@ -323,6 +323,17 @@ fflush(fp); //------------------------------------------------------------------------------ +bool Root::HaveIdleWork() +{ + // If a scheduled exit condition is satisfied, we have work to do. + if((pCmCall->IsEmpty() and exitOnEmpty) or (appJustStopped and exitOnStop)){ + return true; + } + + // Otherwise, simply check the queue. + return !pCmCall->IsEmpty(); +} + void Root::OnIdle() { Cli Cm = pCmCall->Front(); // Anything in the batch queue? diff --git a/Source/Root/Root.h b/Source/Root/Root.h index 2fa4d817..fef649d7 100644 --- a/Source/Root/Root.h +++ b/Source/Root/Root.h @@ -43,6 +43,7 @@ unsigned CmRetu(Cli *); bool Config(); #include "Decode.cpp" void Dump(unsigned = 0,FILE * = stdout); +bool HaveIdleWork(); void OnIdle(); unsigned OnInje(PMsg_p *); unsigned OnKeyb(PMsg_p *);