Reactor: Copy System/Debug code to Reactor copy

Delete Reactor/DebugAndroid.cpp and Reactor/DebugAndroid.hpp for the same reasons explained in the parent change.

The System / Reactor debug implementations are still not merged, but at least they're now consistent.
System/Debug requires `UNIMPLEMENTED()` to have a bug number for each message, but reactor has a whole bunch of ancient uses without any mention of a bug. I don't have the context to create these bugs, so for now I've created a temporary `UNIMPLEMENTED_NO_BUG()` variant. With this we can easily grep the codebase to locate these usages and create bugs as needed.

Bug: b/146051794
Bug: b/144093703
Change-Id: Id5208f924e63dae7443f95aab5b601a290c297e7
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/40969
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/Reactor/Debug.cpp b/src/Reactor/Debug.cpp
index 0e87015..5b10036 100644
--- a/src/Reactor/Debug.cpp
+++ b/src/Reactor/Debug.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,33 +14,158 @@
 
 #include "Debug.hpp"
 
+#include <atomic>
 #include <cstdarg>
 #include <cstdio>
 #include <string>
 
-#if defined(_WIN32)
-#	include <windows.h>
+#if __ANDROID__
+#	include <android/log.h>
 #endif
 
-namespace rr {
+#if defined(__unix__)
+#	define PTRACE
+#	include <sys/ptrace.h>
+#	include <sys/types.h>
+#elif defined(_WIN32) || defined(_WIN64)
+#	include <windows.h>
+#elif defined(__APPLE__) || defined(__MACH__)
+#	include <sys/sysctl.h>
+#	include <unistd.h>
+#endif
 
-void tracev(const char *format, va_list args)
+#ifdef ERROR
+#	undef ERROR  // b/127920555
+#endif
+
+#ifndef REACTOR_LOGGING_LEVEL
+#	define REACTOR_LOGGING_LEVEL INFO
+#endif
+
+namespace {
+
+bool IsUnderDebugger()
 {
-#ifndef RR_DISABLE_TRACE
-	const bool traceToDebugOut = false;
-	const bool traceToFile = false;
+#if defined(PTRACE) && !defined(__APPLE__) && !defined(__MACH__)
+	static bool checked = false;
+	static bool res = false;
 
-	if(traceToDebugOut)
+	if(!checked)
 	{
-		char buffer[2048];
-		vsnprintf(buffer, sizeof(buffer), format, args);
-#	if defined(_WIN32)
-		::OutputDebugString(buffer);
-#	else
-		printf("%s", buffer);
-#	endif
+		// If a debugger is attached then we're already being ptraced and ptrace
+		// will return a non-zero value.
+		checked = true;
+		if(ptrace(PTRACE_TRACEME, 0, 1, 0) != 0)
+		{
+			res = true;
+		}
+		else
+		{
+			ptrace(PTRACE_DETACH, 0, 1, 0);
+		}
 	}
 
+	return res;
+#elif defined(_WIN32) || defined(_WIN64)
+	return IsDebuggerPresent() != 0;
+#elif defined(__APPLE__) || defined(__MACH__)
+	// Code comes from the Apple Technical Q&A QA1361
+
+	// Tell sysctl what info we're requestion. Specifically we're asking for
+	// info about this our PID.
+	int res = 0;
+	int request[4] = {
+		CTL_KERN,
+		KERN_PROC,
+		KERN_PROC_PID,
+		getpid()
+	};
+	struct kinfo_proc info;
+	size_t size = sizeof(info);
+
+	info.kp_proc.p_flag = 0;
+
+	// Get the info we're requesting, if sysctl fails then info.kp_proc.p_flag will remain 0.
+	res = sysctl(request, sizeof(request) / sizeof(*request), &info, &size, NULL, 0);
+	ASSERT_MSG(res == 0, "syscl returned %d", res);
+
+	// We're being debugged if the P_TRACED flag is set
+	return ((info.kp_proc.p_flag & P_TRACED) != 0);
+#else
+	return false;
+#endif
+}
+
+enum class Level
+{
+	DEBUG,
+	INFO,
+	WARN,
+	ERROR,
+	FATAL,
+};
+
+#ifdef __ANDROID__
+void logv_android(Level level, const char *msg)
+{
+	switch(level)
+	{
+		case Level::DEBUG:
+			__android_log_write(ANDROID_LOG_DEBUG, "SwiftShader", msg);
+			break;
+		case Level::INFO:
+			__android_log_write(ANDROID_LOG_INFO, "SwiftShader", msg);
+			break;
+		case Level::WARN:
+			__android_log_write(ANDROID_LOG_WARN, "SwiftShader", msg);
+			break;
+		case Level::ERROR:
+			__android_log_write(ANDROID_LOG_ERROR, "SwiftShader", msg);
+			break;
+		case Level::FATAL:
+			__android_log_write(ANDROID_LOG_FATAL, "SwiftShader", msg);
+			break;
+	}
+}
+#else
+void logv_std(Level level, const char *msg)
+{
+	switch(level)
+	{
+		case Level::DEBUG:
+		case Level::INFO:
+			fprintf(stdout, "%s", msg);
+			break;
+		case Level::WARN:
+		case Level::ERROR:
+		case Level::FATAL:
+			fprintf(stderr, "%s", msg);
+			break;
+	}
+}
+#endif
+
+void logv(Level level, const char *format, va_list args)
+{
+	if(static_cast<int>(level) < static_cast<int>(Level::REACTOR_LOGGING_LEVEL))
+	{
+		return;
+	}
+
+#ifndef SWIFTSHADER_DISABLE_TRACE
+	char buffer[2048];
+	vsnprintf(buffer, sizeof(buffer), format, args);
+
+#	if defined(__ANDROID__)
+	logv_android(level, buffer);
+#	elif defined(_WIN32)
+	logv_std(level, buffer);
+	::OutputDebugString(buffer);
+#	else
+	logv_std(level, buffer);
+#	endif
+
+	const bool traceToFile = false;
 	if(traceToFile)
 	{
 		FILE *file = fopen(TRACE_OUTPUT_FILE, "a");
@@ -51,14 +176,18 @@
 			fclose(file);
 		}
 	}
-#endif
+#endif  // SWIFTSHADER_DISABLE_TRACE
 }
 
+}  // anonymous namespace
+
+namespace rr {
+
 void trace(const char *format, ...)
 {
 	va_list vararg;
 	va_start(vararg, format);
-	tracev(format, vararg);
+	logv(Level::DEBUG, format, vararg);
 	va_end(vararg);
 }
 
@@ -66,11 +195,7 @@
 {
 	va_list vararg;
 	va_start(vararg, format);
-	tracev(format, vararg);
-	va_end(vararg);
-
-	va_start(vararg, format);
-	vfprintf(stderr, format, vararg);
+	logv(Level::WARN, format, vararg);
 	va_end(vararg);
 }
 
@@ -79,14 +204,32 @@
 	va_list vararg;
 
 	va_start(vararg, format);
-	tracev(format, vararg);
-	va_end(vararg);
-
-	va_start(vararg, format);
-	vfprintf(stderr, format, vararg);
+	logv(Level::FATAL, format, vararg);
 	va_end(vararg);
 
 	::abort();
 }
 
+void trace_assert(const char *format, ...)
+{
+	static std::atomic<bool> asserted = { false };
+	if(IsUnderDebugger() && !asserted.exchange(true))
+	{
+		// Abort after tracing and printing to stderr
+		va_list vararg;
+		va_start(vararg, format);
+		logv(Level::FATAL, format, vararg);
+		va_end(vararg);
+
+		::abort();
+	}
+	else if(!asserted)
+	{
+		va_list vararg;
+		va_start(vararg, format);
+		logv(Level::FATAL, format, vararg);
+		va_end(vararg);
+	}
+}
+
 }  // namespace rr
diff --git a/src/Reactor/Debug.hpp b/src/Reactor/Debug.hpp
index c0f3232..bac94d8 100644
--- a/src/Reactor/Debug.hpp
+++ b/src/Reactor/Debug.hpp
@@ -21,6 +21,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <cctype>
+#include <string>
+
 #if !defined(TRACE_OUTPUT_FILE)
 #	define TRACE_OUTPUT_FILE "debug.txt"
 #endif
@@ -44,14 +47,19 @@
 // Outputs the message to the debugging log and stderr, and calls abort().
 void abort(const char *format, ...) CHECK_PRINTF_ARGS;
 
+// Outputs text to the debugging log, and asserts once if a debugger is attached.
+void trace_assert(const char *format, ...) CHECK_PRINTF_ARGS;
+
 }  // namespace rr
 
 // A macro to output a trace of a function call and its arguments to the
 // debugging log. Disabled if RR_DISABLE_TRACE is defined.
 #if defined(RR_DISABLE_TRACE)
 #	define TRACE(message, ...) (void(0))
+#	define TRACE_ASSERT(message, ...) (void(0))
 #else
 #	define TRACE(message, ...) rr::trace("%s:%d TRACE: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
+#	define TRACE_ASSERT(message, ...) rr::trace_assert("%s:%d %s TRACE_ASSERT: " message "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
 #endif
 
 // A macro to print a warning message to the debugging log and stderr to denote
@@ -104,11 +112,31 @@
 		}                                        \
 	} while(0)
 
-// A macro to indicate unimplemented functionality.
-#undef UNIMPLEMENTED
-#define UNIMPLEMENTED(format, ...) DABORT("UNIMPLEMENTED: " format, ##__VA_ARGS__)
+// A macro to indicate functionality currently unimplemented, for a feature advertised
+// as supported. This is similar to UNIMPLEMENTED() but does not check there's a bug
+// number.
+#undef UNIMPLEMENTED_NO_BUG
+#define UNIMPLEMENTED_NO_BUG(format, ...) \
+	DABORT("UNIMPLEMENTED: " format, ##__VA_ARGS__);
 
-// A macro for code which is not expected to be reached under valid assumptions.
+// A macro to indicate functionality currently unimplemented, for a feature advertised
+// as supported. Since this is a bug, a bug ID must be provided, in b/### format.
+// For unimplemented functionality not advertised as supported, use UNSUPPORTED() instead.
+#undef UNIMPLEMENTED
+#define UNIMPLEMENTED(format, ...)                                                                                                                            \
+	static_assert(format[0] == 'b' && format[1] == '/' && format[2] >= '0' && format[2] <= '9', "explanation must start with bug reference in b/### format"); \
+	UNIMPLEMENTED_NO_BUG(format, ##__VA_ARGS__)
+
+// A macro to indicate unsupported functionality.
+// This should be called when a feature is attempted to be used, but is not
+// currently implemented by Reactor.
+// Note that in a well-behaved application these should not be reached as the
+// application should be respecting the advertised features / limits.
+#undef UNSUPPORTED
+#define UNSUPPORTED(format, ...) DABORT("UNSUPPORTED: " format, ##__VA_ARGS__)
+
+// A macro for code which should never be reached, even with misbehaving
+// applications.
 #undef UNREACHABLE
 #define UNREACHABLE(format, ...) DABORT("UNREACHABLE: " format, ##__VA_ARGS__)
 
diff --git a/src/Reactor/DebugAndroid.cpp b/src/Reactor/DebugAndroid.cpp
deleted file mode 100644
index 5194cc3..0000000
--- a/src/Reactor/DebugAndroid.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "DebugAndroid.hpp"
-
-#include <cutils/properties.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-void AndroidEnterDebugger()
-{
-	ALOGE(__FUNCTION__);
-#ifndef NDEBUG
-	static volatile int *const makefault = nullptr;
-	char value[PROPERTY_VALUE_MAX];
-	property_get("debug.db.uid", value, "-1");
-	int debug_uid = atoi(value);
-	if((debug_uid >= 0) && (geteuid() < static_cast<uid_t>(debug_uid)))
-	{
-		ALOGE("Waiting for debugger: gdbserver :${PORT} --attach %u. Look for thread %u", getpid(), gettid());
-		volatile int waiting = 1;
-		while(waiting)
-		{
-			sleep(1);
-		}
-	}
-	else
-	{
-		ALOGE("No debugger");
-	}
-#endif
-}
-
-void trace(const char *format, ...)
-{
-#ifndef NDEBUG
-	va_list vararg;
-	va_start(vararg, format);
-	android_vprintLog(ANDROID_LOG_VERBOSE, NULL, LOG_TAG, format, vararg);
-	va_end(vararg);
-#endif
-}
diff --git a/src/Reactor/DebugAndroid.hpp b/src/Reactor/DebugAndroid.hpp
deleted file mode 100644
index a8cbc9f..0000000
--- a/src/Reactor/DebugAndroid.hpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef DebugAndroid_hpp
-#define DebugAndroid_hpp
-
-#if ANDROID_PLATFORM_SDK_VERSION < 27
-#	include <cutils/log.h>
-#elif ANDROID_PLATFORM_SDK_VERSION >= 27
-#	include <log/log.h>
-#else
-#	error "ANDROID_PLATFORM_SDK_VERSION is not defined"
-#endif
-
-#include <cassert>
-
-// On Android Virtual Devices we heavily depend on logging, even in
-// production builds. We do this because AVDs are components of larger
-// systems, and may be configured in ways that are difficult to
-// reproduce locally. For example some system run tests against
-// third-party code that we cannot access.  Aborting (cf. assert) on
-// unimplemented functionality creates two problems. First, it produces
-// a service failure where none is needed. Second, it puts the
-// customer on the critical path for notifying us of a problem.
-// The alternative, skipping unimplemented functionality silently, is
-// arguably worse: neither the service provider nor the customer will
-// learn that unimplemented functionality may have compromised the test
-// results.
-// Logging invocations of unimplemented functionality is useful to both
-// service provider and the customer. The service provider can learn
-// that the functionality is needed. The customer learns that the test
-// results may be compromised.
-
-/**
- * Enter the debugger with a memory fault iff debuggerd is set to capture this
- * process. Otherwise return.
- */
-void AndroidEnterDebugger();
-
-#define ASSERT(E)                                                    \
-	do                                                               \
-	{                                                                \
-		if(!(E))                                                     \
-		{                                                            \
-			ALOGE("badness: assertion_failed %s in %s at %s:%d", #E, \
-			      __FUNCTION__, __FILE__, __LINE__);                 \
-			AndroidEnterDebugger();                                  \
-		}                                                            \
-	} while(0)
-
-#undef assert
-#define assert(E) ASSERT(E)
-
-#define ERR(format, ...)                                                    \
-	do                                                                      \
-	{                                                                       \
-		ALOGE("badness: err %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
-		      __LINE__, ##__VA_ARGS__);                                     \
-		AndroidEnterDebugger();                                             \
-	} while(0)
-
-#define FIXME(format, ...)                                                    \
-	do                                                                        \
-	{                                                                         \
-		ALOGE("badness: fixme %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
-		      __LINE__, ##__VA_ARGS__);                                       \
-		AndroidEnterDebugger();                                               \
-	} while(0)
-
-// TODO: Handle __VA_ARGS__ (can be empty)
-#define UNIMPLEMENTED(...)                        \
-	do                                            \
-	{                                             \
-		ALOGE("badness: unimplemented: %s %s:%d", \
-		      __FUNCTION__, __FILE__, __LINE__);  \
-		AndroidEnterDebugger();                   \
-	} while(0)
-
-#define UNREACHABLE(value)                                           \
-	do                                                               \
-	{                                                                \
-		ALOGE("badness: unreachable case reached: %s %s:%d. %s: %d", \
-		      __FUNCTION__, __FILE__, __LINE__, #value, value);      \
-		AndroidEnterDebugger();                                      \
-	} while(0)
-
-#ifndef NDEBUG
-#	define TRACE(format, ...)                                 \
-		ALOGV("%s %s:%d (" format ")", __FUNCTION__, __FILE__, \
-		      __LINE__, ##__VA_ARGS__)
-#else
-#	define TRACE(...) ((void)0)
-#endif
-
-void trace(const char *format, ...);
-
-#endif  // DebugAndroid_hpp
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index 29c29e1..2a36d98 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -414,7 +414,7 @@
 				case 4: atomicLoad<uint32_t>(ptr, ret, ordering); break;
 				case 8: atomicLoad<uint64_t>(ptr, ret, ordering); break;
 				default:
-					UNIMPLEMENTED("Atomic::load(size: %d)", int(size));
+					UNIMPLEMENTED_NO_BUG("Atomic::load(size: %d)", int(size));
 			}
 		}
 		static void store(size_t size, void *ptr, void *ret, llvm::AtomicOrdering ordering)
@@ -426,7 +426,7 @@
 				case 4: atomicStore<uint32_t>(ptr, ret, ordering); break;
 				case 8: atomicStore<uint64_t>(ptr, ret, ordering); break;
 				default:
-					UNIMPLEMENTED("Atomic::store(size: %d)", int(size));
+					UNIMPLEMENTED_NO_BUG("Atomic::store(size: %d)", int(size));
 			}
 		}
 	};
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 7d154b8..b0c014e 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -53,7 +53,7 @@
 #if defined(__x86_64__) && defined(_WIN32)
 extern "C" void X86CompilationCallback()
 {
-	UNIMPLEMENTED("X86CompilationCallback");
+	UNIMPLEMENTED_NO_BUG("X86CompilationCallback");
 }
 #endif
 
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 98d144a..4624064 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -1169,7 +1169,7 @@
 {
 	// TODO(b/148139679) Fix Subzero generating invalid code for FRem on vector types
 	// createArithmetic(Ice::InstArithmetic::Frem, lhs, rhs);
-	UNIMPLEMENTED("Nucleus::createFRem");
+	UNIMPLEMENTED("b/148139679 Nucleus::createFRem");
 	return nullptr;
 }
 
@@ -2272,7 +2272,7 @@
 
 Short4::Short4(RValue<Float4> cast)
 {
-	UNIMPLEMENTED("Short4::Short4(RValue<Float4> cast)");
+	UNIMPLEMENTED_NO_BUG("Short4::Short4(RValue<Float4> cast)");
 }
 
 RValue<Short4> operator<<(RValue<Short4> lhs, unsigned char rhs)
@@ -2750,7 +2750,7 @@
 
 RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)
 {
-	UNIMPLEMENTED("RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)");
+	UNIMPLEMENTED_NO_BUG("RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y)");
 	return UShort4(0);
 }
 
@@ -2815,13 +2815,13 @@
 
 RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)
 {
-	UNIMPLEMENTED("RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)");
+	UNIMPLEMENTED_NO_BUG("RValue<Int4> MulAdd(RValue<Short8> x, RValue<Short8> y)");
 	return Int4(0);
 }
 
 RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)
 {
-	UNIMPLEMENTED("RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)");
+	UNIMPLEMENTED_NO_BUG("RValue<Short8> MulHigh(RValue<Short8> x, RValue<Short8> y)");
 	return Short8(0);
 }
 
@@ -2886,7 +2886,7 @@
 
 RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)
 {
-	UNIMPLEMENTED("RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)");
+	UNIMPLEMENTED_NO_BUG("RValue<UShort8> MulHigh(RValue<UShort8> x, RValue<UShort8> y)");
 	return UShort8(0);
 }
 
@@ -3801,7 +3801,7 @@
 
 RValue<Long> Ticks()
 {
-	UNIMPLEMENTED("RValue<Long> Ticks()");
+	UNIMPLEMENTED_NO_BUG("RValue<Long> Ticks()");
 	return Long(Int(0));
 }
 
@@ -3851,12 +3851,12 @@
 
 Value *Nucleus::createMaskedLoad(Value *ptr, Type *elTy, Value *mask, unsigned int alignment, bool zeroMaskedLanes)
 {
-	UNIMPLEMENTED("Subzero createMaskedLoad()");
+	UNIMPLEMENTED_NO_BUG("Subzero createMaskedLoad()");
 	return nullptr;
 }
 void Nucleus::createMaskedStore(Value *ptr, Value *val, Value *mask, unsigned int alignment)
 {
-	UNIMPLEMENTED("Subzero createMaskedStore()");
+	UNIMPLEMENTED_NO_BUG("Subzero createMaskedStore()");
 }
 
 RValue<Float4> Gather(RValue<Pointer<Float>> base, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment, bool zeroMaskedLanes /* = false */)
@@ -3983,7 +3983,7 @@
 {
 	if(emulateIntrinsics)
 	{
-		UNIMPLEMENTED("Subzero Ctlz()");
+		UNIMPLEMENTED_NO_BUG("Subzero Ctlz()");
 		return UInt(0);
 	}
 	else
@@ -4003,7 +4003,7 @@
 {
 	if(emulateIntrinsics)
 	{
-		UNIMPLEMENTED("Subzero Ctlz()");
+		UNIMPLEMENTED_NO_BUG("Subzero Ctlz()");
 		return UInt4(0);
 	}
 	else
@@ -4022,7 +4022,7 @@
 {
 	if(emulateIntrinsics)
 	{
-		UNIMPLEMENTED("Subzero Cttz()");
+		UNIMPLEMENTED_NO_BUG("Subzero Cttz()");
 		return UInt(0);
 	}
 	else
@@ -4042,7 +4042,7 @@
 {
 	if(emulateIntrinsics)
 	{
-		UNIMPLEMENTED("Subzero Cttz()");
+		UNIMPLEMENTED_NO_BUG("Subzero Cttz()");
 		return UInt4(0);
 	}
 	else
@@ -4130,7 +4130,7 @@
 	}
 	ASSERT(coroData->mainFiber);
 #else
-	UNIMPLEMENTED("convertThreadToMainFiber not implemented for current platform");
+	UNIMPLEMENTED_NO_BUG("convertThreadToMainFiber not implemented for current platform");
 #endif
 }
 
@@ -4147,7 +4147,7 @@
 		coroData->mainFiber = nullptr;
 	}
 #else
-	UNIMPLEMENTED("convertMainFiberToThread not implemented for current platform");
+	UNIMPLEMENTED_NO_BUG("convertMainFiberToThread not implemented for current platform");
 #endif
 }
 using FiberFunc = std::function<void()>;
@@ -4172,7 +4172,7 @@
 	coroData->routineFiber = ::CreateFiber(StackSize, &Invoker::fiberEntry, fiberFunc);
 	ASSERT(coroData->routineFiber);
 #else
-	UNIMPLEMENTED("createRoutineFiber not implemented for current platform");
+	UNIMPLEMENTED_NO_BUG("createRoutineFiber not implemented for current platform");
 #endif
 }
 
@@ -4184,7 +4184,7 @@
 	::DeleteFiber(coroData->routineFiber);
 	coroData->routineFiber = nullptr;
 #else
-	UNIMPLEMENTED("deleteRoutineFiber not implemented for current platform");
+	UNIMPLEMENTED_NO_BUG("deleteRoutineFiber not implemented for current platform");
 #endif
 }
 
@@ -4197,7 +4197,7 @@
 	ASSERT(coroData->mainFiber);
 	::SwitchToFiber(coroData->mainFiber);
 #else
-	UNIMPLEMENTED("switchToMainFiber not implemented for current platform");
+	UNIMPLEMENTED_NO_BUG("switchToMainFiber not implemented for current platform");
 #endif
 }
 
@@ -4210,7 +4210,7 @@
 	ASSERT(coroData->routineFiber);
 	::SwitchToFiber(coroData->routineFiber);
 #else
-	UNIMPLEMENTED("switchToRoutineFiber not implemented for current platform");
+	UNIMPLEMENTED_NO_BUG("switchToRoutineFiber not implemented for current platform");
 #endif
 }