/*** * * Copyright (c) 1998, Valve LLC. All rights reserved. * * This product contains software technology licensed from Id * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * ****/ #include "cmdlib.h" #define NO_THREAD_NAMES #include "threads.h" #define MAX_THREADS 64 int dispatch; int workcount; int oldf; qboolean pacifier; qboolean threaded; /* ============= GetThreadWork ============= */ int GetThreadWork (void) { int r; int f; ThreadLock (); if (dispatch == workcount) { ThreadUnlock (); return -1; } f = 10*dispatch / workcount; if (f != oldf) { oldf = f; if (pacifier) printf ("%i...", f); } r = dispatch; dispatch++; ThreadUnlock (); return r; } void (*workfunction) (int); void ThreadWorkerFunction (int threadnum) { int work; while (1) { work = GetThreadWork (); if (work == -1) break; workfunction(work); } } void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int)) { workfunction = func; RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction); } /* =================================================================== WIN32 =================================================================== */ #ifdef WIN32 #define USED #include int numthreads = -1; CRITICAL_SECTION crit; static int enter; void ThreadSetDefault (void) { SYSTEM_INFO info; if (numthreads == -1) // not set manually { GetSystemInfo (&info); numthreads = info.dwNumberOfProcessors; if (numthreads < 1 || numthreads > 32) numthreads = 1; } qprintf ("%i threads\n", numthreads); } void ThreadLock (void) { if (!threaded) return; EnterCriticalSection (&crit); if (enter) Error ("Recursive ThreadLock\n"); enter = 1; } void ThreadUnlock (void) { if (!threaded) return; if (!enter) Error ("ThreadUnlock without lock\n"); enter = 0; LeaveCriticalSection (&crit); } /* ============= RunThreadsOn ============= */ void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int)) { int threadid[MAX_THREADS]; HANDLE threadhandle[MAX_THREADS]; int i; int start, end; start = I_FloatTime (); dispatch = 0; workcount = workcnt; oldf = -1; pacifier = showpacifier; threaded = true; // // run threads in parallel // InitializeCriticalSection (&crit); for (i=0 ; i pthread_mutex_t *my_mutex; void ThreadLock (void) { if (my_mutex) pthread_mutex_lock (my_mutex); } void ThreadUnlock (void) { if (my_mutex) pthread_mutex_unlock (my_mutex); } /* ============= RunThreadsOn ============= */ void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int)) { int i; pthread_t work_threads[MAX_THREADS]; pthread_addr_t status; pthread_attr_t attrib; pthread_mutexattr_t mattrib; int start, end; start = I_FloatTime (); dispatch = 0; workcount = workcnt; oldf = -1; pacifier = showpacifier; threaded = true; if (pacifier) setbuf (stdout, NULL); if (!my_mutex) { my_mutex = malloc (sizeof(*my_mutex)); if (pthread_mutexattr_create (&mattrib) == -1) Error ("pthread_mutex_attr_create failed"); if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1) Error ("pthread_mutexattr_setkind_np failed"); if (pthread_mutex_init (my_mutex, mattrib) == -1) Error ("pthread_mutex_init failed"); } if (pthread_attr_create (&attrib) == -1) Error ("pthread_attr_create failed"); if (pthread_attr_setstacksize (&attrib, 0x100000) == -1) Error ("pthread_attr_setstacksize failed"); for (i=0 ; i