suricata
threads-debug.h
Go to the documentation of this file.
1/* Copyright (C) 2007-2013 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
23 *
24 * Threading functions defined as macros: debug variants
25 */
26
27#ifndef SURICATA_THREADS_DEBUG_H
28#define SURICATA_THREADS_DEBUG_H
29
30/* mutex */
31
32/** When dbg threads is defined, if a mutex fail to lock, it's
33 * initialized, logged, and does a second try; This is to prevent the system to freeze;
34 * It is for Mac OS X users;
35 * If you see a mutex, spinlock or condition not initialized, report it please!
36 */
37#define SCMutexLock_dbg(mut) ({ \
38 printf("%16s(%s:%d): (thread:%"PRIuMAX") locking mutex %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut); \
39 int retl = pthread_mutex_lock(mut); \
40 printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl); \
41 if (retl != 0) { \
42 switch (retl) { \
43 case EINVAL: \
44 printf("The value specified by attr is invalid\n"); \
45 retl = pthread_mutex_init(mut, NULL); \
46 if (retl != 0) \
47 exit(EXIT_FAILURE); \
48 retl = pthread_mutex_lock(mut); \
49 break; \
50 case EDEADLK: \
51 printf("A deadlock would occur if the thread blocked waiting for mutex\n"); \
52 break; \
53 } \
54 } \
55 retl; \
56})
57
58#define SCMutexTrylock_dbg(mut) ({ \
59 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking mutex %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut); \
60 int rett = pthread_mutex_trylock(mut); \
61 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, rett); \
62 if (rett != 0) { \
63 switch (rett) { \
64 case EINVAL: \
65 printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \
66 break; \
67 case EBUSY: \
68 printf("Mutex is already locked\n"); \
69 break; \
70 } \
71 } \
72 rett; \
73})
74
75#define SCMutexInit_dbg(mut, mutattr) ({ \
76 int ret; \
77 ret = pthread_mutex_init(mut, mutattr); \
78 if (ret != 0) { \
79 switch (ret) { \
80 case EINVAL: \
81 printf("The value specified by attr is invalid\n"); \
82 printf("%16s(%s:%d): (thread:%"PRIuMAX") mutex %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \
83 break; \
84 case EAGAIN: \
85 printf("The system temporarily lacks the resources to create another mutex\n"); \
86 printf("%16s(%s:%d): (thread:%"PRIuMAX") mutex %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \
87 break; \
88 case ENOMEM: \
89 printf("The process cannot allocate enough memory to create another mutex\n"); \
90 printf("%16s(%s:%d): (thread:%"PRIuMAX") mutex %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \
91 break; \
92 } \
93 } \
94 ret; \
95})
96
97#define SCMutexUnlock_dbg(mut) ({ \
98 printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocking mutex %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut); \
99 int retu = pthread_mutex_unlock(mut); \
100 printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retu); \
101 if (retu != 0) { \
102 switch (retu) { \
103 case EINVAL: \
104 printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \
105 break; \
106 case EPERM: \
107 printf("The current thread does not hold a lock on mutex\n"); \
108 break; \
109 } \
110 } \
111 retu; \
112})
113
114#define SCMutex pthread_mutex_t
115#define SCMutexAttr pthread_mutexattr_t
116#define SCMutexInit(mut, mutattrs) SCMutexInit_dbg(mut, mutattrs)
117#define SCMutexLock(mut) SCMutexLock_dbg(mut)
118#define SCMutexTrylock(mut) SCMutexTrylock_dbg(mut)
119#define SCMutexUnlock(mut) SCMutexUnlock_dbg(mut)
120#define SCMutexDestroy pthread_mutex_destroy
121#define SCMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
122
123/* conditions */
124
125#define SCCondWait_dbg(cond, mut) ({ \
126 int ret = pthread_cond_wait(cond, mut); \
127 switch (ret) { \
128 case EINVAL: \
129 printf("The value specified by attr is invalid (or a SCCondT not initialized!)\n"); \
130 printf("%16s(%s:%d): (thread:%"PRIuMAX") failed SCCondWait %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \
131 break; \
132 } \
133 ret; \
134})
135
136/* conditions */
137#define SCCondT pthread_cond_t
138#define SCCondInit pthread_cond_init
139#define SCCondSignal pthread_cond_signal
140#define SCCondDestroy pthread_cond_destroy
141#define SCCondWait SCCondWait_dbg
142
143/* spinlocks */
144
145#define SCSpinLock_dbg(spin) ({ \
146 printf("%16s(%s:%d): (thread:%"PRIuMAX") locking spin %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \
147 int ret = pthread_spin_lock(spin); \
148 printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocked spin %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \
149 switch (ret) { \
150 case EINVAL: \
151 printf("The value specified by attr is invalid\n"); \
152 break; \
153 case EDEADLK: \
154 printf("A deadlock would occur if the thread blocked waiting for spin\n"); \
155 break; \
156 } \
157 ret; \
158})
159
160#define SCSpinTrylock_dbg(spin) ({ \
161 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking spin %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \
162 int ret = pthread_spin_trylock(spin); \
163 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked spin %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \
164 switch (ret) { \
165 case EINVAL: \
166 printf("The value specified by attr is invalid\n"); \
167 break; \
168 case EDEADLK: \
169 printf("A deadlock would occur if the thread blocked waiting for spin\n"); \
170 break; \
171 case EBUSY: \
172 printf("A thread currently holds the lock\n"); \
173 break; \
174 } \
175 ret; \
176})
177
178#define SCSpinUnlock_dbg(spin) ({ \
179 printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocking spin %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \
180 int ret = pthread_spin_unlock(spin); \
181 printf("%16s(%s:%d): (thread:%"PRIuMAX") unlockedspin %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \
182 switch (ret) { \
183 case EINVAL: \
184 printf("The value specified by attr is invalid\n"); \
185 break; \
186 case EPERM: \
187 printf("The calling thread does not hold the lock\n"); \
188 break; \
189 } \
190 ret; \
191})
192
193#define SCSpinInit_dbg(spin, spin_attr) ({ \
194 int ret = pthread_spin_init(spin, spin_attr); \
195 printf("%16s(%s:%d): (thread:%"PRIuMAX") spinlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \
196 switch (ret) { \
197 case EINVAL: \
198 printf("The value specified by attr is invalid\n"); \
199 break; \
200 case EBUSY: \
201 printf("A thread currently holds the lock\n"); \
202 break; \
203 case ENOMEM: \
204 printf("The process cannot allocate enough memory to create another spin\n"); \
205 break; \
206 case EAGAIN: \
207 printf("The system temporarily lacks the resources to create another spin\n"); \
208 break; \
209 } \
210 ret; \
211})
212
213#define SCSpinDestroy_dbg(spin) ({ \
214 printf("%16s(%s:%d): (thread:%"PRIuMAX") condition %p waiting\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \
215 int ret = pthread_spin_destroy(spin); \
216 printf("%16s(%s:%d): (thread:%"PRIuMAX") condition %p passed %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \
217 switch (ret) { \
218 case EINVAL: \
219 printf("The value specified by attr is invalid\n"); \
220 break; \
221 case EBUSY: \
222 printf("A thread currently holds the lock\n"); \
223 break; \
224 case ENOMEM: \
225 printf("The process cannot allocate enough memory to create another spin\n"); \
226 break; \
227 case EAGAIN: \
228 printf("The system temporarily lacks the resources to create another spin\n"); \
229 break; \
230 } \
231 ret; \
232})
233
234#define SCSpinlock pthread_spinlock_t
235#define SCSpinLock SCSpinLock_dbg
236#define SCSpinTrylock SCSpinTrylock_dbg
237#define SCSpinUnlock SCSpinUnlock_dbg
238#define SCSpinInit SCSpinInit_dbg
239#define SCSpinDestroy SCSpinDestroy_dbg
240
241/* rwlocks */
242
243/** When dbg threads is defined, if a rwlock fail to lock, it's
244 * initialized, logged, and does a second try; This is to prevent the system to freeze;
245 * If you see a rwlock, spinlock or condition not initialized, report it please!
246 */
247#define SCRWLockRDLock_dbg(rwl) ({ \
248 printf("%16s(%s:%d): (thread:%"PRIuMAX") locking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \
249 int retl = pthread_rwlock_rdlock(rwl); \
250 printf("%16s(%s:%d): (thread:%"PRIuMAX") locked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, retl); \
251 if (retl != 0) { \
252 switch (retl) { \
253 case EINVAL: \
254 printf("The value specified by attr is invalid\n"); \
255 retl = pthread_rwlock_init(rwl, NULL); \
256 if (retl != 0) \
257 exit(EXIT_FAILURE); \
258 retl = pthread_rwlock_rdlock(rwl); \
259 break; \
260 case EDEADLK: \
261 printf("A deadlock would occur if the thread blocked waiting for rwlock\n"); \
262 break; \
263 } \
264 } \
265 retl; \
266})
267
268#define SCRWLockWRLock_dbg(rwl) ({ \
269 printf("%16s(%s:%d): (thread:%"PRIuMAX") locking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \
270 int retl = pthread_rwlock_wrlock(rwl); \
271 printf("%16s(%s:%d): (thread:%"PRIuMAX") locked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, retl); \
272 if (retl != 0) { \
273 switch (retl) { \
274 case EINVAL: \
275 printf("The value specified by attr is invalid\n"); \
276 retl = pthread_rwlock_init(rwl, NULL); \
277 if (retl != 0) \
278 exit(EXIT_FAILURE); \
279 retl = pthread_rwlock_wrlock(rwl); \
280 break; \
281 case EDEADLK: \
282 printf("A deadlock would occur if the thread blocked waiting for rwlock\n"); \
283 break; \
284 } \
285 } \
286 retl; \
287})
288
289
290#define SCRWLockTryWRLock_dbg(rwl) ({ \
291 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \
292 int rett = pthread_rwlock_trywrlock(rwl); \
293 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, rett); \
294 if (rett != 0) { \
295 switch (rett) { \
296 case EINVAL: \
297 printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \
298 break; \
299 case EBUSY: \
300 printf("RWLock is already locked\n"); \
301 break; \
302 } \
303 } \
304 rett; \
305})
306
307#define SCRWLockTryRDLock_dbg(rwl) ({ \
308 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \
309 int rett = pthread_rwlock_tryrdlock(rwl); \
310 printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, rett); \
311 if (rett != 0) { \
312 switch (rett) { \
313 case EINVAL: \
314 printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \
315 break; \
316 case EBUSY: \
317 printf("RWLock is already locked\n"); \
318 break; \
319 } \
320 } \
321 rett; \
322})
323
324#define SCRWLockInit_dbg(rwl, rwlattr) ({ \
325 int ret; \
326 ret = pthread_rwlock_init(rwl, rwlattr); \
327 if (ret != 0) { \
328 switch (ret) { \
329 case EINVAL: \
330 printf("The value specified by attr is invalid\n"); \
331 printf("%16s(%s:%d): (thread:%"PRIuMAX") rwlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, ret); \
332 break; \
333 case EAGAIN: \
334 printf("The system temporarily lacks the resources to create another rwlock\n"); \
335 printf("%16s(%s:%d): (thread:%"PRIuMAX") rwlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, ret); \
336 break; \
337 case ENOMEM: \
338 printf("The process cannot allocate enough memory to create another rwlock\n"); \
339 printf("%16s(%s:%d): (thread:%"PRIuMAX") rwlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, ret); \
340 break; \
341 } \
342 } \
343 ret; \
344})
345
346#define SCRWLockUnlock_dbg(rwl) ({ \
347 printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \
348 int retu = pthread_rwlock_unlock(rwl); \
349 printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, retu); \
350 if (retu != 0) { \
351 switch (retu) { \
352 case EINVAL: \
353 printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \
354 break; \
355 case EPERM: \
356 printf("The current thread does not hold a lock on rwlock\n"); \
357 break; \
358 } \
359 } \
360 retu; \
361})
362
363#define SCRWLock pthread_rwlock_t
364#define SCRWLockInit(rwl, rwlattrs) SCRWLockInit_dbg(rwl, rwlattrs)
365#define SCRWLockRDLock(rwl) SCRWLockRDLock_dbg(rwl)
366#define SCRWLockWRLock(rwl) SCRWLockWRLock_dbg(rwl)
367#define SCRWLockTryWRLock(rwl) SCRWLockTryWRLock_dbg(rwl)
368#define SCRWLockTryRDLock(rwl) SCRWLockTryRDLock_dbg(rwl)
369#define SCRWLockUnlock(rwl) SCRWLockUnlock_dbg(rwl)
370#define SCRWLockDestroy pthread_rwlock_destroy
371
372/* ctrl mutex */
373#define SCCtrlMutex pthread_mutex_t
374#define SCCtrlMutexAttr pthread_mutexattr_t
375#define SCCtrlMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr)
376#define SCCtrlMutexLock(mut) pthread_mutex_lock(mut)
377#define SCCtrlMutexTrylock(mut) pthread_mutex_trylock(mut)
378#define SCCtrlMutexUnlock(mut) pthread_mutex_unlock(mut)
379#define SCCtrlMutexDestroy pthread_mutex_destroy
380
381/* ctrl conditions */
382#define SCCtrlCondT pthread_cond_t
383#define SCCtrlCondInit pthread_cond_init
384#define SCCtrlCondSignal pthread_cond_signal
385#define SCCtrlCondTimedwait pthread_cond_timedwait
386#define SCCtrlCondWait pthread_cond_wait
387#define SCCtrlCondDestroy pthread_cond_destroy
388
389#endif