Changeset 20815

Show
Ignore:
Timestamp:
09/16/07 19:55:49 (1 year ago)
Author:
patrick
Message:

Added a Linux-specific implementation of vpr::ThreadPosix::[gs]etRunOn().
Added vpr::ThreadWin?32::[gs]etRunOn() and vpr::ThreadNSPR::[gs]etRunOn().
The NSPR implementation currently does nothing. Changed the signatuer of
vpr::Thread::getRunOn() to return std::vector<unsigned int>. While
vpr::Thread::setRunOn() only allows choosing a single processor, threads are
allowed to run on multiple processors by default. In this way, we can
retrieve that information if necessary.

Bumped the version to 2.1.6.

Files:

Legend:

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

    r20773 r20815  
    11DATE       AUTHOR   CHANGE 
    22---------- -------- ----------------------------------------------------------- 
     32007-09-16 patrick  Added vpr::ThreadWin32::setRunOn() and 
     4                    vpr::ThreadWin32::getRunOn(). Added Linux-specific 
     5                    implementations of vpr::ThreadPosix::setRunOn() and 
     6                    vpr::ThreadPosix::getRunOn(). Changed 
     7                    vpr::Thread::getRunOn() so that it now returns 
     8                    std::vector<unsigned int>. 
     9                    NEW VERSION: 2.1.6 
    3102007-09-06 patrick  Implemented stack trace printing on Mac OS X. 
    4112007-09-04 patrick  Set VPR_BASE_DIR automatically on all platforms. 
  • juggler/trunk/modules/vapor/VERSION

    r20733 r20815  
     12.1.6-0 @09/16/2007 00:55:00 UTC@ 
    122.1.5-0 @08/22/2007 00:45:00 UTC@ 
    232.1.4-0 @07/08/2007 21:15:00 UTC@ 
  • juggler/trunk/modules/vapor/vpr/md/NSPR/Thread/ThreadNSPR.h

    r19729 r20815  
    245245   virtual void setPrio(const VPRThreadPriority prio); 
    246246 
     247   virtual void setRunOn(const unsigned int) 
     248   { 
     249      /* Do nothing. */ ; 
     250   } 
     251 
     252   virtual std::vector<unsigned int> getRunOn() 
     253   { 
     254      return std::vector<unsigned int>(); 
     255   } 
     256 
    247257   /** 
    248258    * Sends the specified signal to this thread (not necessarily \c SIGKILL). 
  • juggler/trunk/modules/vapor/vpr/md/POSIX/Thread/ThreadPosix.cpp

    r19897 r20815  
    5858// include vpr/Thread/Thread.h or ThreadPosix.h. 
    5959#include <vpr/Util/Debug.h> 
     60#include <vpr/Util/Error.h> 
    6061#include <vpr/Util/IllegalArgumentException.h> 
    6162#include <vpr/Util/ResourceException.h> 
     
    382383} 
    383384 
    384 void ThreadPosix::setRunOn(const int cpu) 
    385 
    386 #ifdef VPR_OS_IRIX 
    387    if ( mScope == VPR_GLOBAL_THREAD ) 
    388    { 
    389       pthread_setrunon_np(cpu); 
     385void ThreadPosix::setRunOn(const unsigned int cpu) 
     386
     387   if ( ThreadPosix::self() == this ) 
     388   { 
     389#if defined(VPR_OS_IRIX) 
     390      if ( mScope == VPR_GLOBAL_THREAD ) 
     391      { 
     392         pthread_setrunon_np(cpu); 
     393      } 
     394      else 
     395      { 
     396         throw vpr::IllegalArgumentException( 
     397            "This thread is not a system-scope thread", VPR_LOCATION 
     398         ); 
     399      } 
     400#elif defined(VPR_OS_Linux) && defined(CPU_SET) 
     401      if ( sysconf(_SC_NPROCESSORS_CONF) > cpu ) 
     402      { 
     403         cpu_set_t cpu_mask; 
     404         CPU_ZERO(&cpu_mask); 
     405         CPU_SET(static_cast<int>(cpu), &cpu_mask); 
     406         const int result = sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask); 
     407 
     408         if ( result != 0 ) 
     409         { 
     410            std::ostringstream msg_stream; 
     411            msg_stream << "Failed to set CPU affinity: " 
     412                       << vpr::Error::getCurrentErrorMsg(); 
     413            throw vpr::Exception(msg_stream.str(), VPR_LOCATION); 
     414         } 
     415      } 
     416#else 
     417      boost::ignore_unused_variable_warning(cpu); 
     418      std::cerr << "vpr::ThreadPosix::setRunOn(): Not available on this " 
     419                << "operating system!\n"; 
     420#endif 
    390421   } 
    391422   else 
    392423   { 
    393424      throw vpr::IllegalArgumentException( 
    394          "This thread is not a system-scope thread", VPR_LOCATION 
     425         "CPU affinity can only be set for a thread object from its thread", 
     426         VPR_LOCATION 
    395427      ); 
    396428   } 
     429} 
     430 
     431std::vector<unsigned int> ThreadPosix::getRunOn() 
     432{ 
     433   std::vector<unsigned int> cpus; 
     434 
     435   if ( ThreadPosix::self() == this ) 
     436   { 
     437#if defined(VPR_OS_IRIX) 
     438      if ( mScope == VPR_GLOBAL_THREAD ) 
     439      { 
     440         int cpu; 
     441         if ( pthread_getrunon_np(&cpu) == 0 ) 
     442         { 
     443            cpus.push_back(cpu); 
     444         } 
     445         else 
     446         { 
     447            std::ostringstream msg_stream; 
     448            msg_stream << "Failed to query CPU affinity: " 
     449                       << Error::getCurrentErrorMsg(); 
     450            throw vpr::Exception(msg_stream.str(), VPR_LOCATION); 
     451         } 
     452      } 
     453      else 
     454      { 
     455         throw vpr::IllegalArgumentException( 
     456            "This thread is not a system-scope thread", VPR_LOCATION 
     457         ); 
     458      } 
     459#elif defined(VPR_OS_Linux) 
     460      cpu_set_t cpu_mask; 
     461      CPU_ZERO(&cpu_mask); 
     462      const int result = sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask); 
     463 
     464      if ( result == 0 ) 
     465      { 
     466         const long cpu_count(sysconf(_SC_NPROCESSORS_CONF)); 
     467         cpus.reserve(cpu_count); 
     468 
     469         for ( int i = 0; i < cpu_count; ++i ) 
     470         { 
     471            if ( CPU_ISSET(i, &cpu_mask) ) 
     472            { 
     473               cpus.push_back(cpu); 
     474            } 
     475         } 
     476      } 
     477      else 
     478      { 
     479         std::ostringstream msg_stream; 
     480         msg_stream << "Failed to query CPU affinity: " 
     481                    << Error::getCurrentErrorMsg(); 
     482         throw vpr::Exception(msg_stream.str(), VPR_LOCATION); 
     483      } 
    397484#else 
    398    boost::ignore_unused_variable_warning(cpu); 
    399    std::cerr << "vpr::ThreadPosix::setRunOn(): Not available on this system.\n"; 
     485      std::cerr << "vpr::ThreadPosix::getRunOn(): Not available on this " 
     486                << "operating system.\n"; 
    400487#endif 
    401 } 
    402  
    403 int ThreadPosix::getRunOn() 
    404 { 
    405 #ifdef VPR_OS_IRIX 
    406    int cur_cpu; 
    407  
    408    if ( mScope == VPR_GLOBAL_THREAD ) 
    409    { 
    410       pthread_getrunon_np(&cur_cpu); 
    411488   } 
    412489   else 
    413490   { 
    414491      throw vpr::IllegalArgumentException( 
    415          "This thread is not a system-scope thread", VPR_LOCATION 
     492         "CPU affinity can only be queired for a thread object from its thread", 
     493         VPR_LOCATION 
    416494      ); 
    417495   } 
    418496 
    419    return cur_cpu; 
    420 #else 
    421    std::cerr << "vpr::ThreadPosix::getRunOn(): Not available on this system.\n"; 
    422    return 0; 
    423 #endif 
     497   return cpus; 
    424498} 
    425499 
  • juggler/trunk/modules/vapor/vpr/md/POSIX/Thread/ThreadPosix.h

    r19729 r20815  
    4646 
    4747#include <stdlib.h> 
     48#include <vector> 
    4849#include <pthread.h> 
    4950#include <sys/types.h> 
     
    307308    * will exclusively run). 
    308309    * 
    309     * @pre The thread must have been set to be a system-scope thread. 
    310     * @post The CPU affinity is set or an error status is returned. 
    311     * 
    312     * @param cpu The CPU on which this thread will run exclusively. 
    313     * 
    314     * @throw vpr::IllegalArgumentException is thrown if this is not a 
    315     *        system-scope (i.e., global) thread. 
    316     * 
    317     * @note This is currently only available on IRIX 6.5 and is non-portable. 
    318     */ 
    319    virtual void setRunOn(const int cpu); 
     310    * @pre The thread must have been set to be a system-scope thread. The 
     311    *      thread from which this method was invoked must be the same as the 
     312    *      thread spawned by this object. 
     313    * @post The CPU affinity is set or an exception is thrown. 
     314    * 
     315    * @param cpu The CPU on which this thread will run exclusively. This value 
     316    *            is zero-based and therefore must be less than the number of 
     317    *            processors available on the computer. 
     318    * 
     319    * @throw vpr::IllegalArgumentException 
     320    *           Thrown if the thread spawned through the use of this object is 
     321    *           not the thread from which this method was invoked. 
     322    * @throw vpr::IllegalArgumentException 
     323    *           Thrown if this is not a system-scope (i.e., global) thread. 
     324    * @throw vpr::Exception 
     325    *           Thrown if the CPU affinity for the running thread could not 
     326    *           be changed. 
     327    * 
     328    * @note Currently, this is only available on IRIX 6.5 and Linux. 
     329    */ 
     330   virtual void setRunOn(const unsigned int cpu); 
    320331 
    321332   /** 
     
    324335    * 
    325336    * @pre The thread must have been set to be a system-scope thread, and 
    326     *      a previous affinity must have been set using setRunOn(). 
    327     * @post The CPU affinity for this thread is stored in the cur_cpu 
    328     *       pointer. 
    329     * 
    330     * @return The CPU affinity for this thread (set by a previous call to 
    331     *         setRunOn()); 
    332     * 
    333     * @throw vpr::IllegalArgumentException is thrown if this is not a 
    334     *        system-scope (i.e., global) thread. 
    335     * 
    336     * @note This is currently only available on IRIX 6.5 and is non-portable. 
    337     */ 
    338    virtual int getRunOn(); 
     337    *      a previous affinity must have been set using setRunOn(). The thread 
     338    *      from which this method was invoked must be the same as the thread 
     339    *      spawned by this object. 
     340    * @post The CPU affinity for this thread is returned to the caller. 
     341    * 
     342    * @return The CPU affinity for this thread (posisbly set by a previous 
     343    *         call to setRunOn()). 
     344    * 
     345    * @throw vpr::IllegalArgumentException 
     346    *           Thrown if the thread spawned through the use of this object is 
     347    *           not the thread from which this method was invoked. 
     348    * @throw vpr::IllegalArgumentException 
     349    *           Thrown if this is not a system-scope (i.e., global) thread. 
     350    * @throw vpr::Exception 
     351    *           Thrown if the CPU affinity for the running thread could not 
     352    *           be queried. 
     353    * 
     354    * @note Currently, this is only available on IRIX 6.5 and Linux. 
     355    * @note The return value of this method was changed from int to 
     356    *       std::vector<unsigned int> in VPR 2.1.7. 
     357    */ 
     358   virtual std::vector<unsigned int> getRunOn(); 
    339359 
    340360   /** 
  • juggler/trunk/modules/vapor/vpr/md/WIN32/Thread/ThreadWin32.cpp

    r19897 r20815  
    304304      throw vpr::IllegalArgumentException(msg_stream.str(), VPR_LOCATION); 
    305305   } 
     306} 
     307 
     308void ThreadWin32::setRunOn(const unsigned int cpu) 
     309{ 
     310   // Even though we have easy access to mThreadHandle, we perform this test 
     311   // to ensure semantic compatibility with vpr::ThreadPosix. 
     312   if ( ThreadWin32::self() == this ) 
     313   { 
     314      // The value of cpu is zero-based, but the CPU identifier values from 
     315      // Windows are one-based. 
     316      DWORD_PTR result = SetThreadAffinityMask(mThreadHandle, 0x1 << cpu); 
     317 
     318      if ( result == 0 ) 
     319      { 
     320         std::ostringstream msg_stream; 
     321         msg_stream << "Failed to set CPU affinity: " 
     322                    << vpr::Error::getCurrentErrorMsg(); 
     323         throw vpr::Exception(msg_stream.str(), VPR_LOCATION); 
     324      } 
     325   } 
     326   else 
     327   { 
     328      throw vpr::IllegalArgumentException( 
     329         "CPU affinity can only be set for a thread object from its thread", 
     330         VPR_LOCATION 
     331      ); 
     332   } 
     333} 
     334 
     335std::vector<unsigned int> ThreadWin32::getRunOn() 
     336{ 
     337   std::vector<unsigned int> cpus; 
     338 
     339   if ( ThreadPosix::self() == this ) 
     340   { 
     341      DWORD_PTR proc_affinity_mask; 
     342      DWORD_PTR sys_affinity_mask; 
     343 
     344      const BOOL result = GetProcessAffinityMask(mThreadHandle, 
     345                                                 &proc_affinity_mask, 
     346                                                 &sys_affinity_mask); 
     347 
     348      if ( result ) 
     349      { 
     350         const size_t cpu_count(sizeof(DWORD_PTR) * 8); 
     351         cpus.reserve(cpu_count); 
     352 
     353         // Find the first CPU in proc_affinity_mask on which this thread is 
     354         // allowed to run. 
     355         for ( int i = 0; i < cpu_count; ++i ) 
     356         { 
     357            if ( (0x1 << i) & proc_affinity_mask ) 
     358            { 
     359               cpus.push_back(i); 
     360            } 
     361         } 
     362      } 
     363      else 
     364      { 
     365      } 
     366   } 
     367   else 
     368   { 
     369      throw vpr::IllegalArgumentException( 
     370         "CPU affinity can only be queired for a thread object from its thread", 
     371         VPR_LOCATION 
     372      ); 
     373   } 
     374 
     375   return cpus; 
    306376} 
    307377 
  • juggler/trunk/modules/vapor/vpr/md/WIN32/Thread/ThreadWin32.h

    r19729 r20815  
    4646 
    4747#include <process.h> 
     48#include <vector> 
    4849 
    4950// To get the Win32 key stuff for storing self. 
     
    262263 
    263264   /** 
     265    * Sets the CPU affinity for this thread (the CPU on which this thread 
     266    * will exclusively run). 
     267    * 
     268    * @pre The thread from which this method was invoked must be the same as 
     269    *      the thread spawned by this object. 
     270    * @post The CPU affinity is set or an exception is thrown. 
     271    * 
     272    * @param cpu The CPU on which this thread will run exclusively. This value 
     273    *            is zero-based and therefore must be less than the number of 
     274    *            processors available on the computer. 
     275    * 
     276    * @throw vpr::IllegalArgumentException 
     277    *           Thrown if the thread spawned through the use of this object is 
     278    *           not the thread from which this method was invoked. 
     279    * @throw vpr::Exception 
     280    *           Thrown if the CPU affinity for the running thread could not 
     281    *           be changed. 
     282    */ 
     283   void setRunOn(const unsigned int cpu); 
     284 
     285   /** 
     286    * Gets the CPU affinity for this thread (the CPU on which this thread 
     287    * exclusively runs). 
     288    * 
     289    * @pre The thread must have been set to be a system-scope thread, and 
     290    *      a previous affinity must have been set using setRunOn(). The thread 
     291    *      from which this method was invoked must be the same as the thread 
     292    *      spawned by this object. 
     293    * @post The CPU affinity for this thread is returned to the caller. 
     294    * 
     295    * @return The CPU affinity for this thread (possibly set by a previous 
     296    *         call to setRunOn()). 
     297    * 
     298    * @throw vpr::IllegalArgumentException 
     299    *           Thrown if the thread spawned through the use of this object is 
     300    *           not the thread from which this method was invoked. 
     301    * @throw vpr::Exception 
     302    *           Thrown if the CPU affinity for the running thread could not 
     303    *           be queried. 
     304    */ 
     305   std::vector<unsigned int> getRunOn(); 
     306 
     307   /** 
    264308    * Yields execution of the calling thread to allow a different blocked 
    265309    * thread to execute.