2 Copyright (C) 1999-2007 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
22 #include "globaldefs.h"
25 // The below define is necessary to use
26 // pthreads extensions like pthread_mutexattr_settype
34 #include "her2_threads.h"
36 #define MAX_THREADS 64
51 int GetThreadWork( void ){
57 if ( dispatch == workcount ) {
62 f = 10 * dispatch / workcount;
66 Sys_Printf( "%i...", f );
67 fflush( stdout ); /* ydnar */
79 void ( *workfunction )( int );
81 void ThreadWorkerFunction( int threadnum ){
86 work = GetThreadWork();
90 //Sys_Printf ("thread %i, work %i\n", threadnum, work);
95 void RunThreadsOnIndividual( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
96 if ( numthreads == -1 ) {
100 RunThreadsOn( workcnt, showpacifier, ThreadWorkerFunction );
105 ===================================================================
109 ===================================================================
118 CRITICAL_SECTION crit;
121 void ThreadSetDefault( void ){
124 if ( numthreads == -1 ) { // not set manually
125 GetSystemInfo( &info );
126 numthreads = info.dwNumberOfProcessors;
127 if ( numthreads < 1 || numthreads > 32 ) {
132 Sys_Printf( "%i threads\n", numthreads );
136 void ThreadLock( void ){
140 EnterCriticalSection( &crit );
142 Error( "Recursive ThreadLock\n" );
147 void ThreadUnlock( void ){
152 Error( "ThreadUnlock without lock\n" );
155 LeaveCriticalSection( &crit );
163 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
164 int threadid[MAX_THREADS];
165 HANDLE threadhandle[MAX_THREADS];
169 start = I_FloatTime();
173 pacifier = showpacifier;
177 // run threads in parallel
179 InitializeCriticalSection( &crit );
181 if ( numthreads == 1 ) { // use same thread
186 for ( i = 0 ; i < numthreads ; i++ )
188 threadhandle[i] = CreateThread(
189 NULL, // LPSECURITY_ATTRIBUTES lpsa,
190 //0, // DWORD cbStack,
192 /* ydnar: cranking stack size to eliminate radiosity crash with 1MB stack on win32 */
195 (LPTHREAD_START_ROUTINE)func, // LPTHREAD_START_ROUTINE lpStartAddr,
196 (LPVOID)i, // LPVOID lpvThreadParm,
197 0, // DWORD fdwCreate,
201 for ( i = 0 ; i < numthreads ; i++ )
202 WaitForSingleObject( threadhandle[i], INFINITE );
204 DeleteCriticalSection( &crit );
209 Sys_Printf( " (%i)\n", end - start );
217 ===================================================================
221 ===================================================================
229 void ThreadSetDefault( void ){
230 if ( numthreads == -1 ) { // not set manually
238 pthread_mutex_t *my_mutex;
240 void ThreadLock( void ){
242 pthread_mutex_lock( my_mutex );
246 void ThreadUnlock( void ){
248 pthread_mutex_unlock( my_mutex );
258 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
260 pthread_t work_threads[MAX_THREADS];
261 pthread_addr_t status;
262 pthread_attr_t attrib;
263 pthread_mutexattr_t mattrib;
266 start = I_FloatTime();
270 pacifier = showpacifier;
274 setbuf( stdout, NULL );
278 my_mutex = safe_malloc( sizeof( *my_mutex ) );
279 if ( pthread_mutexattr_create( &mattrib ) == -1 ) {
280 Error( "pthread_mutex_attr_create failed" );
282 if ( pthread_mutexattr_setkind_np( &mattrib, MUTEX_FAST_NP ) == -1 ) {
283 Error( "pthread_mutexattr_setkind_np failed" );
285 if ( pthread_mutex_init( my_mutex, mattrib ) == -1 ) {
286 Error( "pthread_mutex_init failed" );
290 if ( pthread_attr_create( &attrib ) == -1 ) {
291 Error( "pthread_attr_create failed" );
293 if ( pthread_attr_setstacksize( &attrib, 0x100000 ) == -1 ) {
294 Error( "pthread_attr_setstacksize failed" );
297 for ( i = 0 ; i < numthreads ; i++ )
299 if ( pthread_create( &work_threads[i], attrib
300 , (pthread_startroutine_t)func, (pthread_addr_t)i ) == -1 ) {
301 Error( "pthread_create failed" );
305 for ( i = 0 ; i < numthreads ; i++ )
307 if ( pthread_join( work_threads[i], &status ) == -1 ) {
308 Error( "pthread_join failed" );
316 Sys_Printf( " (%i)\n", end - start );
324 ===================================================================
328 ===================================================================
335 #include <abi_mutex.h>
336 #include <sys/types.h>
337 #include <sys/prctl.h>
343 void ThreadSetDefault( void ){
344 if ( numthreads == -1 ) {
345 numthreads = prctl( PR_MAXPPROCS );
347 Sys_Printf( "%i threads\n", numthreads );
348 usconfig( CONF_INITUSERS, numthreads );
352 void ThreadLock( void ){
356 void ThreadUnlock( void ){
357 release_lock( &lck );
366 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
368 int pid[MAX_THREADS];
371 start = I_FloatTime();
375 pacifier = showpacifier;
379 setbuf( stdout, NULL );
384 for ( i = 0 ; i < numthreads - 1 ; i++ )
386 pid[i] = sprocsp( ( void ( * )( void *, size_t ) )func, PR_SALL, (void *)i
387 , NULL, 0x200000 ); // 2 meg stacks
388 if ( pid[i] == -1 ) {
390 Error( "sproc failed" );
396 for ( i = 0 ; i < numthreads - 1 ; i++ )
403 Sys_Printf( " (%i)\n", end - start );
412 =======================================================================
416 =======================================================================
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 __GLIBC_MINOR__ == 1
545 if ( pthread_mutexattr_settype( &mattrib, PTHREAD_MUTEX_FAST_NP ) != 0 )
547 if ( pthread_mutexattr_settype( &mattrib, PTHREAD_MUTEX_ADAPTIVE_NP ) != 0 )
549 { Error( "pthread_mutexattr_settype failed" ); }
550 recursive_mutex_init( mattrib );
552 for ( i = 0 ; i < numthreads ; i++ )
554 /* Default pthread attributes: joinable & non-realtime scheduling */
555 if ( pthread_create( &work_threads[i], NULL, (void*)func, (void*)i ) != 0 ) {
556 Error( "pthread_create failed" );
559 for ( i = 0 ; i < numthreads ; i++ )
561 if ( pthread_join( work_threads[i], (void **)&status ) != 0 ) {
562 Error( "pthread_join failed" );
565 pthread_mutexattr_destroy( &mattrib );
571 Sys_Printf( " (%i)\n", end - start );
574 #endif // ifdef __linux__
578 =======================================================================
582 =======================================================================
589 void ThreadSetDefault( void ){
593 void ThreadLock( void ){
596 void ThreadUnlock( void ){
604 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
611 pacifier = showpacifier;
612 start = I_FloatTime();
617 Sys_Printf( " (%i)\n", end - start );