33 #ifndef __INCLUDE_MIST_THREAD__
34 #define __INCLUDE_MIST_THREAD__
37 #ifndef __INCLUDE_MIST_CONF_H__
41 #ifndef __INCLUDE_MIST_SINGLETON__
48 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
50 #define __THREAD_POOL_SUPPORT__ 0
51 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
52 #if !defined( _WIN32_WINNT )
53 #define __THREAD_POOL_SUPPORT__ 0
54 #pragma message( "To use mist thread pool functionality, you must define _WIN32_WINNT (>=0x0400) in the project setting page." )
55 #elif _WIN32_WINNT < 0x0400
56 #define __THREAD_POOL_SUPPORT__ 0
57 #pragma message( "To use mist thread pool functionality, _WIN32_WINNT must be greater than 0x0400." )
59 #define __THREAD_POOL_SUPPORT__ 1
65 #pragma comment ( lib, "winmm.lib" )
72 #define __THREAD_POOL_SUPPORT__ 1
76 #define INFINITE ( ( unsigned long ) -1 )
91 typedef unsigned long ThreadExitCode;
92 typedef ThreadExitCode ( LPTHREADFUNC ) (
void *thread_param );
96 struct thread_dmy_class{ };
101 virtual bool create( ) = 0;
102 virtual bool wait(
unsigned long dwMilliseconds = INFINITE ) = 0;
103 virtual bool close( ) = 0;
104 virtual ~thread_object( ){ }
126 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
129 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
131 GetSystemInfo( &sysInfo );
132 return( static_cast< size_t >( sysInfo.dwNumberOfProcessors ) );
134 return( static_cast< size_t >( sysconf( _SC_NPROCESSORS_ONLN ) ) );
140 inline void sleep(
size_t dwMilliseconds )
142 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
143 SleepEx( static_cast< DWORD >( dwMilliseconds ),
false );
146 treq.tv_sec =
static_cast< time_t
>( dwMilliseconds / 1000 );
147 treq.tv_nsec =
static_cast< long >( ( dwMilliseconds % 1000 ) * 1000000 );
149 while( nanosleep( &treq, &trem ) != 0 )
191 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
192 typedef char lock_object_type;
193 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
194 typedef CRITICAL_SECTION lock_object_type;
196 typedef pthread_mutex_t lock_object_type;
205 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
207 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
209 InitializeCriticalSection( &__lock__ );
211 pthread_mutex_init( &__lock__, NULL );
218 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
220 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
221 DeleteCriticalSection( &__lock__ );
223 pthread_mutex_destroy( &__lock__ );
227 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
230 bool lock( ){
return(
true ); }
231 bool unlock( ){
return(
true ); }
232 bool try_lock( ){
return(
true ); }
243 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
244 EnterCriticalSection( &__lock__ );
246 pthread_mutex_lock( &__lock__ );
252 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
263 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
264 return( TryEnterCriticalSection( &__lock__ ) != FALSE );
266 return( pthread_mutex_trylock( &__lock__ ) == 0 );
274 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
275 LeaveCriticalSection( &__lock__ );
277 pthread_mutex_unlock( &__lock__ );
289 template <
class MUTEX >
290 class lock_object_table :
public ::std::map< ::std::string, MUTEX >
293 typedef ::std::map< ::std::string, MUTEX > base;
294 typedef MUTEX lock_object_type;
301 ~lock_object_table( )
303 typename base::iterator ite = base::begin( );
304 for( ; ite != base::end( ) ; ++ite )
306 destroy( ite->second );
312 static void destroy( lock_object_type &l )
314 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
316 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
317 DeleteCriticalSection( &l );
319 pthread_mutex_destroy( &l );
365 ::std::string lock_name_;
367 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
368 typedef char lock_object_type;
369 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
370 typedef CRITICAL_SECTION lock_object_type;
372 typedef pthread_mutex_t lock_object_type;
375 typedef lock_object_table< lock_object_type > lock_table;
378 lock_object( ) : lock_name_(
"mist default lock object!!" ){ }
379 lock_object(
const std::string &name ) : lock_name_( name ){ }
381 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
384 bool lock( ){
return(
true ); }
385 bool unlock( ){
return(
true ); }
396 static lock_object_type &__double_lock__ = double_lock_object( );
399 lock( __double_lock__ );
402 lock_table::iterator ite = table.find( lock_name_ );
403 if( ite == table.end( ) )
406 ::std::pair< lock_table::iterator, bool > p = table.insert( lock_table::value_type( lock_name_, lock_object_type( ) ) );
409 lock_object_type &obj = p.first->second;
413 unlock( __double_lock__ );
420 unlock( __double_lock__ );
429 unlock( __double_lock__ );
438 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
448 static lock_object_type &__double_lock__ = double_lock_object( );
451 lock( __double_lock__ );
454 lock_table::iterator ite = table.find( lock_name_ );
455 if( ite == table.end( ) )
458 ::std::pair< lock_table::iterator, bool > p = table.insert( lock_table::value_type( lock_name_, lock_object_type( ) ) );
461 lock_object_type &obj = p.first->second;
465 unlock( __double_lock__ );
467 return( try_lock( obj ) );
472 unlock( __double_lock__ );
481 unlock( __double_lock__ );
484 return( try_lock( ite->second ) );
493 lock_table::iterator ite = table.find( lock_name_ );
494 if( ite == table.end( ) )
501 unlock( ite->second );
511 static lock_object_type &double_lock_object( )
513 static bool isFirst =
true;
514 static lock_object_type __double_lock__;
518 initialize( __double_lock__ );
520 return( __double_lock__ );
527 static void initialize( lock_object_type &l )
529 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
531 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
532 InitializeCriticalSection( &l );
534 pthread_mutex_init( &l, NULL );
543 static void lock( lock_object_type &l )
545 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
547 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
548 EnterCriticalSection( &l );
550 pthread_mutex_lock( &l );
554 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
564 static bool try_lock( lock_object_type &l )
567 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
570 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
571 return( TryEnterCriticalSection( &l ) != FALSE );
573 return( pthread_mutex_trylock( &l ) == 0 );
582 static void unlock( lock_object_type &l )
584 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
586 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
587 LeaveCriticalSection( &l );
589 pthread_mutex_unlock( &l );
620 lock_object_.lock( );
625 lock(
const std::string &name ) : lock_object_( name )
627 lock_object_.lock( );
634 lock_object_.unlock( );
639 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
648 signal( ) : handle_( CreateEvent( NULL, FALSE, FALSE, NULL ) )
655 CloseHandle( handle_ );
659 bool wait(
unsigned long dwMilliseconds = INFINITE )
661 DWORD ret = WaitForSingleObject( handle_, dwMilliseconds );
662 if( SUCCEEDED( ret ) )
664 ResetEvent( handle_ );
682 ResetEvent( handle_ );
689 pthread_cond_t cond_;
690 pthread_mutex_t mutex_;
695 signal( ) : flag_( false )
697 pthread_mutex_init( &mutex_, NULL );
698 pthread_cond_init( &cond_, NULL );
699 pthread_mutex_lock ( &mutex_ );
705 pthread_cond_destroy( &cond_ );
706 pthread_mutex_destroy( &mutex_ );
710 bool wait(
unsigned long dwMilliseconds = INFINITE )
712 if( dwMilliseconds == INFINITE )
716 if( pthread_cond_wait( &cond_, &mutex_ ) == 0 )
727 gettimeofday( &now, NULL );
730 tm.tv_sec = now.tv_sec +
static_cast< time_t
>( dwMilliseconds / 1000 );
731 tm.tv_nsec = now.tv_usec * 1000 +
static_cast< long >( ( dwMilliseconds % 1000 ) * 1000000 );
733 tm.tv_sec += tm.tv_nsec / 1000000000;
734 tm.tv_nsec = tm.tv_nsec % 1000000000;
738 if( pthread_cond_timedwait( &cond_, &mutex_, &tm ) == 0 )
757 pthread_cond_broadcast( &cond_ );
777 template <
class thread_parameter = thread_dmy_
class >
785 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
787 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
788 HANDLE thread_handle_;
789 unsigned int thread_id_;
791 pthread_t thread_id_;
815 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
817 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
818 thread_handle_ = t.thread_handle_;
819 thread_id_ = t.thread_id_;
821 thread_id_ = t.thread_id_;
824 thread_exit_code_ = t.thread_exit_code_;
838 bool operator ==(
const thread &t )
const
840 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
842 return(
this == &t );
843 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
844 return( thread_id_ == t.thread_id_ );
846 return( pthread_equal( thread_id_, t.thread_id_ ) != 0 );
850 bool operator !=(
const thread &t )
const
852 return( !( *
this == t ) );
856 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
858 thread(
const thread &t ) : thread_exit_code_( t.thread_exit_code_ ){ }
859 thread( ) : thread_exit_code_( 0 ){ }
860 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
861 thread(
const thread &t ) : thread_handle_( t.thread_handle_ ), thread_id_( t.thread_id_ ), thread_exit_code_( t.thread_exit_code_ ){ }
862 thread( ) : thread_handle_( NULL ), thread_id_( ( unsigned int )-1 ), thread_exit_code_( 0 ){ }
864 thread(
const thread &t ) : thread_id_( t.thread_id ), joined_( false ), thread_exit_code_( t.thread_exit_code ){ }
865 thread( ) : thread_id_( ( pthread_t ) ( -1 ) ), joined_( false ), thread_exit_code_( 0 ){ }
879 virtual bool create( )
881 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
884 thread_exit_code_ = thread_function( );
885 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
886 if( thread_handle_ != NULL )
return(
false );
887 thread_handle_ = ( HANDLE )_beginthreadex( NULL, 0, map_thread_function, (
void * )
this, 0, &thread_id_ );
888 bool ret = thread_handle_ != NULL ?
true :
false;
890 if( thread_id_ != ( pthread_t ) ( -1 ) )
return(
false );
891 bool ret = pthread_create( &( thread_id_ ), NULL, map_thread_function, (
void * )
this ) == 0 ?
true :
false;
904 virtual bool create_without_thread( )
906 thread_exit_code_ = thread_function( );
920 virtual bool wait(
unsigned long dwMilliseconds = INFINITE )
922 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
926 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
927 DWORD ret = WaitForSingleObject( thread_handle_, dwMilliseconds );
928 return ( ret == WAIT_OBJECT_0 );
930 if( dwMilliseconds == INFINITE )
932 if( pthread_join( thread_id_, NULL ) == 0 )
944 if( finish_.wait( dwMilliseconds ) )
946 if( pthread_join( thread_id_, NULL ) == 0 )
972 virtual bool close( )
974 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
977 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
978 if( thread_handle_ != NULL )
981 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
982 while( !exit_.try_lock( ) ){}
986 BOOL ret = CloseHandle( thread_handle_ );
987 thread_handle_ = NULL;
995 if( thread_id_ != ( pthread_t ) ( -1 ) )
998 while( !exit_.try_lock( ) ){}
1003 pthread_join( thread_id_, NULL );
1006 thread_id_ = ( pthread_t ) ( -1 );
1025 virtual thread_exit_type thread_function( ) = 0;
1028 #if !defined( _MIST_THREAD_SUPPORT_ ) || _MIST_THREAD_SUPPORT_ == 0
1030 #elif defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
1031 static unsigned int __stdcall map_thread_function(
void *p )
1040 static void *map_thread_function(
void *p )
1042 thread *obj =
static_cast< thread *
>( p );
1044 obj->thread_exit_code_ = obj->thread_function( );
1045 obj->exit_.unlock( );
1046 obj->finish_.send( );
1062 template <
class Thread >
1063 inline bool do_threads_( Thread *threads,
size_t num_threads,
unsigned long dwMilliseconds = INFINITE )
1069 for( i = 1 ; i < num_threads ; i++ )
1071 if( !threads[ i ].create( ) )
1076 if( num_threads > 0 )
1079 threads[ 0 ].create_without_thread( );
1083 for( i = 1 ; i < num_threads ; i++ )
1085 if( !threads[ i ].wait( dwMilliseconds ) )
1092 for( i = 1 ; i < num_threads ; i++ )
1094 if( !threads[ i ].close( ) )
1112 template <
class Thread >
1113 inline bool do_threads_( Thread **threads,
size_t num_threads,
unsigned long dwMilliseconds = INFINITE )
1119 for( i = 1 ; i < num_threads ; i++ )
1121 if( !threads[ i ]->create( ) )
1126 if( num_threads > 0 )
1129 threads[ 0 ]->create_without_thread( );
1133 for( i = 1 ; i < num_threads ; i++ )
1135 if( !threads[ i ]->wait( dwMilliseconds ) )
1142 for( i = 1 ; i < num_threads ; i++ )
1144 if( !threads[ i ]->close( ) )
1164 template <
class Thread >
1165 inline bool do_threads( Thread *threads,
size_t num_threads,
unsigned long dwMilliseconds = INFINITE )
1171 for( i = 0 ; i < num_threads ; i++ )
1173 if( !threads[ i ].create( ) )
1180 for( i = 0 ; i < num_threads ; i++ )
1182 if( !threads[ i ].wait( dwMilliseconds ) )
1189 for( i = 0 ; i < num_threads ; i++ )
1191 if( !threads[ i ].close( ) )
1205 namespace __thread_controller__
1207 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
1208 inline unsigned long _timeGetTime_( )
1210 return( timeGetTime( ) );
1213 inline unsigned long _timeGetTime_( )
1216 gettimeofday( &dmy, NULL );
1217 return( dmy.tv_sec );
1221 template <
class Param,
class Functor >
1222 class thread_object_functor :
public thread< thread_object_functor< Param, Functor > >
1225 typedef thread< thread_object_functor< Param, Functor > > base;
1226 typedef typename base::thread_exit_type thread_exit_type;
1233 thread_object_functor( Param &p, Functor f ) : param_( p ), func_( f ){ }
1234 virtual ~thread_object_functor( ){ }
1238 virtual thread_exit_type thread_function( )
1245 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
1246 struct __thread_pool_functor__
1248 typedef size_t size_type;
1249 typedef ptrdiff_t difference_type;
1251 virtual void run( size_type
id, size_type nthreads ) = 0;
1253 virtual ~__thread_pool_functor__( ){}
1256 template <
class Param,
class Functor >
1257 class thread_pool_functor_base :
public __thread_pool_functor__
1264 thread_pool_functor_base( Param p, Functor f ) : param_( p ), func_( f ){ }
1265 virtual ~thread_pool_functor_base( ){}
1269 virtual void run( size_type , size_type )
1275 template <
class Param1,
class Param2,
class Functor >
1276 class thread_pool_functor_base2 :
public __thread_pool_functor__
1284 thread_pool_functor_base2( Param1 p1, Param2 p2, Functor f ) : param1_( p1 ), param2_( p2 ), func_( f ){ }
1285 virtual ~thread_pool_functor_base2( ){ }
1289 virtual void run( size_type , size_type )
1291 func_( param1_, param2_ );
1295 template <
class Param1,
class Param2,
class Param3,
class Functor >
1296 class thread_pool_functor_base3 :
public __thread_pool_functor__
1305 thread_pool_functor_base3( Param1 p1, Param2 p2, Param3 p3, Functor f ) : param1_( p1 ), param2_( p2 ), param3_( p3 ), func_( f ){ }
1306 virtual ~thread_pool_functor_base3( ){ }
1310 virtual void run( size_type , size_type )
1312 func_( param1_, param2_, param3_ );
1316 template <
class Param1,
class Param2,
class Param3,
class Param4,
class Functor >
1317 class thread_pool_functor_base4 :
public __thread_pool_functor__
1327 thread_pool_functor_base4( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Functor f ) : param1_( p1 ), param2_( p2 ), param3_( p3 ), param4_( p4 ), func_( f ){ }
1328 virtual ~thread_pool_functor_base4( ){ }
1332 virtual void run( size_type , size_type )
1334 func_( param1_, param2_, param3_, param4_ );
1339 template <
class Functor >
1340 class thread_pool_void_functor_base :
public __thread_pool_functor__
1346 thread_pool_void_functor_base( Functor f ) : func_( f ){ }
1347 virtual ~thread_pool_void_functor_base( ){ }
1351 virtual void run( size_type , size_type )
1357 class thread_pool_functor :
public thread< thread_pool_functor >
1360 typedef thread< thread_pool_functor > base;
1361 typedef base::thread_exit_type thread_exit_type;
1362 typedef size_t size_type;
1363 typedef ptrdiff_t difference_type;
1366 std::list< __thread_pool_functor__ * > &functors_;
1367 simple_lock_object &lock_;
1368 simple_lock_object suspend_lock_;
1369 simple_lock_object wait_lock_;
1373 size_type nthreads_;
1377 thread_pool_functor( std::list< __thread_pool_functor__ * > &functors, simple_lock_object &l, size_type
id, size_type nthreads )
1378 : functors_( functors ), lock_( l ), is_running_( false ), is_end_( false ), id_( id ), nthreads_( nthreads )
1381 suspend_lock_.lock( );
1384 virtual ~thread_pool_functor( ){ }
1386 size_type num_jobs( )
const {
return( functors_.size( ) ); }
1387 bool is_end( )
const {
return( is_end_ ); }
1389 bool is_suspended( )
1391 if( wait_lock_.try_lock( ) )
1393 wait_lock_.unlock( );
1402 virtual bool create( )
1404 if( base::create( ) )
1429 virtual bool close( )
1438 while( !wait_lock_.try_lock( ) ){}
1439 wait_lock_.unlock( );
1441 return( base::close( ) );
1446 if( is_suspended( ) )
1448 suspend_lock_.unlock( );
1449 while( wait_lock_.try_lock( ) )
1451 wait_lock_.unlock( );
1453 suspend_lock_.lock( );
1457 bool wait(
unsigned long dwMilliseconds = INFINITE )
1460 if( !wait_lock_.try_lock( ) )
1463 return( signal_.wait( dwMilliseconds ) );
1467 wait_lock_.unlock( );
1475 virtual thread_exit_type thread_function( )
1491 else if( functors_.empty( ) )
1494 wait_lock_.unlock( );
1497 suspend_lock_.lock( );
1500 suspend_lock_.unlock( );
1505 __thread_pool_functor__ *f = functors_.front( );
1506 functors_.pop_front( );
1511 f->run( id_, nthreads_ );
1517 wait_lock_.unlock( );
1531 #if defined( __THREAD_POOL_SUPPORT__ ) && __THREAD_POOL_SUPPORT__ != 0
1570 typedef __thread_controller__::thread_pool_functor thread_pool_functor;
1571 typedef __thread_controller__::__thread_pool_functor__ __thread_pool_functor__;
1573 std::vector< thread_pool_functor * > threads_;
1574 std::list< __thread_pool_functor__ * > functors_;
1587 initialize( number_of_max_threads );
1607 if( number_of_max_threads == 0 )
1613 threads_.resize( number_of_max_threads );
1616 for(
size_type i = 0 ; i < threads_.size( ) ; i++ )
1618 threads_[ i ] =
new thread_pool_functor( functors_, lock_, i, threads_.size( ) );
1619 threads_[ i ]->create( );
1623 initialized_ =
true;
1632 bool uninitialize( )
1636 for(
size_type i = 0 ; i < threads_.size( ) ; i++ )
1639 threads_[ i ]->close( );
1642 delete threads_[ i ];
1649 while( !functors_.empty( ) )
1651 __thread_pool_functor__ *f = functors_.front( );
1652 functors_.pop_front( );
1658 initialized_ =
false;
1671 template <
class Functor,
class Param >
1672 bool execute( Functor f, Param p )
1674 if( threads_.empty( ) || !initialized_ )
1679 return( exec(
new __thread_controller__::thread_pool_functor_base< Param, Functor >( p, f ) ) );
1691 template <
class Functor,
class Param1,
class Param2 >
1692 bool execute( Functor f, Param1 p1, Param2 p2 )
1694 if( threads_.empty( ) || !initialized_ )
1699 return( exec(
new __thread_controller__::thread_pool_functor_base2< Param1, Param2, Functor >( p1, p2, f ) ) );
1712 template <
class Functor,
class Param1,
class Param2,
class Param3 >
1713 bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3 )
1715 if( threads_.empty( ) || !initialized_ )
1720 return( exec(
new __thread_controller__::thread_pool_functor_base3< Param1, Param2, Param3, Functor >( p1, p2, p3, f ) ) );
1734 template <
class Functor,
class Param1,
class Param2,
class Param3,
class Param4 >
1735 bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3, Param4 p4 )
1737 if( threads_.empty( ) || !initialized_ )
1742 return( exec(
new __thread_controller__::thread_pool_functor_base4< Param1, Param2, Param3, Param4, Functor >( p1, p2, p3, p4, f ) ) );
1751 template <
class Functor >
1752 bool execute( Functor f )
1754 if( threads_.empty( ) || !initialized_ )
1759 return( exec(
new __thread_controller__::thread_pool_void_functor_base< Functor >( f ) ) );
1771 template <
class Functor,
class Param >
1772 bool executes( Functor f, Param *param,
size_t num_threads )
1774 if( threads_.empty( ) || !initialized_ )
1781 for(
size_type i = 0 ; i < num_threads ; i++ )
1783 functors_.push_back(
new __thread_controller__::thread_pool_functor_base< Param, Functor >( param[ i ], f ) );
1787 resume_thread_from_queue( num_threads );
1802 template <
class Functor,
class Param1,
class Param2 >
1803 bool executes( Functor f, Param1 *param1, Param2 *param2,
size_t num_threads )
1805 if( threads_.empty( ) || !initialized_ )
1812 for(
size_type i = 0 ; i < num_threads ; i++ )
1814 functors_.push_back(
new __thread_controller__::thread_pool_functor_base2< Param1, Param2, Functor >( param1[ i ], param2[ i ], f ) );
1818 resume_thread_from_queue( num_threads );
1834 template <
class Functor,
class Param1,
class Param2,
class Param3 >
1835 bool executes( Functor f, Param1 *param1, Param2 *param2, Param3 *param3,
size_t num_threads )
1837 if( threads_.empty( ) || !initialized_ )
1844 for(
size_type i = 0 ; i < num_threads ; i++ )
1846 functors_.push_back(
new __thread_controller__::thread_pool_functor_base3< Param1, Param2, Param3, Functor >( param1[ i ], param2[ i ], param3[ i ], f ) );
1850 resume_thread_from_queue( num_threads );
1867 template <
class Functor,
class Param1,
class Param2,
class Param3,
class Param4 >
1868 bool executes( Functor f, Param1 *param1, Param2 *param2, Param3 *param3, Param4 *param4,
size_t num_threads )
1870 if( threads_.empty( ) || !initialized_ )
1877 for(
size_type i = 0 ; i < num_threads ; i++ )
1879 functors_.push_back(
new __thread_controller__::thread_pool_functor_base4< Param1, Param2, Param3, Param4, Functor >( param1[ i ], param2[ i ], param3[ i ], param4[ i ], f ) );
1883 resume_thread_from_queue( num_threads );
1898 virtual bool wait(
unsigned long dwMilliseconds = INFINITE )
1904 else if( threads_.empty( ) )
1909 unsigned long st = __thread_controller__::_timeGetTime_( );
1911 for( ; i < threads_.size( ) ; i++ )
1913 if( !threads_[ i ]->wait( dwMilliseconds ) )
1917 else if( dwMilliseconds != INFINITE )
1919 unsigned long ct = __thread_controller__::_timeGetTime_( );
1920 if( dwMilliseconds <= ct - st )
1926 dwMilliseconds -= ct - st;
1932 return( i == threads_.size( ) );
1940 bool exec( __thread_controller__::__thread_pool_functor__ *func )
1946 functors_.push_back( func );
1950 resume_thread_from_queue( 1 );
1962 for(
size_type i = 0 ; i < threads_.size( ) ; i++ )
1964 thread_pool_functor &t = *threads_[ i ];
1966 if( t.is_suspended( ) )
1974 if( count >= num_threads )
2016 __thread_controller__::thread_pool_functor *thread_;
2017 std::list< __thread_controller__::__thread_pool_functor__ * > functors_;
2024 thread_ =
new __thread_controller__::thread_pool_functor( functors_, lock_, 0, 1 );
2036 bool is_suspended( )
2038 if( thread_ == NULL )
2043 return( thread_->is_suspended( ) );
2052 if( thread_ == NULL )
2066 while( !functors_.empty( ) )
2068 __thread_controller__::__thread_pool_functor__ *f = functors_.front( );
2069 functors_.pop_front( );
2085 template <
class Functor,
class Param >
2086 bool execute( Functor f, Param p )
2088 if( thread_ == NULL )
2093 return( exec(
new __thread_controller__::thread_pool_functor_base< Param, Functor >( p, f ) ) );
2106 template <
class Functor,
class Param1,
class Param2 >
2107 bool execute( Functor f, Param1 p1, Param2 p2 )
2109 if( thread_ == NULL )
2114 return( exec(
new __thread_controller__::thread_pool_functor_base2< Param1, Param2, Functor >( p1, p2, f ) ) );
2127 template <
class Functor,
class Param1,
class Param2,
class Param3 >
2128 bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3 )
2130 if( thread_ == NULL )
2135 return( exec(
new __thread_controller__::thread_pool_functor_base3< Param1, Param2, Param3, Functor >( p1, p2, p3, f ) ) );
2149 template <
class Functor,
class Param1,
class Param2,
class Param3,
class Param4 >
2150 bool execute( Functor f, Param1 p1, Param2 p2, Param3 p3, Param4 p4 )
2152 if( thread_ == NULL )
2157 return( exec(
new __thread_controller__::thread_pool_functor_base4< Param1, Param2, Param3, Param4, Functor >( p1, p2, p3, p4, f ) ) );
2166 template <
class Functor >
2167 bool execute( Functor f )
2169 if( thread_ == NULL )
2174 return( exec(
new __thread_controller__::thread_pool_void_functor_base< Functor >( f ) ) );
2187 virtual bool wait(
unsigned long dwMilliseconds = INFINITE )
2189 if( thread_ == NULL )
2195 return( thread_->wait( dwMilliseconds ) );
2204 bool exec( __thread_controller__::__thread_pool_functor__ *func )
2210 functors_.push_back( func );
2227 thread_object *thread_;
2232 bool create( ){
return( thread_ == NULL ?
false : thread_->create( ) ); }
2239 bool wait(
unsigned long dwMilliseconds = INFINITE ){
return( thread_ == NULL ?
false : thread_->wait( dwMilliseconds ) ); }
2245 if( thread_ == NULL )
2249 bool b = thread_->close( );
2257 thread_handle( thread_object *t ) : thread_( t ){ }
2259 const thread_handle &operator =(
const thread_handle &t )
2263 thread_ = t.thread_;
2309 template <
class Param,
class Functor >
2312 thread_handle thread_(
new __thread_controller__::thread_object_functor< Param, Functor >( param, f ) );
2324 template <
class Param,
class Functor >
2327 for(
size_t i = 0 ; i < num_threads ; i++ )
2329 handles[ i ] =
thread_handle(
new __thread_controller__::thread_object_functor< Param, Functor >( param[ i ], f ) );
2357 for(
size_t i = 0 ; i < num_threads ; i++ )
2359 if( !handles[ i ].close( ) )
2391 if( dwMilliseconds == INFINITE )
2394 for(
size_t i = 0 ; i < num_threads ; i++ )
2396 if( !handles[ i ].wait( INFINITE ) )
2406 for(
size_t i = 0 ; i < num_threads ; i++ )
2408 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
2409 DWORD st = timeGetTime( );
2412 gettimeofday( &dmy, NULL );
2413 unsigned long st = dmy.tv_sec * 1000 + dmy.tv_usec / 1000;
2415 if( !handles[ i ].wait( dwMilliseconds ) )
2420 #if defined( __MIST_WINDOWS__ ) && __MIST_WINDOWS__ > 0
2421 DWORD et = timeGetTime( );
2423 gettimeofday( &dmy, NULL );
2424 unsigned long et = dmy.tv_sec * 1000 + dmy.tv_usec / 1000;
2427 if( st + dwMilliseconds <= et )
2433 dwMilliseconds -= et - st;
2450 template <
class Param,
class Functor >
2451 inline bool do_thread( Param ¶m, Functor f,
unsigned long dwMilliseconds = INFINITE )
2483 template <
class Param,
class Functor >
2484 inline bool do_threads( Param *params,
size_t num_threads, Functor f,
unsigned long dwMilliseconds = INFINITE )
2493 if( !
wait_threads( threads_, num_threads, dwMilliseconds ) )
2518 #endif // __INCLUDE_MIST_THREAD__