1/* -*- C++ -*-
2
3 This file declares debugging aids for multithreaded applications.
4
5 $ Author: Mirko Boehm $
6 $ Copyright: (C) 2004-2013 Mirko Boehm $
7 $ Contact: mirko@kde.org
8 http://www.kde.org
9 http://creative-destruction.me $
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License as published by the Free Software Foundation; either
14 version 2 of the License, or (at your option) any later version.
15
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Library General Public License for more details.
20
21 You should have received a copy of the GNU Library General Public License
22 along with this library; see the file COPYING.LIB. If not, write to
23 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 Boston, MA 02110-1301, USA.
25
26 $Id: DebuggingAids.h 30 2005-08-16 16:16:04Z mirko $
27*/
28
29//krazy:excludeall=inline
30
31#ifndef DEBUGGINGAIDS_H
32#define DEBUGGINGAIDS_H
33
34#include <QtCore/QtGlobal>
35
36extern "C"
37{
38#include <stdarg.h>
39#ifndef Q_WS_WIN
40#include <unistd.h>
41#endif
42#include <stdio.h>
43#include <stdlib.h>
44#include <assert.h>
45}
46
47#include <QtCore/QMutex>
48#include <QtCore/QString>
49#include "threadweaver/threadweaver_export.h"
50
51namespace ThreadWeaver {
52
53 extern THREADWEAVER_EXPORT bool Debug;
54 extern THREADWEAVER_EXPORT int DebugLevel;
55 extern THREADWEAVER_EXPORT QMutex GlobalMutex;
56
57 /** Set the debug log level.
58 @see debug
59 */
60 extern inline void setDebugLevel (bool debug, int level);
61
62 /** This method prints a text message on the screen, if debugging is
63 enabled. Otherwise, it does nothing. The message is thread safe,
64 therefore providing that the messages appear in the order they where
65 issued by the different threads.
66 All messages are suppressed when Debug is false. All messages with a
67 lower importance (higher number) than DebugLevel will be suppressed,
68 too. Debug level 0 messages will always be printed as long as
69 Debug is true.
70 We use our own debugging method, since debugging threads is a more
71 complicated experience than debugging single threaded
72 contexts. This might change in future in the way that debug
73 prints its messages to another logging facility provided by
74 the platform.
75 Use setDebugLevel () to integrate adapt debug () to your platform.
76 */
77 inline void debug(int severity, const char * cformat, ...)
78#ifdef __GNUC__
79 __attribute__ ( (format (printf, 2, 3 ) ) )
80#endif
81;
82
83 /** Prints the message to the console if condition is true. */
84 inline void debug(bool condition, int severity, const char * cformat, ...)
85#ifdef __GNUC__
86 __attribute__ ( (format (printf, 3, 4 ) ) )
87#endif
88;
89
90
91/** PROTECT executes x with GlobalMutex locked.
92 Mostly used for debugging, as in P_ASSERT. */
93#ifdef PROTECT
94#undef PROTECT
95#endif
96#define PROTECT(x) do { QMutexLocker l(&ThreadWeaver::GlobalMutex); (x); } while (0)
97
98/** P_ASSERT ensures that error messages occur in the correct order. */
99#ifdef P_ASSERT
100#undef P_ASSERT
101#endif
102
103#define P_ASSERT(x) do { QMutexLocker l(&ThreadWeaver::GlobalMutex); Q_ASSERT(x); } while (0)
104
105 inline void setDebugLevel (bool debug, int level)
106 {
107 Debug = debug;
108 DebugLevel = level;
109 }
110
111#ifndef QT_NO_DEBUG
112 inline void debug(int severity, const char * cformat, ...)
113 {
114 if ( Debug == true && ( severity<=DebugLevel || severity == 0) )
115 {
116 QString text;
117
118 va_list ap;
119 va_start( ap, cformat );
120 PROTECT (vprintf (cformat, ap));
121 va_end (ap);
122 }
123 }
124
125 inline void debug(bool condition, int severity, const char *cformat, ...)
126 {
127 if (condition && Debug == true && ( severity<=DebugLevel || severity == 0) )
128 {
129 QString text;
130
131 va_list ap;
132 va_start( ap, cformat );
133 PROTECT (vprintf (cformat, ap));
134 va_end (ap);
135 }
136 }
137#else
138 inline void debug(int, const char *, ...) {}
139 inline void debug(bool, int, const char *, ...) {}
140#endif
141
142 inline bool invariant() { return true; }
143
144#define INVARIANT Q_ASSERT_X (invariant(), __FILE__, "class invariant failed" );
145
146#define REQUIRE(x) \
147INVARIANT \
148Q_ASSERT_X (x, Q_FUNC_INFO, "unfulfilled requirement " #x );
149
150#define ENSURE(x) \
151INVARIANT \
152Q_ASSERT_X (x, Q_FUNC_INFO, "broken guarantee " #x );
153
154
155#ifdef QT_NO_DEBUG
156#define DEBUGONLY(x)
157#else
158#define DEBUGONLY(x) x
159#endif
160
161}
162
163#endif // DEBUGGINGAIDS_H
164