-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathubut_top.h
401 lines (345 loc) · 10.7 KB
/
ubut_top.h
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
#ifndef UBUT_TOP_INC
#define UBUT_TOP_INC
#if defined(__clang__)
#pragma clang system_header
#endif // __clang__
/*
-------------------------------------------------------------------------------
nicked from <yvals_core.h>
this is used in the MS STL source whenever they use what they do
advise customers not to use ;)
*/
// clang-format off
#ifndef _STL_DISABLE_DEPRECATED_WARNING
#ifdef __clang__
#define _STL_DISABLE_DEPRECATED_WARNING \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
#else // __clang__
#define _STL_DISABLE_DEPRECATED_WARNING \
__pragma(warning(push)) \
__pragma(warning(disable : 4996)) // was declared deprecated
#endif // __clang__
#endif // _STL_DISABLE_DEPRECATED_WARNING
// clang-format on
#ifndef _STL_RESTORE_DEPRECATED_WARNING
#ifdef __clang__
#define _STL_RESTORE_DEPRECATED_WARNING _Pragma("clang diagnostic pop")
#else // __clang__
#define _STL_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
#endif // __clang__
#endif // _STL_RESTORE_DEPRECATED_WARNING
// instead of including the whole <atomic> because of line 32
#ifndef _Compiler_barrier
#define _Compiler_barrier() _STL_DISABLE_DEPRECATED_WARNING _ReadWriteBarrier() _STL_RESTORE_DEPRECATED_WARNING
#endif
/*
official advice is not to use _ReadWriteBarrier, but then there is a lot of _Compiler_barrier() all arround the
<atomic> et all in the MS STL code
*/
/*
-------------------------------------------------------------------------------
set the WINVER and _WIN32_WINNT macros to the oldest supported platform
#include <winsdkver.h>
*/
#undef WINVER
#define WINVER 0x0A00
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#define NOMINMAX
#define STRICT 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// #include <processenv.h>
/*
-------------------------------------------------------------------------------
*/
#ifdef __STDC_ALLOC_LIB__
#define __STDC_WANT_LIB_EXT2__ 1
#else
#define _POSIX_C_SOURCE 200809L
#endif
#include <crtdbg.h>
#include <errno.h>
#include <stdbool.h>
// ubut_sqrt replaced sqrt
// #include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include <inttypes.h>
/*
io.h contains definitions for some structures with natural padding. This is
uninteresting, but for some reason MSVC's behaviour is to warn about
including this system header. That *is* interesting
*/
#pragma warning(disable : 4820)
#pragma warning(push, 1)
#include <io.h>
#pragma warning(pop)
/*
-------------------------------------------------------------------------------
UBUT stuff begins here
-------------------------------------------------------------------------------
*/
// clang-cl.exe has them both defined
// thus it is not enugh to use _MSC_VER only
#ifdef _WIN32
#define UBUT_IS_WIN
#else
/* but then ... */
#error This is WIN32 only, for OS agnostic experience please use sheredom/ubench from GitHub
#endif
/*
clang_cl.exe is LLVM c++ compiler compiled by MSFT and included
with VS 2019
*/
#undef UBUT_IS_CLANG_CL
#ifdef _MSC_VER
#ifdef __clang__
#define UBUT_IS_CLANG_CL 1
#endif // __clang__
#endif // _MSC_VER
#ifdef __clang__
#define UBUT_UNUSED __attribute__((unused))
#else
#define UBUT_UNUSED
#endif
/*
Disable warning about not inlining 'inline' functions.
TODO: We'll fix this later by not using fprintf within our macros, and
instead use snprintf to a realloc'ed buffer.
*/
#pragma warning(disable : 4710)
/*
Disable warning about inlining functions that are not marked 'inline'.
TODO: add a UBUT_NOINLINE onto the macro generated functions to fix this.
*/
#pragma warning(disable : 4711)
#pragma warning(push, 1)
typedef __int64 ubut_int64_t;
typedef unsigned __int64 ubut_uint64_t;
#pragma warning(pop)
#if defined(__cplusplus)
#define UBUT_C_FUNC extern "C"
#else
#define UBUT_C_FUNC
#endif
#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define UBUT_NOEXCEPT noexcept
#else
#define UBUT_NOEXCEPT
#endif
#ifdef UBUT_IS_CLANG_CL
#define UBUT_NOTHROW __declspec(nothrow)
#else
#define UBUT_NOTHROW
#endif
#define UBUT_PRId64 "I64d"
#define UBUT_PRIu64 "I64u"
// #define UBUT_INLINE __forceinline
#define UBUT_NOINLINE __declspec(noinline)
#define UBUT_FORCEINLINE __forceinline
#if defined(_WIN64)
#define UBUT_SYMBOL_PREFIX
#else
#define UBUT_SYMBOL_PREFIX "_"
#endif
#pragma section(".CRT$XCU", read)
#define UBUT_INITIALIZER(f) \
static void __cdecl f(void); \
__pragma(comment(linker, "/include:" UBUT_SYMBOL_PREFIX #f "_")); \
UBUT_C_FUNC __declspec(allocate(".CRT$XCU")) void(__cdecl * f##_)(void) = \
f; \
static void __cdecl f(void)
// clang on win aka clang-cl.exe
#ifdef __clang__
#undef UBUT_INITIALIZER
#define UBUT_INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#endif // __clang__
#define __STDC_FORMAT_MACROS 1
#if defined(__clang__) && defined(__has_warning)
#if __has_warning("-Wreserved-id-macro")
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic pop
#endif
#endif // clang has warning
#if defined(__cplusplus)
#define UBUT_CAST(type, x) static_cast<type>(x)
#define UBUT_PTR_CAST(type, x) reinterpret_cast<type>(x)
#define UBUT_EXTERN extern "C"
#define UBUT_NULL NULL
#else
#define UBUT_CAST(type, x) ((type)x)
#define UBUT_PTR_CAST(type, x) ((type)x)
#define UBUT_EXTERN extern
#define UBUT_NULL 0
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wvariadic-macros"
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
//#ifdef UBUT_IS_WIN
#define UBUT_SNPRINTF(BUFFER, N, ...) _snprintf_s(BUFFER, N, N, __VA_ARGS__)
//#else
//#ifdef __clang__
//#pragma clang diagnostic push
//#pragma clang diagnostic ignored "-Wvariadic-macros"
//#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
//#endif
//#define UBUT_SNPRINTF(...) snprintf(__VA_ARGS__)
//#ifdef __clang__
//#pragma clang diagnostic pop
//#endif
//#endif
#ifdef __cplusplus
#define UBUT_BEGIN_EXTERN_C extern "C" {
#else
#define UBUT_BEGIN_EXTERN_C
#endif
#ifdef __cplusplus
#define UBUT_END_EXTERN_C }
#else
#define UBUT_END_EXTERN_C
#endif
UBUT_BEGIN_EXTERN_C
// https://stackoverflow.com/a/54143846/10870835
// ubench requires math.h just because of sqrt, thus
// we will provide our own
UBUT_FORCEINLINE double ubut_sqrt( double number )
{
static const float threehalfs = 1.5F;
float x2 = number * 0.5F;
float y = number;
long i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // ;)
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
return y;
}
UBUT_FORCEINLINE int ubut_strncmp(const char *a, const char *b, size_t n)
{
/* strncmp breaks on Wall / Werror on gcc/clang, so we avoid using it */
unsigned i;
for (i = 0; i < n; i++)
{
if (a[i] < b[i])
{
return -1;
}
else if (a[i] > b[i])
{
return 1;
}
}
return 0;
}
UBUT_FORCEINLINE FILE *ubut_fopen(const char *filename, const char *mode)
{
#ifdef UBUT_IS_WIN
FILE *file;
if (0 == fopen_s(&file, filename, mode))
{
return file;
}
else
{
return 0;
}
#else
return fopen(filename, mode);
#endif
}
/*
CAUTION: this is WIN32 only version that replaces
utest_ns() and ubut_ns() from original OS agnostic
separate headers utest.h and ubench.h
*/
UBUT_FORCEINLINE ubut_int64_t ubut_ns(void)
{
//#ifdef UBENCH_IS_WIN
LARGE_INTEGER counter;
LARGE_INTEGER frequency;
QueryPerformanceCounter(&counter);
QueryPerformanceFrequency(&frequency);
return UBUT_CAST(ubut_int64_t,
(counter.QuadPart * 1000000000) / frequency.QuadPart);
}
UBUT_END_EXTERN_C
/*
-------------------------------------------------------------------------------
CAUTION: This is compile time. You must define _WIN32_WINNT in project settings.
(and WINVER too)
Meaning: you compile and run on W10 and all is fine.
But, you run the same exe on W7, and squigly bits will be shown instead of colours
If you check at runtime and stop if running bellow W10, in that respect you will be ok.
-------------------------------------------------------------------------------
*/
#if (_WIN32_WINNT == 0x0A00)
#define UBUT_VT_ESC "\x1b["
#define UBUT_VT_RESET UBUT_VT_ESC "0m"
#define UBUT_VT_GRAY UBUT_VT_ESC "90m"
#define UBUT_VT_BLUE UBUT_VT_ESC "94m"
#define UBUT_VT_CYAN UBUT_VT_ESC "36m"
#define UBUT_VT_YELLOW UBUT_VT_ESC "33m"
#define UBUT_VT_GREEN UBUT_VT_ESC "32m"
#define UBUT_VT_RED UBUT_VT_ESC "31m"
#define UBUT_VT_MAGENTA UBUT_VT_ESC "35m"
#else // ! WIN10
#define UBUT_VT_ESC ""
#define UBUT_VT_RESET UBUT_VT_ESC ""
#define UBUT_VT_GRAY UBUT_VT_ESC ""
#define UBUT_VT_BLUE UBUT_VT_ESC ""
#define UBUT_VT_CYAN UBUT_VT_ESC ""
#define UBUT_VT_YELLOW UBUT_VT_ESC ""
#define UBUT_VT_GREEN UBUT_VT_ESC ""
#define UBUT_VT_RED UBUT_VT_ESC ""
#define UBUT_VT_MAGENTA UBUT_VT_ESC ""
#endif
// #define DBJ_UBUT_SIMPLE_LOG // THE BIG ISSUE
#ifdef DBJ_UBUT_SIMPLE_LOG
#define DBJ_SIMPLELOG_USER_DEFINED_MACRO_NAMES
#include "../simplelog/dbj_simple_log.h"
#undef UBUT_TRACE
#undef UBUT_DEBUG
#undef UBUT_INFO
#undef UBUT_WARN
#undef UBUT_ERROR
#undef UBUT_FATAL
#define UBUT_TRACE(...) dbj_log_trace(__VA_ARGS__)
#define UBUT_DEBUG(...) dbj_log_debug(__VA_ARGS__)
#define UBUT_INFO(...) dbj_log_info(__VA_ARGS__)
#define UBUT_WARN(...) dbj_log_warn(__VA_ARGS__)
#define UBUT_ERROR(...) dbj_log_error(__VA_ARGS__)
#define UBUT_FATAL(...) dbj_log_fatal(__VA_ARGS__)
#else
// If not using simple log, what are you using?
#define UBUT_TRACE(...) fprintf(stderr, UBUT_VT_RESET "\n" UBUT_VT_GRAY), fprintf(stderr, __VA_ARGS__)
#define UBUT_DEBUG(...) fprintf(stderr, UBUT_VT_RESET "\n" UBUT_VT_GREEN), fprintf(stderr, __VA_ARGS__)
#define UBUT_INFO(...) fprintf(stderr, UBUT_VT_RESET "\n" UBUT_VT_RESET), fprintf(stderr, __VA_ARGS__)
#define UBUT_WARN(...) fprintf(stderr, UBUT_VT_RESET "\n" UBUT_VT_YELLOW), fprintf(stderr, __VA_ARGS__)
#define UBUT_ERROR(...) fprintf(stderr, UBUT_VT_RESET "\n" UBUT_VT_RED), fprintf(stderr, __VA_ARGS__)
#define UBUT_FATAL(...) fprintf(stderr, UBUT_VT_RESET "\n" UBUT_VT_RED), fprintf(stderr, __VA_ARGS__)
#endif // ! DBJ_UBUT_SIMPLE_LOG
#define UBUT_CONSOLE_COLOR_RESET(...) \
do \
{ \
fprintf(stdout, UBUT_VT_RESET); \
fprintf(stderr, UBUT_VT_RESET); \
fflush(stdout); \
fflush(stderr); \
} while (0)
/*
-------------------------------------------------------------------------------
EOF
-------------------------------------------------------------------------------
*/
#endif // UBUT_TOP_INC