Bug Summary

File:tools/ufo2map/threads.cpp
Location:line 153, column 3
Description:Function call argument is an uninitialized value

Annotated Source Code

1/**
2 * @file
3 */
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 "../../shared/mutex.h"
28#include "bsp.h"
29
30#define MAX_THREADS8 8
31
32threadstate_t threadstate;
33
34/**
35 * @brief Return an iteration of work, updating progress when appropriate.
36 */
37static int GetThreadWork (void)
38{
39 int r;
40 int f;
41
42 ThreadLock();
43
44 if (threadstate.workindex == threadstate.workcount) { /* done */
45 ThreadUnlock();
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__stdoutp, "%i...", f);
55 fflush(stdout__stdoutp);
56 }
57 } else if (threadstate.progress && threadstate.workindex % threadstate.worktick == 0) {
58 fprintf(stdout__stdoutp, "%c\b", "-\\|/"[(threadstate.workindex / threadstate.worktick) & 3]);
59 fflush(stdout__stdoutp);
60 }
61
62 /* assign the next work iteration */
63 r = threadstate.workindex;
64 threadstate.workindex++;
65
66 ThreadUnlock();
67
68 return r;
69}
70
71
72/** @brief Generic function pointer to actual work to be done */
73static void (*WorkFunction) (unsigned int);
74
75
76/**
77 * @brief Shared work entry point by all threads. Retrieve and perform
78 * chunks of work iteratively until work is finished.
79 */
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 threads_mutex_t *lock = NULL__null;
94
95static void ThreadInit (void)
96{
97 if (lock != NULL__null)
98 Sys_Error("Mutex already created!");
99
100 lock = TH_MutexCreate("ufo2map");
101}
102
103static void ThreadRelease (void)
104{
105 TH_MutexDestroy(lock);
106 lock = NULL__null;
107}
108
109/**
110 * @brief Lock the shared data by the calling thread.
111 */
112void ThreadLock (void)
113{
114 if (threadstate.numthreads == 1) {
115 /* do nothing */
116 } else if (lock != NULL__null && TH_MutexLock(lock)_TH_MutexLock((lock), "src/tools/ufo2map/threads.cpp", 116) != -1) {
117 /* already locked */
118 } else {
119 Sys_Error("Couldn't lock mutex (%p)!", (void*)lock);
120 }
121}
122
123/**
124 * @brief Release the lock on the shared data.
125 */
126void ThreadUnlock (void)
127{
128 if (threadstate.numthreads == 1) {
129 /* do nothing */
130 } else if (lock != NULL__null && TH_MutexUnlock(lock)_TH_MutexUnlock((lock), "src/tools/ufo2map/threads.cpp", 130) != -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_THREADS8];
140 int i;
141
142 if (threadstate.numthreads == 1) {
5
Taking false branch
143 ThreadWork(NULL__null);
144 return;
145 }
146
147 ThreadInit();
148
149 for (i = 0; i < threadstate.numthreads; i++)
6
Loop condition is true. Entering loop body
7
Loop condition is false. Execution continues on line 152
150 threads[i] = SDL_CreateThread(ThreadWork, NULL__null);
151
152 for (i = 0; i < threadstate.numthreads; i++)
8
Loop condition is true. Entering loop body
9
Loop condition is true. Entering loop body
153 SDL_WaitThread(threads[i], NULL__null);
10
Function call argument is an uninitialized value
154
155 ThreadRelease();
156}
157
158
159/**
160 * @brief Entry point for all thread work requests.
161 */
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 */
1
Taking false branch
167 threadstate.numthreads = 1;
168
169 if (threadstate.numthreads > MAX_THREADS8)
2
Taking false branch
170 threadstate.numthreads = MAX_THREADS8;
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(NULL__null);
181
182 if (threadstate.progress) {
3
Taking false branch
183 fprintf(stdout__stdoutp, "%10s: ", id);
184 fflush(stdout__stdoutp);
185 }
186
187 RunThreads();
4
Calling 'RunThreads'
188
189 end = time(NULL__null);
190
191 if (threadstate.progress) {
192 Verb_Printf(VERB_NORMAL, " (time: %6is, #: %i)\n", end - start, workcount);
193 }
194}
195
196/**
197 * @brief Entry point for all thread work requests.
198 */
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}