summaryrefslogtreecommitdiff
path: root/plugins/Dbx_mdbx/src/libmdbx/test
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-03-30 22:50:46 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-03-30 22:50:46 +0300
commit628f23ab62e342bb0b1dddedb563e7f13faf9528 (patch)
tree55c97c8453e2dc0036dfa65fb5eb268c886ada13 /plugins/Dbx_mdbx/src/libmdbx/test
parent67cd8dbde997606b40bd7dc2712ccc4c66d8d06f (diff)
merge with the final version of libmdbx
Diffstat (limited to 'plugins/Dbx_mdbx/src/libmdbx/test')
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/base.h8
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/config.cc7
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/config.h3
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/log.cc2
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/log.h1
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/main.cc17
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/osal-unix.cc19
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc6
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/osal.h1
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/test.cc24
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/test.h2
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/utils.cc134
-rw-r--r--plugins/Dbx_mdbx/src/libmdbx/test/utils.h30
13 files changed, 154 insertions, 100 deletions
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/base.h b/plugins/Dbx_mdbx/src/libmdbx/test/base.h
index 63554e730d..f0c6043220 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/base.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/base.h
@@ -76,14 +76,6 @@
#include <unordered_set>
#include <vector>
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
-#if defined(__i386__) || defined(__x86_64__)
-#include <x86intrin.h>
-#endif
-
#include "../mdbx.h"
#include "../src/defs.h"
#include "../src/osal.h"
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/config.cc b/plugins/Dbx_mdbx/src/libmdbx/test/config.cc
index 2b9c6e5a0c..cbff68ce4e 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/config.cc
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/config.cc
@@ -278,8 +278,6 @@ void dump(const char *title) {
logging::local_suffix indent(title);
for (auto i = global::actors.begin(); i != global::actors.end(); ++i) {
- const std::string tableid =
- i->space_id ? "MAINDB" : ("SUB#" + std::to_string(i->space_id));
log_info("#%u, testcase %s, space_id/table %u\n", i->actor_id,
testcase2str(i->testcase), i->space_id);
indent.push();
@@ -326,6 +324,11 @@ void dump(const char *title) {
else
log_info("no-delay\n");
+ if (i->params.inject_writefaultn)
+ log_info("inject-writefault on %u ops\n", i->params.inject_writefaultn);
+ else
+ log_info("no-inject-writefault\n");
+
log_info("limits: readers %u, tables %u\n", i->params.max_readers,
i->params.max_tables);
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/config.h b/plugins/Dbx_mdbx/src/libmdbx/test/config.h
index 5efd31100a..86f37fbed8 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/config.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/config.h
@@ -218,6 +218,7 @@ struct actor_params_pod {
unsigned delaystart;
unsigned waitfor_nops;
+ unsigned inject_writefaultn;
unsigned max_readers;
unsigned max_tables;
@@ -244,7 +245,7 @@ void dump(const char *title = "config-dump: ");
struct actor_params : public config::actor_params_pod {
std::string pathname_log;
std::string pathname_db;
- void set_defaults(void);
+ void set_defaults(const std::string &tmpdir);
};
struct actor_config : public config::actor_config_pod {
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/log.cc b/plugins/Dbx_mdbx/src/libmdbx/test/log.cc
index 8697effd8f..6ad33ced35 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/log.cc
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/log.cc
@@ -285,3 +285,5 @@ void log_trouble(const char *where, const char *what, int errnum) {
bool log_enabled(const logging::loglevel priority) {
return (priority >= logging::level);
}
+
+void log_flush(void) { fflushall(); }
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/log.h b/plugins/Dbx_mdbx/src/libmdbx/test/log.h
index c321f3ce91..81eaf2ca91 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/log.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/log.h
@@ -81,6 +81,7 @@ void __printf_args(1, 2) log_warning(const char *msg, ...);
void __printf_args(1, 2) log_error(const char *msg, ...);
void log_trouble(const char *where, const char *what, int errnum);
+void log_flush(void);
bool log_enabled(const logging::loglevel priority);
#ifdef _DEBUG
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/main.cc b/plugins/Dbx_mdbx/src/libmdbx/test/main.cc
index adf60aae62..98461a245d 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/main.cc
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/main.cc
@@ -22,21 +22,16 @@ void __noreturn usage(void) {
//-----------------------------------------------------------------------------
-void actor_params::set_defaults(void) {
+void actor_params::set_defaults(const std::string &tmpdir) {
pathname_log = "";
loglevel =
#ifdef NDEBUG
- logging::notice;
+ logging::info;
#else
logging::trace;
#endif
- pathname_db =
-#ifdef __linux__
- "/dev/shm/test_tmpdb.mdbx";
-#else
- "test_tmpdb.mdbx";
-#endif
+ pathname_db = tmpdir + "mdbx-test.db";
mode_flags = MDBX_NOSUBDIR | MDBX_WRITEMAP | MDBX_MAPASYNC | MDBX_NORDAHEAD |
MDBX_NOMEMINIT | MDBX_COALESCE | MDBX_LIFORECLAIM;
table_flags = MDBX_DUPSORT;
@@ -65,6 +60,7 @@ void actor_params::set_defaults(void) {
delaystart = 0;
waitfor_nops = 0;
+ inject_writefaultn = 0;
drop_table = false;
@@ -135,7 +131,7 @@ int main(int argc, char *const argv[]) {
: EXIT_FAILURE;
actor_params params;
- params.set_defaults();
+ params.set_defaults(osal_tempdir());
global::config::dump_config = true;
logging::setup((logging::loglevel)params.loglevel, "main");
unsigned last_space_id = 0;
@@ -219,6 +215,9 @@ int main(int argc, char *const argv[]) {
if (config::parse_option(argc, argv, narg, "wait4ops", params.waitfor_nops,
config::decimal))
continue;
+ if (config::parse_option(argc, argv, narg, "inject-writefault",
+ params.inject_writefaultn, config::decimal))
+ continue;
if (config::parse_option(argc, argv, narg, "drop", params.drop_table))
continue;
if (config::parse_option(argc, argv, narg, "dump-config",
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/osal-unix.cc b/plugins/Dbx_mdbx/src/libmdbx/test/osal-unix.cc
index 7625e0f419..8132e267ef 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/osal-unix.cc
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/osal-unix.cc
@@ -272,3 +272,22 @@ void osal_udelay(unsigned us) {
}
bool osal_istty(int fd) { return isatty(fd) == 1; }
+
+std::string osal_tempdir(void) {
+ const char *tempdir = getenv("TMPDIR");
+ if (!tempdir)
+ tempdir = getenv("TMP");
+ if (!tempdir)
+ tempdir = getenv("TEMPDIR");
+ if (!tempdir)
+ tempdir = getenv("TEMP");
+ if (tempdir) {
+ std::string dir(tempdir);
+ if (!dir.empty() && dir.at(dir.length() - 1) != '/')
+ dir.append("/");
+ return dir;
+ }
+ if (access("/dev/shm/", R_OK | W_OK | X_OK) == 0)
+ return "/dev/shm/";
+ return "";
+}
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc b/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc
index b1a8928cbb..5d2e51a66d 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc
@@ -305,3 +305,9 @@ void osal_udelay(unsigned us) {
}
bool osal_istty(int fd) { return _isatty(fd) != 0; }
+
+std::string osal_tempdir(void) {
+ char buf[MAX_PATH + 1];
+ DWORD len = GetTempPathA(sizeof(buf), buf);
+ return std::string(buf, len);
+}
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/osal.h b/plugins/Dbx_mdbx/src/libmdbx/test/osal.h
index f75aae3831..c27282a656 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/osal.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/osal.h
@@ -31,6 +31,7 @@ int osal_delay(unsigned seconds);
void osal_udelay(unsigned us);
void osal_yield(void);
bool osal_istty(int fd);
+std::string osal_tempdir(void);
#ifdef _MSC_VER
#ifndef STDIN_FILENO
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/test.cc b/plugins/Dbx_mdbx/src/libmdbx/test/test.cc
index 8700d74add..02986b3d1a 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/test.cc
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/test.cc
@@ -123,7 +123,7 @@ void testcase::db_prepare() {
if (config.params.loglevel <= logging::verbose)
mdbx_dbg_opts |= MDBX_DBG_PRINT;
int rc = mdbx_setup_debug(mdbx_dbg_opts, mdbx_logger);
- log_info("set mdbx debug-opts: 0x%02x", rc);
+ log_trace("set mdbx debug-opts: 0x%02x", rc);
MDBX_env *env = nullptr;
rc = mdbx_env_create(&env);
@@ -204,6 +204,7 @@ void testcase::txn_end(bool abort) {
if (unlikely(rc != MDBX_SUCCESS))
failure_perror("mdbx_txn_abort()", rc);
} else {
+ txn_inject_writefault(txn);
int rc = mdbx_txn_commit(txn);
if (unlikely(rc != MDBX_SUCCESS))
failure_perror("mdbx_txn_commit()", rc);
@@ -218,6 +219,27 @@ void testcase::txn_restart(bool abort, bool readonly, unsigned flags) {
txn_begin(readonly, flags);
}
+void testcase::txn_inject_writefault(void) {
+ if (txn_guard)
+ txn_inject_writefault(txn_guard.get());
+}
+
+void testcase::txn_inject_writefault(MDBX_txn *txn) {
+ if (config.params.inject_writefaultn && txn) {
+ if (config.params.inject_writefaultn <= nops_completed &&
+ (mdbx_txn_flags(txn) & MDBX_RDONLY) == 0) {
+ log_info("== txn_inject_writefault(): got %u nops or more, inject FAULT",
+ config.params.inject_writefaultn);
+ log_flush();
+#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
+ TerminateProcess(GetCurrentProcess(), 42);
+#else
+ raise(SIGKILL);
+#endif
+ }
+ }
+}
+
bool testcase::wait4start() {
if (config.wait4id) {
log_trace(">> wait4start(%u)", config.wait4id);
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/test.h b/plugins/Dbx_mdbx/src/libmdbx/test/test.h
index 4158aba457..ef1c4caa47 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/test.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/test.h
@@ -107,6 +107,8 @@ protected:
void txn_begin(bool readonly, unsigned flags = 0);
void txn_end(bool abort);
void txn_restart(bool abort, bool readonly, unsigned flags = 0);
+ void txn_inject_writefault(void);
+ void txn_inject_writefault(MDBX_txn *txn);
void fetch_canary();
void update_canary(uint64_t increment);
void kick_progress(bool active) const;
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/utils.cc b/plugins/Dbx_mdbx/src/libmdbx/test/utils.cc
index 96866f61b7..0855c7eef3 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/utils.cc
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/utils.cc
@@ -14,44 +14,10 @@
#include "test.h"
#include <float.h>
-#ifdef HAVE_IEEE754_H
+#if defined(HAVE_IEEE754_H) || __has_include(<ieee754.h>)
#include <ieee754.h>
#endif
-/* Compiler's includes for builtins/intrinsics */
-#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
-#include <intrin.h>
-#elif __GNUC_PREREQ(4, 4) || defined(__clang__)
-#if defined(__ia32__) || defined(__e2k__)
-#include <x86intrin.h>
-#endif /* __ia32__ */
-#if defined(__ia32__)
-#include <cpuid.h>
-#endif /* __ia32__ */
-#elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
-#include <mbarrier.h>
-#elif (defined(_HPUX_SOURCE) || defined(__hpux) || defined(__HP_aCC)) && \
- (defined(HP_IA64) || defined(__ia64))
-#include <machine/sys/inline.h>
-#elif defined(__IBMC__) && defined(__powerpc)
-#include <atomic.h>
-#elif defined(_AIX)
-#include <builtins.h>
-#include <sys/atomic_op.h>
-#elif (defined(__osf__) && defined(__DECC)) || defined(__alpha)
-#include <c_asm.h>
-#include <machine/builtins.h>
-#elif defined(__MWERKS__)
-/* CodeWarrior - troubles ? */
-#pragma gcc_extensions
-#elif defined(__SNC__)
-/* Sony PS3 - troubles ? */
-#elif defined(__hppa__) || defined(__hppa)
-#include <machine/inline.h>
-#else
-#error Unsupported C compiler, please use GNU C 4.4 or newer
-#endif /* Compiler */
-
std::string format(const char *fmt, ...) {
va_list ap, ones;
va_start(ap, fmt);
@@ -127,8 +93,22 @@ bool hex2data(const char *hex_begin, const char *hex_end, void *ptr,
//-----------------------------------------------------------------------------
+/* TODO: replace my 'libmera' fomr t1ha. */
uint64_t entropy_ticks(void) {
+#if defined(EMSCRIPTEN)
+ return (uint64_t)emscripten_get_now();
+#endif /* EMSCRIPTEN */
+
+#if defined(__APPLE__) || defined(__MACH__)
+ return mach_absolute_time();
+#endif /* defined(__APPLE__) || defined(__MACH__) */
+
+#if defined(__sun__) || defined(__sun)
+ return gethrtime();
+#endif /* __sun__ */
+
#if defined(__GNUC__) || defined(__clang__)
+
#if defined(__ia64__)
uint64_t ticks;
__asm __volatile("mov %0=ar.itc" : "=r"(ticks));
@@ -145,29 +125,81 @@ uint64_t entropy_ticks(void) {
uint64_t ticks;
__asm __volatile("rpcc %0" : "=r"(ticks));
return ticks;
-#elif defined(__sparc_v9__)
- uint64_t ticks;
- __asm __volatile("rd %%tick, %0" : "=r"(ticks));
- return ticks;
-#elif defined(__powerpc64__) || defined(__ppc64__)
+#elif defined(__sparc__) || defined(__sparc) || defined(__sparc64__) || \
+ defined(__sparc64) || defined(__sparc_v8plus__) || \
+ defined(__sparc_v8plus) || defined(__sparc_v8plusa__) || \
+ defined(__sparc_v8plusa) || defined(__sparc_v9__) || defined(__sparc_v9)
+
+ union {
+ uint64_t u64;
+ struct {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ uint32_t h, l;
+#else
+ uint32_t l, h;
+#endif
+ } u32;
+ } cycles;
+
+#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || \
+ defined(__sparc_v9__) || defined(__sparc_v8plus) || \
+ defined(__sparc_v8plusa) || defined(__sparc_v9)
+
+#if UINTPTR_MAX > 0xffffFFFFul || ULONG_MAX > 0xffffFFFFul || \
+ defined(__sparc64__) || defined(__sparc64)
+ __asm __volatile("rd %%tick, %0" : "=r"(cycles.u64));
+#else
+ __asm __volatile("rd %%tick, %1; srlx %1, 32, %0"
+ : "=r"(cycles.u32.h), "=r"(cycles.u32.l));
+#endif /* __sparc64__ */
+
+#else
+ __asm __volatile(".byte 0x83, 0x41, 0x00, 0x00; mov %%g1, %0"
+ : "=r"(cycles.u64)
+ :
+ : "%g1");
+#endif /* __sparc8plus__ || __sparc_v9__ */
+ return cycles.u64;
+
+#elif (defined(__powerpc64__) || defined(__ppc64__) || defined(__ppc64) || \
+ defined(__powerpc64))
uint64_t ticks;
__asm __volatile("mfspr %0, 268" : "=r"(ticks));
return ticks;
-#elif defined(__ppc__) || defined(__powerpc__)
- unsigned tbl, tbu;
-
- /* LY: Here not a problem if a high-part (tbu)
- * would been updated during reading. */
- __asm __volatile("mftb %0" : "=r"(tbl));
- __asm __volatile("mftbu %0" : "=r"(tbu));
-
- return (((uin64_t)tbu0) << 32) | tbl;
+#elif (defined(__powerpc__) || defined(__ppc__) || defined(__powerpc) || \
+ defined(__ppc))
+#if UINTPTR_MAX > 0xffffFFFFul || ULONG_MAX > 0xffffFFFFul
+ uint64_t ticks;
+ __asm __volatile("mftb %0" : "=r"(ticks));
+ *now = ticks;
+#else
+ uint64_t ticks;
+ uint32_t low, high_before, high_after;
+ __asm __volatile("mftbu %0; mftb %1; mftbu %2"
+ : "=r"(high_before), "=r"(low), "=r"(high_after));
+ ticks = (uint64_t)high_after << 32;
+ ticks |= low & /* zeroes if high part has changed */
+ ~(high_before - high_after);
+#endif
+#elif defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH > 7)
+ uint64_t virtual_timer;
+ __asm __volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer));
+ return virtual_timer;
+#elif defined(__ARM_ARCH) && __ARM_ARCH > 5 && __ARM_ARCH < 8
+ unsigned long pmccntr;
+ __asm __volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr));
+ return pmccntr;
+#elif defined(__mips__) || defined(__mips) || defined(_R4000)
+ unsigned count;
+ __asm __volatile("rdhwr %0, $2" : "=r"(count));
+ return count;
#endif /* arch selector */
#endif /* __GNUC__ || __clang__ */
-#if defined(__e2k__) || defined(__elbrus__) || defined(_M_IX86) || \
- defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
+#if defined(__e2k__) || defined(__ia32__)
return __rdtsc();
+#elif defined(_M_ARM)
+ return __rdpmccntr64();
#elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
LARGE_INTEGER PerformanceCount;
if (QueryPerformanceCounter(&PerformanceCount))
diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/utils.h b/plugins/Dbx_mdbx/src/libmdbx/test/utils.h
index 176823c60b..5d62909fd5 100644
--- a/plugins/Dbx_mdbx/src/libmdbx/test/utils.h
+++ b/plugins/Dbx_mdbx/src/libmdbx/test/utils.h
@@ -17,33 +17,8 @@
#if !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__) || \
!defined(__ORDER_BIG_ENDIAN__)
-#ifndef _MSC_VER
-#include <sys/param.h> /* for endianness */
-#endif
-#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
-#define __ORDER_LITTLE_ENDIAN__ __LITTLE_ENDIAN
-#define __ORDER_BIG_ENDIAN__ __BIG_ENDIAN
-#define __BYTE_ORDER__ __BYTE_ORDER
-#else
-#define __ORDER_LITTLE_ENDIAN__ 1234
-#define __ORDER_BIG_ENDIAN__ 4321
-#if defined(__LITTLE_ENDIAN__) || defined(_LITTLE_ENDIAN) || \
- defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
- defined(__MIPSEL__) || defined(_MIPSEL) || defined(__MIPSEL) || \
- defined(__i386) || defined(__x86_64__) || defined(_M_IX86) || \
- defined(_M_X64) || defined(i386) || defined(_X86_) || defined(__i386__) || \
- defined(_X86_64_) || defined(_M_ARM) || defined(_M_ARM64) || \
- defined(__e2k__)
-#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
-#elif defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN) || defined(__ARMEB__) || \
- defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(__MIPSEB__) || \
- defined(_MIPSEB) || defined(__MIPSEB) || defined(_M_IA64)
-#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
-#else
#error __BYTE_ORDER__ should be defined.
#endif
-#endif
-#endif
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ && \
__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
@@ -274,7 +249,7 @@ static __inline void memory_barrier(void) {
#elif defined(__INTEL_COMPILER) /* LY: Intel Compiler may mimic GCC and MSC */
#if defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
__mf();
-#elif defined(__i386__) || defined(__x86_64__)
+#elif defined(__ia32__)
_mm_mfence();
#else
#error "Unknown target for Intel Compiler, please report to us."
@@ -293,8 +268,7 @@ static __inline void memory_barrier(void) {
}
static __inline void cpu_relax() {
-#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \
- defined(_M_X64)
+#if defined(__ia32__)
_mm_pause();
#elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || \
defined(YieldProcessor)