Changeset 20824

Show
Ignore:
Timestamp:
09/19/07 14:11:56 (1 year ago)
Author:
patrick
Message:

Added render thread CPU affinity capabilities. The default way that this is
utilized is by setting the new environment variable VJ_DRAW_THREAD_AFFINITY
to a space-separated list of zero-based integer CPU identifiers. User-level
code can change the mechanism (for the OpenGL Draw Manager) by calling
vrj::opengl::DrawManager::setCpuAffinityStrategy(). For now, only the OpenGL
Draw Manager is utilizing this new feature. The Direct3D Draw Manager does
not appear to be multi-threaded at the moment, so it has not use for it. I
did not look into usage of this with the Performer Draw Manager.

This is based on an idea proposed by Todd Furlong and refined through
discussion on the vrjuggler-devel mailing list.

Bumped the version to 2.3.14.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • juggler/trunk/modules/vrjuggler/ChangeLog

    r20811 r20824  
    11DATE        AUTHOR      CHANGE 
    22----------- ----------- ------------------------------------------------------- 
     3Sep-19-2007 patrick     Added draw thread CPU affinity capabilities through the 
     4                        new environment variable VJ_DRAW_THREAD_AFFINITY. This 
     5                        is currently used only by the OpenGL Draw Manager. 
     6                        NEW VERSION: 2.3.14 
    37Sep-09-2007 patrick     Added vrjuggler-direct3d fpc file. 
    48Sep-07-2007 dshipton    Added vrjuggler-opengl and vrjuggler-performer fpc 
  • juggler/trunk/modules/vrjuggler/VERSION

    r20757 r20824  
     12.3.14-0 @09/19/2007 19:10:00 UTC@ 
    122.3.13-0 @09/05/2007 02:05:00 UTC@ 
    232.3.12-0 @08/25/2007 13:15:00 UTC@ 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OpenGL/DrawManager.cpp

    r20629 r20824  
    4343#include <vrj/Display/SimViewport.h> 
    4444#include <vrj/Display/SurfaceViewport.h> 
     45#include <vrj/Draw/CpuAffinityFromEnv.h> 
    4546 
    4647#include <vrj/Draw/OpenGL/App.h> 
     
    7475   , mControlThread(NULL) 
    7576{ 
    76    /* Do nothing. */
     77   setCpuAffinityStrategy(vrj::CpuAffinityFromEnv())
    7778} 
    7879 
     
    9091      mControlThread = NULL; 
    9192   } 
     93} 
     94 
     95void 
     96DrawManager::setCpuAffinityStrategy(const cpu_affinity_strategy_t& strategy) 
     97{ 
     98   getDrawThreadAffinity = strategy; 
    9299} 
    93100 
     
    310317            new vrj::opengl::Pipe(pipes.size(), this, &mCreateWindowMutex);  // Create a new pipe to use 
    311318         pipes.push_back(new_pipe);                          // Add the pipe 
    312          new_pipe->start();                                  // Start the pipe running 
     319         new_pipe->start(getDrawThreadAffinity(pipe_num));   // Start the pipe running 
    313320                                                             // NOTE: Run pipe even if no windows.  Then it waits for windows. 
    314321      } 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OpenGL/DrawManager.h

    r20495 r20824  
    3232#include <vector> 
    3333#include <boost/noncopyable.hpp> 
     34#include <boost/function.hpp> 
    3435 
    3536#include <vpr/vpr.h> 
     
    9091   friend class ContextDataBase; 
    9192 
     93   typedef boost::function<int (const unsigned int)> cpu_affinity_strategy_t; 
     94 
     95   /** 
     96    * Changes the callable object used for determining the draw thread CPU 
     97    * affinity to use the given value. In order for this to have the 
     98    * desired effect, it must be called before any render threads have been 
     99    * started. 
     100    * 
     101    * @post \c getDrawThreadAffinity is assigned the value of \p strategy. 
     102    * 
     103    * @param strategy A callable (either a C function pointer, a value 
     104    *                 returned by boost::bind(), or an object whose class 
     105    *                 overloads operator()) that serves to map zero-based 
     106    *                 thread identifiers to zero-based CPU values in order 
     107    *                 to assign affinity. 
     108    * 
     109    * @see vpr::Thead::setRunOn() 
     110    * @see addDisplay() 
     111    * 
     112    * @since 2.3.14 
     113    */ 
     114   void setCpuAffinityStrategy(const cpu_affinity_strategy_t& strategy); 
     115 
    92116   /** Starts the control loop. */ 
    93117   virtual void start(); 
     
    241265   DrawManager(); 
    242266 
     267   cpu_affinity_strategy_t getDrawThreadAffinity; 
     268 
    243269   vprSingletonHeader(DrawManager); 
    244270}; 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OpenGL/Pipe.cpp

    r20657 r20824  
    8484 
    8585// Starts the pipe running. 
    86 int Pipe::start(
     86int Pipe::start(const int cpuAffinity
    8787{ 
    8888   vprASSERT(mThreadRunning == false);        // We should not be running yet 
     
    9393   try 
    9494   { 
    95       mActiveThread = new vpr::Thread(boost::bind(&Pipe::controlLoop, this)); 
     95      // mActiveThread is assigned at the start of controlLoop(). 
     96      vpr::Thread* thread = 
     97         new vpr::Thread(boost::bind(&Pipe::controlLoop, this, cpuAffinity)); 
    9698      vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL) 
    9799         << "[vrj::opengl::Pipe::start()] Started control loop. " 
    98          << mActiveThread << std::endl << vprDEBUG_FLUSH; 
     100         << thread<< std::endl << vprDEBUG_FLUSH; 
    99101      started = 1; 
    100102   } 
     
    182184// - Signal swap completed <br> 
    183185// 
    184 void Pipe::controlLoop() 
    185 
     186void Pipe::controlLoop(const int cpuAffinity) 
     187
     188   vprASSERT(NULL != vpr::Thread::self()); 
     189   mActiveThread = vpr::Thread::self(); 
     190 
     191   if ( cpuAffinity >= 0 ) 
     192   { 
     193      vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) 
     194         << "[vrj::opengl::Pipe::controlLoop()] Setting CPU affinity for " 
     195         << "pipe " << mPipeNum << " to " << cpuAffinity << std::endl 
     196         << vprDEBUG_FLUSH; 
     197 
     198      try 
     199      { 
     200         mActiveThread->setRunOn(cpuAffinity); 
     201      } 
     202      catch (vpr::Exception& ex) 
     203      { 
     204         vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_WARNING_LVL) 
     205            << clrOutBOLD(clrYELLOW, "WARNING") 
     206            << ": Failed to set draw thread affinity in vrj::opengl::Pipe:\n" 
     207            << ex.what() << std::endl << vprDEBUG_FLUSH; 
     208      } 
     209   } 
     210 
    186211   mThreadRunning = true;     // We are running so set flag 
    187212   // Loop until flag set 
  • juggler/trunk/modules/vrjuggler/vrj/Draw/OpenGL/Pipe.h

    r20657 r20824  
    8282    * 
    8383    * @pre The pipe should not have a thread of control yet. 
    84     * @post The pipe has it's own thread of control and is ready to operate 
     84    * @post The pipe has its own thread of control and is ready to operate 
    8585    *       The Thread of control is running controlLoop. 
     86    * 
     87    * @param cpuAffinity The CPU affinity to assign for the rendering thread 
     88    *                    spawned by this method. A value less than 0 
     89    *                    indicates that no CPU affinity will be assigned to 
     90    *                    the rendering thread. 
     91    * 
    8692    * @note The pipe does NOT have to have any windows in order to run 
    8793    *       that way we can add windows to pipes at run-time. 
    88     */ 
    89    int start(); 
     94    * @note The signature of this method changed in version 2.3.14 to take the 
     95    *       CPU affinity value. 
     96    */ 
     97   int start(const int cpuAffinity); 
    9098 
    9199   /** 
    92100    * The main loop routine. 
    93     * -Checks for new windows <br> 
    94     * -renders all windows when triggered <br> 
    95     */ 
    96    void controlLoop(); 
     101    *  - Checks for new windows. 
     102    *  - Renders all windows when triggered. 
     103    * 
     104    * @param cpuAffinity The CPU affinity to assign for the rendering thread 
     105    *                    spawned by this method. A value less than 0 
     106    *                    indicates that no CPU affinity will be assigned to 
     107    *                    the rendering thread. 
     108    * 
     109    * @note The signature of this method changed in version 2.3.14 to take the 
     110    *       CPU affinity value. 
     111    * 
     112    * @see vpr::Thead::setRunOn() 
     113    */ 
     114   void controlLoop(const int cpuAffinity); 
    97115 
    98116   /**