Commit 713b8d35 by Ben Clayton

clang-format the src/Reactor directory

Bug: b/144825072 Change-Id: I1f14af4446536c760d11d32aa03edb5f497e75e4 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/39656 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent bc1c067b
...@@ -15,16 +15,16 @@ ...@@ -15,16 +15,16 @@
#include "CPUID.hpp" #include "CPUID.hpp"
#if defined(_WIN32) #if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN # ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#endif # endif
#include <windows.h> # include <windows.h>
#include <intrin.h> # include <intrin.h>
#include <float.h> # include <float.h>
#else #else
#include <unistd.h> # include <unistd.h>
#include <sched.h> # include <sched.h>
#include <sys/types.h> # include <sys/types.h>
#endif #endif
namespace rr { namespace rr {
...@@ -162,18 +162,20 @@ void CPUID::setEnableSSE4_1(bool enable) ...@@ -162,18 +162,20 @@ void CPUID::setEnableSSE4_1(bool enable)
static void cpuid(int registers[4], int info) static void cpuid(int registers[4], int info)
{ {
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
#if defined(_WIN32) # if defined(_WIN32)
__cpuid(registers, info); __cpuid(registers, info);
#else # else
__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info)); __asm volatile("cpuid"
#endif : "=a"(registers[0]), "=b"(registers[1]), "=c"(registers[2]), "=d"(registers[3])
#else : "a"(info));
# endif
#else
registers[0] = 0; registers[0] = 0;
registers[1] = 0; registers[1] = 0;
registers[2] = 0; registers[2] = 0;
registers[3] = 0; registers[3] = 0;
#endif #endif
} }
bool CPUID::detectMMX() bool CPUID::detectMMX()
......
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
namespace rr { namespace rr {
#if !defined(__i386__) && defined(_M_IX86) #if !defined(__i386__) && defined(_M_IX86)
#define __i386__ 1 # define __i386__ 1
#endif #endif
#if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64)) #if !defined(__x86_64__) && (defined(_M_AMD64) || defined(_M_X64))
#define __x86_64__ 1 # define __x86_64__ 1
#endif #endif
class CPUID class CPUID
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <memory> #include <memory>
#ifndef rr_ReactorCoroutine_hpp #ifndef rr_ReactorCoroutine_hpp
#define rr_ReactorCoroutine_hpp # define rr_ReactorCoroutine_hpp
namespace rr { namespace rr {
...@@ -26,17 +26,19 @@ class StreamBase ...@@ -26,17 +26,19 @@ class StreamBase
{ {
protected: protected:
StreamBase(const std::shared_ptr<Routine> &routine, Nucleus::CoroutineHandle handle) StreamBase(const std::shared_ptr<Routine> &routine, Nucleus::CoroutineHandle handle)
: routine(routine), handle(handle) {} : routine(routine)
, handle(handle)
{}
~StreamBase() ~StreamBase()
{ {
auto pfn = (Nucleus::CoroutineDestroy*)routine->getEntry(Nucleus::CoroutineEntryDestroy); auto pfn = (Nucleus::CoroutineDestroy *)routine->getEntry(Nucleus::CoroutineEntryDestroy);
pfn(handle); pfn(handle);
} }
bool await(void* out) bool await(void *out)
{ {
auto pfn = (Nucleus::CoroutineAwait*)routine->getEntry(Nucleus::CoroutineEntryAwait); auto pfn = (Nucleus::CoroutineAwait *)routine->getEntry(Nucleus::CoroutineEntryAwait);
return pfn(handle, out); return pfn(handle, out);
} }
...@@ -53,13 +55,14 @@ class Stream : public StreamBase ...@@ -53,13 +55,14 @@ class Stream : public StreamBase
{ {
public: public:
inline Stream(const std::shared_ptr<Routine> &routine, Nucleus::CoroutineHandle handle) inline Stream(const std::shared_ptr<Routine> &routine, Nucleus::CoroutineHandle handle)
: StreamBase(routine, handle) {} : StreamBase(routine, handle)
{}
// await() retrieves the next yielded value from the coroutine. // await() retrieves the next yielded value from the coroutine.
// Returns true if the coroutine yieled a value and out was assigned a // Returns true if the coroutine yieled a value and out was assigned a
// new value. If await() returns false, the coroutine has finished // new value. If await() returns false, the coroutine has finished
// execution and await() will return false for all future calls. // execution and await() will return false for all future calls.
inline bool await(T& out) { return StreamBase::await(&out); } inline bool await(T &out) { return StreamBase::await(&out); }
}; };
template<typename FunctionType> template<typename FunctionType>
...@@ -143,7 +146,7 @@ public: ...@@ -143,7 +146,7 @@ public:
protected: protected:
std::unique_ptr<Nucleus> core; std::unique_ptr<Nucleus> core;
std::shared_ptr<Routine> routine; std::shared_ptr<Routine> routine;
std::vector<Type*> arguments; std::vector<Type *> arguments;
}; };
template<typename Return, typename... Arguments> template<typename Return, typename... Arguments>
...@@ -151,7 +154,7 @@ Coroutine<Return(Arguments...)>::Coroutine() ...@@ -151,7 +154,7 @@ Coroutine<Return(Arguments...)>::Coroutine()
{ {
core.reset(new Nucleus()); core.reset(new Nucleus());
std::vector<Type*> types = {CToReactorT<Arguments>::getType()...}; std::vector<Type *> types = { CToReactorT<Arguments>::getType()... };
for(auto type : types) for(auto type : types)
{ {
if(type != Void::getType()) if(type != Void::getType())
...@@ -180,19 +183,22 @@ Coroutine<Return(Arguments...)>::operator()(Arguments... args) ...@@ -180,19 +183,22 @@ Coroutine<Return(Arguments...)>::operator()(Arguments... args)
finalize(); finalize();
using Sig = Nucleus::CoroutineBegin<Arguments...>; using Sig = Nucleus::CoroutineBegin<Arguments...>;
auto pfn = (Sig*)routine->getEntry(Nucleus::CoroutineEntryBegin); auto pfn = (Sig *)routine->getEntry(Nucleus::CoroutineEntryBegin);
auto handle = pfn(args...); auto handle = pfn(args...);
return std::unique_ptr<Stream<Return>>(new Stream<Return>(routine, handle)); return std::unique_ptr<Stream<Return>>(new Stream<Return>(routine, handle));
} }
#ifdef Yield // Defined in WinBase.h # ifdef Yield // Defined in WinBase.h
#undef Yield # undef Yield
#endif # endif
// Suspends execution of the coroutine and yields val to the caller. // Suspends execution of the coroutine and yields val to the caller.
// Execution of the coroutine will resume after val is retrieved. // Execution of the coroutine will resume after val is retrieved.
template<typename T> template<typename T>
inline void Yield(const T &val) { Nucleus::yield(ValueOf(val)); } inline void Yield(const T &val)
{
Nucleus::yield(ValueOf(val));
}
} // namespace rr } // namespace rr
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include "Debug.hpp" #include "Debug.hpp"
#include <string>
#include <stdarg.h> #include <stdarg.h>
#include <string>
namespace rr { namespace rr {
......
...@@ -17,18 +17,18 @@ ...@@ -17,18 +17,18 @@
#ifndef rr_DEBUG_H_ #ifndef rr_DEBUG_H_
#define rr_DEBUG_H_ #define rr_DEBUG_H_
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#if !defined(TRACE_OUTPUT_FILE) #if !defined(TRACE_OUTPUT_FILE)
#define TRACE_OUTPUT_FILE "debug.txt" # define TRACE_OUTPUT_FILE "debug.txt"
#endif #endif
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#define CHECK_PRINTF_ARGS __attribute__((format(printf, 1, 2))) # define CHECK_PRINTF_ARGS __attribute__((format(printf, 1, 2)))
#else #else
#define CHECK_PRINTF_ARGS # define CHECK_PRINTF_ARGS
#endif #endif
namespace rr { namespace rr {
...@@ -49,9 +49,9 @@ void abort(const char *format, ...) CHECK_PRINTF_ARGS; ...@@ -49,9 +49,9 @@ void abort(const char *format, ...) CHECK_PRINTF_ARGS;
// A macro to output a trace of a function call and its arguments to the // A macro to output a trace of a function call and its arguments to the
// debugging log. Disabled if RR_DISABLE_TRACE is defined. // debugging log. Disabled if RR_DISABLE_TRACE is defined.
#if defined(RR_DISABLE_TRACE) #if defined(RR_DISABLE_TRACE)
#define TRACE(message, ...) (void(0)) # define TRACE(message, ...) (void(0))
#else #else
#define TRACE(message, ...) rr::trace("%s:%d TRACE: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__) # define TRACE(message, ...) rr::trace("%s:%d TRACE: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#endif #endif
// A macro to print a warning message to the debugging log and stderr to denote // A macro to print a warning message to the debugging log and stderr to denote
...@@ -75,26 +75,34 @@ void abort(const char *format, ...) CHECK_PRINTF_ARGS; ...@@ -75,26 +75,34 @@ void abort(const char *format, ...) CHECK_PRINTF_ARGS;
// WARN() in release builds (NDEBUG && !DCHECK_ALWAYS_ON) // WARN() in release builds (NDEBUG && !DCHECK_ALWAYS_ON)
#undef DABORT #undef DABORT
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define DABORT(message, ...) ABORT(message, ##__VA_ARGS__) # define DABORT(message, ...) ABORT(message, ##__VA_ARGS__)
#else #else
#define DABORT(message, ...) WARN(message, ##__VA_ARGS__) # define DABORT(message, ...) WARN(message, ##__VA_ARGS__)
#endif #endif
// A macro asserting a condition. // A macro asserting a condition.
// If the condition fails, the condition and message is passed to DABORT(). // If the condition fails, the condition and message is passed to DABORT().
#undef ASSERT_MSG #undef ASSERT_MSG
#define ASSERT_MSG(expression, format, ...) do { \ #define ASSERT_MSG(expression, format, ...) \
if(!(expression)) { \ do \
{ \
if(!(expression)) \
{ \
DABORT("ASSERT(%s): " format "\n", #expression, ##__VA_ARGS__); \ DABORT("ASSERT(%s): " format "\n", #expression, ##__VA_ARGS__); \
} } while(0) } \
} while(0)
// A macro asserting a condition. // A macro asserting a condition.
// If the condition fails, the condition is passed to DABORT(). // If the condition fails, the condition is passed to DABORT().
#undef ASSERT #undef ASSERT
#define ASSERT(expression) do { \ #define ASSERT(expression) \
if(!(expression)) { \ do \
{ \
if(!(expression)) \
{ \
DABORT("ASSERT(%s)\n", #expression); \ DABORT("ASSERT(%s)\n", #expression); \
} } while(0) } \
} while(0)
// A macro to indicate unimplemented functionality. // A macro to indicate unimplemented functionality.
#undef UNIMPLEMENTED #undef UNIMPLEMENTED
...@@ -107,12 +115,16 @@ void abort(const char *format, ...) CHECK_PRINTF_ARGS; ...@@ -107,12 +115,16 @@ void abort(const char *format, ...) CHECK_PRINTF_ARGS;
// A macro asserting a condition and performing a return. // A macro asserting a condition and performing a return.
#undef ASSERT_OR_RETURN #undef ASSERT_OR_RETURN
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define ASSERT_OR_RETURN(expression) ASSERT(expression) # define ASSERT_OR_RETURN(expression) ASSERT(expression)
#else #else
#define ASSERT_OR_RETURN(expression) do { \ # define ASSERT_OR_RETURN(expression) \
if(!(expression)) { \ do \
{ \
if(!(expression)) \
{ \
return; \ return; \
} } while(0) } \
} while(0)
#endif #endif
#endif // rr_DEBUG_H_ #endif // rr_DEBUG_H_
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
#include "DebugAndroid.hpp" #include "DebugAndroid.hpp"
#include <cutils/properties.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <cutils/properties.h> #include <unistd.h>
void AndroidEnterDebugger() void AndroidEnterDebugger()
{ {
ALOGE(__FUNCTION__); ALOGE(__FUNCTION__);
#ifndef NDEBUG #ifndef NDEBUG
static volatile int * const makefault = nullptr; static volatile int *const makefault = nullptr;
char value[PROPERTY_VALUE_MAX]; char value[PROPERTY_VALUE_MAX];
property_get("debug.db.uid", value, "-1"); property_get("debug.db.uid", value, "-1");
int debug_uid = atoi(value); int debug_uid = atoi(value);
...@@ -31,7 +31,8 @@ void AndroidEnterDebugger() ...@@ -31,7 +31,8 @@ void AndroidEnterDebugger()
{ {
ALOGE("Waiting for debugger: gdbserver :${PORT} --attach %u. Look for thread %u", getpid(), gettid()); ALOGE("Waiting for debugger: gdbserver :${PORT} --attach %u. Look for thread %u", getpid(), gettid());
volatile int waiting = 1; volatile int waiting = 1;
while(waiting) { while(waiting)
{
sleep(1); sleep(1);
} }
} }
......
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
#define DebugAndroid_hpp #define DebugAndroid_hpp
#if ANDROID_PLATFORM_SDK_VERSION < 27 #if ANDROID_PLATFORM_SDK_VERSION < 27
#include <cutils/log.h> # include <cutils/log.h>
#elif ANDROID_PLATFORM_SDK_VERSION >= 27 #elif ANDROID_PLATFORM_SDK_VERSION >= 27
#include <log/log.h> # include <log/log.h>
#else #else
#error "ANDROID_PLATFORM_SDK_VERSION is not defined" # error "ANDROID_PLATFORM_SDK_VERSION is not defined"
#endif #endif
#include <cassert> #include <cassert>
...@@ -48,8 +48,11 @@ ...@@ -48,8 +48,11 @@
*/ */
void AndroidEnterDebugger(); void AndroidEnterDebugger();
#define ASSERT(E) do { \ #define ASSERT(E) \
if(!(E)) { \ do \
{ \
if(!(E)) \
{ \
ALOGE("badness: assertion_failed %s in %s at %s:%d", #E, \ ALOGE("badness: assertion_failed %s in %s at %s:%d", #E, \
__FUNCTION__, __FILE__, __LINE__); \ __FUNCTION__, __FILE__, __LINE__); \
AndroidEnterDebugger(); \ AndroidEnterDebugger(); \
...@@ -60,38 +63,44 @@ void AndroidEnterDebugger(); ...@@ -60,38 +63,44 @@ void AndroidEnterDebugger();
#define assert(E) ASSERT(E) #define assert(E) ASSERT(E)
#define ERR(format, ...) \ #define ERR(format, ...) \
do { \ do \
{ \
ALOGE("badness: err %s %s:%d (" format ")", __FUNCTION__, __FILE__, \ ALOGE("badness: err %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
__LINE__, ##__VA_ARGS__); \ __LINE__, ##__VA_ARGS__); \
AndroidEnterDebugger(); \ AndroidEnterDebugger(); \
} while(0) } while(0)
#define FIXME(format, ...) \ #define FIXME(format, ...) \
do { \ do \
{ \
ALOGE("badness: fixme %s %s:%d (" format ")", __FUNCTION__, __FILE__, \ ALOGE("badness: fixme %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
__LINE__, ##__VA_ARGS__); \ __LINE__, ##__VA_ARGS__); \
AndroidEnterDebugger(); \ AndroidEnterDebugger(); \
} while(0) } while(0)
// TODO: Handle __VA_ARGS__ (can be empty) // TODO: Handle __VA_ARGS__ (can be empty)
#define UNIMPLEMENTED(...) do { \ #define UNIMPLEMENTED(...) \
do \
{ \
ALOGE("badness: unimplemented: %s %s:%d", \ ALOGE("badness: unimplemented: %s %s:%d", \
__FUNCTION__, __FILE__, __LINE__); \ __FUNCTION__, __FILE__, __LINE__); \
AndroidEnterDebugger(); \ AndroidEnterDebugger(); \
} while(0) } while(0)
#define UNREACHABLE(value) do { \ #define UNREACHABLE(value) \
do \
{ \
ALOGE("badness: unreachable case reached: %s %s:%d. %s: %d", \ ALOGE("badness: unreachable case reached: %s %s:%d. %s: %d", \
__FUNCTION__, __FILE__, __LINE__, #value, value); \ __FUNCTION__, __FILE__, __LINE__, #value, value); \
AndroidEnterDebugger(); \ AndroidEnterDebugger(); \
} while(0) } while(0)
#ifndef NDEBUG #ifndef NDEBUG
#define TRACE(format, ...) \ # define TRACE(format, ...) \
ALOGV("%s %s:%d (" format ")", __FUNCTION__, __FILE__, \ ALOGV("%s %s:%d (" format ")", __FUNCTION__, __FILE__, \
__LINE__, ##__VA_ARGS__) __LINE__, ##__VA_ARGS__)
#else #else
#define TRACE(...) ((void)0) # define TRACE(...) ((void)0)
#endif #endif
void trace(const char *format, ...); void trace(const char *format, ...);
......
...@@ -7,18 +7,18 @@ ...@@ -7,18 +7,18 @@
namespace rr { namespace rr {
namespace { namespace {
template <typename T> template<typename T>
struct UnderlyingType struct UnderlyingType
{ {
using Type = typename decltype(rr::Extract(std::declval<RValue<T>>(), 0))::rvalue_underlying_type; using Type = typename decltype(rr::Extract(std::declval<RValue<T>>(), 0))::rvalue_underlying_type;
}; };
template <typename T> template<typename T>
using UnderlyingTypeT = typename UnderlyingType<T>::Type; using UnderlyingTypeT = typename UnderlyingType<T>::Type;
// Call single arg function on a vector type // Call single arg function on a vector type
template <typename Func, typename T> template<typename Func, typename T>
RValue<T> call4(Func func, const RValue<T>& x) RValue<T> call4(Func func, const RValue<T> &x)
{ {
T result; T result;
result = Insert(result, Call(func, Extract(x, 0)), 0); result = Insert(result, Call(func, Extract(x, 0)), 0);
...@@ -29,8 +29,8 @@ RValue<T> call4(Func func, const RValue<T>& x) ...@@ -29,8 +29,8 @@ RValue<T> call4(Func func, const RValue<T>& x)
} }
// Call two arg function on a vector type // Call two arg function on a vector type
template <typename Func, typename T> template<typename Func, typename T>
RValue<T> call4(Func func, const RValue<T>& x, const RValue<T>& y) RValue<T> call4(Func func, const RValue<T> &x, const RValue<T> &y)
{ {
T result; T result;
result = Insert(result, Call(func, Extract(x, 0), Extract(y, 0)), 0); result = Insert(result, Call(func, Extract(x, 0), Extract(y, 0)), 0);
...@@ -40,8 +40,8 @@ RValue<T> call4(Func func, const RValue<T>& x, const RValue<T>& y) ...@@ -40,8 +40,8 @@ RValue<T> call4(Func func, const RValue<T>& x, const RValue<T>& y)
return result; return result;
} }
template <typename T, typename EL = UnderlyingTypeT<T>> template<typename T, typename EL = UnderlyingTypeT<T>>
void gather(T& out, RValue<Pointer<EL>> base, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment, bool zeroMaskedLanes) void gather(T &out, RValue<Pointer<EL>> base, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment, bool zeroMaskedLanes)
{ {
constexpr bool atomic = false; constexpr bool atomic = false;
constexpr std::memory_order order = std::memory_order_relaxed; constexpr std::memory_order order = std::memory_order_relaxed;
...@@ -64,7 +64,7 @@ void gather(T& out, RValue<Pointer<EL>> base, RValue<Int4> offsets, RValue<Int4> ...@@ -64,7 +64,7 @@ void gather(T& out, RValue<Pointer<EL>> base, RValue<Int4> offsets, RValue<Int4>
} }
} }
template <typename T, typename EL = UnderlyingTypeT<T>> template<typename T, typename EL = UnderlyingTypeT<T>>
void scatter(RValue<Pointer<EL>> base, RValue<T> val, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment) void scatter(RValue<Pointer<EL>> base, RValue<T> val, RValue<Int4> offsets, RValue<Int4> mask, unsigned int alignment)
{ {
constexpr bool atomic = false; constexpr bool atomic = false;
......
...@@ -17,20 +17,20 @@ ...@@ -17,20 +17,20 @@
#include "Debug.hpp" #include "Debug.hpp"
#if defined(_WIN32) #if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN # ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#endif # endif
#include <windows.h> # include <windows.h>
#include <intrin.h> # include <intrin.h>
#elif defined(__Fuchsia__) #elif defined(__Fuchsia__)
#include <unistd.h> # include <unistd.h>
#include <zircon/process.h> # include <zircon/process.h>
#include <zircon/syscalls.h> # include <zircon/syscalls.h>
#else #else
#include <errno.h> # include <errno.h>
#include <sys/mman.h> # include <sys/mman.h>
#include <stdlib.h> # include <stdlib.h>
#include <unistd.h> # include <unistd.h>
#endif #endif
#include <memory.h> #include <memory.h>
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
#undef allocate #undef allocate
#undef deallocate #undef deallocate
#if(defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined (_M_X64)) && !defined(__x86__) #if(defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) && !defined(__x86__)
#define __x86__ # define __x86__
#endif #endif
namespace rr { namespace rr {
...@@ -47,7 +47,7 @@ namespace { ...@@ -47,7 +47,7 @@ namespace {
struct Allocation struct Allocation
{ {
// size_t bytes; // size_t bytes;
unsigned char *block; unsigned char *block;
}; };
...@@ -55,8 +55,8 @@ void *allocateRaw(size_t bytes, size_t alignment) ...@@ -55,8 +55,8 @@ void *allocateRaw(size_t bytes, size_t alignment)
{ {
ASSERT((alignment & (alignment - 1)) == 0); // Power of 2 alignment. ASSERT((alignment & (alignment - 1)) == 0); // Power of 2 alignment.
#if defined(LINUX_ENABLE_NAMED_MMAP) #if defined(LINUX_ENABLE_NAMED_MMAP)
if(alignment < sizeof(void*)) if(alignment < sizeof(void *))
{ {
return malloc(bytes); return malloc(bytes);
} }
...@@ -71,27 +71,28 @@ void *allocateRaw(size_t bytes, size_t alignment) ...@@ -71,27 +71,28 @@ void *allocateRaw(size_t bytes, size_t alignment)
} }
return allocation; return allocation;
} }
#else #else
unsigned char *block = new unsigned char[bytes + sizeof(Allocation) + alignment]; unsigned char *block = new unsigned char[bytes + sizeof(Allocation) + alignment];
unsigned char *aligned = nullptr; unsigned char *aligned = nullptr;
if(block) if(block)
{ {
aligned = (unsigned char*)((uintptr_t)(block + sizeof(Allocation) + alignment - 1) & -(intptr_t)alignment); aligned = (unsigned char *)((uintptr_t)(block + sizeof(Allocation) + alignment - 1) & -(intptr_t)alignment);
Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation)); Allocation *allocation = (Allocation *)(aligned - sizeof(Allocation));
// allocation->bytes = bytes; // allocation->bytes = bytes;
allocation->block = block; allocation->block = block;
} }
return aligned; return aligned;
#endif #endif
} }
#if defined(_WIN32) #if defined(_WIN32)
DWORD permissionsToProtectMode(int permissions) DWORD permissionsToProtectMode(int permissions)
{ {
switch(permissions) { switch(permissions)
{
case PERMISSION_READ: case PERMISSION_READ:
return PAGE_READONLY; return PAGE_READONLY;
case PERMISSION_EXECUTE: case PERMISSION_EXECUTE:
...@@ -131,26 +132,26 @@ int permissionsToMmapProt(int permissions) ...@@ -131,26 +132,26 @@ int permissionsToMmapProt(int permissions)
// Create a file descriptor for anonymous memory with the given // Create a file descriptor for anonymous memory with the given
// name. Returns -1 on failure. // name. Returns -1 on failure.
// TODO: remove once libc wrapper exists. // TODO: remove once libc wrapper exists.
int memfd_create(const char* name, unsigned int flags) int memfd_create(const char *name, unsigned int flags)
{ {
#if __aarch64__ # if __aarch64__
#define __NR_memfd_create 279 # define __NR_memfd_create 279
#elif __arm__ # elif __arm__
#define __NR_memfd_create 279 # define __NR_memfd_create 279
#elif __powerpc64__ # elif __powerpc64__
#define __NR_memfd_create 360 # define __NR_memfd_create 360
#elif __i386__ # elif __i386__
#define __NR_memfd_create 356 # define __NR_memfd_create 356
#elif __x86_64__ # elif __x86_64__
#define __NR_memfd_create 319 # define __NR_memfd_create 319
#endif /* __NR_memfd_create__ */ # endif /* __NR_memfd_create__ */
#ifdef __NR_memfd_create # ifdef __NR_memfd_create
// In the event of no system call this returns -1 with errno set // In the event of no system call this returns -1 with errno set
// as ENOSYS. // as ENOSYS.
return syscall(__NR_memfd_create, name, flags); return syscall(__NR_memfd_create, name, flags);
#else # else
return -1; return -1;
#endif # endif
} }
// Returns a file descriptor for use with an anonymous mmap, if // Returns a file descriptor for use with an anonymous mmap, if
...@@ -175,7 +176,8 @@ void ensureAnonFileSize(int anonFd, size_t length) ...@@ -175,7 +176,8 @@ void ensureAnonFileSize(int anonFd, size_t length)
#endif // defined(LINUX_ENABLE_NAMED_MMAP) #endif // defined(LINUX_ENABLE_NAMED_MMAP)
#if defined(__Fuchsia__) #if defined(__Fuchsia__)
zx_vm_option_t permissionsToZxVmOptions(int permissions) { zx_vm_option_t permissionsToZxVmOptions(int permissions)
{
zx_vm_option_t result = 0; zx_vm_option_t result = 0;
if(permissions & PERMISSION_READ) if(permissions & PERMISSION_READ)
{ {
...@@ -201,13 +203,13 @@ size_t memoryPageSize() ...@@ -201,13 +203,13 @@ size_t memoryPageSize()
if(pageSize == 0) if(pageSize == 0)
{ {
#if defined(_WIN32) #if defined(_WIN32)
SYSTEM_INFO systemInfo; SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo); GetSystemInfo(&systemInfo);
pageSize = systemInfo.dwPageSize; pageSize = systemInfo.dwPageSize;
#else #else
pageSize = sysconf(_SC_PAGESIZE); pageSize = sysconf(_SC_PAGESIZE);
#endif #endif
} }
return pageSize; return pageSize;
...@@ -227,17 +229,17 @@ void *allocate(size_t bytes, size_t alignment) ...@@ -227,17 +229,17 @@ void *allocate(size_t bytes, size_t alignment)
void deallocate(void *memory) void deallocate(void *memory)
{ {
#if defined(LINUX_ENABLE_NAMED_MMAP) #if defined(LINUX_ENABLE_NAMED_MMAP)
free(memory); free(memory);
#else #else
if(memory) if(memory)
{ {
unsigned char *aligned = (unsigned char*)memory; unsigned char *aligned = (unsigned char *)memory;
Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation)); Allocation *allocation = (Allocation *)(aligned - sizeof(Allocation));
delete[] allocation->block; delete[] allocation->block;
} }
#endif #endif
} }
// Rounds |x| up to a multiple of |m|, where |m| is a power of 2. // Rounds |x| up to a multiple of |m|, where |m| is a power of 2.
...@@ -253,7 +255,7 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec) ...@@ -253,7 +255,7 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec)
size_t length = roundUp(bytes, pageSize); size_t length = roundUp(bytes, pageSize);
void *mapping = nullptr; void *mapping = nullptr;
#if defined(LINUX_ENABLE_NAMED_MMAP) #if defined(LINUX_ENABLE_NAMED_MMAP)
int flags = MAP_PRIVATE; int flags = MAP_PRIVATE;
// Try to name the memory region for the executable code, // Try to name the memory region for the executable code,
...@@ -275,9 +277,10 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec) ...@@ -275,9 +277,10 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec)
{ {
mapping = nullptr; mapping = nullptr;
} }
#elif defined(__Fuchsia__) #elif defined(__Fuchsia__)
zx_handle_t vmo; zx_handle_t vmo;
if(zx_vmo_create(length, 0, &vmo) != ZX_OK) { if(zx_vmo_create(length, 0, &vmo) != ZX_OK)
{
return nullptr; return nullptr;
} }
if(need_exec && if(need_exec &&
...@@ -290,15 +293,16 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec) ...@@ -290,15 +293,16 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec)
zx_vmar_root_self(), permissionsToZxVmOptions(permissions), 0, vmo, zx_vmar_root_self(), permissionsToZxVmOptions(permissions), 0, vmo,
0, length, &reservation); 0, length, &reservation);
zx_handle_close(vmo); zx_handle_close(vmo);
if(status != ZX_OK) { if(status != ZX_OK)
{
return nullptr; return nullptr;
} }
// zx_vmar_map() returns page-aligned address. // zx_vmar_map() returns page-aligned address.
ASSERT(roundUp(reservation, pageSize) == reservation); ASSERT(roundUp(reservation, pageSize) == reservation);
mapping = reinterpret_cast<void*>(reservation); mapping = reinterpret_cast<void *>(reservation);
#elif defined(__APPLE__) #elif defined(__APPLE__)
int prot = permissionsToMmapProt(permissions); int prot = permissionsToMmapProt(permissions);
int flags = MAP_PRIVATE | MAP_ANONYMOUS; int flags = MAP_PRIVATE | MAP_ANONYMOUS;
// On macOS 10.14 and higher, executables that are code signed with the // On macOS 10.14 and higher, executables that are code signed with the
...@@ -317,10 +321,10 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec) ...@@ -317,10 +321,10 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec)
{ {
mapping = nullptr; mapping = nullptr;
} }
#else #else
mapping = allocate(length, pageSize); mapping = allocate(length, pageSize);
protectMemoryPages(mapping, length, permissions); protectMemoryPages(mapping, length, permissions);
#endif #endif
return mapping; return mapping;
} }
...@@ -331,48 +335,48 @@ void protectMemoryPages(void *memory, size_t bytes, int permissions) ...@@ -331,48 +335,48 @@ void protectMemoryPages(void *memory, size_t bytes, int permissions)
return; return;
bytes = roundUp(bytes, memoryPageSize()); bytes = roundUp(bytes, memoryPageSize());
#if defined(_WIN32) #if defined(_WIN32)
unsigned long oldProtection; unsigned long oldProtection;
BOOL result = BOOL result =
VirtualProtect(memory, bytes, permissionsToProtectMode(permissions), VirtualProtect(memory, bytes, permissionsToProtectMode(permissions),
&oldProtection); &oldProtection);
ASSERT(result); ASSERT(result);
#elif defined(__Fuchsia__) #elif defined(__Fuchsia__)
zx_status_t status = zx_vmar_protect( zx_status_t status = zx_vmar_protect(
zx_vmar_root_self(), permissionsToZxVmOptions(permissions), zx_vmar_root_self(), permissionsToZxVmOptions(permissions),
reinterpret_cast<zx_vaddr_t>(memory), bytes); reinterpret_cast<zx_vaddr_t>(memory), bytes);
ASSERT(status == ZX_OK); ASSERT(status == ZX_OK);
#else #else
int result = int result =
mprotect(memory, bytes, permissionsToMmapProt(permissions)); mprotect(memory, bytes, permissionsToMmapProt(permissions));
ASSERT(result == 0); ASSERT(result == 0);
#endif #endif
} }
void deallocateMemoryPages(void *memory, size_t bytes) void deallocateMemoryPages(void *memory, size_t bytes)
{ {
#if defined(_WIN32) #if defined(_WIN32)
unsigned long oldProtection; unsigned long oldProtection;
BOOL result = BOOL result =
VirtualProtect(memory, bytes, PAGE_READWRITE, &oldProtection); VirtualProtect(memory, bytes, PAGE_READWRITE, &oldProtection);
ASSERT(result); ASSERT(result);
deallocate(memory); deallocate(memory);
#elif defined(LINUX_ENABLE_NAMED_MMAP) || defined(__APPLE__) #elif defined(LINUX_ENABLE_NAMED_MMAP) || defined(__APPLE__)
size_t pageSize = memoryPageSize(); size_t pageSize = memoryPageSize();
size_t length = (bytes + pageSize - 1) & ~(pageSize - 1); size_t length = (bytes + pageSize - 1) & ~(pageSize - 1);
int result = munmap(memory, length); int result = munmap(memory, length);
ASSERT(result == 0); ASSERT(result == 0);
#elif defined(__Fuchsia__) #elif defined(__Fuchsia__)
size_t pageSize = memoryPageSize(); size_t pageSize = memoryPageSize();
size_t length = roundUp(bytes, pageSize); size_t length = roundUp(bytes, pageSize);
zx_status_t status = zx_vmar_unmap( zx_status_t status = zx_vmar_unmap(
zx_vmar_root_self(), reinterpret_cast<zx_vaddr_t>(memory), length); zx_vmar_root_self(), reinterpret_cast<zx_vaddr_t>(memory), length);
ASSERT(status == ZX_OK); ASSERT(status == ZX_OK);
#else #else
int result = mprotect(memory, bytes, PROT_READ | PROT_WRITE); int result = mprotect(memory, bytes, PROT_READ | PROT_WRITE);
ASSERT(result == 0); ASSERT(result == 0);
deallocate(memory); deallocate(memory);
#endif #endif
} }
} // namespace rr } // namespace rr
...@@ -23,7 +23,8 @@ namespace rr { ...@@ -23,7 +23,8 @@ namespace rr {
size_t memoryPageSize(); size_t memoryPageSize();
enum MemoryPermission { enum MemoryPermission
{
PERMISSION_READ = 1, PERMISSION_READ = 1,
PERMISSION_WRITE = 2, PERMISSION_WRITE = 2,
PERMISSION_EXECUTE = 4, PERMISSION_EXECUTE = 4,
...@@ -31,7 +32,7 @@ enum MemoryPermission { ...@@ -31,7 +32,7 @@ enum MemoryPermission {
// Allocates memory with the specified permissions. If |need_exec| is true then // Allocates memory with the specified permissions. If |need_exec| is true then
// the allocate memory can be made marked executable using protectMemoryPages(). // the allocate memory can be made marked executable using protectMemoryPages().
void* allocateMemoryPages(size_t bytes, int permissions, bool need_exec); void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec);
// Sets permissions for memory allocated with allocateMemoryPages(). // Sets permissions for memory allocated with allocateMemoryPages().
void protectMemoryPages(void *memory, size_t bytes, int permissions); void protectMemoryPages(void *memory, size_t bytes, int permissions);
...@@ -58,7 +59,9 @@ template<typename P> ...@@ -58,7 +59,9 @@ template<typename P>
class unaligned_ref class unaligned_ref
{ {
public: public:
explicit unaligned_ref(void *ptr) : ptr((P*)ptr) {} explicit unaligned_ref(void *ptr)
: ptr((P *)ptr)
{}
template<typename V> template<typename V>
P operator=(V value) P operator=(V value)
...@@ -69,7 +72,7 @@ public: ...@@ -69,7 +72,7 @@ public:
operator P() operator P()
{ {
return unaligned_read((P*)ptr); return unaligned_read((P *)ptr);
} }
private: private:
...@@ -83,7 +86,9 @@ class unaligned_ptr ...@@ -83,7 +86,9 @@ class unaligned_ptr
friend class unaligned_ptr; friend class unaligned_ptr;
public: public:
unaligned_ptr(P *ptr) : ptr(ptr) {} unaligned_ptr(P *ptr)
: ptr(ptr)
{}
unaligned_ref<P> operator*() unaligned_ref<P> operator*()
{ {
......
...@@ -31,17 +31,17 @@ llvm::Type *T(Type *t); ...@@ -31,17 +31,17 @@ llvm::Type *T(Type *t);
inline Type *T(llvm::Type *t) inline Type *T(llvm::Type *t)
{ {
return reinterpret_cast<Type*>(t); return reinterpret_cast<Type *>(t);
} }
inline llvm::Value *V(Value *t) inline llvm::Value *V(Value *t)
{ {
return reinterpret_cast<llvm::Value*>(t); return reinterpret_cast<llvm::Value *>(t);
} }
inline Value *V(llvm::Value *t) inline Value *V(llvm::Value *t)
{ {
return reinterpret_cast<Value*>(t); return reinterpret_cast<Value *>(t);
} }
// Emits a no-op instruction that will not be optimized away. // Emits a no-op instruction that will not be optimized away.
......
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
#include <unordered_set> # include <memory>
#include <unordered_map> # include <unordered_map>
#include <vector> # include <unordered_set>
#include <memory> # include <vector>
// Forward declarations // Forward declarations
namespace llvm { namespace llvm {
...@@ -46,12 +46,12 @@ class Module; ...@@ -46,12 +46,12 @@ class Module;
class Type; class Type;
class Value; class Value;
namespace object namespace object {
{ class ObjectFile;
class ObjectFile;
} }
template <typename T, typename Inserter> class IRBuilder; template<typename T, typename Inserter>
class IRBuilder;
} // namespace llvm } // namespace llvm
...@@ -116,8 +116,8 @@ private: ...@@ -116,8 +116,8 @@ private:
std::string name; std::string name;
std::string file; std::string file;
bool operator == (const FunctionLocation &rhs) const { return name == rhs.name && file == rhs.file; } bool operator==(const FunctionLocation &rhs) const { return name == rhs.name && file == rhs.file; }
bool operator != (const FunctionLocation &rhs) const { return !(*this == rhs); } bool operator!=(const FunctionLocation &rhs) const { return !(*this == rhs); }
struct Hash struct Hash
{ {
...@@ -134,8 +134,8 @@ private: ...@@ -134,8 +134,8 @@ private:
FunctionLocation function; FunctionLocation function;
unsigned int line = 0; unsigned int line = 0;
bool operator == (const Location &rhs) const { return function == rhs.function && line == rhs.line; } bool operator==(const Location &rhs) const { return function == rhs.function && line == rhs.line; }
bool operator != (const Location &rhs) const { return !(*this == rhs); } bool operator!=(const Location &rhs) const { return !(*this == rhs); }
struct Hash struct Hash
{ {
...@@ -181,14 +181,14 @@ private: ...@@ -181,14 +181,14 @@ private:
// frames will be returned. // frames will be returned.
Backtrace getCallerBacktrace(size_t limit = 0) const; Backtrace getCallerBacktrace(size_t limit = 0) const;
llvm::DILocation* getLocation(const Backtrace &backtrace, size_t i); llvm::DILocation *getLocation(const Backtrace &backtrace, size_t i);
llvm::DIType *getOrCreateType(llvm::Type* type); llvm::DIType *getOrCreateType(llvm::Type *type);
llvm::DIFile *getOrCreateFile(const char* path); llvm::DIFile *getOrCreateFile(const char *path);
LineTokens const *getOrParseFileTokens(const char* path); LineTokens const *getOrParseFileTokens(const char *path);
// Synchronizes diScope with the current backtrace. // Synchronizes diScope with the current backtrace.
void syncScope(Backtrace const& backtrace); void syncScope(Backtrace const &backtrace);
IRBuilder *builder; IRBuilder *builder;
llvm::LLVMContext *context; llvm::LLVMContext *context;
...@@ -200,10 +200,10 @@ private: ...@@ -200,10 +200,10 @@ private:
llvm::DISubprogram *diSubprogram; llvm::DISubprogram *diSubprogram;
llvm::DILocation *diRootLocation; llvm::DILocation *diRootLocation;
std::vector<Scope> diScope; std::vector<Scope> diScope;
std::unordered_map<std::string, llvm::DIFile*> diFiles; std::unordered_map<std::string, llvm::DIFile *> diFiles;
std::unordered_map<llvm::Type*, llvm::DIType*> diTypes; std::unordered_map<llvm::Type *, llvm::DIType *> diTypes;
std::unordered_map<std::string, std::unique_ptr<LineTokens>> fileTokens; std::unordered_map<std::string, std::unique_ptr<LineTokens>> fileTokens;
std::vector<void const*> pushed; std::vector<void const *> pushed;
}; };
} // namespace rr } // namespace rr
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#if defined(__linux__) #if defined(__linux__)
// Use a pthread mutex on Linux. Since many processes may use Reactor // Use a pthread mutex on Linux. Since many processes may use Reactor
// at the same time it's best to just have the scheduler overhead. // at the same time it's best to just have the scheduler overhead.
#include <pthread.h> # include <pthread.h>
namespace rr { namespace rr {
...@@ -60,7 +60,7 @@ private: ...@@ -60,7 +60,7 @@ private:
#else // !__linux__ #else // !__linux__
#include <atomic> # include <atomic>
namespace rr { namespace rr {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <vector> #include <vector>
#ifdef None #ifdef None
#undef None // TODO(b/127920555) # undef None // TODO(b/127920555)
#endif #endif
static_assert(sizeof(short) == 2, "Reactor's 'Short' type is 16-bit, and requires the C++ 'short' to match that."); static_assert(sizeof(short) == 2, "Reactor's 'Short' type is 16-bit, and requires the C++ 'short' to match that.");
...@@ -68,18 +68,19 @@ public: ...@@ -68,18 +68,19 @@ public:
using Passes = std::vector<Pass>; using Passes = std::vector<Pass>;
Optimization(Level level = Level::Default, const Passes& passes = {}) Optimization(Level level = Level::Default, const Passes &passes = {})
: level(level), passes(passes) : level(level)
, passes(passes)
{ {
#if defined(REACTOR_DEFAULT_OPT_LEVEL) #if defined(REACTOR_DEFAULT_OPT_LEVEL)
{ {
this->level = Level::REACTOR_DEFAULT_OPT_LEVEL; this->level = Level::REACTOR_DEFAULT_OPT_LEVEL;
} }
#endif #endif
} }
Level getLevel() const { return level; } Level getLevel() const { return level; }
const Passes & getPasses() const { return passes; } const Passes &getPasses() const { return passes; }
private: private:
Level level = Level::Default; Level level = Level::Default;
...@@ -98,19 +99,41 @@ public: ...@@ -98,19 +99,41 @@ public:
public: public:
static const Edit None; static const Edit None;
Edit & set(Optimization::Level level) { optLevel = level; optLevelChanged = true; return *this; } Edit &set(Optimization::Level level)
Edit & add(Optimization::Pass pass) { optPassEdits.push_back({ListEdit::Add, pass}); return *this; } {
Edit & remove(Optimization::Pass pass) { optPassEdits.push_back({ListEdit::Remove, pass}); return *this; } optLevel = level;
Edit & clearOptimizationPasses() { optPassEdits.push_back({ListEdit::Clear, Optimization::Pass::Disabled}); return *this; } optLevelChanged = true;
return *this;
}
Edit &add(Optimization::Pass pass)
{
optPassEdits.push_back({ ListEdit::Add, pass });
return *this;
}
Edit &remove(Optimization::Pass pass)
{
optPassEdits.push_back({ ListEdit::Remove, pass });
return *this;
}
Edit &clearOptimizationPasses()
{
optPassEdits.push_back({ ListEdit::Clear, Optimization::Pass::Disabled });
return *this;
}
Config apply(const Config &cfg) const; Config apply(const Config &cfg) const;
private: private:
enum class ListEdit { Add, Remove, Clear }; enum class ListEdit
{
Add,
Remove,
Clear
};
using OptPassesEdit = std::pair<ListEdit, Optimization::Pass>; using OptPassesEdit = std::pair<ListEdit, Optimization::Pass>;
template <typename T> template<typename T>
void apply(const std::vector<std::pair<ListEdit, T>> & edits, std::vector<T>& list) const; void apply(const std::vector<std::pair<ListEdit, T>> &edits, std::vector<T> &list) const;
Optimization::Level optLevel; Optimization::Level optLevel;
bool optLevelChanged = false; bool optLevelChanged = false;
...@@ -118,9 +141,11 @@ public: ...@@ -118,9 +141,11 @@ public:
}; };
Config() = default; Config() = default;
Config(const Optimization & optimization) : optimization(optimization) {} Config(const Optimization &optimization)
: optimization(optimization)
{}
const Optimization & getOptimization() const { return optimization; } const Optimization &getOptimization() const { return optimization; }
private: private:
Optimization optimization; Optimization optimization;
...@@ -146,15 +171,15 @@ public: ...@@ -146,15 +171,15 @@ public:
static BasicBlock *getInsertBlock(); static BasicBlock *getInsertBlock();
static void setInsertBlock(BasicBlock *basicBlock); static void setInsertBlock(BasicBlock *basicBlock);
static void createFunction(Type *ReturnType, std::vector<Type*> &Params); static void createFunction(Type *ReturnType, std::vector<Type *> &Params);
static Value *getArgument(unsigned int index); static Value *getArgument(unsigned int index);
// Coroutines // Coroutines
using CoroutineHandle = void*; using CoroutineHandle = void *;
template <typename... ARGS> template<typename... ARGS>
using CoroutineBegin = CoroutineHandle(ARGS...); using CoroutineBegin = CoroutineHandle(ARGS...);
using CoroutineAwait = bool(CoroutineHandle, void* yieldValue); using CoroutineAwait = bool(CoroutineHandle, void *yieldValue);
using CoroutineDestroy = void(CoroutineHandle); using CoroutineDestroy = void(CoroutineHandle);
enum CoroutineEntries enum CoroutineEntries
...@@ -165,9 +190,9 @@ public: ...@@ -165,9 +190,9 @@ public:
CoroutineEntryCount CoroutineEntryCount
}; };
static void createCoroutine(Type *ReturnType, std::vector<Type*> &Params); static void createCoroutine(Type *ReturnType, std::vector<Type *> &Params);
std::shared_ptr<Routine> acquireCoroutine(const char *name, const Config::Edit &cfg = Config::Edit::None); std::shared_ptr<Routine> acquireCoroutine(const char *name, const Config::Edit &cfg = Config::Edit::None);
static void yield(Value*); static void yield(Value *);
// Terminators // Terminators
static void createRetVoid(); static void createRetVoid();
...@@ -201,7 +226,7 @@ public: ...@@ -201,7 +226,7 @@ public:
static Value *createNot(Value *V); static Value *createNot(Value *V);
// Memory instructions // Memory instructions
static Value *createLoad(Value *ptr, Type *type, bool isVolatile = false, unsigned int alignment = 0, bool atomic = false , std::memory_order memoryOrder = std::memory_order_relaxed); static Value *createLoad(Value *ptr, Type *type, bool isVolatile = false, unsigned int alignment = 0, bool atomic = false, std::memory_order memoryOrder = std::memory_order_relaxed);
static Value *createStore(Value *value, Value *ptr, Type *type, bool isVolatile = false, unsigned int aligment = 0, bool atomic = false, std::memory_order memoryOrder = std::memory_order_relaxed); static Value *createStore(Value *value, Value *ptr, Type *type, bool isVolatile = false, unsigned int aligment = 0, bool atomic = false, std::memory_order memoryOrder = std::memory_order_relaxed);
static Value *createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex); static Value *createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex);
......
...@@ -50,45 +50,45 @@ private: ...@@ -50,45 +50,45 @@ private:
Ice::Cfg *function; Ice::Cfg *function;
Ice::GlobalContext *context; Ice::GlobalContext *context;
struct Uses : std::vector<Ice::Inst*> struct Uses : std::vector<Ice::Inst *>
{ {
bool areOnlyLoadStore() const; bool areOnlyLoadStore() const;
void insert(Ice::Operand *value, Ice::Inst *instruction); void insert(Ice::Operand *value, Ice::Inst *instruction);
void erase(Ice::Inst *instruction); void erase(Ice::Inst *instruction);
std::vector<Ice::Inst*> loads; std::vector<Ice::Inst *> loads;
std::vector<Ice::Inst*> stores; std::vector<Ice::Inst *> stores;
}; };
struct LoadStoreInst struct LoadStoreInst
{ {
LoadStoreInst(Ice::Inst* inst, bool isStore) LoadStoreInst(Ice::Inst *inst, bool isStore)
: inst(inst), : inst(inst)
address(isStore ? storeAddress(inst) : loadAddress(inst)), , address(isStore ? storeAddress(inst) : loadAddress(inst))
isStore(isStore) , isStore(isStore)
{ {
} }
Ice::Inst* inst; Ice::Inst *inst;
Ice::Operand *address; Ice::Operand *address;
bool isStore; bool isStore;
}; };
Optimizer::Uses* getUses(Ice::Operand*); Optimizer::Uses *getUses(Ice::Operand *);
void setUses(Ice::Operand*, Optimizer::Uses*); void setUses(Ice::Operand *, Optimizer::Uses *);
bool hasUses(Ice::Operand*) const; bool hasUses(Ice::Operand *) const;
Ice::CfgNode* getNode(Ice::Inst*); Ice::CfgNode *getNode(Ice::Inst *);
void setNode(Ice::Inst*, Ice::CfgNode*); void setNode(Ice::Inst *, Ice::CfgNode *);
Ice::Inst* getDefinition(Ice::Variable*); Ice::Inst *getDefinition(Ice::Variable *);
void setDefinition(Ice::Variable*, Ice::Inst*); void setDefinition(Ice::Variable *, Ice::Inst *);
const std::vector<LoadStoreInst>& getLoadStoreInsts(Ice::CfgNode*); const std::vector<LoadStoreInst> &getLoadStoreInsts(Ice::CfgNode *);
void setLoadStoreInsts(Ice::CfgNode*, std::vector<LoadStoreInst>*); void setLoadStoreInsts(Ice::CfgNode *, std::vector<LoadStoreInst> *);
bool hasLoadStoreInsts(Ice::CfgNode* node) const; bool hasLoadStoreInsts(Ice::CfgNode *node) const;
std::vector<Optimizer::Uses*> allocatedUses; std::vector<Optimizer::Uses *> allocatedUses;
}; };
void Optimizer::run(Ice::Cfg *function) void Optimizer::run(Ice::Cfg *function)
...@@ -133,8 +133,7 @@ void Optimizer::eliminateDeadCode() ...@@ -133,8 +133,7 @@ void Optimizer::eliminateDeadCode()
} }
} }
} }
} } while(modified);
while(modified);
} }
void Optimizer::eliminateUnitializedLoads() void Optimizer::eliminateUnitializedLoads()
...@@ -313,7 +312,7 @@ void Optimizer::optimizeStoresInSingleBasicBlock() ...@@ -313,7 +312,7 @@ void Optimizer::optimizeStoresInSingleBasicBlock()
{ {
Ice::CfgNode *entryBlock = function->getEntryNode(); Ice::CfgNode *entryBlock = function->getEntryNode();
std::vector<std::vector<LoadStoreInst>* > allocatedVectors; std::vector<std::vector<LoadStoreInst> *> allocatedVectors;
for(Ice::Inst &alloca : entryBlock->getInsts()) for(Ice::Inst &alloca : entryBlock->getInsts())
{ {
...@@ -357,7 +356,7 @@ void Optimizer::optimizeStoresInSingleBasicBlock() ...@@ -357,7 +356,7 @@ void Optimizer::optimizeStoresInSingleBasicBlock()
{ {
if(!hasLoadStoreInsts(singleBasicBlock)) if(!hasLoadStoreInsts(singleBasicBlock))
{ {
std::vector<LoadStoreInst>* loadStoreInstVector = new std::vector<LoadStoreInst>(); std::vector<LoadStoreInst> *loadStoreInstVector = new std::vector<LoadStoreInst>();
setLoadStoreInsts(singleBasicBlock, loadStoreInstVector); setLoadStoreInsts(singleBasicBlock, loadStoreInstVector);
allocatedVectors.push_back(loadStoreInstVector); allocatedVectors.push_back(loadStoreInstVector);
for(Ice::Inst &inst : singleBasicBlock->getInsts()) for(Ice::Inst &inst : singleBasicBlock->getInsts())
...@@ -381,9 +380,9 @@ void Optimizer::optimizeStoresInSingleBasicBlock() ...@@ -381,9 +380,9 @@ void Optimizer::optimizeStoresInSingleBasicBlock()
Ice::Operand *storeValue = nullptr; Ice::Operand *storeValue = nullptr;
bool unmatchedLoads = false; bool unmatchedLoads = false;
for(auto& loadStoreInst : getLoadStoreInsts(singleBasicBlock)) for(auto &loadStoreInst : getLoadStoreInsts(singleBasicBlock))
{ {
Ice::Inst* inst = loadStoreInst.inst; Ice::Inst *inst = loadStoreInst.inst;
if((loadStoreInst.address != address) || inst->isDeleted()) if((loadStoreInst.address != address) || inst->isDeleted())
{ {
...@@ -547,7 +546,7 @@ bool Optimizer::isDead(Ice::Inst *instruction) ...@@ -547,7 +546,7 @@ bool Optimizer::isDead(Ice::Inst *instruction)
{ {
if(hasUses(address)) if(hasUses(address))
{ {
Optimizer::Uses* uses = getUses(address); Optimizer::Uses *uses = getUses(address);
return uses->size() == uses->stores.size(); // Dead if all uses are stores return uses->size() == uses->stores.size(); // Dead if all uses are stores
} }
else else
...@@ -707,9 +706,9 @@ bool Optimizer::loadTypeMatchesStore(const Ice::Inst *load, const Ice::Inst *sto ...@@ -707,9 +706,9 @@ bool Optimizer::loadTypeMatchesStore(const Ice::Inst *load, const Ice::Inst *sto
return false; return false;
} }
Optimizer::Uses* Optimizer::getUses(Ice::Operand* operand) Optimizer::Uses *Optimizer::getUses(Ice::Operand *operand)
{ {
Optimizer::Uses* uses = (Optimizer::Uses*)operand->Ice::Operand::getExternalData(); Optimizer::Uses *uses = (Optimizer::Uses *)operand->Ice::Operand::getExternalData();
if(!uses) if(!uses)
{ {
uses = new Optimizer::Uses; uses = new Optimizer::Uses;
...@@ -719,47 +718,47 @@ Optimizer::Uses* Optimizer::getUses(Ice::Operand* operand) ...@@ -719,47 +718,47 @@ Optimizer::Uses* Optimizer::getUses(Ice::Operand* operand)
return uses; return uses;
} }
void Optimizer::setUses(Ice::Operand* operand, Optimizer::Uses* uses) void Optimizer::setUses(Ice::Operand *operand, Optimizer::Uses *uses)
{ {
operand->Ice::Operand::setExternalData(uses); operand->Ice::Operand::setExternalData(uses);
} }
bool Optimizer::hasUses(Ice::Operand* operand) const bool Optimizer::hasUses(Ice::Operand *operand) const
{ {
return operand->Ice::Operand::getExternalData() != nullptr; return operand->Ice::Operand::getExternalData() != nullptr;
} }
Ice::CfgNode* Optimizer::getNode(Ice::Inst* inst) Ice::CfgNode *Optimizer::getNode(Ice::Inst *inst)
{ {
return (Ice::CfgNode*)inst->Ice::Inst::getExternalData(); return (Ice::CfgNode *)inst->Ice::Inst::getExternalData();
} }
void Optimizer::setNode(Ice::Inst* inst, Ice::CfgNode* node) void Optimizer::setNode(Ice::Inst *inst, Ice::CfgNode *node)
{ {
inst->Ice::Inst::setExternalData(node); inst->Ice::Inst::setExternalData(node);
} }
Ice::Inst* Optimizer::getDefinition(Ice::Variable* var) Ice::Inst *Optimizer::getDefinition(Ice::Variable *var)
{ {
return (Ice::Inst*)var->Ice::Variable::getExternalData(); return (Ice::Inst *)var->Ice::Variable::getExternalData();
} }
void Optimizer::setDefinition(Ice::Variable* var, Ice::Inst* inst) void Optimizer::setDefinition(Ice::Variable *var, Ice::Inst *inst)
{ {
var->Ice::Variable::setExternalData(inst); var->Ice::Variable::setExternalData(inst);
} }
const std::vector<Optimizer::LoadStoreInst>& Optimizer::getLoadStoreInsts(Ice::CfgNode* node) const std::vector<Optimizer::LoadStoreInst> &Optimizer::getLoadStoreInsts(Ice::CfgNode *node)
{ {
return *((const std::vector<LoadStoreInst>*)node->Ice::CfgNode::getExternalData()); return *((const std::vector<LoadStoreInst> *)node->Ice::CfgNode::getExternalData());
} }
void Optimizer::setLoadStoreInsts(Ice::CfgNode* node, std::vector<LoadStoreInst>* insts) void Optimizer::setLoadStoreInsts(Ice::CfgNode *node, std::vector<LoadStoreInst> *insts)
{ {
node->Ice::CfgNode::setExternalData(insts); node->Ice::CfgNode::setExternalData(insts);
} }
bool Optimizer::hasLoadStoreInsts(Ice::CfgNode* node) const bool Optimizer::hasLoadStoreInsts(Ice::CfgNode *node) const
{ {
return node->Ice::CfgNode::getExternalData() != nullptr; return node->Ice::CfgNode::getExternalData() != nullptr;
} }
......
...@@ -38,12 +38,12 @@ class RoutineT<Return(Arguments...)> ...@@ -38,12 +38,12 @@ class RoutineT<Return(Arguments...)>
public: public:
RoutineT() = default; RoutineT() = default;
explicit RoutineT(const std::shared_ptr<Routine>& routine) explicit RoutineT(const std::shared_ptr<Routine> &routine)
: routine(routine) : routine(routine)
{ {
if(routine) if(routine)
{ {
callable = reinterpret_cast<CallableType>(const_cast<void*>(routine->getEntry(0))); callable = reinterpret_cast<CallableType>(const_cast<void *>(routine->getEntry(0)));
} }
} }
...@@ -52,20 +52,20 @@ public: ...@@ -52,20 +52,20 @@ public:
return callable != nullptr; return callable != nullptr;
} }
template <typename... Args> template<typename... Args>
Return operator()(Args&&... args) const Return operator()(Args &&... args) const
{ {
return callable(std::forward<Args>(args)...); return callable(std::forward<Args>(args)...);
} }
const void* getEntry() const const void *getEntry() const
{ {
return reinterpret_cast<void*>(callable); return reinterpret_cast<void *>(callable);
} }
private: private:
std::shared_ptr<Routine> routine; std::shared_ptr<Routine> routine;
using CallableType = Return(*)(Arguments...); using CallableType = Return (*)(Arguments...);
CallableType callable = nullptr; CallableType callable = nullptr;
}; };
......
...@@ -19,13 +19,13 @@ namespace rr { ...@@ -19,13 +19,13 @@ namespace rr {
Thread::Thread(void (*threadFunction)(void *parameters), void *parameters) Thread::Thread(void (*threadFunction)(void *parameters), void *parameters)
{ {
Event init; Event init;
Entry entry = {threadFunction, parameters, &init}; Entry entry = { threadFunction, parameters, &init };
#if defined(_WIN32) #if defined(_WIN32)
handle = CreateThread(NULL, 1024 * 1024, startFunction, &entry, 0, NULL); handle = CreateThread(NULL, 1024 * 1024, startFunction, &entry, 0, NULL);
#else #else
pthread_create(&handle, NULL, startFunction, &entry); pthread_create(&handle, NULL, startFunction, &entry);
#endif #endif
init.wait(); init.wait();
} }
...@@ -39,54 +39,54 @@ void Thread::join() ...@@ -39,54 +39,54 @@ void Thread::join()
{ {
if(!hasJoined) if(!hasJoined)
{ {
#if defined(_WIN32) #if defined(_WIN32)
WaitForSingleObject(handle, INFINITE); WaitForSingleObject(handle, INFINITE);
CloseHandle(handle); CloseHandle(handle);
#else #else
pthread_join(handle, NULL); pthread_join(handle, NULL);
#endif #endif
hasJoined = true; hasJoined = true;
} }
} }
#if defined(_WIN32) #if defined(_WIN32)
unsigned long __stdcall Thread::startFunction(void *parameters) unsigned long __stdcall Thread::startFunction(void *parameters)
{ {
Entry entry = *(Entry*)parameters; Entry entry = *(Entry *)parameters;
entry.init->signal(); entry.init->signal();
entry.threadFunction(entry.threadParameters); entry.threadFunction(entry.threadParameters);
return 0; return 0;
} }
#else #else
void *Thread::startFunction(void *parameters) void *Thread::startFunction(void *parameters)
{ {
Entry entry = *(Entry*)parameters; Entry entry = *(Entry *)parameters;
entry.init->signal(); entry.init->signal();
entry.threadFunction(entry.threadParameters); entry.threadFunction(entry.threadParameters);
return nullptr; return nullptr;
} }
#endif #endif
Event::Event() Event::Event()
{ {
#if defined(_WIN32) #if defined(_WIN32)
handle = CreateEvent(NULL, FALSE, FALSE, NULL); handle = CreateEvent(NULL, FALSE, FALSE, NULL);
#else #else
pthread_cond_init(&handle, NULL); pthread_cond_init(&handle, NULL);
pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&mutex, NULL);
signaled = false; signaled = false;
#endif #endif
} }
Event::~Event() Event::~Event()
{ {
#if defined(_WIN32) #if defined(_WIN32)
CloseHandle(handle); CloseHandle(handle);
#else #else
pthread_cond_destroy(&handle); pthread_cond_destroy(&handle);
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
#endif #endif
} }
} // namespace rr } // namespace rr
...@@ -16,31 +16,31 @@ ...@@ -16,31 +16,31 @@
#define rr_Thread_hpp #define rr_Thread_hpp
#if defined(_WIN32) #if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN # ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
#endif # endif
#include <windows.h> # include <windows.h>
#include <intrin.h> # include <intrin.h>
#else #else
#include <pthread.h> # include <pthread.h>
#include <sched.h> # include <sched.h>
#include <unistd.h> # include <unistd.h>
#define TLS_OUT_OF_INDEXES (pthread_key_t)(~0) # define TLS_OUT_OF_INDEXES (pthread_key_t)(~0)
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#if defined(__clang__) #if defined(__clang__)
#if __has_include(<atomic>) // clang has an explicit check for the availability of atomic # if __has_include(<atomic>) // clang has an explicit check for the availability of atomic
#define USE_STD_ATOMIC 1 # define USE_STD_ATOMIC 1
#endif # endif
// atomic is available in C++11 or newer, and in Visual Studio 2012 or newer // atomic is available in C++11 or newer, and in Visual Studio 2012 or newer
#elif (defined(_MSC_VER) && (_MSC_VER >= 1700)) || (__cplusplus >= 201103L) #elif(defined(_MSC_VER) && (_MSC_VER >= 1700)) || (__cplusplus >= 201103L)
#define USE_STD_ATOMIC 1 # define USE_STD_ATOMIC 1
#endif #endif
#if USE_STD_ATOMIC #if USE_STD_ATOMIC
#include <atomic> # include <atomic>
#endif #endif
namespace rr { namespace rr {
...@@ -59,11 +59,11 @@ public: ...@@ -59,11 +59,11 @@ public:
static void yield(); static void yield();
static void sleep(int milliseconds); static void sleep(int milliseconds);
#if defined(_WIN32) #if defined(_WIN32)
typedef DWORD LocalStorageKey; typedef DWORD LocalStorageKey;
#else #else
typedef pthread_key_t LocalStorageKey; typedef pthread_key_t LocalStorageKey;
#endif #endif
static LocalStorageKey allocateLocalStorageKey(void (*destructor)(void *storage) = free); static LocalStorageKey allocateLocalStorageKey(void (*destructor)(void *storage) = free);
static void freeLocalStorageKey(LocalStorageKey key); static void freeLocalStorageKey(LocalStorageKey key);
...@@ -79,13 +79,13 @@ private: ...@@ -79,13 +79,13 @@ private:
Event *init; Event *init;
}; };
#if defined(_WIN32) #if defined(_WIN32)
static unsigned long __stdcall startFunction(void *parameters); static unsigned long __stdcall startFunction(void *parameters);
HANDLE handle; HANDLE handle;
#else #else
static void *startFunction(void *parameters); static void *startFunction(void *parameters);
pthread_t handle; pthread_t handle;
#endif #endif
bool hasJoined = false; bool hasJoined = false;
}; };
...@@ -103,13 +103,13 @@ public: ...@@ -103,13 +103,13 @@ public:
void wait(); void wait();
private: private:
#if defined(_WIN32) #if defined(_WIN32)
HANDLE handle; HANDLE handle;
#else #else
pthread_cond_t handle; pthread_cond_t handle;
pthread_mutex_t mutex; pthread_mutex_t mutex;
volatile bool signaled; volatile bool signaled;
#endif #endif
}; };
#if PERF_PROFILE #if PERF_PROFILE
...@@ -130,42 +130,42 @@ namespace rr { ...@@ -130,42 +130,42 @@ namespace rr {
inline void Thread::yield() inline void Thread::yield()
{ {
#if defined(_WIN32) #if defined(_WIN32)
Sleep(0); Sleep(0);
#elif defined(__APPLE__) #elif defined(__APPLE__)
pthread_yield_np(); pthread_yield_np();
#else #else
sched_yield(); sched_yield();
#endif #endif
} }
inline void Thread::sleep(int milliseconds) inline void Thread::sleep(int milliseconds)
{ {
#if defined(_WIN32) #if defined(_WIN32)
Sleep(milliseconds); Sleep(milliseconds);
#else #else
usleep(1000 * milliseconds); usleep(1000 * milliseconds);
#endif #endif
} }
inline Thread::LocalStorageKey Thread::allocateLocalStorageKey(void (*destructor)(void *storage)) inline Thread::LocalStorageKey Thread::allocateLocalStorageKey(void (*destructor)(void *storage))
{ {
#if defined(_WIN32) #if defined(_WIN32)
return TlsAlloc(); return TlsAlloc();
#else #else
LocalStorageKey key; LocalStorageKey key;
pthread_key_create(&key, destructor); pthread_key_create(&key, destructor);
return key; return key;
#endif #endif
} }
inline void Thread::freeLocalStorageKey(LocalStorageKey key) inline void Thread::freeLocalStorageKey(LocalStorageKey key)
{ {
#if defined(_WIN32) #if defined(_WIN32)
TlsFree(key); TlsFree(key);
#else #else
pthread_key_delete(key); // Using an invalid key is an error but not undefined behavior. pthread_key_delete(key); // Using an invalid key is an error but not undefined behavior.
#endif #endif
} }
inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size) inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size)
...@@ -179,133 +179,143 @@ inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size) ...@@ -179,133 +179,143 @@ inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size)
void *storage = malloc(size); void *storage = malloc(size);
#if defined(_WIN32) #if defined(_WIN32)
TlsSetValue(key, storage); TlsSetValue(key, storage);
#else #else
pthread_setspecific(key, storage); pthread_setspecific(key, storage);
#endif #endif
return storage; return storage;
} }
inline void *Thread::getLocalStorage(LocalStorageKey key) inline void *Thread::getLocalStorage(LocalStorageKey key)
{ {
#if defined(_WIN32) #if defined(_WIN32)
return TlsGetValue(key); return TlsGetValue(key);
#else #else
if(key == TLS_OUT_OF_INDEXES) // Avoid undefined behavior. if(key == TLS_OUT_OF_INDEXES) // Avoid undefined behavior.
{ {
return nullptr; return nullptr;
} }
return pthread_getspecific(key); return pthread_getspecific(key);
#endif #endif
} }
inline void Thread::freeLocalStorage(LocalStorageKey key) inline void Thread::freeLocalStorage(LocalStorageKey key)
{ {
free(getLocalStorage(key)); free(getLocalStorage(key));
#if defined(_WIN32) #if defined(_WIN32)
TlsSetValue(key, nullptr); TlsSetValue(key, nullptr);
#else #else
pthread_setspecific(key, nullptr); pthread_setspecific(key, nullptr);
#endif #endif
} }
inline void Event::signal() inline void Event::signal()
{ {
#if defined(_WIN32) #if defined(_WIN32)
SetEvent(handle); SetEvent(handle);
#else #else
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
signaled = true; signaled = true;
pthread_cond_signal(&handle); pthread_cond_signal(&handle);
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
#endif #endif
} }
inline void Event::wait() inline void Event::wait()
{ {
#if defined(_WIN32) #if defined(_WIN32)
WaitForSingleObject(handle, INFINITE); WaitForSingleObject(handle, INFINITE);
#else #else
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
while(!signaled) pthread_cond_wait(&handle, &mutex); while(!signaled) pthread_cond_wait(&handle, &mutex);
signaled = false; signaled = false;
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
#endif #endif
} }
#if PERF_PROFILE #if PERF_PROFILE
inline int64_t atomicExchange(volatile int64_t *target, int64_t value) inline int64_t atomicExchange(volatile int64_t *target, int64_t value)
{ {
#if defined(_WIN32) # if defined(_WIN32)
return InterlockedExchange64(target, value); return InterlockedExchange64(target, value);
#else # else
int ret; int ret;
__asm__ __volatile__("lock; xchg8 %x0,(%x1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" ); __asm__ __volatile__("lock; xchg8 %x0,(%x1)"
: "=r"(ret)
: "r"(target), "0"(value)
: "memory");
return ret; return ret;
#endif # endif
} }
inline int atomicExchange(volatile int *target, int value) inline int atomicExchange(volatile int *target, int value)
{ {
#if defined(_WIN32) # if defined(_WIN32)
return InterlockedExchange((volatile long*)target, (long)value); return InterlockedExchange((volatile long *)target, (long)value);
#else # else
int ret; int ret;
__asm__ __volatile__("lock; xchgl %x0,(%x1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" ); __asm__ __volatile__("lock; xchgl %x0,(%x1)"
: "=r"(ret)
: "r"(target), "0"(value)
: "memory");
return ret; return ret;
#endif # endif
} }
#endif #endif
inline int atomicIncrement(volatile int *value) inline int atomicIncrement(volatile int *value)
{ {
#if defined(_WIN32) #if defined(_WIN32)
return InterlockedIncrement((volatile long*)value); return InterlockedIncrement((volatile long *)value);
#else #else
return __sync_add_and_fetch(value, 1); return __sync_add_and_fetch(value, 1);
#endif #endif
} }
inline int atomicDecrement(volatile int *value) inline int atomicDecrement(volatile int *value)
{ {
#if defined(_WIN32) #if defined(_WIN32)
return InterlockedDecrement((volatile long*)value); return InterlockedDecrement((volatile long *)value);
#else #else
return __sync_sub_and_fetch(value, 1); return __sync_sub_and_fetch(value, 1);
#endif #endif
} }
inline int atomicAdd(volatile int* target, int value) inline int atomicAdd(volatile int *target, int value)
{ {
#if defined(_WIN32) #if defined(_WIN32)
return InterlockedExchangeAdd((volatile long*)target, value) + value; return InterlockedExchangeAdd((volatile long *)target, value) + value;
#else #else
return __sync_add_and_fetch(target, value); return __sync_add_and_fetch(target, value);
#endif #endif
} }
inline void nop() inline void nop()
{ {
#if defined(_WIN32) #if defined(_WIN32)
__nop(); __nop();
#else #else
__asm__ __volatile__ ("nop"); __asm__ __volatile__("nop");
#endif #endif
} }
#if USE_STD_ATOMIC #if USE_STD_ATOMIC
class AtomicInt class AtomicInt
{ {
public: public:
AtomicInt() : ai() {} AtomicInt()
AtomicInt(int i) : ai(i) {} : ai()
{}
AtomicInt(int i)
: ai(i)
{}
inline operator int() const { return ai.load(std::memory_order_acquire); } inline operator int() const { return ai.load(std::memory_order_acquire); }
inline void operator=(const AtomicInt& i) { ai.store(i.ai.load(std::memory_order_acquire), std::memory_order_release); } inline void operator=(const AtomicInt &i) { ai.store(i.ai.load(std::memory_order_acquire), std::memory_order_release); }
inline void operator=(int i) { ai.store(i, std::memory_order_release); } inline void operator=(int i) { ai.store(i, std::memory_order_release); }
inline void operator--() { ai.fetch_sub(1, std::memory_order_acq_rel); } inline void operator--() { ai.fetch_sub(1, std::memory_order_acq_rel); }
inline void operator++() { ai.fetch_add(1, std::memory_order_acq_rel); } inline void operator++() { ai.fetch_add(1, std::memory_order_acq_rel); }
...@@ -313,18 +323,21 @@ inline void nop() ...@@ -313,18 +323,21 @@ inline void nop()
inline int operator++(int) { return ai.fetch_add(1, std::memory_order_acq_rel) + 1; } inline int operator++(int) { return ai.fetch_add(1, std::memory_order_acq_rel) + 1; }
inline void operator-=(int i) { ai.fetch_sub(i, std::memory_order_acq_rel); } inline void operator-=(int i) { ai.fetch_sub(i, std::memory_order_acq_rel); }
inline void operator+=(int i) { ai.fetch_add(i, std::memory_order_acq_rel); } inline void operator+=(int i) { ai.fetch_add(i, std::memory_order_acq_rel); }
private:
private:
std::atomic<int> ai; std::atomic<int> ai;
}; };
#else #else
class AtomicInt class AtomicInt
{ {
public: public:
AtomicInt() {} AtomicInt() {}
AtomicInt(int i) : vi(i) {} AtomicInt(int i)
: vi(i)
{}
inline operator int() const { return vi; } // Note: this isn't a guaranteed atomic operation inline operator int() const { return vi; } // Note: this isn't a guaranteed atomic operation
inline void operator=(const AtomicInt& i) { atomicExchange(&vi, i.vi); } inline void operator=(const AtomicInt &i) { atomicExchange(&vi, i.vi); }
inline void operator=(int i) { atomicExchange(&vi, i); } inline void operator=(int i) { atomicExchange(&vi, i); }
inline void operator--() { atomicDecrement(&vi); } inline void operator--() { atomicDecrement(&vi); }
inline void operator++() { atomicIncrement(&vi); } inline void operator++() { atomicIncrement(&vi); }
...@@ -332,9 +345,10 @@ inline void nop() ...@@ -332,9 +345,10 @@ inline void nop()
inline int operator++(int) { return atomicIncrement(&vi); } inline int operator++(int) { return atomicIncrement(&vi); }
inline void operator-=(int i) { atomicAdd(&vi, -i); } inline void operator-=(int i) { atomicAdd(&vi, -i); }
inline void operator+=(int i) { atomicAdd(&vi, i); } inline void operator+=(int i) { atomicAdd(&vi, i); }
private:
private:
volatile int vi; volatile int vi;
}; };
#endif #endif
} // namespace rr } // namespace rr
......
...@@ -20,7 +20,7 @@ namespace rr { ...@@ -20,7 +20,7 @@ namespace rr {
// Non-specialized implementation of CToReactorPtr::cast() defaults to // Non-specialized implementation of CToReactorPtr::cast() defaults to
// returning a ConstantPointer for v. // returning a ConstantPointer for v.
template<typename T, typename ENABLE> template<typename T, typename ENABLE>
Pointer<Byte> CToReactorPtr<T, ENABLE>::cast(const T* v) Pointer<Byte> CToReactorPtr<T, ENABLE>::cast(const T *v)
{ {
return ConstantPointer(v); return ConstantPointer(v);
} }
...@@ -29,13 +29,13 @@ Pointer<Byte> CToReactorPtr<T, ENABLE>::cast(const T* v) ...@@ -29,13 +29,13 @@ Pointer<Byte> CToReactorPtr<T, ENABLE>::cast(const T* v)
// specialization. // specialization.
template<typename T> template<typename T>
Pointer<CToReactorT<T>> Pointer<CToReactorT<T>>
CToReactorPtr<T, enable_if_t< HasReactorType<T>::value > >::cast(const T* v) CToReactorPtr<T, enable_if_t<HasReactorType<T>::value>>::cast(const T *v)
{ {
return type(v); return type(v);
} }
// CToReactorPtr specialization for void*. // CToReactorPtr specialization for void*.
Pointer<Byte> CToReactorPtr<void, void>::cast(const void* v) Pointer<Byte> CToReactorPtr<void, void>::cast(const void *v)
{ {
return ConstantPointer(v); return ConstantPointer(v);
} }
...@@ -43,7 +43,7 @@ Pointer<Byte> CToReactorPtr<void, void>::cast(const void* v) ...@@ -43,7 +43,7 @@ Pointer<Byte> CToReactorPtr<void, void>::cast(const void* v)
// CToReactorPtrT specialization for function pointer types. // CToReactorPtrT specialization for function pointer types.
template<typename T> template<typename T>
Pointer<Byte> Pointer<Byte>
CToReactorPtr<T, enable_if_t< std::is_function<T>::value > >::cast(T* v) CToReactorPtr<T, enable_if_t<std::is_function<T>::value>>::cast(T *v)
{ {
return ConstantPointer(v); return ConstantPointer(v);
} }
...@@ -51,7 +51,7 @@ CToReactorPtr<T, enable_if_t< std::is_function<T>::value > >::cast(T* v) ...@@ -51,7 +51,7 @@ CToReactorPtr<T, enable_if_t< std::is_function<T>::value > >::cast(T* v)
// CToReactor specialization for pointer types. // CToReactor specialization for pointer types.
template<typename T> template<typename T>
CToReactorPtrT<typename std::remove_pointer<T>::type> CToReactorPtrT<typename std::remove_pointer<T>::type>
CToReactor<T, enable_if_t<std::is_pointer<T>::value> >::cast(T v) CToReactor<T, enable_if_t<std::is_pointer<T>::value>>::cast(T v)
{ {
return CToReactorPtr<elem>::cast(v); return CToReactorPtr<elem>::cast(v);
} }
...@@ -59,7 +59,7 @@ CToReactor<T, enable_if_t<std::is_pointer<T>::value> >::cast(T v) ...@@ -59,7 +59,7 @@ CToReactor<T, enable_if_t<std::is_pointer<T>::value> >::cast(T v)
// CToReactor specialization for enum types. // CToReactor specialization for enum types.
template<typename T> template<typename T>
CToReactorT<typename std::underlying_type<T>::type> CToReactorT<typename std::underlying_type<T>::type>
CToReactor<T, enable_if_t<std::is_enum<T>::value> >::cast(T v) CToReactor<T, enable_if_t<std::is_enum<T>::value>>::cast(T v)
{ {
return CToReactor<underlying>::cast(v); return CToReactor<underlying>::cast(v);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment