GraphChi 0.1

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Macros
assertions.hpp
1
24 // Copyright (c) 2005, Google Inc.
25 // All rights reserved.
26 //
27 // Redistribution and use in source and binary forms, with or without
28 // modification, are permitted provided that the following conditions are
29 // met:
30 //
31 // * Redistributions of source code must retain the above copyright
32 // notice, this list of conditions and the following disclaimer.
33 // * Redistributions in binary form must reproduce the above
34 // copyright notice, this list of conditions and the following disclaimer
35 // in the documentation and/or other materials provided with the
36 // distribution.
37 // * Neither the name of Google Inc. nor the names of its
38 // contributors may be used to endorse or promote products derived from
39 // this software without specific prior written permission.
40 //
41 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
42 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
43 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
44 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
45 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52
53 // ---
54 // This file contains #include information about logging-related stuff.
55 // Pretty much everybody needs to #include this file so that they can
56 // log various happenings.
57 //
58 #ifndef _ASSERTIONS_H_
59 #define _ASSERTIONS_H_
60
61 #include <stdarg.h>
62 #include <stdlib.h>
63 #include <stdio.h>
64 #ifdef HAVE_UNISTD_H
65 #include <unistd.h> // for write()
66 #endif
67 #include <string.h> // for strlen(), strcmp()
68 #include <assert.h>
69 #include <errno.h> // for errno
70 #include <sstream>
71 #include <cassert>
72
73 #include "logger/logger.hpp"
74 #include <boost/typeof/typeof.hpp>
75
76 static void __print_back_trace() {
77 logstream(LOG_ERROR) << "GraphChi does not currently have the _print_back_trace implementation!" << std::endl;
78 }
79 // On some systems (like freebsd), we can't call write() at all in a
80 // global constructor, perhaps because errno hasn't been set up.
81 // Calling the write syscall is safer (it doesn't set errno), so we
82 // prefer that. Note we don't care about errno for logging: we just
83 // do logging on a best-effort basis.
84 #define WRITE_TO_STDERR(buf, len) (logbuf(LOG_FATAL, buf, len))
85
86 // CHECK dies with a fatal error if condition is not true. It is *not*
87 // controlled by NDEBUG, so the check will be executed regardless of
88 // compilation mode. Therefore, it is safe to do things like:
89 // CHECK(fp->Write(x) == 4)
90 #define CHECK(condition) \
91 do { \
92 if (__builtin_expect(!(condition), 0)) { \
93 logstream(LOG_ERROR) \
94 << "Check failed: " << #condition << std::endl; \
95 __print_back_trace(); \
96 throw("assertion failure"); \
97 } \
98 } while(0)
99
100
101 // This prints errno as well. errno is the posix defined last error
102 // number. See errno.h
103 #define PCHECK(condition) \
104 do { \
105 if (__builtin_expect(!(condition), 0)) { \
106 const int _PCHECK_err_no_ = errno; \
107 logstream(LOG_ERROR) \
108 << "Check failed: " << #condition << ": " \
109 << strerror(err_no) << std::endl; \
110 __print_back_trace(); \
111 throw("assertion failure"); \
112 } \
113 } while(0)
114
115 // Helper macro for binary operators; prints the two values on error
116 // Don't use this macro directly in your code, use CHECK_EQ et al below
117
118 // WARNING: These don't compile correctly if one of the arguments is a pointer
119 // and the other is NULL. To work around this, simply static_cast NULL to the
120 // type of the desired pointer.
121 #define CHECK_OP(op, val1, val2) \
122 do { \
123 const typeof(val1) _CHECK_OP_v1_ = val1; \
124 const typeof(val2) _CHECK_OP_v2_ = (typeof(val2))val2; \
125 if (__builtin_expect(!((_CHECK_OP_v1_) op \
126 (typeof(val1))(_CHECK_OP_v2_)), 0)) { \
127 logstream(LOG_ERROR) \
128 << "Check failed: " \
129 << #val1 << #op << #val2 \
130 << " [" \
131 << _CHECK_OP_v1_ \
132 << ' ' << #op << ' ' \
133 << _CHECK_OP_v2_ << "]" << std::endl; \
134 __print_back_trace(); \
135 throw("assertion failure"); \
136 } \
137 } while(0)
138
139 #define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
140 #define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)
141 #define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)
142 #define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)
143 #define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
144 #define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
145
146 // Synonyms for CHECK_* that are used in some unittests.
147 #define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)
148 #define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)
149 #define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)
150 #define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)
151 #define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)
152 #define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)
153 #define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)
154 #define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)
155 #define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)
156 #define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)
157 #define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)
158 #define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)
159 // As are these variants.
160 #define EXPECT_TRUE(cond) CHECK(cond)
161 #define EXPECT_FALSE(cond) CHECK(!(cond))
162 #define EXPECT_STREQ(a, b) CHECK(strcmp(a, b) == 0)
163 #define ASSERT_TRUE(cond) EXPECT_TRUE(cond)
164 #define ASSERT_FALSE(cond) EXPECT_FALSE(cond)
165 #define ASSERT_STREQ(a, b) EXPECT_STREQ(a, b)
166
167
168 #define ASSERT_MSG(condition, fmt, ...) \
169 do { \
170 if (__builtin_expect(!(condition), 0)) { \
171 logstream(LOG_ERROR) \
172 << "Check failed: " << #condition << ":\n"; \
173 logger(LOG_ERROR, fmt, ##__VA_ARGS__); \
174 __print_back_trace(); \
175 throw("assertion failure"); \
176 } \
177 } while(0)
178
179 // Used for (libc) functions that return -1 and set errno
180 #define CHECK_ERR(invocation) PCHECK((invocation) != -1)
181
182 // A few more checks that only happen in debug mode
183 #ifdef NDEBUG
184 #define DCHECK_EQ(val1, val2)
185 #define DCHECK_NE(val1, val2)
186 #define DCHECK_LE(val1, val2)
187 #define DCHECK_LT(val1, val2)
188 #define DCHECK_GE(val1, val2)
189 #define DCHECK_GT(val1, val2)
190 #define DASSERT_TRUE(cond)
191 #define DASSERT_FALSE(cond)
192 #define DASSERT_MSG(condition, fmt, ...)
193
194 #else
195 #define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
196 #define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
197 #define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
198 #define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
199 #define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
200 #define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
201 #define DASSERT_TRUE(cond) ASSERT_TRUE(cond)
202 #define DASSERT_FALSE(cond) ASSERT_FALSE(cond)
203 #define DASSERT_MSG(condition, fmt, ...) \
204 do { \
205 if (__builtin_expect(!(condition), 0)) { \
206 logstream(LOG_ERROR) \
207 << "Check failed: " << #condition << ":\n"; \
208 logger(LOG_ERROR, fmt, ##__VA_ARGS__); \
209 __print_back_trace(); \
210 throw("assertion failure"); \
211 } \
212 } while(0)
213
214 #endif
215
216
217 #ifdef ERROR
218 #undef ERROR // may conflict with ERROR macro on windows
219 #endif
220
221 #endif // _LOGGING_H_
222