UFO: Alien Invasion
Loading...
Searching...
No Matches
threads.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright(c) 1997-2001 Id Software, Inc.
7Copyright(c) 2002 The Quakeforge Project.
8Copyright(c) 2006 Quake2World.
9
10This program is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12as published by the Free Software Foundation; either version 2
13of the License, or(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
19See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25*/
26
27#include "bsp.h"
28#include "../../shared/thread.h"
29
30#define MAX_THREADS 8
31
33
37static int GetThreadWork (void)
38{
39 int r;
40 int f;
41
42 ThreadLock();
43
44 if (threadstate.workindex == threadstate.workcount) { /* done */
46 return -1;
47 }
48
49 /* update work fraction and output progress if desired */
50 f = 10 * threadstate.workindex / threadstate.workcount;
51 if (f != threadstate.workfrac) {
52 threadstate.workfrac = f;
53 if (threadstate.progress) {
54 fprintf(stdout, "%i...", f);
55 fflush(stdout);
56 }
57 } else if (threadstate.progress && threadstate.workindex % threadstate.worktick == 0) {
58 fprintf(stdout, "%c\b", "-\\|/"[(threadstate.workindex / threadstate.worktick) & 3]);
59 fflush(stdout);
60 }
61
62 /* assign the next work iteration */
63 r = threadstate.workindex;
64 threadstate.workindex++;
65
67
68 return r;
69}
70
71
73static void (*WorkFunction) (unsigned int);
74
75
80static int ThreadWork (void* p)
81{
82 while (true) {
83 int work = GetThreadWork();
84 if (work == -1)
85 break;
86 WorkFunction(work);
87 }
88
89 return 0;
90}
91
92
93static SDL_mutex *lock = nullptr;
94
95static void ThreadInit (void)
96{
97 if (lock != nullptr)
98 Sys_Error("Mutex already created!");
99
100 lock = SDL_CreateMutex();
101}
102
103static void ThreadRelease (void)
104{
105 SDL_DestroyMutex(lock);
106 lock = nullptr;
107}
108
112void ThreadLock (void)
113{
114 if (threadstate.numthreads == 1) {
115 /* do nothing */
116 } else if (lock != nullptr && SDL_LockMutex(lock) != -1) {
117 /* already locked */
118 } else {
119 Sys_Error("Couldn't lock mutex (%p)!", (void*)lock);
120 }
121}
122
126void ThreadUnlock (void)
127{
128 if (threadstate.numthreads == 1) {
129 /* do nothing */
130 } else if (lock != nullptr && SDL_UnlockMutex(lock) != -1) {
131 /* already locked */
132 } else {
133 Sys_Error("Couldn't unlock mutex (%p)!", (void*)lock);
134 }
135}
136
137static void RunThreads (void)
138{
139 SDL_Thread *threads[MAX_THREADS];
140 int i;
141
142 if (threadstate.numthreads == 1) {
143 ThreadWork(nullptr);
144 return;
145 }
146
147 ThreadInit();
148
149 for (i = 0; i < threadstate.numthreads; i++)
150 threads[i] = Com_CreateThread(ThreadWork, "CompileWorker");
151
152 for (i = 0; i < threadstate.numthreads; i++)
153 SDL_WaitThread(threads[i], nullptr);
154
156}
157
158
162void RunThreadsOn (void (*func)(unsigned int), int unsigned workcount, bool progress, const char* id)
163{
164 int start, end;
165
166 if (threadstate.numthreads < 1) /* ensure safe thread counts */
167 threadstate.numthreads = 1;
168
169 if (threadstate.numthreads > MAX_THREADS)
170 threadstate.numthreads = MAX_THREADS;
171
172 threadstate.workindex = 0;
173 threadstate.workcount = workcount;
174 threadstate.workfrac = -1;
175 threadstate.progress = progress;
176 threadstate.worktick = sqrt(workcount) + 1;
177
178 WorkFunction = func;
179
180 start = time(nullptr);
181
182 if (threadstate.progress) {
183 fprintf(stdout, "%10s: ", id);
184 fflush(stdout);
185 }
186
187 RunThreads();
188
189 end = time(nullptr);
190
191 if (threadstate.progress) {
192 Verb_Printf(VERB_NORMAL, " (time: %6is, #: %i)\n", end - start, workcount);
193 }
194}
195
199void RunSingleThreadOn (void (*func)(unsigned int), int unsigned workcount, bool progress, const char* id)
200{
201 int saved_numthreads = threadstate.numthreads;
202
203 threadstate.numthreads = 1;
204
205 RunThreadsOn(func, workcount, progress, id);
206
207 threadstate.numthreads = saved_numthreads;
208}
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
QGL_EXTERN void(APIENTRY *qglActiveTexture)(GLenum texture)
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLint i
Definition r_gl.h:113
SDL_Thread * Com_CreateThread(int(*fn)(void *), const char *name, void *data=nullptr)
Definition thread.h:5
void ThreadUnlock(void)
Release the lock on the shared data.
Definition threads.cpp:126
static int ThreadWork(void *p)
Shared work entry point by all threads. Retrieve and perform chunks of work iteratively until work is...
Definition threads.cpp:80
static void(* WorkFunction)(unsigned int)
Generic function pointer to actual work to be done.
Definition threads.cpp:73
static void ThreadRelease(void)
Definition threads.cpp:103
void RunThreadsOn(void(*func)(unsigned int), int unsigned workcount, bool progress, const char *id)
Entry point for all thread work requests.
Definition threads.cpp:162
#define MAX_THREADS
Definition threads.cpp:30
void RunSingleThreadOn(void(*func)(unsigned int), int unsigned workcount, bool progress, const char *id)
Entry point for all thread work requests.
Definition threads.cpp:199
static int GetThreadWork(void)
Return an iteration of work, updating progress when appropriate.
Definition threads.cpp:37
static void ThreadInit(void)
Definition threads.cpp:95
static void RunThreads(void)
Definition threads.cpp:137
void ThreadLock(void)
Lock the shared data by the calling thread.
Definition threads.cpp:112
static SDL_mutex * lock
Definition threads.cpp:93
void Verb_Printf(const verbosityLevel_t importance, const char *format,...) __attribute__((format(__printf__
@ VERB_NORMAL
Definition shared.h:45
threadstate_t threadstate
Definition threads.cpp:32