TuttleOFX  1
ofxsMultiThread.cpp
Go to the documentation of this file.
00001 /*
00002  * OFX Support Library, a library that skins the OFX plug-in API with C++ classes.
00003  * Copyright (C) 2004-2005 The Open Effects Association Ltd
00004  * Author Bruno Nicoletti bruno@thefoundry.co.uk
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  * Redistributions of source code must retain the above copyright notice,
00010  * this list of conditions and the following disclaimer.
00011  * Redistributions in binary form must reproduce the above copyright notice,
00012  * this list of conditions and the following disclaimer in the documentation
00013  * and/or other materials provided with the distribution.
00014  * Neither the name The Open Effects Association Ltd, nor the names of its
00015  * contributors may be used to endorse or promote products derived from this
00016  * software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00021  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
00022  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00024  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00025  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00027  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  *
00029  * The Open Effects Association Ltd
00030  * 1 Wardour St
00031  * London W1D 6PA
00032  * England
00033  *
00034  *
00035  */
00036 
00037 #include "ofxsSupportPrivate.h"
00038 #include "ofxsUtilities.h"
00039 #include <iostream>
00040 
00041 namespace OFX {
00042 
00043 namespace MultiThread {
00044 
00045 ////////////////////////////////////////////////////////////////////////////////
00046 // SMP class
00047 
00048 /** @brief ctor */
00049 Processor::Processor( void )
00050 {}
00051 
00052 /** @brief dtor */
00053 Processor::~Processor()
00054 {}
00055 
00056 /** @brief Function to pass to the multi thread suite */
00057 void Processor::staticMultiThreadFunction( unsigned int threadIndex, unsigned int threadMax, void* customArg )
00058 {
00059         // cast the custom arg to one of me
00060         Processor* me = (Processor*)  customArg;
00061 
00062         // and call my thread function
00063         me->multiThreadFunction( threadIndex, threadMax );
00064 }
00065 
00066 /** @brief Function to pass to the multi thread suite */
00067 void Processor::multiThread( const unsigned int nCPUs )
00068 {
00069         unsigned int realNbCPUs = nCPUs;
00070         // if 0, use all the CPUs we can
00071         if( realNbCPUs == 0 )
00072                 realNbCPUs = OFX::MultiThread::getNumCPUs();
00073 
00074         if( realNbCPUs == 0 )
00075         {
00076                 OFXS_COUT_ERROR( "Run process on 0 cpus... it seems to be a problem." );
00077         }
00078         else if( realNbCPUs == 1 ) // if 1 cpu, don't bother with the threading
00079         {
00080                 multiThreadFunction( 0, 1 );
00081         }
00082         else
00083         {
00084                 // OK do it
00085                 OfxStatus stat = OFX::Private::gThreadSuite->multiThread( staticMultiThreadFunction, realNbCPUs, (void*)this );
00086 
00087                 // did we do it?
00088                 throwSuiteStatusException( stat );
00089         }
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////////////////
00093 // futility functions
00094 
00095 /** @brief Has the current thread been spawned from an MP */
00096 bool isSpawnedThread( void )
00097 {
00098         int v = OFX::Private::gThreadSuite->multiThreadIsSpawnedThread();
00099 
00100         return v != 0;
00101 }
00102 
00103 /** @brief The number of CPUs that can be used for MP-ing */
00104 unsigned int getNumCPUs( void )
00105 {
00106         unsigned int n = 1;
00107         OfxStatus stat = OFX::Private::gThreadSuite->multiThreadNumCPUs( &n );
00108 
00109         if( stat != kOfxStatOK )
00110                 n = 1;
00111         return n;
00112 }
00113 
00114 /** @brief The index of the current thread. From 0 to numCPUs() - 1 */
00115 unsigned int getThreadIndex( void )
00116 {
00117         unsigned int n = 0;
00118         OfxStatus stat = OFX::Private::gThreadSuite->multiThreadIndex( &n );
00119 
00120         if( stat != kOfxStatOK )
00121                 n = 0;
00122         return n;
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////////////////
00126 // MUTEX class
00127 
00128 /** @brief ctor */
00129 Mutex::Mutex( int lockCount )
00130         : _handle( 0 )
00131 {
00132         OfxStatus stat = OFX::Private::gThreadSuite->mutexCreate( &_handle, lockCount );
00133 
00134         throwSuiteStatusException( stat );
00135 }
00136 
00137 /** @brief dtor */
00138 Mutex::~Mutex( void )
00139 {
00140         /*OfxStatus stat = */OFX::Private::gThreadSuite->mutexDestroy( _handle );
00141 }
00142 
00143 /** @brief lock it, blocks until lock is gained */
00144 void Mutex::lock()
00145 {
00146         OfxStatus stat = OFX::Private::gThreadSuite->mutexLock( _handle );
00147 
00148         throwSuiteStatusException( stat );
00149 }
00150 
00151 /** @brief unlock it */
00152 void Mutex::unlock()
00153 {
00154         OfxStatus stat = OFX::Private::gThreadSuite->mutexUnLock( _handle );
00155 
00156         throwSuiteStatusException( stat );
00157 }
00158 
00159 /** @brief attempt to lock, non-blocking */
00160 bool Mutex::tryLock()
00161 {
00162         OfxStatus stat = OFX::Private::gThreadSuite->mutexTryLock( _handle );
00163 
00164         return stat == kOfxStatOK;
00165 }
00166 
00167 };
00168 };