1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
|
/*
* Copyright © 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Benjamin Segovia <benjamin.segovia@intel.com>
*/
#ifndef __GBE_PLATFORM_HPP__
#define __GBE_PLATFORM_HPP__
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ostream>
#include <istream>
#include <string>
#include <cassert>
#include <new>
////////////////////////////////////////////////////////////////////////////////
/// CPU architecture
////////////////////////////////////////////////////////////////////////////////
/* detect 32 or 64 platform */
#if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
#define __X86_64__
#else
#define __X86__
#endif
/* We require SSE ... */
#ifndef __SSE__
#define __SSE__
#endif
/* ... and SSE2 */
#ifndef __SSE2__
#define __SSE2__
#endif
#if defined(_INCLUDED_IMM)
// #define __AVX__
#endif
#if defined(_MSC_VER) && (_MSC_VER < 1600) && !defined(__INTEL_COMPILER) || defined(_DEBUG) && defined(_WIN32)
#define __NO_AVX__
#endif
#if defined(_MSC_VER) && !defined(__SSE4_2__)
// #define __SSE4_2__ //! activates SSE4.2 support
#endif
////////////////////////////////////////////////////////////////////////////////
/// Operating system
////////////////////////////////////////////////////////////////////////////////
/* detect Linux platform */
#if defined(linux) || defined(__linux__) || defined(__LINUX__)
# if !defined(__LINUX__)
# define __LINUX__
# endif
# if !defined(__UNIX__)
# define __UNIX__
# endif
#endif
/* detect FreeBSD platform */
#if defined(__FreeBSD__) || defined(__FREEBSD__)
# if !defined(__FREEBSD__)
# define __FREEBSD__
# endif
# if !defined(__UNIX__)
# define __UNIX__
# endif
#endif
/* detect Windows 95/98/NT/2000/XP/Vista/7 platform */
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(__CYGWIN__)
# if !defined(__WIN32__)
# define __WIN32__
# endif
#endif
/* detect Cygwin platform */
#if defined(__CYGWIN__)
# if !defined(__UNIX__)
# define __UNIX__
# endif
#endif
/* detect MAC OS X platform */
#if defined(__APPLE__) || defined(MACOSX) || defined(__MACOSX__)
# if !defined(__MACOSX__)
# define __MACOSX__
# endif
# if !defined(__UNIX__)
# define __UNIX__
# endif
#endif
/* try to detect other Unix systems */
#if defined(__unix__) || defined (unix) || defined(__unix) || defined(_unix)
# if !defined(__UNIX__)
# define __UNIX__
# endif
#endif
////////////////////////////////////////////////////////////////////////////////
/// Compiler
////////////////////////////////////////////////////////////////////////////////
/*! GCC compiler */
#ifdef __GNUC__
// #define __GNUC__
#endif
/*! Intel compiler */
#ifdef __INTEL_COMPILER
#define __ICC__
#endif
/*! Visual C compiler */
#ifdef _MSC_VER
#define __MSVC__
#endif
////////////////////////////////////////////////////////////////////////////////
/// Makros
////////////////////////////////////////////////////////////////////////////////
#ifdef __WIN32__
#define __dllexport extern "C" __declspec(dllexport)
#define __dllimport extern "C" __declspec(dllimport)
#else
#define __dllexport extern "C"
#define __dllimport extern "C"
#endif
#ifdef __MSVC__
#undef NOINLINE
#define NOINLINE __declspec(noinline)
#define INLINE __forceinline
#define RESTRICT __restrict
#define THREAD __declspec(thread)
#define ALIGNED(...) __declspec(align(__VA_ARGS__))
//#define __FUNCTION__ __FUNCTION__
#define DEBUGBREAK() __debugbreak()
#else
#undef NOINLINE
#undef INLINE
#define NOINLINE __attribute__((noinline))
#define INLINE inline __attribute__((always_inline))
#define RESTRICT __restrict
#define THREAD __thread
#define ALIGNED(...) __attribute__((aligned(__VA_ARGS__)))
#define __FUNCTION__ __PRETTY_FUNCTION__
#define DEBUGBREAK() asm ("int $3")
#endif
/*! Modern x86 processors */
#define CACHE_LINE 64
#define CACHE_LINE_ALIGNED ALIGNED(CACHE_LINE)
#ifdef __GNUC__
#define MAYBE_UNUSED __attribute__((used))
#else
#define MAYBE_UNUSED
#endif
#if defined(_MSC_VER)
#define __builtin_expect(expr,b) expr
#endif
/*! Debug syntactic sugar */
#if GBE_DEBUG
#define IF_DEBUG(EXPR) EXPR
#else
#define IF_DEBUG(EXPR)
#endif /* GBE_DEBUG */
/*! Debug printing macros */
#define STRING(x) #x
#define PING std::cout << __FILE__ << " (" << __LINE__ << "): " << __FUNCTION__ << std::endl
#define PRINT(x) std::cout << STRING(x) << " = " << (x) << std::endl
/*! Branch hint */
#define LIKELY(x) __builtin_expect(!!(x),1)
#define UNLIKELY(x) __builtin_expect((x),0)
/*! Stringify macros */
#define JOIN(X, Y) _DO_JOIN(X, Y)
#define _DO_JOIN(X, Y) _DO_JOIN2(X, Y)
#define _DO_JOIN2(X, Y) X##Y
/*! Run-time assertion */
#if GBE_DEBUG
#define GBE_ASSERT(EXPR) do { \
if (UNLIKELY(!(EXPR))) \
gbe::onFailedAssertion(#EXPR, __FILE__, __FUNCTION__, __LINE__); \
} while (0)
#define GBE_ASSERTM(EXPR, MSG) do { \
if (UNLIKELY(!(EXPR))) \
gbe::onFailedAssertion(MSG, __FILE__, __FUNCTION__, __LINE__); \
} while (0)
#else
#define GBE_ASSERT(EXPR) do { } while (0)
#define GBE_ASSERTM(EXPR, MSG) do { } while (0)
#endif /* GBE_DEBUG */
#define NOT_IMPLEMENTED GBE_ASSERTM (false, "Not implemented")
#define NOT_SUPPORTED GBE_ASSERTM (false, "Not supported")
/*! Fatal error macros */
#define FATAL_IF(COND, MSG) \
do { \
if(UNLIKELY(COND)) FATAL(MSG); \
} while (0)
/* Safe deletion macros */
#define GBE_SAFE_DELETE_ARRAY(x) do { if (x != NULL) GBE_DELETE_ARRAY(x); } while (0)
#define GBE_SAFE_DELETE(x) do { if (x != NULL) GBE_DELETE(x); } while (0)
/* Number of elements in an array */
#define ARRAY_ELEM_NUM(x) (sizeof(x) / sizeof(x[0]))
/* Align X on A */
#define ALIGN(X,A) (((X) % (A)) ? ((X) + (A) - ((X) % (A))) : (X))
/*! Produce a string from the macro locatiom */
#define HERE (STRING(__LINE__) "@" __FILE__)
/*! Typesafe encapusalation of a type (mostly for integers) */
#define TYPE_SAFE(SAFE, UNSAFE) \
class SAFE \
{ \
public: \
INLINE SAFE(void) {} \
explicit INLINE SAFE(uint16_t unsafe) : unsafe(unsafe) {} \
INLINE operator UNSAFE (void) const { return unsafe; } \
UNSAFE value(void) const { return unsafe; } \
private: \
UNSAFE unsafe; \
};
/*! Default alignment for the platform */
#define GBE_DEFAULT_ALIGNMENT 16
/*! Useful constants */
#define KB 1024
#define MB (KB*KB)
/*! Portable AlignOf */
template <typename T>
struct AlignOf {
struct Helper { char x; T t; };
enum { value = offsetof(Helper, t) };
};
//gcc 4.8+ support C++11 alignof keyword
#if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 8)
#define ALIGNOF(T) (alignof(T))
#else
#define ALIGNOF(T) (AlignOf<T>::value)
#endif
////////////////////////////////////////////////////////////////////////////////
/// Visibility parameters (DLL export and so on)
////////////////////////////////////////////////////////////////////////////////
#if defined __WIN32__
#if defined __GNUC__
#define GBE_EXPORT_SYMBOL __attribute__ ((dllexport))
#define GBE_IMPORT_SYMBOL __attribute__ ((dllimport))
#else
#define GBE_IMPORT_SYMBOL __declspec(dllimport)
#define GBE_EXPORT_SYMBOL __declspec(dllexport)
#endif /* __GNUC__ */
#else
#define GBE_EXPORT_SYMBOL __attribute__ ((visibility ("default")))
#define GBE_IMPORT_SYMBOL
#endif /* __WIN32__ */
////////////////////////////////////////////////////////////////////////////////
/// Basic Types
////////////////////////////////////////////////////////////////////////////////
#if defined(__MSVC__)
typedef __int64_t int64_t;
typedef unsigned __int64_t uint64_t;
typedef __int32_t int32_t;
typedef unsigned __int32_t uint32_t;
typedef __int16_t int16_t;
typedef unsigned __int16_t uint16_t;
typedef __int8_t int8_t;
typedef unsigned __int8_t uint8_t;
#else
#include <cstdint>
#endif
#if defined(__X86_64__)
typedef int64_t index_t;
#else
typedef int32_t index_t;
#endif
/*! To protect some classes from being copied */
class NonCopyable
{
protected:
INLINE NonCopyable(void) {}
INLINE ~NonCopyable(void) {}
private:
INLINE NonCopyable(const NonCopyable&) {}
INLINE NonCopyable& operator= (const NonCopyable&) {return *this;}
};
#define TO_MAGIC(A, B, C, D) (A<<24 | B<<16 | C<<8 | D)
class Serializable
{
public:
INLINE Serializable(void) = default;
INLINE Serializable(const Serializable&) = default;
INLINE Serializable& operator= (const Serializable&) = default;
virtual size_t serializeToBin(std::ostream& outs) = 0;
virtual size_t deserializeFromBin(std::istream& ins) = 0;
/* These two will follow LLVM's ABI. */
virtual size_t serializeToLLVM(void) { return 0;/* not implemented now. */}
virtual size_t deserializeFromLLVM(void) { return 0;/* not implemented now. */}
virtual void printStatus(int indent = 0, std::ostream& outs = std::cout) { }
virtual ~Serializable(void) { }
protected:
static std::string indent_to_str(int indent) {
std::string ind(indent, ' ');
return ind;
}
};
/* Help Macro for serialization. */
#define SERIALIZE_OUT(elt, out, sz) \
do { \
auto tmp_val = elt; \
out.write((char *)(&tmp_val), sizeof(elt)); \
sz += sizeof(elt); \
} while(0)
#define DESERIALIZE_IN(elt, in, sz) \
do { \
in.read((char *)(&(elt)), sizeof(elt)); \
sz += sizeof(elt); \
} while(0)
////////////////////////////////////////////////////////////////////////////////
/// Disable some compiler warnings
////////////////////////////////////////////////////////////////////////////////
#ifdef __ICC__
#pragma warning(disable:265) // floating-point operation result is out of range
#pragma warning(disable:383) // value copied to temporary, reference to temporary used
#pragma warning(disable:869) // parameter was never referenced
#pragma warning(disable:981) // operands are evaluated in unspecified order
#pragma warning(disable:1418) // external function definition with no prior declaration
#pragma warning(disable:1419) // external declaration in primary source file
#pragma warning(disable:1572) // floating-point equality and inequality comparisons are unreliable
#pragma warning(disable:1125) // virtual function override intended?
#endif /* __ICC__ */
////////////////////////////////////////////////////////////////////////////////
/// Default Includes and Functions
////////////////////////////////////////////////////////////////////////////////
#include "sys/alloc.hpp"
namespace gbe
{
/*! selects */
INLINE bool select(bool s, bool t , bool f) { return s ? t : f; }
INLINE int select(bool s, int t, int f) { return s ? t : f; }
INLINE float select(bool s, float t, float f) { return s ? t : f; }
/*! Fatal error function */
void FATAL(const std::string&);
/*! Return the next power of 2 */
INLINE uint32_t nextHighestPowerOf2(uint32_t x) {
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return ++x;
}
INLINE uint32_t logi2(uint32_t x) {
uint32_t r = 0;
while(x >>= 1) r++;
return r;
}
template<uint32_t N>
INLINE uint32_t isPowerOf(uint32_t i) {
while (i > 1) {
if (i%N) return false;
i = i/N;
}
return true;
}
template<> INLINE uint32_t isPowerOf<2>(uint32_t i) { return ((i-1)&i) == 0; }
/*! random functions */
template<typename T> T random() { return T(0); }
template<> INLINE int32_t random() { return int(rand()); }
template<> INLINE uint32_t random() { return uint32_t(rand()); }
template<> INLINE float random() { return random<uint32_t>()/float(RAND_MAX); }
template<> INLINE double random() { return random<uint32_t>()/double(RAND_MAX); }
/** returns performance counter in seconds */
double getSeconds();
} /* namespace gbe */
#endif /* __GBE_PLATFORM_HPP__ */
|