TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ofx/OfxhMultiThreadSuite.cpp
Go to the documentation of this file.
00001 #include "OfxhMultiThreadSuite.hpp"
00002 #include "OfxhCore.hpp"
00003 
00004 #include <boost/thread/thread.hpp>
00005 #include <boost/thread/recursive_mutex.hpp>
00006 #include <boost/thread/tss.hpp>
00007 #include <boost/bind.hpp>
00008 
00009 struct OfxMutex
00010 {
00011         boost::recursive_mutex _mutex;
00012 };
00013 
00014 namespace tuttle {
00015 namespace host {
00016 namespace ofx {
00017 
00018 namespace {
00019 
00020 struct ThreadSpecificData
00021 {
00022         ThreadSpecificData( unsigned int threadIndex ) : _index( 0 ) {}
00023         unsigned int _index;
00024 };
00025 
00026 boost::thread_specific_ptr<ThreadSpecificData> ptr;
00027 
00028 void launchThread( OfxThreadFunctionV1 func,
00029                    unsigned int        threadIndex,
00030                    unsigned int        threadMax,
00031                    void*               customArg )
00032 {
00033         ptr.reset( new ThreadSpecificData( threadIndex ) );
00034         func( threadIndex, threadMax, customArg );
00035 }
00036 
00037 OfxStatus multiThread( OfxThreadFunctionV1 func,
00038                        const unsigned int  nThreads,
00039                        void*               customArg )
00040 {
00041         if( nThreads == 0 )
00042         {
00043                 return kOfxStatErrValue;
00044         }
00045         else if( nThreads == 1 )
00046         {
00047                 func( 0, 1, customArg );
00048         }
00049         else
00050         {
00051                 boost::thread_group group;
00052                 for( unsigned int i = 0; i < nThreads; ++i )
00053                 {
00054                         group.create_thread( boost::bind( launchThread, func, i, nThreads, customArg ) );
00055                 }
00056                 group.join_all();
00057         }
00058         return kOfxStatOK;
00059 }
00060 
00061 OfxStatus multiThreadNumCPUs( unsigned int* const nCPUs )
00062 {
00063 //      *nCPUs = 1; /// @todo tuttle: needs to have an option to disable multithreading (force only one cpu).
00064         *nCPUs = boost::thread::hardware_concurrency();
00065         TUTTLE_TLOG( TUTTLE_INFO, "[Multi thread] CPUs used: " << *nCPUs );
00066         return kOfxStatOK;
00067 }
00068 
00069 OfxStatus multiThreadIndex( unsigned int* const threadIndex )
00070 {
00071         //      *threadIndex = boost::this_thread::get_id(); // we don't want a global thead id, but the thead index inside a node multithread process.
00072         if( ptr.get() != NULL )
00073         {
00074                 *threadIndex = 0;
00075                 return kOfxStatFailed;
00076         }
00077         *threadIndex = ptr->_index;
00078         return kOfxStatOK;
00079 }
00080 
00081 int multiThreadIsSpawnedThread( void )
00082 {
00083         return ptr.get() != NULL;
00084 }
00085 
00086 /**
00087  * @todo tuttle: support lockCount init value.
00088  */
00089 OfxStatus mutexCreate( OfxMutexHandle* mutex, const int lockCount )
00090 {
00091         *mutex = new OfxMutex();
00092         return kOfxStatOK;
00093 }
00094 
00095 OfxStatus mutexDestroy( OfxMutexHandle mutex )
00096 {
00097         if( mutex == NULL )
00098                 return kOfxStatErrBadHandle;
00099         delete mutex;
00100         mutex = NULL;
00101         return kOfxStatOK;
00102 }
00103 
00104 OfxStatus mutexLock( OfxMutexHandle mutex )
00105 {
00106         if( mutex == NULL )
00107                 return kOfxStatErrBadHandle;
00108         mutex->_mutex.lock();
00109         return kOfxStatOK;
00110 }
00111 
00112 OfxStatus mutexUnLock( OfxMutexHandle mutex )
00113 {
00114         if( mutex == NULL )
00115                 return kOfxStatErrBadHandle;
00116         mutex->_mutex.unlock();
00117         return kOfxStatOK;
00118 }
00119 
00120 OfxStatus mutexTryLock( OfxMutexHandle mutex )
00121 {
00122         if( mutex == NULL )
00123                 return kOfxStatErrBadHandle;
00124         if( mutex->_mutex.try_lock() )
00125                 return kOfxStatOK;
00126         return kOfxStatFailed;
00127 }
00128 
00129 struct OfxMultiThreadSuiteV1 gSingleThreadedSuite =
00130 {
00131         multiThread,
00132         multiThreadNumCPUs,
00133         multiThreadIndex,
00134         multiThreadIsSpawnedThread,
00135         mutexCreate,
00136         mutexDestroy,
00137         mutexLock,
00138         mutexUnLock,
00139         mutexTryLock
00140 };
00141 
00142 }
00143 
00144 void* getMultithreadSuite( const int version )
00145 {
00146         if( version == 1 )
00147                 return &gSingleThreadedSuite;
00148         return NULL;
00149 }
00150 
00151 }
00152 }
00153 }
00154