/[pcsx2_0.9.7]/trunk/common/include/Utilities/Assertions.h
ViewVC logotype

Annotation of /trunk/common/include/Utilities/Assertions.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (hide annotations) (download)
Fri Nov 12 01:10:22 2010 UTC (9 years, 9 months ago) by william
File MIME type: text/plain
File size: 8218 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4013 local: v0.9.7.197-latest) in ./trunk
1 william 31 /* PCSX2 - PS2 Emulator for PCs
2     * Copyright (C) 2002-2010 PCSX2 Dev Team
3     *
4     * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5     * of the GNU Lesser General Public License as published by the Free Software Found-
6     * ation, either version 3 of the License, or (at your option) any later version.
7     *
8     * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10     * PURPOSE. See the GNU General Public License for more details.
11     *
12     * You should have received a copy of the GNU General Public License along with PCSX2.
13     * If not, see <http://www.gnu.org/licenses/>.
14     */
15    
16     #pragma once
17    
18     #ifndef __pxFUNCTION__
19     #if defined(__GNUG__)
20     # define __pxFUNCTION__ __PRETTY_FUNCTION__
21     #else
22     # define __pxFUNCTION__ __FUNCTION__
23     #endif
24     #endif
25    
26     #ifndef wxNullChar
27     # define wxNullChar ((wxChar*)NULL)
28     #endif
29    
30     // FnChar_t - function name char type; typedef'd in case it ever changes between compilers
31     // (ie, a compiler decides to wchar_t it instead of char/UTF8).
32     typedef char FnChar_t;
33    
34     // --------------------------------------------------------------------------------------
35     // DiagnosticOrigin
36     // --------------------------------------------------------------------------------------
37     struct DiagnosticOrigin
38     {
39     const wxChar* srcfile;
40     const FnChar_t* function;
41     const wxChar* condition;
42     int line;
43    
44     DiagnosticOrigin( const wxChar *_file, int _line, const FnChar_t *_func, const wxChar* _cond = NULL )
45     : srcfile( _file )
46     , function( _func )
47     , condition( _cond )
48     , line( _line )
49     {
50     }
51    
52     wxString ToString( const wxChar* msg=NULL ) const;
53     };
54    
55     // Returns ture if the assertion is to trap into the debugger, or false if execution
56     // of the program should continue unimpeded.
57     typedef bool pxDoAssertFnType(const DiagnosticOrigin& origin, const wxChar *msg);
58    
59     extern pxDoAssertFnType pxAssertImpl_LogIt;
60    
61     extern pxDoAssertFnType* pxDoAssert;
62    
63     // ----------------------------------------------------------------------------------------
64     // pxAssert / pxAssertDev
65     // ----------------------------------------------------------------------------------------
66     // Standard "nothrow" assertions. All assertions act as valid conditional statements that
67     // return the result of the specified conditional; useful for handling failed assertions in
68     // a "graceful" fashion when utilizing the "ignore" feature of assertion debugging.
69     // These macros are mostly intended for "pseudo-weak" assumptions within code, most often for
70     // testing threaded user interface code (threading of the UI is a prime example since often
71     // even very robust assertions can fail in very rare conditions, due to the complex variety
72     // of ways the user can invoke UI events).
73     //
74     // All macros return TRUE if the assertion succeeds, or FALSE if the assertion failed
75     // (thus matching the condition of the assertion itself).
76     //
77     // pxAssertDev is an assertion tool for Devel builds, intended for sanity checking and/or
78     // bounds checking variables in areas which are not performance critical. Another common
79     // use is for checking thread affinity on utility functions.
80     //
81     // Credits: These macros are based on a combination of wxASSERT, MSVCRT's assert and the
82     // ATL's Assertion/Assumption macros. the best of all worlds!
83    
84     // --------------------------------------------------------------------------------------
85     // pxAssume / pxAssumeDev / pxFail / pxFailDev
86     // --------------------------------------------------------------------------------------
87     // Assumptions are like "extra rigid" assertions, which should never fail under any circum-
88     // stance in release build optimized code.
89     //
90     // Performance: All assumption/fail types optimize into __assume()/likely() directives in
91     // Release builds (non-dev varieties optimize as such in Devel builds as well). If using
92 william 62 //
93     // Having pxFail and pxFailDev translate into __assume statements is very dangerous, since
94     // it can lead to the compiler optimizing out code and leading to crashes in dev/release
95     // builds. To have code optimized, explicitly use pxAssume(false) or pxAssumeDev(false,msg);
96 william 31
97     #define pxDiagSpot DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__ )
98     #define pxAssertSpot(cond) DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__, _T(#cond) )
99    
100     // pxAssertRel ->
101     // Special release-mode assertion. Limited use since stack traces in release mode builds
102     // (especially with LTCG) are highly suspect. But when troubleshooting crashes that only
103     // rear ugly heads in optimized builds, this is one of the few tools we have.
104    
105     #define pxAssertRel(cond, msg) ( (likely(cond)) || (pxOnAssert(pxAssertSpot(cond), msg), false) )
106     #define pxAssumeRel(cond, msg) ((void) ( (!likely(cond)) && (pxOnAssert(pxAssertSpot(cond), msg), false) ))
107 william 62 #define pxFailRel(msg) pxAssertRel(false, msg)
108 william 31
109     #if defined(PCSX2_DEBUG)
110    
111     # define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
112     # define pxAssertDev(cond, msg) pxAssertMsg(cond, msg)
113    
114     # define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg)
115     # define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
116    
117 william 62 # define pxFail(msg) pxAssertMsg(false, msg)
118     # define pxFailDev(msg) pxAssertDev(false, msg)
119 william 31
120     #elif defined(PCSX2_DEVBUILD)
121    
122     // Devel builds use __assume for standard assertions and call pxOnAssertDevel
123     // for AssertDev brand assertions (which typically throws a LogicError exception).
124    
125     # define pxAssertMsg(cond, msg) (likely(cond))
126     # define pxAssertDev(cond, msg) pxAssertRel(cond, msg)
127    
128     # define pxAssumeMsg(cond, msg) (__assume(cond))
129 william 62 # define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
130 william 31
131 william 62 # define pxFail(msg)
132     # define pxFailDev(msg) pxAssertDev(false, msg)
133 william 31
134     #else
135    
136     // Release Builds just use __assume as an optimization, and return the conditional
137     // as a result (which is optimized to nil if unused).
138    
139     # define pxAssertMsg(cond, msg) (likely(cond))
140     # define pxAssertDev(cond, msg) (likely(cond))
141    
142     # define pxAssumeMsg(cond, msg) (__assume(cond))
143     # define pxAssumeDev(cond, msg) (__assume(cond))
144    
145 william 62 # define pxFail(msg)
146     # define pxFailDev(msg)
147 william 31
148     #endif
149    
150     #define pxAssert(cond) pxAssertMsg(cond, wxNullChar)
151     #define pxAssume(cond) pxAssumeMsg(cond, wxNullChar)
152    
153     #define pxAssertRelease( cond, msg )
154    
155     // Performs an unsigned index bounds check, and generates a debug assertion if the check fails.
156     // For stricter checking in Devel builds as well as debug builds (but possibly slower), use
157     // IndexBoundsCheckDev.
158    
159     #define IndexBoundsCheck( objname, idx, sze ) pxAssertMsg( (uint)(idx) < (uint)(sze), \
160 william 273 pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
161 william 31
162     #define IndexBoundsCheckDev( objname, idx, sze ) pxAssertDev( (uint)(idx) < (uint)(sze), \
163 william 273 pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
164 william 31
165 william 62 #define IndexBoundsAssume( objname, idx, sze ) pxAssumeMsg( (uint)(idx) < (uint)(sze), \
166 william 273 pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
167 william 31
168 william 62 #define IndexBoundsAssumeDev( objname, idx, sze ) pxAssumeDev( (uint)(idx) < (uint)(sze), \
169 william 273 pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
170 william 62
171    
172 william 31 extern void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg=NULL );
173     extern void pxOnAssert( const DiagnosticOrigin& origin, const char* msg );
174    
175 william 62 // --------------------------------------------------------------------------------------
176 william 31 // jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization
177     // under MSVC.
178 william 62 // --------------------------------------------------------------------------------------
179     // How it Works: pxAssumeDev turns into an __assume(0) under msvc compilers, which when specified
180 william 31 // in the 'default:' case of a switch tells the compiler that the case is unreachable, so
181     // that it will not generate any code, LUTs, or conditionals to handle it.
182     //
183     // * In debug/devel builds the default case will cause an assertion.
184     //
185     #ifndef jNO_DEFAULT
186     # define jNO_DEFAULT \
187     default: \
188     { \
189 william 62 pxAssumeDev( false, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)" ); \
190 william 31 break; \
191     }
192     #endif

  ViewVC Help
Powered by ViewVC 1.1.22