threads.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <SDL_thread.h>
00024
00025 #include "bsp.h"
00026
00027 #define MAX_THREADS 8
00028
00029 threadstate_t threadstate;
00030
00034 static int GetThreadWork (void)
00035 {
00036 int r;
00037 int f;
00038
00039 ThreadLock();
00040
00041 if (threadstate.workindex == threadstate.workcount) {
00042 ThreadUnlock();
00043 return -1;
00044 }
00045
00046
00047 f = 10 * threadstate.workindex / threadstate.workcount;
00048 if (f != threadstate.workfrac) {
00049 threadstate.workfrac = f;
00050 if (threadstate.progress) {
00051 fprintf(stdout, "%i...", f);
00052 fflush(stdout);
00053 }
00054 } else if (threadstate.progress && threadstate.workindex % threadstate.worktick == 0) {
00055 fprintf(stdout, "%c\b", "-\\|/"[(threadstate.workindex / threadstate.worktick) & 3]);
00056 fflush(stdout);
00057 }
00058
00059
00060 r = threadstate.workindex;
00061 threadstate.workindex++;
00062
00063 ThreadUnlock();
00064
00065 return r;
00066 }
00067
00068
00070 static void (*WorkFunction) (unsigned int);
00071
00072
00077 static int ThreadWork (void *p)
00078 {
00079 while (qtrue) {
00080 int work = GetThreadWork();
00081 if (work == -1)
00082 break;
00083 WorkFunction(work);
00084 }
00085
00086 return 0;
00087 }
00088
00089
00090 static SDL_mutex *lock = NULL;
00091
00092 static void ThreadInit (void)
00093 {
00094 if (lock != NULL)
00095 Sys_Error("Mutex already created!");
00096
00097 lock = SDL_CreateMutex();
00098
00099 if (lock == NULL)
00100 Sys_Error("Couldn't create mutex!");
00101 }
00102
00103 static void ThreadRelease (void)
00104 {
00105 SDL_DestroyMutex(lock);
00106 lock = NULL;
00107 }
00108
00112 void ThreadLock (void)
00113 {
00114 if (threadstate.numthreads == 1) {
00115
00116 } else if (lock != NULL && SDL_mutexP(lock) != -1) {
00117
00118 } else {
00119 Sys_Error("Couldn't lock mutex (%p)!", lock);
00120 }
00121 }
00122
00126 void ThreadUnlock (void)
00127 {
00128 if (threadstate.numthreads == 1) {
00129
00130 } else if (lock != NULL && SDL_mutexV(lock) != -1) {
00131
00132 } else {
00133 Sys_Error("Couldn't unlock mutex (%p)!", lock);
00134 }
00135 }
00136
00137 static void RunThreads (void)
00138 {
00139 SDL_Thread *threads[MAX_THREADS];
00140 int i;
00141
00142 if (threadstate.numthreads == 1) {
00143 ThreadWork(0);
00144 return;
00145 }
00146
00147 ThreadInit();
00148
00149 for (i = 0; i < threadstate.numthreads; i++)
00150 threads[i] = SDL_CreateThread(ThreadWork, NULL);
00151
00152 for (i = 0; i < threadstate.numthreads; i++)
00153 SDL_WaitThread(threads[i], NULL);
00154
00155 ThreadRelease();
00156 }
00157
00158
00162 void RunThreadsOn (void (*func)(unsigned int), int unsigned workcount, qboolean progress, const char *id)
00163 {
00164 int start, end;
00165
00166 if (threadstate.numthreads < 1)
00167 threadstate.numthreads = 1;
00168
00169 if (threadstate.numthreads > MAX_THREADS)
00170 threadstate.numthreads = MAX_THREADS;
00171
00172 threadstate.workindex = 0;
00173 threadstate.workcount = workcount;
00174 threadstate.workfrac = -1;
00175 threadstate.progress = progress;
00176 threadstate.worktick = sqrt(workcount) + 1;
00177
00178 WorkFunction = func;
00179
00180 start = time(NULL);
00181
00182 if (threadstate.progress) {
00183 fprintf(stdout, "%10s: ", id);
00184 fflush(stdout);
00185 }
00186
00187 RunThreads();
00188
00189 end = time(NULL);
00190
00191 if (threadstate.progress) {
00192 Verb_Printf(VERB_NORMAL, " (time: %6is, #: %i)\n", end - start, workcount);
00193 }
00194 }
00195
00199 void RunSingleThreadOn (void (*func)(unsigned int), int unsigned workcount, qboolean progress, const char *id)
00200 {
00201 int saved_numthreads = threadstate.numthreads;
00202
00203 threadstate.numthreads = 1;
00204
00205 RunThreadsOn(func, workcount, progress, id);
00206
00207 threadstate.numthreads = saved_numthreads;
00208 }