2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 // The below define is necessary to use
24 // pthreads extensions like pthread_mutexattr_settype
32 #include "q2_threads.h"
34 #define MAX_THREADS 64
49 int GetThreadWork( void ){
55 if ( dispatch == workcount ) {
60 f = 10 * dispatch / workcount;
64 Sys_Printf( "%i...", f );
65 fflush( stdout ); /* ydnar */
77 void ( *workfunction )( int );
79 void ThreadWorkerFunction( int threadnum ){
84 work = GetThreadWork();
88 //Sys_FPrintf( SYS_VRB,"thread %i, work %i\n", threadnum, work);
93 void RunThreadsOnIndividual( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
94 if ( numthreads == -1 ) {
98 RunThreadsOn( workcnt, showpacifier, ThreadWorkerFunction );
103 ===================================================================
107 ===================================================================
115 // Setting default Threads to 1
117 CRITICAL_SECTION crit;
120 void ThreadSetDefault( void ){
123 if ( numthreads == -1 ) { // not set manually
124 GetSystemInfo( &info );
125 numthreads = info.dwNumberOfProcessors;
126 if ( numthreads < 1 || numthreads > 32 ) {
131 Sys_Printf( "%i threads\n", numthreads );
135 void ThreadLock( void ){
139 EnterCriticalSection( &crit );
141 Error( "Recursive ThreadLock\n" );
146 void ThreadUnlock( void ){
151 Error( "ThreadUnlock without lock\n" );
154 LeaveCriticalSection( &crit );
162 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
163 int threadid[MAX_THREADS];
164 HANDLE threadhandle[MAX_THREADS];
168 start = I_FloatTime();
172 pacifier = showpacifier;
176 // run threads in parallel
178 InitializeCriticalSection( &crit );
180 if ( numthreads == 1 ) { // use same thread
185 for ( i = 0 ; i < numthreads ; i++ )
187 threadhandle[i] = CreateThread(
188 NULL, // LPSECURITY_ATTRIBUTES lpsa,
189 //0, // DWORD cbStack,
191 /* ydnar: cranking stack size to eliminate radiosity crash with 1MB stack on win32 */
194 (LPTHREAD_START_ROUTINE)func, // LPTHREAD_START_ROUTINE lpStartAddr,
195 (LPVOID)i, // LPVOID lpvThreadParm,
196 0, // DWORD fdwCreate,
200 for ( i = 0 ; i < numthreads ; i++ )
201 WaitForSingleObject( threadhandle[i], INFINITE );
203 DeleteCriticalSection( &crit );
208 Sys_Printf( " (%i)\n", end - start );
216 ===================================================================
220 ===================================================================
228 void ThreadSetDefault( void ){
229 if ( numthreads == -1 ) { // not set manually
237 pthread_mutex_t *my_mutex;
239 void ThreadLock( void ){
241 pthread_mutex_lock( my_mutex );
245 void ThreadUnlock( void ){
247 pthread_mutex_unlock( my_mutex );
257 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
259 pthread_t work_threads[MAX_THREADS];
260 pthread_addr_t status;
261 pthread_attr_t attrib;
262 pthread_mutexattr_t mattrib;
265 start = I_FloatTime();
269 pacifier = showpacifier;
273 setbuf( stdout, NULL );
277 my_mutex = safe_malloc( sizeof( *my_mutex ) );
278 if ( pthread_mutexattr_create( &mattrib ) == -1 ) {
279 Error( "pthread_mutex_attr_create failed" );
281 if ( pthread_mutexattr_setkind_np( &mattrib, MUTEX_FAST_NP ) == -1 ) {
282 Error( "pthread_mutexattr_setkind_np failed" );
284 if ( pthread_mutex_init( my_mutex, mattrib ) == -1 ) {
285 Error( "pthread_mutex_init failed" );
289 if ( pthread_attr_create( &attrib ) == -1 ) {
290 Error( "pthread_attr_create failed" );
292 if ( pthread_attr_setstacksize( &attrib, 0x100000 ) == -1 ) {
293 Error( "pthread_attr_setstacksize failed" );
296 for ( i = 0 ; i < numthreads ; i++ )
298 if ( pthread_create( &work_threads[i], attrib
299 , (pthread_startroutine_t)func, (pthread_addr_t)i ) == -1 ) {
300 Error( "pthread_create failed" );
304 for ( i = 0 ; i < numthreads ; i++ )
306 if ( pthread_join( work_threads[i], &status ) == -1 ) {
307 Error( "pthread_join failed" );
315 Sys_Printf( " (%i)\n", end - start );
323 ===================================================================
327 ===================================================================
334 #include <abi_mutex.h>
335 #include <sys/types.h>
336 #include <sys/prctl.h>
342 void ThreadSetDefault( void ){
343 if ( numthreads == -1 ) {
344 numthreads = prctl( PR_MAXPPROCS );
346 Sys_Printf( "%i threads\n", numthreads );
347 usconfig( CONF_INITUSERS, numthreads );
351 void ThreadLock( void ){
355 void ThreadUnlock( void ){
356 release_lock( &lck );
365 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
367 int pid[MAX_THREADS];
370 start = I_FloatTime();
374 pacifier = showpacifier;
378 setbuf( stdout, NULL );
383 for ( i = 0 ; i < numthreads - 1 ; i++ )
385 pid[i] = sprocsp( ( void ( * )( void *, size_t ) )func, PR_SALL, (void *)i
386 , NULL, 0x200000 ); // 2 meg stacks
387 if ( pid[i] == -1 ) {
389 Error( "sproc failed" );
395 for ( i = 0 ; i < numthreads - 1 ; i++ )
402 Sys_Printf( " (%i)\n", end - start );
411 =======================================================================
415 =======================================================================
418 #if defined( __linux__ ) || defined( __APPLE__ )
421 // Setting default Threads to 1
424 void ThreadSetDefault( void ){
425 if ( numthreads == -1 ) { // not set manually
426 /* default to one thread, only multi-thread when specifically told to */
429 if ( numthreads > 1 ) {
430 Sys_Printf( "threads: %d\n", numthreads );
436 typedef struct pt_mutex_s
439 pthread_mutex_t a_mutex;
444 pt_mutex_t global_lock;
446 void ThreadLock( void ){
447 pt_mutex_t *pt_mutex = &global_lock;
453 pthread_mutex_lock( &pt_mutex->a_mutex );
454 if ( pthread_equal( pthread_self(), (pthread_t)&pt_mutex->owner ) ) {
459 if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
460 pt_mutex->owner = (pthread_t *)pthread_self();
467 pthread_cond_wait( &pt_mutex->cond, &pt_mutex->a_mutex );
468 if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
469 pt_mutex->owner = (pthread_t *)pthread_self();
476 pthread_mutex_unlock( &pt_mutex->a_mutex );
479 void ThreadUnlock( void ){
480 pt_mutex_t *pt_mutex = &global_lock;
486 pthread_mutex_lock( &pt_mutex->a_mutex );
489 if ( pt_mutex->lock == 0 ) {
490 pt_mutex->owner = NULL;
491 pthread_cond_signal( &pt_mutex->cond );
494 pthread_mutex_unlock( &pt_mutex->a_mutex );
497 void recursive_mutex_init( pthread_mutexattr_t attribs ){
498 pt_mutex_t *pt_mutex = &global_lock;
500 pt_mutex->owner = NULL;
501 if ( pthread_mutex_init( &pt_mutex->a_mutex, &attribs ) != 0 ) {
502 Error( "pthread_mutex_init failed\n" );
504 if ( pthread_cond_init( &pt_mutex->cond, NULL ) != 0 ) {
505 Error( "pthread_cond_init failed\n" );
516 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
517 pthread_mutexattr_t mattrib;
518 pthread_t work_threads[MAX_THREADS];
521 int i = 0, status = 0;
523 start = I_FloatTime();
524 pacifier = showpacifier;
530 if ( numthreads == 1 ) {
538 setbuf( stdout, NULL );
541 if ( pthread_mutexattr_init( &mattrib ) != 0 ) {
542 Error( "pthread_mutexattr_init failed" );
544 if ( pthread_mutexattr_settype( &mattrib, PTHREAD_MUTEX_ERRORCHECK ) != 0 ) {
545 Error( "pthread_mutexattr_settype failed" );
547 recursive_mutex_init( mattrib );
549 for ( i = 0 ; i < numthreads ; i++ )
551 /* Default pthread attributes: joinable & non-realtime scheduling */
552 if ( pthread_create( &work_threads[i], NULL, (void*)func, (void*)i ) != 0 ) {
553 Error( "pthread_create failed" );
556 for ( i = 0 ; i < numthreads ; i++ )
558 if ( pthread_join( work_threads[i], (void **)&status ) != 0 ) {
559 Error( "pthread_join failed" );
562 pthread_mutexattr_destroy( &mattrib );
568 Sys_Printf( " (%i)\n", end - start );
571 #endif // ifdef __linux__
575 =======================================================================
579 =======================================================================
586 void ThreadSetDefault( void ){
590 void ThreadLock( void ){
593 void ThreadUnlock( void ){
601 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
608 pacifier = showpacifier;
609 start = I_FloatTime();
614 Sys_Printf( " (%i)\n", end - start );