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
28 #endif // !GDEF_OS_WINDOWS
33 #include "her2_threads.h"
35 #define MAX_THREADS 64
50 int GetThreadWork( void ){
56 if ( dispatch == workcount ) {
61 f = 10 * dispatch / workcount;
65 Sys_Printf( "%i...", f );
66 fflush( stdout ); /* ydnar */
78 void ( *workfunction )( int );
80 void ThreadWorkerFunction( int threadnum ){
85 work = GetThreadWork();
89 //Sys_Printf ("thread %i, work %i\n", threadnum, work);
94 void RunThreadsOnIndividual( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
95 if ( numthreads == -1 ) {
99 RunThreadsOn( workcnt, showpacifier, ThreadWorkerFunction );
106 ===================================================================
110 ===================================================================
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 ===================================================================
225 void ThreadSetDefault( void ){
226 if ( numthreads == -1 ) { // not set manually
234 pthread_mutex_t *my_mutex;
236 void ThreadLock( void ){
238 pthread_mutex_lock( my_mutex );
242 void ThreadUnlock( void ){
244 pthread_mutex_unlock( my_mutex );
254 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
256 pthread_t work_threads[MAX_THREADS];
257 pthread_addr_t status;
258 pthread_attr_t attrib;
259 pthread_mutexattr_t mattrib;
262 start = I_FloatTime();
266 pacifier = showpacifier;
270 setbuf( stdout, NULL );
274 my_mutex = safe_malloc( sizeof( *my_mutex ) );
275 if ( pthread_mutexattr_create( &mattrib ) == -1 ) {
276 Error( "pthread_mutex_attr_create failed" );
278 if ( pthread_mutexattr_setkind_np( &mattrib, MUTEX_FAST_NP ) == -1 ) {
279 Error( "pthread_mutexattr_setkind_np failed" );
281 if ( pthread_mutex_init( my_mutex, mattrib ) == -1 ) {
282 Error( "pthread_mutex_init failed" );
286 if ( pthread_attr_create( &attrib ) == -1 ) {
287 Error( "pthread_attr_create failed" );
289 if ( pthread_attr_setstacksize( &attrib, 0x100000 ) == -1 ) {
290 Error( "pthread_attr_setstacksize failed" );
293 for ( i = 0 ; i < numthreads ; i++ )
295 if ( pthread_create( &work_threads[i], attrib
296 , (pthread_startroutine_t)func, (pthread_addr_t)i ) == -1 ) {
297 Error( "pthread_create failed" );
301 for ( i = 0 ; i < numthreads ; i++ )
303 if ( pthread_join( work_threads[i], &status ) == -1 ) {
304 Error( "pthread_join failed" );
312 Sys_Printf( " (%i)\n", end - start );
320 ===================================================================
324 ===================================================================
328 #include <abi_mutex.h>
329 #include <sys/types.h>
330 #include <sys/prctl.h>
335 void ThreadSetDefault( void ){
336 if ( numthreads == -1 ) {
337 numthreads = prctl( PR_MAXPPROCS );
339 Sys_Printf( "%i threads\n", numthreads );
340 usconfig( CONF_INITUSERS, numthreads );
344 void ThreadLock( void ){
348 void ThreadUnlock( void ){
349 release_lock( &lck );
358 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
360 int pid[MAX_THREADS];
363 start = I_FloatTime();
367 pacifier = showpacifier;
371 setbuf( stdout, NULL );
376 for ( i = 0 ; i < numthreads - 1 ; i++ )
378 pid[i] = sprocsp( ( void ( * )( void *, size_t ) )func, PR_SALL, (void *)i
379 , NULL, 0x200000 ); // 2 meg stacks
380 if ( pid[i] == -1 ) {
382 Error( "sproc failed" );
388 for ( i = 0 ; i < numthreads - 1 ; i++ )
395 Sys_Printf( " (%i)\n", end - start );
400 #elif GDEF_OS_LINUX || GDEF_OS_BSD || GDEF_OS_MACOS
403 =======================================================================
407 =======================================================================
410 // Setting default Threads to 1
413 void ThreadSetDefault( void ){
414 if ( numthreads == -1 ) { // not set manually
415 /* default to one thread, only multi-thread when specifically told to */
418 if ( numthreads > 1 ) {
419 Sys_Printf( "threads: %d\n", numthreads );
425 typedef struct pt_mutex_s
428 pthread_mutex_t a_mutex;
433 pt_mutex_t global_lock;
435 void ThreadLock( void ){
436 pt_mutex_t *pt_mutex = &global_lock;
442 pthread_mutex_lock( &pt_mutex->a_mutex );
443 if ( pthread_equal( pthread_self(), (pthread_t)&pt_mutex->owner ) ) {
448 if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
449 pt_mutex->owner = (pthread_t *)pthread_self();
456 pthread_cond_wait( &pt_mutex->cond, &pt_mutex->a_mutex );
457 if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
458 pt_mutex->owner = (pthread_t *)pthread_self();
465 pthread_mutex_unlock( &pt_mutex->a_mutex );
468 void ThreadUnlock( void ){
469 pt_mutex_t *pt_mutex = &global_lock;
475 pthread_mutex_lock( &pt_mutex->a_mutex );
478 if ( pt_mutex->lock == 0 ) {
479 pt_mutex->owner = NULL;
480 pthread_cond_signal( &pt_mutex->cond );
483 pthread_mutex_unlock( &pt_mutex->a_mutex );
486 void recursive_mutex_init( pthread_mutexattr_t attribs ){
487 pt_mutex_t *pt_mutex = &global_lock;
489 pt_mutex->owner = NULL;
490 if ( pthread_mutex_init( &pt_mutex->a_mutex, &attribs ) != 0 ) {
491 Error( "pthread_mutex_init failed\n" );
493 if ( pthread_cond_init( &pt_mutex->cond, NULL ) != 0 ) {
494 Error( "pthread_cond_init failed\n" );
505 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
506 pthread_mutexattr_t mattrib;
507 pthread_t work_threads[MAX_THREADS];
510 int i = 0, status = 0;
512 start = I_FloatTime();
513 pacifier = showpacifier;
519 if ( numthreads == 1 ) {
527 setbuf( stdout, NULL );
530 if ( pthread_mutexattr_init( &mattrib ) != 0 ) {
531 Error( "pthread_mutexattr_init failed" );
533 if ( pthread_mutexattr_settype( &mattrib, PTHREAD_MUTEX_ERRORCHECK ) != 0 ) {
534 Error( "pthread_mutexattr_settype failed" );
536 recursive_mutex_init( mattrib );
538 for ( i = 0 ; i < numthreads ; i++ )
540 /* Default pthread attributes: joinable & non-realtime scheduling */
541 if ( pthread_create( &work_threads[i], NULL, (void*)func, (void*)i ) != 0 ) {
542 Error( "pthread_create failed" );
545 for ( i = 0 ; i < numthreads ; i++ )
547 if ( pthread_join( work_threads[i], (void **)&status ) != 0 ) {
548 Error( "pthread_join failed" );
551 pthread_mutexattr_destroy( &mattrib );
557 Sys_Printf( " (%i)\n", end - start );
565 =======================================================================
569 =======================================================================
574 void ThreadSetDefault( void ){
578 void ThreadLock( void ){
581 void ThreadUnlock( void ){
589 void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
596 pacifier = showpacifier;
597 start = I_FloatTime();
602 Sys_Printf( " (%i)\n", end - start );