From 7f24b9ffbb50224ebb8c697bf3e8c67eb389d9a5 Mon Sep 17 00:00:00 2001 From: foreman Date: Wed, 26 Aug 2015 14:07:03 -0400 Subject: [PATCH] P4 to Git Change 1184767 by lmoriche@lmoriche_opencl_dev on 2015/08/26 13:54:18 ECR #304775 - Remove the complib oclutils Affected files ... ... //depot/stg/opencl/drivers/opencl/Makefile#52 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/Makefile#36 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/build/Makefile.complib#92 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/complibdefs#43 edit ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/Makefile#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/build/Makefile#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/build/Makefile.oclutils#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/alloc.cpp#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/alloc.hpp#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/os.cpp#6 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/os.hpp#7 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/os_posix.cpp#11 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/os_win32.cpp#6 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/setjmp.S#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/os/setjmp.asm#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/thread/atomic.hpp#5 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/thread/monitor.cpp#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/thread/monitor.hpp#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/thread/semaphore.cpp#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/thread/semaphore.hpp#4 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/thread/thread.cpp#4 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/thread/thread.hpp#4 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/top.hpp#6 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/utils/debug.cpp#2 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/utils/debug.hpp#3 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/utils/macros.hpp#4 delete ... //depot/stg/opencl/drivers/opencl/compiler/lib/promotions/oclutils/utils/util.hpp#3 delete ... //depot/stg/opencl/drivers/opencl/runtime/Makefile#19 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/debug.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/debug.hpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.hpp#238 edit --- rocclr/compiler/lib/complibdefs | 4 +- .../lib/promotions/oclutils/os/alloc.cpp | 87 -- .../lib/promotions/oclutils/os/alloc.hpp | 30 - .../lib/promotions/oclutils/os/os.cpp | 145 --- .../lib/promotions/oclutils/os/os.hpp | 519 -------- .../lib/promotions/oclutils/os/os_posix.cpp | 888 -------------- .../lib/promotions/oclutils/os/os_win32.cpp | 1083 ----------------- .../lib/promotions/oclutils/os/setjmp.S | 63 - .../lib/promotions/oclutils/os/setjmp.asm | 110 -- .../lib/promotions/oclutils/thread/atomic.hpp | 548 --------- .../promotions/oclutils/thread/monitor.cpp | 321 ----- .../promotions/oclutils/thread/monitor.hpp | 263 ---- .../promotions/oclutils/thread/semaphore.cpp | 95 -- .../promotions/oclutils/thread/semaphore.hpp | 65 - .../lib/promotions/oclutils/thread/thread.cpp | 191 --- .../lib/promotions/oclutils/thread/thread.hpp | 231 ---- .../compiler/lib/promotions/oclutils/top.hpp | 221 ---- .../lib/promotions/oclutils/utils/debug.cpp | 102 -- .../lib/promotions/oclutils/utils/debug.hpp | 182 --- .../lib/promotions/oclutils/utils/macros.hpp | 177 --- .../lib/promotions/oclutils/utils/util.hpp | 281 ----- rocclr/runtime/utils/debug.cpp | 10 - rocclr/runtime/utils/debug.hpp | 15 - rocclr/runtime/utils/flags.hpp | 4 - 24 files changed, 3 insertions(+), 5632 deletions(-) delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/alloc.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/alloc.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/os.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/os.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/os_posix.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/os_win32.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/setjmp.S delete mode 100644 rocclr/compiler/lib/promotions/oclutils/os/setjmp.asm delete mode 100644 rocclr/compiler/lib/promotions/oclutils/thread/atomic.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/thread/monitor.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/thread/monitor.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/thread/semaphore.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/thread/semaphore.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/thread/thread.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/thread/thread.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/top.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/utils/debug.cpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/utils/debug.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/utils/macros.hpp delete mode 100644 rocclr/compiler/lib/promotions/oclutils/utils/util.hpp diff --git a/rocclr/compiler/lib/complibdefs b/rocclr/compiler/lib/complibdefs index 0b7b3c175c..7fb916a83d 100644 --- a/rocclr/compiler/lib/complibdefs +++ b/rocclr/compiler/lib/complibdefs @@ -37,8 +37,10 @@ endif GCPPFLAGS += $(INCSWITCH) "$(DEPTH)/drivers" GCPPFLAGS += $(INCSWITCH) "$(DEPTH)/drivers/inc/asic_reg" GCPPFLAGS += $(INCSWITCH) "$(COMPLIB_DEPTH)" -GCPPFLAGS += $(INCSWITCH) "$(COMPLIB_DEPTH)/promotions/oclutils" +GCPPFLAGS += $(INCSWITCH) "$(OPENCL_DEPTH)/runtime" +GCPPFLAGS += $(INCSWITCH) "$(OPENCL_DEPTH)/runtime/utils" GCPPFLAGS += $(INCSWITCH) "$(COMPLIB_DEPTH)/utils" +GCPPFLAGS += $(INCSWITCH) "$(OPENCL_DEPTH)/api/opencl/khronos/headers/opencl2.0" # Do we build the 0.9 version? ifeq ($(BUILD_VERSION_0_9), 1) diff --git a/rocclr/compiler/lib/promotions/oclutils/os/alloc.cpp b/rocclr/compiler/lib/promotions/oclutils/os/alloc.cpp deleted file mode 100644 index 53e5f61499..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/alloc.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#include "os/alloc.hpp" -#include "os/os.hpp" -#include "utils/util.hpp" - -#include - -namespace amd { - -void* -AlignedMemory::allocate(size_t size, size_t alignment) -{ - return Os::alignedMalloc(size, alignment); -} - -void* -GuardedMemory::allocate(size_t size, size_t alignment, size_t guardSize) -{ - size_t sizeToAllocate = guardSize + alignment; - sizeToAllocate += size + guardSize + Os::pageSize(); - - sizeToAllocate = amd::alignUp(sizeToAllocate, Os::pageSize()); - address userHostMemGuarded = Os::reserveMemory(NULL, sizeToAllocate); - if (!userHostMemGuarded || !Os::commitMemory( - userHostMemGuarded, sizeToAllocate, Os::MEM_PROT_RW)) { - return NULL; - } - - address userHostMem = userHostMemGuarded + sizeToAllocate; - userHostMem = amd::alignDown(userHostMem - guardSize, Os::pageSize()); - - // Protect the guard pages after the end of the users's buffer. - if (!Os::protectMemory(userHostMem, guardSize, Os::MEM_PROT_NONE)) { - fatal("Protect memory (up) failed"); - } - - userHostMem = userHostMem - size; - userHostMem = amd::alignDown(userHostMem, alignment); - // Write the actual size allocated including all the guard pages, - // alignment, page file size... as well as the size of guarded byte - // count before the beginning of the user's buffer. - size_t* temp = reinterpret_cast(userHostMem); - *--temp = sizeToAllocate; - *--temp = userHostMem - userHostMemGuarded; - - // Protect the guard pages before the beginning of the user's buffer. - if (!Os::protectMemory(userHostMemGuarded, guardSize, Os::MEM_PROT_NONE)) { - fatal("Protect memory (down) failed"); - } - - return userHostMem; -} - -void -AlignedMemory::deallocate(void* ptr) -{ - Os::alignedFree(ptr); -} - -void -GuardedMemory::deallocate(void* ptr) -{ - size_t* userHostMem = static_cast(ptr); - - size_t size = *--userHostMem; - size_t offset = *--userHostMem; - - Os::releaseMemory(static_cast
(ptr) - offset, size); -} - -void* -HeapObject::operator new(size_t size) -{ - return malloc(size); -} - -void -HeapObject::operator delete(void* obj) -{ - free(obj); -} - - -} // namespace amd diff --git a/rocclr/compiler/lib/promotions/oclutils/os/alloc.hpp b/rocclr/compiler/lib/promotions/oclutils/os/alloc.hpp deleted file mode 100644 index c243d2b0d0..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/alloc.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef ALLOC_HPP_ -#define ALLOC_HPP_ - -#include "top.hpp" - -namespace amd { - -class AlignedMemory : public AllStatic -{ -public: - static void* allocate(size_t size, size_t alignment); - - static void deallocate(void* ptr); -}; - -class GuardedMemory : public AllStatic -{ -public: - static void* allocate(size_t size, size_t alignment, size_t guardSize); - - static void deallocate(void* ptr); -}; - -} // namespace amd - -#endif /*ALLOC_HPP_*/ diff --git a/rocclr/compiler/lib/promotions/oclutils/os/os.cpp b/rocclr/compiler/lib/promotions/oclutils/os/os.cpp deleted file mode 100644 index 0f01f31902..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/os.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#include "os/os.hpp" -#include "thread/thread.hpp" - -#include -#include - -#if defined(_WIN32) || defined(__CYGWIN__) -# include -#else // !_WIN32 -# include -# include -#endif // !_WIN32 - -#if defined(ATI_ARCH_X86) -#include // for _mm_pause -#endif // ATI_ARCH_X86 - -namespace amd { - -void* -Os::loadLibrary(const char* libraryname) -{ - void* handle = Os::loadLibrary_(libraryname); - if (handle != NULL) { - return handle; - } - - // Try with the system library prefix and extension instead. - std::string str = libraryname; - - size_t namestart = str.rfind(fileSeparator()); - namestart = (namestart != std::string::npos) ? namestart + 1 : 0; - - const char* prefix = Os::libraryPrefix(); - if (prefix != NULL - && str.compare(namestart, strlen(prefix), prefix) == 0) { - // It is alread present, not need to prepend it. - prefix = NULL; - } - size_t dot = str.rfind('.'); - if (dot != std::string::npos) { - // check that the dot was on the filename not a dir name. - if (namestart < dot) { - // strip the previous extension. - str.resize(dot); - } - } - if (prefix != NULL && prefix[0] != '\0') { - str.insert(namestart, prefix); - } - str.append(Os::libraryExtension()); - - handle = Os::loadLibrary_(str.c_str()); - if (handle != NULL || str.find(fileSeparator()) != std::string::npos) { - return handle; - } - - // Try to find the lib in the current directory. - return Os::loadLibrary((std::string(".") + fileSeparator() - + std::string(libraryname)).c_str()); -} - -size_t Os::pageSize_ = 0; - -int Os::processorCount_ = 0; - -void -Os::spinPause() -{ -#if defined(ATI_ARCH_X86) - _mm_pause(); -#elif defined(__ARM_ARCH_7A__) - __asm__ __volatile__("yield"); -#endif -} - -void -Os::sleep(long n) -{ - // FIXME_lmoriche: Should be nano-seconds not seconds. -#ifdef _WIN32 - ::Sleep(n); -#else // !_WIN32 - time_t seconds = (time_t) n / 1000; - long nanoseconds = ((long) n - seconds * 1000) * 1000000; - timespec ts = { seconds, nanoseconds }; - ::nanosleep(&ts, NULL); -#endif // !_WIN32 -} - -void -Os::touchStackPages(address bottom, address top) -{ - top = alignDown(top, pageSize_) - pageSize_; - while (top >= bottom) { - *top = 0; - top -= pageSize_; - } -} - -bool -Os::skipIDIV(address& pc) -{ - address insn = pc; - if (insn[0] == 0x66) { // LCP prefix - insn += 1; - } - if ((insn[0] & 0xf0) == 0x40) { // REX prefix - insn += 1; - } - if (insn[0] == 0xf6 || insn[0] == 0xf7) { // IDIV - // This is a DivisionError: skip the insn and resume execution - char mod = insn[1] >> 6; - char rm = insn[1] & 0x7; - insn += 2; // skip opcode and mod/rm - - if (rm == 0x4 && mod != 0x3) { - insn += 1; // sib follows mod/rm - } - - if ((mod == 0x0 && rm == 0x5) || mod == 0x2) { - insn += 4; // disp32 - } - else if (mod == 0x1) { - insn += 1; // disp8 - } - pc = insn; - return true; - } - return false; -} - -void -Os::setThreadAffinity(const void* handle, unsigned int cpu) -{ - ThreadAffinityMask mask; - mask.set(cpu); - setThreadAffinity(handle, mask); -} - -} // namespace amd diff --git a/rocclr/compiler/lib/promotions/oclutils/os/os.hpp b/rocclr/compiler/lib/promotions/oclutils/os/os.hpp deleted file mode 100644 index e361a96f4f..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/os.hpp +++ /dev/null @@ -1,519 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef OS_HPP_ -#define OS_HPP_ - -#include "top.hpp" -#include "utils/util.hpp" - -#include -#include - -#if defined(__linux__) -# include -#endif - -#ifdef _WIN32 -# include // For KAFFINITY -#endif // _WIN32 - -// Smallest supported VM page size. -#define MIN_PAGE_SHIFT 12 -#define MIN_PAGE_SIZE (1UL << MIN_PAGE_SHIFT) - -namespace amd { - -/*! \addtogroup Os Operating System Abstraction - * - * \copydoc amd::Os - * - * @{ - */ - -class Thread; // For Os::createOsThread() - -class Os : AllStatic -{ -public: - enum MemProt - { - MEM_PROT_NONE = 0, - MEM_PROT_READ, - MEM_PROT_RW, - MEM_PROT_RWX - }; - - class ThreadAffinityMask - { - friend class Os; - private: -#if defined(__linux__) - cpu_set_t mask_; -#else // _WIN32 - #if !defined(_WIN32) - typedef uint KAFFINITY; - #endif - KAFFINITY mask_[512 / sizeof(KAFFINITY)]; -#endif - - public: - ThreadAffinityMask() { init(); } - - inline void init(); - inline void set(uint cpu); - inline void clear(uint cpu); - inline bool isSet(uint cpu) const; - inline bool isEmpty() const; - inline uint countSet() const; - - inline uint getFirstSet() const; - inline uint getNextSet(uint cpu) const; - -#if defined(__linux__) - inline void set(const cpu_set_t& mask); - inline void clear(const cpu_set_t& mask); - inline void adjust(cpu_set_t& mask) const; - inline cpu_set_t& getNative() { return mask_; } -#else - inline void set(size_t group, KAFFINITY affinity); - inline void adjust(size_t group, KAFFINITY& affinity) const; -#endif - }; - -private: - static const size_t FILE_PATH_MAX_LENGTH = 1024; - - static size_t pageSize_; //!< The default os page size. - static int processorCount_; //!< The number of active processors. - -private: - //! Load the shared library named by \a filename - static void* loadLibrary_(const char* filename); - -public: - //! Initialize the Os package. - static bool init(); - //! Tear down the Os package. - static void tearDown(); - - // Topology helper routines: - // - - //! Return the number of active processors in the system. - inline static int processorCount(); - -#if defined(ATI_ARCH_X86) - //! Query the processor information about supported features and CPU type. - static void cpuid(int regs[4], int info); - //! Get value of extended control register - static uint64_t xgetbv(uint32_t which); -#endif // ATI_ARCH_X86 - - // Stack helper routines: - // - - //! Return the current stack base and size information. - static void currentStackInfo(address* base, size_t *size); - - //! Return the value of the current stack pointer. - static NOT_WIN64(inline) address currentStackPtr(); - //! Set the value of the current stack pointer. - static WIN64_ONLY(inline) void WINDOWS_ONLY(__stdcall/*callee cleanup*/) - setCurrentStackPtr(address sp); - //! Touches all stack pages between [bottom,top[ - static void touchStackPages(address bottom, address top); - - // Thread routines: - // - - //! Create a native thread and link it to the given OsThread. - static const void* createOsThread(Thread* osThread); - //! Set the thread's affinity to the given cpu ordinal. - static void setThreadAffinity(const void* handle, unsigned int cpu); - //! Set the thread's affinity to the given cpu mask. - static void setThreadAffinity(const void* handle, const ThreadAffinityMask& mask); - //! Set the currently running thread's name. - static void setCurrentThreadName(const char* name); - //! Check if the thread is alive - static bool isThreadAlive(const Thread& osThread); - - //! Sleep for n milli-seconds. - static void sleep(long n); - //! Yield to threads of the same or lower priority - static void yield(); - //! Execute a pause instruction (for spin loops). - static void spinPause(); - - // Memory routines: - // - - //! Return the default os page size. - inline static size_t pageSize(); - //! Return the amount of host total physical memory in bytes. - static uint64_t hostTotalPhysicalMemory(); - - //! Reserve a chunk of memory (priv | anon | noreserve). - static address reserveMemory(address start, size_t size, size_t alignment = 0, MemProt prot = MEM_PROT_NONE); - //! Release a chunk of memory reserved with reserveMemory. - static bool releaseMemory(void* addr, size_t size); - //! Commit a chunk of memory previously reserved with reserveMemory. - static bool commitMemory(void* addr, size_t size, MemProt prot = MEM_PROT_NONE); - //! Uncommit a chunk of memory previously committed with commitMemory. - static bool uncommitMemory(void* addr, size_t size); - //! Set the page protections for the given memory region. - static bool protectMemory(void* addr, size_t size, MemProt prot); - - //! Allocate an aligned chunk of memory. - static void* alignedMalloc(size_t size, size_t alignment); - //! Deallocate an aligned chunk of memory. - static void alignedFree(void* mem); - - //! Platform-specific optimized memcpy() - static void* fastMemcpy(void *dest, const void *src, size_t n); - - // File/Path helper routines: - // - - //! Return the shared library extension string. - static const char* libraryExtension(); - //! Return the shared library prefix string. - static const char* libraryPrefix(); - //! Return the object extension string. - static const char* objectExtension(); - //! Return the file separator char. - static char fileSeparator(); - //! Return the path separator char. - static char pathSeparator(); - //! Return whether the path exists - static bool pathExists(const std::string& path); - //! Create the path if it does not exist - static bool createPath(const std::string& path); - //! Remove the path if it is empty - static bool removePath(const std::string& path); - //! Printf re-implementation (due to MS CRT problem) - static int printf(const char*fmt,...); - /*! \brief Invokes the command processor for the command execution - * - * \result Returns the operation result - */ - static int systemCall( - const std::string& command); //!< command for execution - - /*! \brief Retrieves a string containing the value - * of the environment variable - * - * \result Returns the environment variable value - */ - static std::string getEnvironment( - const std::string& name); //!< the environment variable's name - - /*! \brief Retrieves the path of the directory designated for temporary - * files - * - * \result Returns the temporary path - */ - static std::string getTempPath(); - - /*! \brief Creates a name for a temporary file - * - * \result Returns the name of temporary file - */ - static std::string getTempFileName(); - - //! Deletes file - static int unlink(const std::string& path); - - // Library routines: - // - typedef bool (*SymbolCallback)(std::string, const void*, void*); - - //! Load the shared library named by \a filename - static void* loadLibrary(const char* filename); - //! Unload the shared library. - static void unloadLibrary(void* handle); - //! Return the address of the function identified by \a name. - static void* getSymbol(void* handle, const char* name); - //! Get all the __kernel functions in the given shared library. - static bool iterateSymbols(void* handle, SymbolCallback func, void* data); - - // Time routines: - // - - //! Return the current system time counter in nanoseconds. - static uint64_t timeNanos(); - //! Return the system timer's resolution in nanoseconds. - static uint64_t timerResolutionNanos(); - //! Return the timeNanos starting point offset to Epoch. - static uint64_t offsetToEpochNanos(); - - // X86 Instructions helpers: - // - - //! Skip an IDIV (F6/F7) instruction and return a pointer to the next insn. - static bool skipIDIV(address& insn); - - // return gloabal memory size to be assigned to device info - static size_t getPhysicalMemSize(); - - //! get Application file name - static std::string getAppFileName(); -}; - -/*@}*/ - -inline size_t -Os::pageSize() -{ - assert(pageSize_ != 0 && "runtime is not initialized"); - return pageSize_; -} - -inline int -Os::processorCount() -{ - return processorCount_; -} - -#if defined(_WIN64) - -extern "C" void _Os_setCurrentStackPtr(address sp); - -ALWAYSINLINE void -Os::setCurrentStackPtr(address sp) -{ - _Os_setCurrentStackPtr(sp); -} - -#else // !_WIN64 - -ALWAYSINLINE address -Os::currentStackPtr() -{ - intptr_t value; - -#if defined(__GNUC__) - __asm__ __volatile__ ( -# if defined(ATI_ARCH_X86) - LP64_SWITCH("movl %%esp", "movq %%rsp") ",%0" : "=r"(value) -# elif defined(ATI_ARCH_ARM) - "mov %0,sp" : "=r"(value) -# endif - ); -#else // !__GNUC__ - __asm mov value, esp; -#endif // !__GNUC__ - - return (address)value; -} - -#endif // !_WIN64 - - -#if defined(__linux__) - -inline void -Os::ThreadAffinityMask::init() -{ - CPU_ZERO(&mask_); -} - -inline void -Os::ThreadAffinityMask::set(uint cpu) -{ - CPU_SET(cpu, &mask_); -} - -inline void -Os::ThreadAffinityMask::clear(uint cpu) -{ - CPU_CLR(cpu, &mask_); -} - -inline bool -Os::ThreadAffinityMask::isSet(uint cpu) const -{ - return CPU_ISSET(cpu, &mask_); -} - -inline bool -Os::ThreadAffinityMask::isEmpty() const -{ - const uint32_t* bits = (const uint32_t*)mask_.__bits; - for (uint i = 0; i < sizeof(mask_.__bits) / sizeof(uint32_t); ++i) { - if (bits[i] != 0) { - return false; - } - } - return true; -} - -inline void -Os::ThreadAffinityMask::set(const cpu_set_t& mask) -{ - mask_ = mask; -} - -inline void -Os::ThreadAffinityMask::clear(const cpu_set_t& mask) -{ - const uint32_t* bitsClear = (const uint32_t*)mask.__bits; - uint32_t* bits = (uint32_t*)mask_.__bits; - for (uint i = 0; i < sizeof(mask_.__bits) / sizeof(uint32_t); ++i) { - bits[i] &= ~bitsClear[i]; - } -} - -inline void -Os::ThreadAffinityMask::adjust(cpu_set_t& mask) const -{ - uint32_t* bitsOut = (uint32_t*)mask.__bits; - const uint32_t* bits = (const uint32_t*)mask_.__bits; - for (uint i = 0; i < sizeof(mask_.__bits) / sizeof(uint32_t); ++i) { - bitsOut[i] &= bits[i]; - } -} - -inline uint -Os::ThreadAffinityMask::countSet() const -{ - uint count = 0; - const uint32_t* bits = (const uint32_t*)mask_.__bits; - for (uint i = 0; i < sizeof(mask_.__bits) / sizeof(uint32_t); ++i) { - count += countBitsSet(bits[i]); - } - return count; -} - -inline uint -Os::ThreadAffinityMask::getFirstSet() const -{ - const uint32_t* bits = (const uint32_t*)mask_.__bits; - for (uint i = 0; i < sizeof(mask_.__bits) / sizeof(uint32_t); ++i) { - if (bits[i] != 0) { - return leastBitSet(bits[i]) + (i * (8*sizeof(uint32_t))); - } - } - return (uint)-1; -} - -inline uint -Os::ThreadAffinityMask::getNextSet(uint cpu) const -{ - const uint32_t* bits = (const uint32_t*)mask_.__bits; - ++cpu; - uint j = cpu % (8*sizeof(uint32_t)); - for (uint i = cpu / (8*sizeof(uint32_t)); - i < sizeof(mask_.__bits) / sizeof(uint32_t); ++i) { - if (bits[i] != 0) { - for (; j < (8*sizeof(uint32_t)); ++j) { - if (0 != (bits[i] & ((uint32_t)1 << j))) { - return i * (8*sizeof(uint32_t)) + j; - } - } - } - j = 0; - } - return (uint)-1; -} - -#else - -inline void -Os::ThreadAffinityMask::init() -{ - for (uint i = 0; i < sizeof(mask_) / sizeof(KAFFINITY); ++i) { - mask_[i] = (KAFFINITY)0; - } -} - -inline void -Os::ThreadAffinityMask::set(uint cpu) -{ - mask_[cpu / (8*sizeof(KAFFINITY))] |= - (KAFFINITY)1 << (cpu % (8*sizeof(KAFFINITY))); -} - -inline void -Os::ThreadAffinityMask::clear(uint cpu) -{ - mask_[cpu / (8*sizeof(KAFFINITY))] &= - ~( (KAFFINITY)1 << (cpu % (8*sizeof(KAFFINITY))) ); -} - -inline bool -Os::ThreadAffinityMask::isSet(uint cpu) const -{ - return (KAFFINITY)0 != (mask_[cpu / (8*sizeof(KAFFINITY))] & - ((KAFFINITY)1 << (cpu % (8*sizeof(KAFFINITY))))); -} - -inline bool -Os::ThreadAffinityMask::isEmpty() const -{ - for (uint i = 0; i < sizeof(mask_) / sizeof(KAFFINITY); ++i) { - if (mask_[i] != (KAFFINITY)0) { - return false; - } - } - return true; -} - -inline void -Os::ThreadAffinityMask::set(size_t group, KAFFINITY affinity) -{ - mask_[group] |= affinity; -} - -inline void -Os::ThreadAffinityMask::adjust(size_t group, KAFFINITY& affinity) const -{ - affinity &= mask_[group]; -} - -inline uint -Os::ThreadAffinityMask::countSet() const -{ - uint count = 0; - for (uint i = 0; i < sizeof(mask_) / sizeof(KAFFINITY); ++i) { - count += countBitsSet(mask_[i]); - } - return count; -} - -inline uint -Os::ThreadAffinityMask::getFirstSet() const -{ - for (uint i = 0; i < sizeof(mask_) / sizeof(KAFFINITY); ++i) { - if (mask_[i] != 0) { - return leastBitSet(mask_[i]) + (i * (8*sizeof(KAFFINITY))); - } - } - return (uint)-1; -} - -inline uint -Os::ThreadAffinityMask::getNextSet(uint cpu) const -{ - ++cpu; - uint j = cpu % (8*sizeof(KAFFINITY)); - for (uint i = cpu / (8*sizeof(KAFFINITY)); - i < sizeof(mask_) / sizeof(KAFFINITY); ++i) { - if (mask_[i] != 0) { - for (; j < (8*sizeof(KAFFINITY)); ++j) { - if (0 != (mask_[i] & ((KAFFINITY)1 << j))) { - return i * (8*sizeof(KAFFINITY)) + j; - } - } - } - j = 0; - } - return (uint)-1; -} - -#endif - -} // namespace amd - -#endif /*OS_HPP_*/ diff --git a/rocclr/compiler/lib/promotions/oclutils/os/os_posix.cpp b/rocclr/compiler/lib/promotions/oclutils/os/os_posix.cpp deleted file mode 100644 index c29f73bcaa..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/os_posix.cpp +++ /dev/null @@ -1,888 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#if !defined(_WIN32) && !defined(__CYGWIN__) - -#include "os/os.hpp" -#include "thread/thread.hpp" -#include "utils/util.hpp" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#ifndef DT_GNU_HASH -# define DT_GNU_HASH 0x6ffffef5 -#endif // DT_GNU_HASH - -#include -#include -#include -#include -#include // for strncmp -#include -#include // for tempnam -#include -#include - -#ifdef ANDROID -//#include -#endif - -namespace amd { - -static struct sigaction oldSigAction; - -static bool -callOldSignalHandler(int sig, siginfo_t* info, void* ptr) -{ - if (oldSigAction.sa_handler == SIG_DFL) { - // no signal handler was previously installed. - return false; - } - else if (oldSigAction.sa_handler != SIG_IGN) { - - if ((oldSigAction.sa_flags & SA_NODEFER) == 0) { - sigaddset(&oldSigAction.sa_mask, sig); - } - - void (*handler)(int) = oldSigAction.sa_handler; - if (oldSigAction.sa_flags & SA_RESETHAND) { - oldSigAction.sa_handler = SIG_DFL; - } - - sigset_t savedSigSet; - pthread_sigmask(SIG_SETMASK, &oldSigAction.sa_mask, &savedSigSet); - - if (oldSigAction.sa_flags & SA_SIGINFO) { - oldSigAction.sa_sigaction(sig, info, ptr); - } - else { - handler(sig); - } - - pthread_sigmask(SIG_SETMASK, &savedSigSet, NULL); - } - - return true; -} - -static void -divisionErrorHandler(int sig, siginfo_t* info, void* ptr) -{ -#ifdef ANDROID - assert(false && "ucontext_t undefined for Android"); - return; -#else - assert(info != NULL && ptr != NULL && "just checking"); - ucontext_t* uc = (ucontext_t*) ptr; - address insn; - -#if defined(ATI_ARCH_X86) - insn = (address)uc->uc_mcontext.gregs[LP64_SWITCH(REG_EIP,REG_RIP)]; -#else - assert(!"Unimplemented"); -#endif - - if(Thread::current()->isWorkerThread()) { - if (Os::skipIDIV(insn)) { -#if defined(ATI_ARCH_X86) - uc->uc_mcontext.gregs[LP64_SWITCH(REG_EIP,REG_RIP)] = (greg_t)insn; -#else - assert(!"Unimplemented"); -#endif - return; - } - } - - // Call the chained signal handler - if (callOldSignalHandler(sig, info, ptr)) { - return; - } - - - std::cerr << "Unhandled signal in divisionErrorHandler()" << std::endl; - ::abort(); -#endif // !ANDROID -} - -typedef int (*pthread_setaffinity_fn)(pthread_t, size_t , const cpu_set_t *); -static pthread_setaffinity_fn pthread_setaffinity_fptr; - -static void init() __attribute__((constructor(101))); -static void init() { Os::init(); } - -bool -Os::init() -{ - static bool initialized_ = false; - - // We could use pthread_once here: - if (initialized_) { - return true; - } - initialized_ = true; - - pageSize_ = (size_t) ::sysconf(_SC_PAGESIZE); - processorCount_ = ::sysconf(_SC_NPROCESSORS_CONF); - - // Install a SIGFPE signal handler @todo: Chain the handlers - struct sigaction sa; - sigfillset(&sa.sa_mask); - sa.sa_handler = SIG_DFL; - sa.sa_sigaction = divisionErrorHandler; - sa.sa_flags = SA_SIGINFO | SA_RESTART; - - if (sigaction(SIGFPE, &sa, &oldSigAction) != 0) { - return false; - } - - pthread_setaffinity_fptr = (pthread_setaffinity_fn) - dlsym(RTLD_NEXT, "pthread_setaffinity_np"); - - return Thread::init(); -} - -static void __exit() __attribute__((destructor(101))); -static void __exit() { Os::tearDown(); } - -void -Os::tearDown() -{ - Thread::tearDown(); -} - -bool -Os::iterateSymbols(void* handle, Os::SymbolCallback callback, void* data) -{ -#ifdef ANDROID - assert(false && "dlinfo undefined for Android in dlfcn.h"); - return false; -#else - const char magic[] = "__OpenCL_"; - const size_t len = sizeof(magic) - 1; - - struct link_map *link_map = NULL; - if (::dlinfo(handle, RTLD_DI_LINKMAP, &link_map) != 0) { - return false; - } - - assert(link_map != NULL && "just checking"); - const ElfW(Dyn)* dyn = (ElfW(Dyn)*)(link_map->l_ld); - - const Elf32_Word* gnuhash = NULL; - const Elf_Symndx* hash = NULL; - const ElfW(Sym)* symbols = NULL; - const char* stringTable = NULL; - size_t tableSize = 0; - - // Search for the string table address and size. - while (dyn->d_tag != DT_NULL) { - switch (dyn->d_tag) { - case DT_HASH: - hash = (Elf_Symndx*) dyn->d_un.d_ptr; - break; - case DT_GNU_HASH: - gnuhash = (Elf32_Word*) dyn->d_un.d_ptr; - break; - case DT_SYMTAB: - symbols = (ElfW(Sym)*) dyn->d_un.d_ptr; - break; - case DT_STRTAB: - stringTable = (const char*) dyn->d_un.d_ptr; - break; - case DT_STRSZ: - tableSize = dyn->d_un.d_val; - break; - default: - break; - } - ++dyn; - } - if (stringTable == NULL || tableSize == 0 || symbols == NULL - || (hash == NULL && gnuhash == NULL)) { - // Could not find the string table - return false; - } - - if (gnuhash == NULL) { - // Read the defined symbols out of the classic SYSV hashtable. - - Elf_Symndx nbuckets = hash[1]; - for (Elf_Symndx i = 0; i < nbuckets; ++i) { - - if (symbols[i].st_shndx == SHN_UNDEF - && symbols[i].st_value == 0) { - continue; - } - - const char* name = &stringTable[symbols[i].st_name]; - if (::strncmp(name, magic, len) == 0) { - callback(name, (const void*) - (link_map->l_addr + symbols[i].st_value), data); - } - } - return true; - } - - // Read the defined symbols out of the GNU hashtable. - - Elf_Symndx nbuckets = gnuhash[0]; - Elf32_Word bias = gnuhash[1]; - Elf32_Word nwords = gnuhash[2]; - const Elf32_Word* buckets = &gnuhash[4 + __ELF_NATIVE_CLASS / 32 * nwords]; - const Elf32_Word* chain0 = &buckets[nbuckets] - bias; - - for (Elf_Symndx i = 0; i < nbuckets; ++i) { - size_t index = buckets[i]; - const Elf32_Word *hasharr = &chain0[index]; - do { - if (symbols[index].st_shndx != SHN_UNDEF - || symbols[index].st_value != 0) { - const char* name = &stringTable[symbols[index].st_name]; - if (::strncmp(name, magic, len) == 0) { - callback(name, (const void*) - (link_map->l_addr + symbols[index].st_value), data); - } - } - ++index; - } while ((*hasharr++ & 1) == 0); - } - -#endif // !ANDROID - return true; -} - -void* -Os::loadLibrary_(const char *filename) -{ - return (*filename == '\0') ? NULL : ::dlopen(filename, RTLD_LAZY); -} - -void -Os::unloadLibrary(void* handle) -{ - ::dlclose(handle); -} - -void* -Os::getSymbol(void* handle, const char* name) -{ - return ::dlsym(handle, name); -} - -static inline int -memProtToOsProt(Os::MemProt prot) -{ - switch (prot) { - case Os::MEM_PROT_NONE: return PROT_NONE; - case Os::MEM_PROT_READ: return PROT_READ; - case Os::MEM_PROT_RW: return PROT_READ | PROT_WRITE; - case Os::MEM_PROT_RWX: return PROT_READ | PROT_WRITE | PROT_EXEC; - default: break; - } - ShouldNotReachHere(); - return -1; -} - -address -Os::reserveMemory(address start, size_t size, size_t alignment, MemProt prot) -{ - size = alignUp(size, pageSize()); - alignment = std::max(pageSize(), alignUp(alignment, pageSize())); - assert(isPowerOfTwo(alignment) && "not a power of 2"); - - size_t requested = size + alignment - pageSize(); - address mem = (address) ::mmap(start, requested, memProtToOsProt(prot), - MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS, 0, 0); - - // check for out of memory - if (mem == NULL) return NULL; - - address aligned = alignUp(mem, alignment); - - // return the unused leading pages to the free state - if (&aligned[0] != &mem[0]) { - assert(&aligned[0] > &mem[0] && "check this code"); - if (::munmap(&mem[0], &aligned[0] - &mem[0]) != 0) { - assert(!"::munmap failed"); - } - } - // return the unused trailing pages to the free state - if (&aligned[size] != &mem[requested]) { - assert(&aligned[size] < &mem[requested] && "check this code"); - if (::munmap(&aligned[size], &mem[requested] - &aligned[size]) != 0) { - assert(!"::munmap failed"); - } - } - - return aligned; -} - -bool -Os::releaseMemory(void* addr, size_t size) -{ - assert(isMultipleOf(addr, pageSize()) && "not page aligned!"); - size = alignUp(size, pageSize()); - - return 0 == ::munmap(addr, size); -} - -bool -Os::commitMemory(void* addr, size_t size, MemProt prot) -{ - assert(isMultipleOf(addr, pageSize()) && "not page aligned!"); - size = alignUp(size, pageSize()); - - return ::mmap(addr, size, memProtToOsProt(prot), - MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, - -1, 0) != MAP_FAILED; -} - -bool -Os::uncommitMemory(void* addr, size_t size) -{ - assert(isMultipleOf(addr, pageSize()) && "not page aligned!"); - size = alignUp(size, pageSize()); - - return ::mmap(addr, size, PROT_NONE, - MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE | MAP_ANONYMOUS, - -1, 0) != MAP_FAILED; -} - -bool -Os::protectMemory(void* addr, size_t size, MemProt prot) -{ - assert(isMultipleOf(addr, pageSize()) && "not page aligned!"); - size = alignUp(size, pageSize()); - - return 0 == ::mprotect(addr, size, memProtToOsProt(prot)); -} - -uint64_t -Os::hostTotalPhysicalMemory() -{ - static uint64_t totalPhys = 0; - - if (totalPhys != 0) { - return totalPhys; - } - - totalPhys = sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES); - return totalPhys; -} - -void* -Os::alignedMalloc(size_t size, size_t alignment) -{ - void * ptr = NULL; - if (0 == ::posix_memalign(&ptr, alignment, size)) { - return ptr; - } - return NULL; -} - -void -Os::alignedFree(void *mem) -{ - ::free(mem); -} - -void -Os::currentStackInfo(address* base, size_t *size) -{ - // There could be some issue trying to get the pthread_attr of - // the primordial thread if the pthread library is not present - // at load time (a binary loads the OpenCL app/runtime dynamically. - // We should look into this... -laurent - - pthread_t self = ::pthread_self(); - - pthread_attr_t threadAttr; - if (0 != ::pthread_getattr_np(self, &threadAttr)) { - fatal("pthread_getattr_np() failed"); - } - - if (0 != ::pthread_attr_getstack(&threadAttr, - (void **) base, size)) { - fatal("pthread_attr_getstack() failed"); - } - *base += *size; - - ::pthread_attr_destroy(&threadAttr); - - assert(Os::currentStackPtr() >= *base - *size - && Os::currentStackPtr() < *base - && "just checking"); -} - -void -Os::setCurrentThreadName(const char* name) -{ - ::prctl(PR_SET_NAME, name); -} - - -void* -Thread::entry(Thread* thread) -{ - sigset_t set; - - sigfillset(&set); - pthread_sigmask(SIG_BLOCK, &set, NULL); - - sigemptyset(&set); - sigaddset(&set, SIGFPE); - pthread_sigmask(SIG_UNBLOCK, &set, NULL); - - return thread->main(); -} - -bool -Os::isThreadAlive(const Thread& thread) -{ - return true; -} - -const void* -Os::createOsThread(amd::Thread* thread) -{ - pthread_attr_t threadAttr; - ::pthread_attr_init(&threadAttr); - - if (thread->stackSize_ != 0) { - size_t guardsize = 0; - if (0 != ::pthread_attr_getguardsize(&threadAttr, - &guardsize)) { - fatal("pthread_attr_getguardsize() failed"); - } - ::pthread_attr_setstacksize(&threadAttr, thread->stackSize_ + guardsize); - } - - // We never plan the use join, so free the resources now. - ::pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED); - - pthread_t handle = 0; - if (0 != ::pthread_create(&handle, &threadAttr, - (void* (*)(void*)) &Thread::entry, thread)) { - thread->setState(Thread::FAILED); - } - - ::pthread_attr_destroy(&threadAttr); - return reinterpret_cast(handle); -} - - -void -Os::setThreadAffinity(const void* handle, const Os::ThreadAffinityMask& mask) -{ - if (pthread_setaffinity_fptr != NULL) { - pthread_setaffinity_fptr((pthread_t)handle, sizeof(cpu_set_t), &mask.mask_); - } -} - -void -Os::yield() -{ - ::sched_yield(); -} - -uint64_t -Os::timeNanos() -{ - struct timespec tp; - ::clock_gettime(CLOCK_MONOTONIC, &tp); - return (uint64_t) tp.tv_sec * (1000ULL*1000ULL*1000ULL) - + (uint64_t) tp.tv_nsec; -} - -uint64_t -Os::timerResolutionNanos() -{ - static uint64_t resolution = 0; - if (resolution == 0) { - struct timespec tp; - ::clock_getres(CLOCK_MONOTONIC, &tp); - resolution = (uint64_t) tp.tv_sec * (1000ULL*1000ULL*1000ULL) - + (uint64_t) tp.tv_nsec; - } - return resolution; -} - - -const char* -Os::libraryExtension() -{ - return MACOS_SWITCH(".dylib", ".so"); -} - -const char* -Os::libraryPrefix() -{ - return "lib"; -} - -const char* -Os::objectExtension() -{ - return ".o"; -} - -char -Os::fileSeparator() -{ - return '/'; -} - -char -Os::pathSeparator() -{ - return ':'; -} - -bool Os::pathExists(const std::string& path) -{ - struct stat st; - if (stat(path.c_str(), &st) != 0) - return false; - return S_ISDIR(st.st_mode); -} - -bool Os::createPath(const std::string& path) -{ - mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; - size_t pos = 0; - while (true) { - pos = path.find(fileSeparator(), pos); - const std::string currPath = path.substr(0, pos); - if (!currPath.empty() && !pathExists(currPath)) { - int ret = mkdir(currPath.c_str(), mode); - if (ret == -1) return false; - } - if (pos == std::string::npos) break; - ++pos; - } - return true; -} - -bool Os::removePath(const std::string& path) -{ - size_t pos = std::string::npos; - bool removed =false; - while (true) { - const std::string currPath = path.substr(0, pos); - if (!currPath.empty()) { - int ret = rmdir(currPath.c_str()); - if (ret == -1) return removed; - removed = true; - } - if (pos == 0) break; - pos = path.rfind(fileSeparator(), pos == std::string::npos?pos:pos-1); - if (pos == std::string::npos) break; - } - return true; -} - -int Os::printf(const char* fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - int len = ::vprintf(fmt, ap); - va_end(ap); - - return len; -} - -// Os::systemCall() -// ================ -// Execute a program and return the program exitcode or -1 if there were problems. -// The input argument 'command' is expected to be a space separated string of -// command-line arguments with arguments containing spaces between double-quotes. -// -// In order to avoid duplication of memory, we use vfork()+exec(). vfork() has -// potiential security risks; read the following for details: -// -// https://www.securecoding.cert.org/confluence/display/seccode/POS33-C.+Do+not+use+vfork() -// -// In spite of these risks, the alternatives (system() or fork()) create resource -// issues when running conformance test_allocation which stretches the system -// memory to its limits. Thus we will accept this compromise under the condition -// that the runtime will soon remove any need to call out to external commands. -// -// Note that stdin/stdout/stderr of the command are sent to /dev/null. -// -int -Os::systemCall(const std::string& command) -{ -#if 1 - size_t len = command.size(); - char* cmd = new char[len + 1]; - fastMemcpy(cmd, command.c_str(), len); - cmd[len] = 0; - - // Split the command into arguments. This is a very - // simple parser that only takes care of quotes and - // doesn't support escaping with back-slash. In - // the future, Os::systemCall() will either - // disappear or it will be replaced with an - // argc/argv interface. This parser also assumes - // that if an argument is quoted, the whole - // argument starts and ends with a double-quote. - bool inQuote = false; - int argLength = 0; - int n = 0; - char* cp = cmd; - while(*cp) { - switch(static_cast(*cp)) { - case ' ': - if(inQuote) { - ++argLength; - } - else { - *cp = '\0'; - argLength = 0; - } - break; - case '"': - if(inQuote) { - inQuote = false; - *cp = '\0'; - } - else { - inQuote = true; - *cp = '\0'; - argLength = 1; - ++n; - } - break; - default: - if(++argLength == 1) { - ++n; - } - break; - } - ++cp; - } - - char** argv = new char*[n + 1]; - int argc = 0; - cp = cmd; - do { - while('\0' == *cp) { - ++cp; - } - argv[argc++] = cp; - while('\0' != *cp) { - ++cp; - } - } while(argc < n); - argv[argc] = NULL; - - int ret = -1; - pid_t pid = vfork(); - if(0 == pid) { - // Child. Redirect stdin/stdout/stderr to /dev/null - int fdIn = open("/dev/null", O_RDONLY); - int fdOut = open("/dev/null", O_WRONLY); - if(0 <= fdIn || 0 <= fdOut) { - dup2(fdIn, 0); - dup2(fdOut, 1); - dup2(fdOut, 2); - - // Execute the program - execvp(argv[0], argv); - } - _exit(-1); - } - else if(0 > pid) { - // Can't vfork - } - else { - // Parent - wait for program to complete and get exit code. - int exitCode; - if(0 <= waitpid(pid, &exitCode, 0)) { - ret = exitCode; - } - } - delete [] argv; - delete [] cmd; - - return ret; -#else - return ::system(command.c_str()); -#endif -} - -std::string -Os::getEnvironment(const std::string& name) -{ - char* dstBuf; - - dstBuf = ::getenv(name.c_str()); - if (dstBuf == NULL) { - return std::string(""); - } - return std::string(dstBuf); -} - -std::string -Os::getTempPath() -{ - std::string tempFolder = amd::Os::getEnvironment("TEMP"); - if (tempFolder.empty()) { - tempFolder = amd::Os::getEnvironment("TMP"); - } - - if (tempFolder.empty()) { - tempFolder = "/tmp";; - } - return tempFolder; -} - -std::string -Os::getTempFileName() -{ - static std::atomic_size_t counter(0); - - std::string tempPath = getTempPath(); - std::stringstream tempFileName; - - tempFileName << tempPath << "/OCLC" << ::getpid() << 'T' << counter++; - return tempFileName.str(); -} - -int -Os::unlink(const std::string& path) -{ - return ::unlink(path.c_str()); -} - -#if defined(ATI_ARCH_X86) -void -Os::cpuid(int regs[4], int info) -{ -#ifdef _LP64 - __asm__ __volatile__ ( - "movq %%rbx, %%rsi;" - "cpuid;" - "xchgq %%rbx, %%rsi;" - : "=a" (regs[0]), "=S" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) - : "a" (info)); -#else - __asm__ __volatile__ ( - "movl %%ebx, %%esi;" - "cpuid;" - "xchgl %%ebx, %%esi;" - : "=a" (regs[0]), "=S" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) - : "a" (info)); -#endif -} - -uint64_t -Os::xgetbv(uint32_t ecx) -{ - uint32_t eax, edx; - - __asm__ __volatile__( - ".byte 0x0f,0x01,0xd0" // in case assembler doesn't recognize xgetbv - : "=a"(eax), "=d"(edx) - : "c"(ecx)); - - return ((uint64_t)edx << 32) | (uint64_t)eax; -} -#endif // ATI_ARCH_X86 - -void* -Os::fastMemcpy(void *dest, const void *src, size_t n) -{ - return memcpy(dest, src, n); -} - -uint64_t -Os::offsetToEpochNanos() -{ - static uint64_t offset = 0; - - if (offset != 0) { - return offset; - } - - struct timeval now; - if (::gettimeofday(&now, NULL) != 0) { - return 0; - } - - offset = (now.tv_sec * UINT64_C(1000000) + now.tv_usec) - * UINT64_C(1000) - timeNanos(); - - return offset; -} - -void -Os::setCurrentStackPtr(address sp) -{ - sp -= sizeof(void*); - *(void**) sp = __builtin_return_address(0); - -#if defined(ATI_ARCH_ARM) - assert(!"Unimplemented"); -#else - __asm__ __volatile__ ( -#if !defined(OMIT_FRAME_POINTER) - LP64_SWITCH("movl (%%ebp),%%ebp;","movq (%%rbp),%%rbp;") -#endif // !OMIT_FRAME_POINTER - LP64_SWITCH("movl %0,%%esp; ret;","movq %0,%%rsp; ret;") - :: "r"(sp) - ); -#endif -} - -size_t Os::getPhysicalMemSize() -{ - struct ::sysinfo si; - - if (::sysinfo(&si) != 0) { - return 0; - } - - if (si.mem_unit == 0) { - // Linux kernels prior to 2.3.23 return sizes in bytes. - si.mem_unit = 1; - } - - return (size_t) si.totalram * si.mem_unit; -} - -std::string Os::getAppFileName() -{ - std::unique_ptr buff(new char[FILE_PATH_MAX_LENGTH]()); - - if (readlink("/proc/self/exe", buff.get(), FILE_PATH_MAX_LENGTH) > 0) { - // Get filename without path and extension. - return std::string(basename(buff.get())); - } - - return ""; -} - -} // namespace amd - -#endif // !defined(_WIN32) && !defined(__CYGWIN__) diff --git a/rocclr/compiler/lib/promotions/oclutils/os/os_win32.cpp b/rocclr/compiler/lib/promotions/oclutils/os/os_win32.cpp deleted file mode 100644 index b07c4ed276..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/os_win32.cpp +++ /dev/null @@ -1,1083 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#if defined(_WIN32) || defined(__CYGWIN__) - -#include "os/os.hpp" -#include "thread/thread.hpp" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifndef WINAPI -#define WINAPI -#endif - - -BOOL (WINAPI *pfnGetNumaNodeProcessorMaskEx)(USHORT,PGROUP_AFFINITY) = NULL; - -namespace amd { - -static size_t allocationGranularity_; - -static LONG WINAPI divExceptionFilter(struct _EXCEPTION_POINTERS* ep); - -#ifdef _WIN64 -PVOID divExceptionHandler = NULL; -#endif // _WIN64 - -static double PerformanceFrequency; - -typedef BOOL (WINAPI *SetThreadGroupAffinity_fn)( - __in HANDLE, __in CONST GROUP_AFFINITY *, __out_opt PGROUP_AFFINITY); -static SetThreadGroupAffinity_fn pfnSetThreadGroupAffinity = NULL; - -#pragma section(".CRT$XCU",long,read) -__declspec(allocate(".CRT$XCU")) bool (*__init)(void) = Os::init; - -bool -Os::init() -{ - static bool initialized_ = false; - - // We could use InitOnceExecuteOnce here: - if (initialized_) { - return true; - } - initialized_ = true; - - SYSTEM_INFO si; - ::GetSystemInfo(&si); - pageSize_ = si.dwPageSize; - allocationGranularity_ = (size_t) si.dwAllocationGranularity; - processorCount_ = si.dwNumberOfProcessors; - - LARGE_INTEGER frequency; - QueryPerformanceFrequency(&frequency); - PerformanceFrequency = (double) frequency.QuadPart; - -#ifdef _WIN64 - divExceptionHandler = AddVectoredExceptionHandler(1, divExceptionFilter); -#endif // _WIN64 - - HMODULE handle = ::LoadLibrary("kernel32.dll"); - if (handle != NULL) { - pfnSetThreadGroupAffinity = (SetThreadGroupAffinity_fn) - ::GetProcAddress(handle, "SetThreadGroupAffinity"); - pfnGetNumaNodeProcessorMaskEx = (BOOL(WINAPI *)(USHORT,PGROUP_AFFINITY)) - ::GetProcAddress(handle, "GetNumaNodeProcessorMaskEx"); - } - - return Thread::init(); -} - -#pragma section(".CRT$XTU",long,read) -__declspec(allocate(".CRT$XTU")) void (*__exit)(void) = Os::tearDown; - -void -Os::tearDown() -{ -#ifdef _WIN64 - if (divExceptionHandler != NULL) { - RemoveVectoredExceptionHandler(divExceptionHandler); - divExceptionHandler = NULL; - } -#endif // _WIN64 - - Thread::tearDown(); -} - -//#define DEBUG_getExportsFromMemory -/** - get export symbols from dll given by start address \param dosHeader - of dll in memory and push_back - addresses and names of exports into \param kernels -*/ -static void -getExportsFromMemory( - PIMAGE_DOS_HEADER dosHeader, - Os::SymbolCallback callback, - void* data) -{ - PCHAR base = (PCHAR)dosHeader; - PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS) - (base + dosHeader->e_lfanew); - - DWORD exportsStart = pNTHeader->OptionalHeader. - DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - - if (exportsStart == 0) { return; } - - PIMAGE_EXPORT_DIRECTORY exportDir = (PIMAGE_EXPORT_DIRECTORY) - (base + exportsStart); - - PSTR filename = (PSTR)(exportDir->Name + base); - - #if defined(DEBUG_getExportsFromMemory) - printf("\nExports Table:\n"); - printf(" Name: %s\n", filename); - printf(" Characteristics: %08X\n", exportDir->Characteristics); - printf(" TimeDateStamp: %08X -> %s", - exportDir->TimeDateStamp, - ctime((const time_t *)&exportDir->TimeDateStamp) ); - printf(" Version: %u.%02u\n", exportDir->MajorVersion, - exportDir->MinorVersion); - printf(" Ordinal base: %08X\n", exportDir->Base); - printf(" # of functions: %08X\n", exportDir->NumberOfFunctions); - printf(" # of Names: %08X\n", exportDir->NumberOfNames); - #endif - - /* address of Export Address table (EAT). */ - PDWORD functions = (PDWORD)(base + (DWORD)exportDir->AddressOfFunctions); - DWORD numberOfFunctions = exportDir->NumberOfFunctions; - - /* address of the Export Name Table (ENT). - ENT is an array of RVAs to ASCII strings - each string corresponds to - a symbol (function or variable) exported by name. */ - DWORD* name = (DWORD *)(base + (DWORD)exportDir->AddressOfNames); - /* \note: number below is always <= numberOfFunctions */ - DWORD numberOfNames = exportDir->NumberOfNames; - - /* address of the Export Ordinal Table. - This table maps an array index from ENT into - the corresponding index in EAT. - */ - PWORD ordinals = (PWORD)(base + (DWORD)exportDir->AddressOfNameOrdinals); - - #if defined (DEBUG_getExportsFromMemory) - /* \note On Ordinals and Algorithm Below. - - Each exported symbol has an ordinal number associated with it that can - be used to look the exported symbol up. Also, there is almost always - an ASCII name associated with the symbol. Expectedly, the exported - symbol name is the same as the name of the function or variable, but - in general it is not guaranteed. Usually, when an executable imports - a symbol, it uses the symbol name rather than its ordinal. If it was - always a case the algorithm below could be much simple - just go over - all the names and print them, but some functions may be exported only - by ordinals. When importing by name, the system just uses the name to - look up the export ordinal of the desired symbol, and retrieves the - address using the ordinal value. It might be slightly faster if an - ordinal had been used in the first place. Exporting and importing by - name is solely a convenience for programmers. - The use of the ORDINAL keyword in the Exports section of a .DEF file - tells the linker to create an import library that forces an API to be - imported by ordinal, not by name. - The algorithm in the comments shows how to retrieve all the exports in - the general case. If we assume that all is exported by names then a - simple version (code below) is sufficient. - - \note removed file exportdump.cpp contains examples of reading - exported symbols from DLL loaded in memory or file. - */ - DWORD exportsEnd = pNTHeader->OptionalHeader. - DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - - printf("\n Entry Pt Ordn Name\n"); - for (DWORD ii=0; ii < numberOfFunctions; ii++) { - DWORD entryPoint = functions[ii]; - - if (entryPoint == 0) { // Skip over gaps in exported function - continue; // ordinals (the entrypoint is 0 for - } // these functions). - printf(" %08X %4u", entryPoint, ii + exportDir->Base); - - // Browse thru all names and check out if a function has - // an associated exported name. - for (DWORD jj=0; jj < exportDir->NumberOfNames; jj++) { - if (ordinals[jj] == ii) { - printf(" %s", name[jj] + base); - } - } - // Is it a forwarder? If so, the entry point RVA is inside the - // .edata section, and is an RVA to the DllName.EntryPointName - if ((entryPoint >= exportsStart) && (entryPoint <= exportsEnd)) { - printf(" (forwarder -> %s)", entryPoint + base); - } - printf("\n"); - } - #endif - - char OpenCL_prefix[] = "___OpenCL_"; - size_t OpenCL_prefix_sz = sizeof( OpenCL_prefix ) - 1; - - for (DWORD jj=0; jj < numberOfNames; jj++) { - const char* OpenCL_name = (const char*)(base + name[jj]); - if (strncmp(OpenCL_name, OpenCL_prefix, OpenCL_prefix_sz) == 0) { - address addr = (address)(base + functions[ordinals[jj]]); - - unsigned char opcode = *(unsigned char*)addr; - if (opcode == 0xE9) { // jmp instruction at address of export name - long disp = *(long*)(addr+1); // dislacement in jmp - addr += 5 /* skip instruction */ + disp; - } - - #if defined (DEBUG_getExportsFromMemory) - printf("%08X: %s\n", addr, OpenCL_name); - #endif - callback(&OpenCL_name[1], (const void*)addr, data); - } - else if (strncmp( - OpenCL_name, &OpenCL_prefix[1], OpenCL_prefix_sz-1) == 0) { - - address addr = (address)(base + functions[ordinals[jj]]); - #if defined (DEBUG_getExportsFromMemory) - printf("%08X: %s\n", addr, OpenCL_name); - #endif - callback(OpenCL_name, (const void*)addr, data); - } - } -} - -bool -Os::iterateSymbols(void* handle, SymbolCallback callback, void* data) -{ - PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)handle; - if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) { - // checking validity of NT header was removed since we do not want - // exception handling. It can be found in rev #21. - getExportsFromMemory((PIMAGE_DOS_HEADER)handle, callback, data); - return TRUE; - } - return FALSE; -} - -void* -Os::loadLibrary_(const char *filename) -{ - if (filename != NULL) { - HMODULE hModule = ::LoadLibrary(filename); - return hModule; - } - return NULL; -} - -void -Os::unloadLibrary(void* handle) -{ - ::FreeLibrary((HMODULE) handle); -} - -void* -Os::getSymbol(void* handle, const char* name) -{ - return ::GetProcAddress((HMODULE) handle, name); -} - -static inline int -memProtToOsProt(Os::MemProt prot) -{ - switch (prot) { - case Os::MEM_PROT_NONE: return PAGE_NOACCESS; - case Os::MEM_PROT_READ: return PAGE_READONLY; - case Os::MEM_PROT_RW: return PAGE_READWRITE; - case Os::MEM_PROT_RWX: return PAGE_EXECUTE_READWRITE; - default: break; - } - ShouldNotReachHere(); - return -1; -} - -address -Os::reserveMemory(address start, size_t size, size_t alignment, MemProt prot) -{ - size = alignUp(size, pageSize()); - alignment = std::max(allocationGranularity_, - alignUp(alignment, allocationGranularity_)); - assert(isPowerOfTwo(alignment) && "not a power of 2"); - - size_t requested = size + alignment - allocationGranularity_; - address mem, aligned; - do { - mem = (address)VirtualAlloc(start, requested, - MEM_RESERVE, memProtToOsProt(prot)); - - // check for out of memory. - if (mem == NULL) return NULL; - - aligned = alignUp(mem, alignment); - - // check for already aligned memory. - if (aligned == mem && size == requested) { - return mem; - } - - // try to reserve the aligned address. - if (VirtualFree(mem, 0, MEM_RELEASE) == 0) { - assert(!"VirtualFree failed"); - } - - mem = (address)VirtualAlloc(aligned, size, - MEM_RESERVE, memProtToOsProt(prot)); - assert((mem == NULL || mem == aligned) && "VirtualAlloc failed"); - - } while (mem != aligned); - - return mem; -} - -bool -Os::releaseMemory(void* addr, size_t size) -{ - return VirtualFree(addr, 0, MEM_RELEASE) != 0; -} - -bool -Os::commitMemory(void* addr, size_t size, MemProt prot) -{ - return VirtualAlloc(addr, size, - MEM_COMMIT, memProtToOsProt(prot)) != NULL; -} - -bool -Os::uncommitMemory(void* addr, size_t size) -{ - return VirtualFree(addr, size, MEM_DECOMMIT) != 0; -} - -bool -Os::protectMemory(void* addr, size_t size, MemProt prot) -{ - DWORD OldProtect; - return VirtualProtect(addr, size, memProtToOsProt(prot), &OldProtect) != 0; -} - - -uint64_t -Os::hostTotalPhysicalMemory() -{ - static uint64_t totalPhys = 0; - - if (totalPhys != 0) { - return totalPhys; - } - - MEMORYSTATUSEX mstatus; - mstatus.dwLength = sizeof(mstatus); - - ::GlobalMemoryStatusEx (&mstatus); - - totalPhys = mstatus.ullTotalPhys; - return totalPhys; -} - -void* -Os::alignedMalloc(size_t size, size_t alignment) -{ - return ::_aligned_malloc(size, alignment); -} - -void -Os::alignedFree(void *mem) -{ - ::_aligned_free(mem); -} - - -void -Os::currentStackInfo(address* base, size_t *size) -{ - MEMORY_BASIC_INFORMATION mbInfo; - - address currentStackPage = (address) alignDown( - (intptr_t) currentStackPtr(), pageSize()); - - ::VirtualQuery(currentStackPage, &mbInfo, sizeof(mbInfo)); - - address stackBottom = (address) mbInfo.AllocationBase; - size_t stackSize = 0; - - do { - stackSize += mbInfo.RegionSize; - ::VirtualQuery(stackBottom + stackSize, &mbInfo, sizeof(mbInfo)); - } while (stackBottom == (address) mbInfo.AllocationBase); - - *base = stackBottom + stackSize; - *size = stackSize; - - assert(currentStackPtr() >= *base - *size && currentStackPtr() < *base - && "just checking"); -} - -#define MS_VC_EXCEPTION 0x406D1388 -#pragma pack(push,8) -struct THREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -}; -#pragma pack(pop) - -static void -SetThreadName(DWORD threadId, const char* name) -{ - if (name == NULL || *name == '\0') { - return; - } - - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = threadId; - info.dwFlags = 0; - - __try { - ::RaiseException( - 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); - } - __except(EXCEPTION_EXECUTE_HANDLER) { } -} - -void -Os::setCurrentThreadName(const char* name) -{ - SetThreadName(GetCurrentThreadId(), name); -} - -static LONG WINAPI -divExceptionFilter(struct _EXCEPTION_POINTERS* ep) -{ - DWORD code = ep->ExceptionRecord->ExceptionCode; - - if ((code == EXCEPTION_INT_DIVIDE_BY_ZERO || - code == EXCEPTION_INT_OVERFLOW) && - Thread::current()->isWorkerThread()) { - address insn = (address)ep->ContextRecord->LP64_SWITCH(Eip,Rip); - - if (Os::skipIDIV(insn)) { - ep->ContextRecord->LP64_SWITCH(Eip,Rip) = (uintptr_t)insn; - return EXCEPTION_CONTINUE_EXECUTION; - } - } - return EXCEPTION_CONTINUE_SEARCH; -} - -void* -Thread::entry(Thread* thread) -{ - void* ret = NULL; -#if !defined(_WIN64) - __try { - ret = thread->main(); - } - __except(divExceptionFilter(GetExceptionInformation())) { - // nothing to do here. - } -#else // _WIN64 - ret = thread->main(); -#endif // _WIN64 - - // The current thread exits, thus clear the pointer -#if defined(USE_DECLSPEC_THREAD) - details::thread_ = NULL; -#else // !USE_DECLSPEC_THREAD - TlsSetValue(details::threadIndex_, NULL); -#endif // !USE_DECLSPEC_THREAD - return ret; -} - -bool -Os::isThreadAlive(const Thread& thread) -{ - HANDLE handle = (HANDLE)(thread.handle()); - - DWORD exitCode = 0; - if (GetExitCodeThread(handle, &exitCode)) { - return exitCode == STILL_ACTIVE; - } - else { - // Could not get thread's exitcode - return false; - } -} - -const void* -Os::createOsThread(Thread* thread) -{ - HANDLE handle = ::CreateThread(NULL, thread->stackSize_, - (LPTHREAD_START_ROUTINE) Thread::entry, thread, 0, NULL); - if (handle == NULL) { - thread->setState(Thread::FAILED); - } - return reinterpret_cast(handle); -} - -void -Os::setThreadAffinity(const void* handle, const Os::ThreadAffinityMask& mask) -{ - if (pfnSetThreadGroupAffinity != NULL) { - GROUP_AFFINITY group = {0}; - for (WORD i = 0; i < sizeof(mask.mask_) / sizeof(KAFFINITY); ++i) { - group.Mask = mask.mask_[i]; - group.Group = i; - if (group.Mask != 0) { - pfnSetThreadGroupAffinity((HANDLE)handle, &group, NULL); - } - } - } - else { // pfnSetThreadGroupAffinity == NULL - DWORD_PTR threadAffinityMask = (DWORD_PTR)mask.mask_[0]; - if (threadAffinityMask != 0) { - ::SetThreadAffinityMask((HANDLE)handle, threadAffinityMask); - } - } -} - -void -Os::yield() -{ - ::SwitchToThread(); -} - -uint64_t -Os::timeNanos() -{ - LARGE_INTEGER current; - QueryPerformanceCounter(¤t); - return (uint64_t) ((double) current.QuadPart / PerformanceFrequency * 1e9); -} - -uint64_t -Os::timerResolutionNanos() -{ - return (uint64_t) (1e9 / PerformanceFrequency); -} - - -const char* -Os::libraryExtension() -{ - return ".DLL"; -} - -const char* -Os::libraryPrefix() -{ - return NULL; -} - -const char* -Os::objectExtension() -{ - return ".OBJ"; -} - -char -Os::fileSeparator() -{ - return '\\'; -} - -char -Os::pathSeparator() -{ - return ';'; -} - -bool Os::pathExists(const std::string& path) -{ - return GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES; -} - -bool Os::createPath(const std::string& path) -{ - size_t pos = 0; - while (true) { - pos = path.find(fileSeparator(), pos); - const std::string currPath = path.substr(0, pos); - if (!currPath.empty() && !pathExists(currPath)) { - if (!CreateDirectory(currPath.c_str(), NULL)) return false; - } - if (pos == std::string::npos) break; - ++pos; - } - return true; -} - -bool Os::removePath(const std::string& path) -{ - size_t pos = std::string::npos; - bool removed = false; - while (true) { - const std::string currPath = path.substr(0, pos); - if (!currPath.empty()) { - if (!RemoveDirectory(currPath.c_str())) return removed; - removed = true; - } - if (pos == 0) break; - pos = path.rfind(fileSeparator(), pos == std::string::npos?pos:pos-1); - if (pos == std::string::npos) break; - } - return true; -} - -int Os::printf(const char* fmt, ...) -{ - va_list ap; - DWORD dwBytesWritten; - - va_start(ap, fmt); - int len = ::_vsnprintf(NULL, 0, fmt, ap); - va_end(ap); - if (len <= 0) return len; - - va_start(ap, fmt); - char* str = static_cast(alloca(len + 1)); - len = ::_vsnprintf(str, len + 1, fmt, ap); - va_end(ap); - if (len <= 0) return len; - - ::WriteFile(::GetStdHandle(STD_OUTPUT_HANDLE), str, len, &dwBytesWritten, NULL); - - return len; -} - -int -Os::systemCall(const std::string& command) -{ -#if 1 - char* cmd = new char[command.size()+1]; - fastMemcpy(cmd, command.c_str(), command.size()); - cmd[command.size()] = 0; - - STARTUPINFO si = {0}; - si.cb = sizeof(si); - PROCESS_INFORMATION pi; - - if (::CreateProcess( NULL, cmd, NULL, NULL, - FALSE, CREATE_NO_WINDOW, NULL, NULL, - &si, &pi ) == 0 ) { - delete [] cmd; - return -1; // failed - }; - - // Wait until child process exits. - ::WaitForSingleObject( pi.hProcess, INFINITE ); - - DWORD ExitCode = 0; - ::GetExitCodeProcess(pi.hProcess, &ExitCode); - - // Close process and thread handles. - ::CloseHandle( pi.hProcess ); - ::CloseHandle( pi.hThread ); - - delete [] cmd; - return (int)ExitCode; -#else - std::stringstream str; - str << "\"" << command << "\""; - return ::system(str.str().c_str()); -#endif -} - -std::string -Os::getEnvironment(const std::string& name) -{ - char dstBuf[MAX_PATH]; - size_t dstSize; - - if (::getenv_s(&dstSize, dstBuf, MAX_PATH, name.c_str())) { - return std::string(""); - } - return std::string(dstBuf); -} - -std::string -Os::getTempPath() -{ - char tempPath[MAX_PATH]; - uint ret = GetTempPath(MAX_PATH, tempPath); - if (ret == 0 || (ret == 1 && tempPath[0] == '?')) { - return std::string("."); - } - - // If the app was started from an UNC path instead of a DOS path, - // the temp env var won't be set correctly and will point to windows - // system directory instead (usually c:/windows/temp), which will be - // blocked. So we check if the temp path returned by GetTempPath is - // under windows directory, use . instead - std::string tempPathStr(tempPath); - char winPath[MAX_PATH]; - if (GetWindowsDirectory(winPath, MAX_PATH) > 0) { - // Need to check if tempPath is C:\Windows or C:\Windows\ // - if (tempPath[strlen(tempPath)-1] == '\\') { - tempPath[strlen(tempPath)-1] = '\0' ; - ret--; - } - if (_memicmp(tempPath, winPath, ret) == 0) { - return std::string("."); - } - } - return tempPathStr; -} - -std::string -Os::getTempFileName() -{ - static std::atomic_size_t counter(0); - - std::string tempPath = getTempPath(); - std::stringstream tempFileName; - - tempFileName << tempPath << "\\OCLC" << ::_getpid() << 'T' << counter++; - return tempFileName.str(); -} - -int -Os::unlink(const std::string& path) -{ - return ::_unlink(path.c_str()); -} - -void -Os::cpuid(int regs[4], int info) -{ - return __cpuid(regs, info); -} - -uint64_t -Os::xgetbv(uint32_t ecx) -{ - return (uint64_t)_xgetbv(ecx); -} - -// Various "fast" memcpy implementation (currently win32 only due to compiler limitations) - -// (dgladdin - "recent" below means MMX and later) - -// Very optimized memcpy() routine for all AMD Athlon and Duron family. -// This code uses any of FOUR different basic copy methods, depending -// on the transfer size. -// NOTE: Since this code uses MOVNTQ (also known as "Non-Temporal MOV" or -// "Streaming Store"), and also uses the software prefetchnta instructions, -// be sure youre running on Athlon/Duron or other recent CPU before calling! - -#define TINY_BLOCK_COPY 64 // upper limit for movsd type copy -// The smallest copy uses the X86 "movsd" instruction, in an optimized -// form which is an "unrolled loop". - -#define IN_CACHE_COPY 64 * 1024 // upper limit for movq/movq copy w/SW prefetch -// Next is a copy that uses the MMX registers to copy 8 bytes at a time, -// also using the "unrolled loop" optimization. This code uses -// the software prefetch instruction to get the data into the cache. - -#define UNCACHED_COPY 197 * 1024 // upper limit for movq/movntq w/SW prefetch -// For larger blocks, which will spill beyond the cache, its faster to -// use the Streaming Store instruction MOVNTQ. This write instruction -// bypasses the cache and writes straight to main memory. This code also -// uses the software prefetch instruction to pre-read the data. -// USE 64 * 1024 FOR THIS VALUE IF YOURE ALWAYS FILLING A "CLEAN CACHE" - -#define BLOCK_PREFETCH_COPY infinity // no limit for movq/movntq w/block prefetch -#define CACHEBLOCK 80h // number of 64-byte blocks (cache lines) for block prefetch -// For the largest size blocks, a special technique called Block Prefetch -// can be used to accelerate the read operations. Block Prefetch reads -// one address per cache line, for a series of cache lines, in a short loop. -// This is faster than using software prefetch. The technique is great for -// getting maximum read bandwidth, especially in DDR memory systems. - -// Inline assembly syntax for use with Visual C++ - -void* -Os::fastMemcpy(void *dest, const void *src, size_t n) -{ -#if !defined(_WIN64) - - __asm { - - mov ecx, [n] ; number of bytes to copy - mov edi, [dest] ; destination - mov esi, [src] ; source - mov ebx, ecx ; keep a copy of count - - cld - cmp ecx, TINY_BLOCK_COPY - jb $memcpy_ic_3 ; tiny? skip mmx copy - - cmp ecx, 32*1024 ; dont align between 32k-64k because - jbe $memcpy_do_align ; it appears to be slower - cmp ecx, 64*1024 - jbe $memcpy_align_done -$memcpy_do_align: - mov ecx, 8 ; a trick thats faster than rep movsb... - sub ecx, edi ; align destination to qword - and ecx, 111b ; get the low bits - sub ebx, ecx ; update copy count - neg ecx ; set up to jump into the array - add ecx, offset $memcpy_align_done - jmp ecx ; jump to array of movsbs - -align 4 - movsb - movsb - movsb - movsb - movsb - movsb - movsb - movsb - -$memcpy_align_done: ; destination is dword aligned - mov ecx, ebx ; number of bytes left to copy - shr ecx, 6 ; get 64-byte block count - jz $memcpy_ic_2 ; finish the last few bytes - - cmp ecx, IN_CACHE_COPY/64 ; too big 4 cache? use uncached copy - jae $memcpy_uc_test - -// This is small block copy that uses the MMX registers to copy 8 bytes -// at a time. It uses the "unrolled loop" optimization, and also uses -// the software prefetch instruction to get the data into the cache. -align 16 -$memcpy_ic_1: ; 64-byte block copies, in-cache copy - - prefetchnta [esi + (200*64/34+192)] ; start reading ahead - - movq mm0, [esi+0] ; read 64 bits - movq mm1, [esi+8] - movq [edi+0], mm0 ; write 64 bits - movq [edi+8], mm1 ; note: the normal movq writes the - movq mm2, [esi+16] ; data to cache; a cache line will be - movq mm3, [esi+24] ; allocated as needed, to store the data - movq [edi+16], mm2 - movq [edi+24], mm3 - movq mm0, [esi+32] - movq mm1, [esi+40] - movq [edi+32], mm0 - movq [edi+40], mm1 - movq mm2, [esi+48] - movq mm3, [esi+56] - movq [edi+48], mm2 - movq [edi+56], mm3 - - add esi, 64 ; update source pointer - add edi, 64 ; update destination pointer - dec ecx ; count down - jnz $memcpy_ic_1 ; last 64-byte block? - -$memcpy_ic_2: - mov ecx, ebx ; has valid low 6 bits of the byte count -$memcpy_ic_3: - shr ecx, 2 ; dword count - and ecx, 1111b ; only look at the "remainder" bits - neg ecx ; set up to jump into the array - add ecx, offset $memcpy_last_few - jmp ecx ; jump to array of movsds - -$memcpy_uc_test: - cmp ecx, UNCACHED_COPY/64 ; big enough? use block prefetch copy - jae $memcpy_bp_1 - -$memcpy_64_test: - or ecx, ecx ; tail end of block prefetch will jump here - jz $memcpy_ic_2 ; no more 64-byte blocks left - -// For larger blocks, which will spill beyond the cache, its faster to -// use the Streaming Store instruction MOVNTQ. This write instruction -// bypasses the cache and writes straight to main memory. This code also -// uses the software prefetch instruction to pre-read the data. -align 16 -$memcpy_uc_1: ; 64-byte blocks, uncached copy - - prefetchnta [esi + (200*64/34+192)] ; start reading ahead - - movq mm0,[esi+0] ; read 64 bits - add edi,64 ; update destination pointer - movq mm1,[esi+8] - add esi,64 ; update source pointer - movq mm2,[esi-48] - movntq [edi-64], mm0 ; write 64 bits, bypassing the cache - movq mm0,[esi-40] ; note: movntq also prevents the CPU - movntq [edi-56], mm1 ; from READING the destination address - movq mm1,[esi-32] ; into the cache, only to be over-written - movntq [edi-48], mm2 ; so that also helps performance - movq mm2,[esi-24] - movntq [edi-40], mm0 - movq mm0,[esi-16] - movntq [edi-32], mm1 - movq mm1,[esi-8] - movntq [edi-24], mm2 - movntq [edi-16], mm0 - dec ecx - movntq [edi-8], mm1 - jnz $memcpy_uc_1 ; last 64-byte block? - - jmp $memcpy_ic_2 ; almost done - -// For the largest size blocks, a special technique called Block Prefetch -// can be used to accelerate the read operations. Block Prefetch reads -// one address per cache line, for a series of cache lines, in a short loop. -// This is faster than using software prefetch, in this case. -// The technique is great for getting maximum read bandwidth, -// especially in DDR memory systems. -$memcpy_bp_1: ; large blocks, block prefetch copy - - cmp ecx, CACHEBLOCK ; big enough to run another prefetch loop? - jl $memcpy_64_test ; no, back to regular uncached copy - - mov eax, CACHEBLOCK / 2 ; block prefetch loop, unrolled 2X - add esi, CACHEBLOCK * 64 ; move to the top of the block -align 16 -$memcpy_bp_2: - mov edx, [esi-64] ; grab one address per cache line - mov edx, [esi-128] ; grab one address per cache line - sub esi, 128 ; go reverse order - dec eax ; count down the cache lines - jnz $memcpy_bp_2 ; keep grabbing more lines into cache - - mov eax, CACHEBLOCK ; now that its in cache, do the copy -align 16 -$memcpy_bp_3: - movq mm0, [esi ] ; read 64 bits - movq mm1, [esi+ 8] - movq mm2, [esi+16] - movq mm3, [esi+24] - movq mm4, [esi+32] - movq mm5, [esi+40] - movq mm6, [esi+48] - movq mm7, [esi+56] - add esi, 64 ; update source pointer - movntq [edi ], mm0 ; write 64 bits, bypassing cache - movntq [edi+ 8], mm1 ; note: movntq also prevents the CPU - movntq [edi+16], mm2 ; from READING the destination address - movntq [edi+24], mm3 ; into the cache, only to be over-written, - movntq [edi+32], mm4 ; so that also helps performance - movntq [edi+40], mm5 - movntq [edi+48], mm6 - movntq [edi+56], mm7 - add edi, 64 ; update dest pointer - - dec eax ; count down - - jnz $memcpy_bp_3 ; keep copying - sub ecx, CACHEBLOCK ; update the 64-byte block count - jmp $memcpy_bp_1 ; keep processing chunks - -// The smallest copy uses the X86 "movsd" instruction, in an optimized -// form which is an "unrolled loop". Then it handles the last few bytes. -align 4 - movsd - movsd ; perform last 1-15 dword copies - movsd - movsd - movsd - movsd - movsd - movsd - movsd - movsd ; perform last 1-7 dword copies - movsd - movsd - movsd - movsd - movsd - movsd - -$memcpy_last_few: ; dword aligned from before movsds - mov ecx, ebx ; has valid low 2 bits of the byte count - and ecx, 11b ; the last few cows must come home - jz $memcpy_final ; no more, lets leave - rep movsb ; the last 1, 2, or 3 bytes - -$memcpy_final: - emms ; clean up the MMX state - sfence ; flush the write buffer - mov eax, [dest] ; ret value = destination pointer - - } -#else // !defined(_WIN64)) - - return memcpy(dest, src, n); - -#endif -} - -uint64_t -Os::offsetToEpochNanos() -{ - static uint64_t offset = 0; - - if (offset != 0) { - return offset; - } - - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - - LARGE_INTEGER li; - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - - uint64_t now = (li.QuadPart - 116444736000000000ull) * 100; - offset = now - timeNanos(); - - return offset; -} - -#ifdef _WIN64 - -address -Os::currentStackPtr() -{ - return (address) _AddressOfReturnAddress() + sizeof(void*); -} - -#else // !_WIN64 - -#pragma warning(disable:4731) - -void __stdcall -Os::setCurrentStackPtr(address newSp) -{ - newSp -= sizeof(void*); - *(void**) newSp = *(void**) _AddressOfReturnAddress(); - __asm { - mov esp,newSp - mov ebp,[ebp] - ret - } -} - -#endif // !_WIN64 - -size_t Os::getPhysicalMemSize() -{ - MEMORYSTATUSEX statex; - - statex.dwLength = sizeof (statex); - - if (GlobalMemoryStatusEx (&statex) == 0) { - return 0; - } - - return (size_t) statex.ullTotalPhys; -} - -std::string Os::getAppFileName() -{ - std::string strFileName; - char* buff = new char[FILE_PATH_MAX_LENGTH]; - - if (GetModuleFileNameA(NULL, buff, FILE_PATH_MAX_LENGTH) != 0) { - // Get filename without path and extension. - strFileName = strrchr(buff, '\\') ? strrchr(buff, '\\') + 1 : buff; - } - - delete buff; - return strFileName; -} - -} // namespace amd - -#endif // _WIN32 || __CYGWIN__ diff --git a/rocclr/compiler/lib/promotions/oclutils/os/setjmp.S b/rocclr/compiler/lib/promotions/oclutils/os/setjmp.S deleted file mode 100644 index 3029b1c1e7..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/setjmp.S +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved. -# - - .text -.globl _StackContext_setjmp - .type _StackContext_setjmp, @function -_StackContext_setjmp: - -#if defined(_LP64) - movq (%rsp), %rsi - movq %rbx, (%rdi) - lea 8(%rsp), %rax - movq %rax, 8(%rdi) - movq %rbp, 16(%rdi) - movq %r12, 24(%rdi) - movq %r13, 32(%rdi) - movq %r14, 40(%rdi) - movq %r15, 48(%rdi) - movq %rsi, 56(%rdi) -#else // _LP64 - movl (%esp), %ecx - movl 4(%esp), %edx - movl %ebx, (%edx) - lea 4(%esp), %eax - movl %eax, 4(%edx) - movl %ebp, 8(%edx) - movl %edi, 12(%edx) - movl %esi, 16(%edx) - movl %ecx, 20(%edx) -#endif // _LP64 - xor %eax, %eax - ret - -.globl _StackContext_longjmp - .type _StackContext_longjmp, @function -_StackContext_longjmp: - -#if defined(_LP64) - mov %rsi, %rax - movq (%rdi), %rbx - movq 8(%rdi), %rsp - movq 16(%rdi), %rbp - movq 24(%rdi), %r12 - movq 32(%rdi), %r13 - movq 40(%rdi), %r14 - movq 48(%rdi), %r15 - movq 56(%rdi), %r8 - jmp *%r8 -#else // !_LP64 - movl 4(%esp), %edx - movl 8(%esp), %eax - movl (%edx), %ebx - movl 4(%edx), %esp - movl 8(%edx), %ebp - movl 12(%edx), %edi - movl 16(%edx), %esi - movl 20(%edx), %ecx - jmp *%ecx -#endif // !_LP64 - -.section .note.GNU-stack,"",%progbits - diff --git a/rocclr/compiler/lib/promotions/oclutils/os/setjmp.asm b/rocclr/compiler/lib/promotions/oclutils/os/setjmp.asm deleted file mode 100644 index dcc22a8c95..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/os/setjmp.asm +++ /dev/null @@ -1,110 +0,0 @@ -; -; Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved. -; - -ifndef _WIN64 - .386 - .model flat, c -endif ; !_WIN64 - -OPTION PROLOGUE:NONE -OPTION EPILOGUE:NONE -.code - -ifndef _WIN64 - -_StackContext_setjmp proc - mov ecx,[esp] - mov edx,4[esp] - mov [edx],ebx - lea eax,4[esp] - mov 4[edx],eax - mov 8[edx],ebp - mov 0Ch[edx],edi - mov 10h[edx],esi - mov 14h[edx],ecx - xor eax,eax - ret -_StackContext_setjmp endp - -_StackContext_longjmp proc - mov edx,4[esp] - mov eax,8[esp] - mov ebx,[edx] - mov esp,4[edx] - mov ebp,8[edx] - mov edi,0Ch[edx] - mov esi,10h[edx] - mov ecx,14h[edx] - jmp ecx -_StackContext_longjmp endp - -else ; _WIN64 - -_Os_setCurrentStackPtr proc - pop r8 - mov rsp,rcx - push r8 - ret -_Os_setCurrentStackPtr endp - -_StackContext_setjmp proc - mov r8,[rsp] - mov [rcx],rbx - lea r9,8[rsp] - mov 8[rcx],r9 - mov 10h[rcx],rbp - mov 18h[rcx],rsi - mov 20h[rcx],rdi - mov 28h[rcx],r12 - mov 30h[rcx],r13 - mov 38h[rcx],r14 - mov 40h[rcx],r15 - mov 48h[rcx],r8 - stmxcsr 50h[rcx] - fnstcw 54h[rcx] - movdqa 60h[rcx],xmm6 - movdqa 70h[rcx],xmm7 - movdqa 80h[rcx],xmm8 - movdqa 90h[rcx],xmm9 - movdqa 0A0h[rcx],xmm10 - movdqa 0B0h[rcx],xmm11 - movdqa 0C0h[rcx],xmm12 - movdqa 0D0h[rcx],xmm13 - movdqa 0E0h[rcx],xmm14 - movdqa 0F0h[rcx],xmm15 - xor rax,rax - ret -_StackContext_setjmp endp - -_StackContext_longjmp proc - mov rax,rdx - mov rbx,[rcx] - mov rsp,8[rcx] - mov rbp,10h[rcx] - mov rsi,18h[rcx] - mov rdi,20h[rcx] - mov r12,28h[rcx] - mov r13,30h[rcx] - mov r14,38h[rcx] - mov r15,40h[rcx] - mov rdx,48h[rcx] - ldmxcsr 50h[rcx] - fnclex - fldcw 54h[rcx] - movdqa xmm6,60h[rcx] - movdqa xmm7,70h[rcx] - movdqa xmm8,80h[rcx] - movdqa xmm9,90h[rcx] - movdqa xmm10,0A0h[rcx] - movdqa xmm11,0B0h[rcx] - movdqa xmm12,0C0h[rcx] - movdqa xmm13,0D0h[rcx] - movdqa xmm14,0E0h[rcx] - movdqa xmm15,0F0h[rcx] - jmp rdx -_StackContext_longjmp endp - -endif ; _WIN64 - -end diff --git a/rocclr/compiler/lib/promotions/oclutils/thread/atomic.hpp b/rocclr/compiler/lib/promotions/oclutils/thread/atomic.hpp deleted file mode 100644 index 8477ece1e0..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/thread/atomic.hpp +++ /dev/null @@ -1,548 +0,0 @@ -// -// Copyright (c) 2009 Advanced Micro Devices, Inc. All rights reserved. -// - -/*! \file atomic.hpp - * \brief Declarations for Memory order access and Atomic operations. - * - * \author Laurent Morichetti (laurent.morichetti@amd.com) - * \date October 2008 - */ - -#ifndef ATOMIC_HPP_ -#define ATOMIC_HPP_ - -#include "top.hpp" - -#include - -#ifdef _WIN32 -# include -#elif defined(ATI_ARCH_X86) -# include -# include -#endif // !_WIN32 - -#include -#include - -namespace amd { - -/*! \addtogroup Threads - * @{ - * - * \addtogroup Atomic Atomic Operations - * @{ - */ - -/*! \brief Static functions for atomic operations. - */ -class AtomicOperation : AllStatic -{ -private: - - //! Template to specialize atomic intrinsics on register size. - template - struct Intrinsics { - /*! \brief %Atomic add. - * - * Atomically add \a inc to \a *dest and return the prior value. - */ - template - static inline T add(T increment, volatile T* dest); - - /*! \brief %Atomic exchange. - * - * Atomically exchange value with *dest and return the prior value. - */ - template - static inline T swap(T value, volatile T* dest); - - /*! \brief %Atomic compare and exchange. - * - * Atomically compare and xchge value with *dest if *dest == compare. - * Return the prior value. - */ - template - static inline T compareAndSwap(T compare, volatile T* dest, T value); - - /*! \brief %Atomic increment. - * - * Atomically increment *dest and return the prior value. - */ - template - static inline T increment(volatile T* dest); - - /*! \brief %Atomic exchange. - * - * Atomically decrement *dest and return the prior value. - */ - template - static inline T decrement(volatile T* dest); - - /*! \brief %Atomic or. - * - * Atomically or \a mask to \a *dest and return the prior value. - */ - template - static inline T _or(T mask, volatile T* dest); - - /*! \brief %Atomic and. - * - * Atomically and \a mask to \a *dest and return the prior value. - */ - template - static inline T _and(T mask, volatile T* dest); -}; - -public: - /*! \brief %Atomic add. - * - * Atomically add \a inc to \a *dest and return the prior value. - */ - template - static T add(T inc, volatile T* dest) - { - return Intrinsics::add((T) inc, dest); - } - - /*! \brief %Atomic exchange. - * - * Atomically exchange value with *dest and return the prior value. - */ - template - static T swap(T value, volatile T* dest) - { - return Intrinsics::swap(value, dest); - } - - /*! \brief %Atomic compare and exchange. - * - * Atomically compare and exchange value with *dest if *dest == compare. - * Return the prior value. - */ - template - static T compareAndSwap(T compare, volatile T* dest, T value) - { - return Intrinsics::compareAndSwap(compare, dest, value); - } - - /*! \brief %Atomic increment. - * - * Atomically increment *dest and return the prior value. - */ - template - static T increment(volatile T* dest) - { - return Intrinsics::increment(dest); - } - - /*! \brief %Atomic decrement. - * - * Atomically decrement *dest and return the prior value. - */ - template - static T decrement(volatile T* dest) - { - return Intrinsics::decrement(dest); - } - - /*! \brief %Atomic or. - * - * Atomically or \a mask to \a *dest and return the prior value. - */ - template - static T _or(T mask, volatile T* dest) - { - return Intrinsics::_or((T) mask, dest); - } - - /*! \brief %Atomic and. - * - * Atomically or \a mask to \a *dest and return the prior value. - */ - template - static T _and(T mask, volatile T* dest) - { - return Intrinsics::_and((T) mask, dest); - } -}; - -/*@}*/ - -#if defined(_MSC_VER) - -template <> -template -inline T -AtomicOperation::Intrinsics<4>::add(T increment, volatile T* dest) -{ - return (T)_InterlockedExchangeAdd( - (volatile long*)dest, (long)increment); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<4>::swap(T value, volatile T* dest) -{ - return (T)_InterlockedExchange( - (volatile long*)dest, (long)value); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<4>::compareAndSwap( - T compare, volatile T* dest, T value) -{ - return (T)_InterlockedCompareExchange( - (volatile long*)dest, (long)value, (long)compare); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<4>::increment(volatile T* dest) -{ - return (T)(_InterlockedIncrement((volatile long*)dest) - 1L); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<4>::decrement(volatile T* dest) -{ - return (T)(_InterlockedDecrement((volatile long*)dest) + 1L); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<4>::_or(T mask, volatile T* dest) -{ - return (T)_InterlockedOr( - (volatile long*)dest, (long)mask); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<4>::_and(T mask, volatile T* dest) -{ - return (T)_InterlockedAnd( - (volatile long*)dest, (long)mask); -} - -#ifdef _WIN64 - -template <> -template -inline T -AtomicOperation::Intrinsics<8>::add(T increment, volatile T* dest) -{ - return (T)_InterlockedExchangeAdd64( - (volatile __int64*)dest, (__int64)increment); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<8>::swap(T value, volatile T* dest) -{ - return (T)_InterlockedExchange64( - (volatile __int64*)dest, (__int64)value); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<8>::compareAndSwap( - T compare, volatile T* dest, T value) -{ - return (T)_InterlockedCompareExchange64( - (volatile __int64*)dest, (__int64)value, (__int64)compare); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<8>::increment(volatile T* dest) -{ - return (T)(_InterlockedIncrement64((volatile __int64*)dest) - 1LL); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<8>::decrement(volatile T* dest) -{ - return (T)(_InterlockedDecrement64((volatile __int64*)dest) + 1LL); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<8>::_or(T mask, volatile T* dest) -{ - return (T)_InterlockedOr64( - (volatile long*)dest, (long)mask); -} - -template <> -template -inline T -AtomicOperation::Intrinsics<8>::_and(T mask, volatile T* dest) -{ - return (T)_InterlockedAnd64( - (volatile long*)dest, (long)mask); -} - -#endif // _LP64 - -#elif defined(__GNUC__) - -template -template -inline T -AtomicOperation::Intrinsics::add(T inc, volatile T* dest) -{ - return __sync_fetch_and_add(dest, inc); -} - -template -template -inline T -AtomicOperation::Intrinsics::swap(T value, volatile T* dest) -{ - return __sync_lock_test_and_set(dest, value); -} - -template -template -inline T -AtomicOperation::Intrinsics::compareAndSwap( - T compare, volatile T* dest, T value) -{ - return __sync_val_compare_and_swap(dest, compare, value); -} - -template -template -inline T -AtomicOperation::Intrinsics::increment(volatile T* dest) -{ - return add(T(1), dest); -} - -template -template -inline T -AtomicOperation::Intrinsics::decrement(volatile T* dest) -{ - return add(T(-1), dest); -} - -template -template -inline T -AtomicOperation::Intrinsics::_or(T mask, volatile T* dest) -{ - return __sync_fetch_and_or(dest, mask); -} - -template -template -inline T -AtomicOperation::Intrinsics::_and(T mask, volatile T* dest) -{ - return __sync_fetch_and_and(dest, mask); -} - -#else -# error Unimplemented -#endif - -/*! \addtogroup Atomic Atomic Operations - * @{ - */ - -/*! \brief A variable of type T with atomic properties. - */ -template -class Atomic -{ -private: - - typedef typename std::remove_volatile::type>::type>::type value_type; - typename std::add_volatile::type value_; //!< \brief The variable. - -public: - //! Construct a new %Atomic variable of type T. - Atomic() : value_(T(0)) {} - //! Construct a new %Atomic variable of type T from \a value. - Atomic(T value) : value_(value) {} - //! Construct a new %Atomic variable of type T from another %Atomic. - Atomic(const Atomic& atomic) : value_(atomic.value_) { } - //! Copy value into this %Atomic variable. - Atomic& operator = (T value) - { - value_ = value; - return *this; - } - - //! Return the %Atomic variable value. - operator T () const { return T(value_); } - //! Return the %Atomic variable value. - T operator ->() const { return T(value_); } - //! Return the %Atomic variable's address. - typename std::add_pointer::type>:: - type operator &() { return &value_; } - - //! Atomically add \a inc to this variable. - Atomic& operator += (value_type inc) - { - if (std::is_pointer::value) { - inc *= sizeof(typename std::remove_pointer::type); - } - AtomicOperation::add(inc, &value_); - return *this; - } - - //! Atomically subtract \a inc to this variable. - Atomic& operator -= (value_type inc) - { - value_type modifier = 0; - if (std::is_pointer::value) { - inc *= sizeof(typename std::remove_pointer::type); - } - AtomicOperation::add(modifier - inc, &value_); - return *this; - } - - //! Atomically OR \a value to this variable. - Atomic& operator |= (value_type mask) - { - AtomicOperation::_or(mask, &value_); - return *this; - } - - //! Atomically AND \a value to this variable. - Atomic& operator &= (value_type mask) - { - AtomicOperation::_and(mask, &value_); - return *this; - } - - //! Atomically increment this variable and return its new value. - typename std::remove_reference::type operator ++ () - { - if (std::is_pointer::value) { - value_type inc = static_cast( - sizeof(typename std::remove_pointer::type)); - return AtomicOperation::add(inc, &value_) + 1; - } - else { - return AtomicOperation::increment(&value_) + 1; - } - } - - //! Atomically decrement this variable and return its new value. - typename std::remove_reference::type operator -- () - { - if (std::is_pointer::value) { - value_type inc = static_cast(- - static_cast::type>( - sizeof(typename std::remove_pointer::type))); - return AtomicOperation::add(inc, &value_) - 1; - } - else { - return AtomicOperation::decrement(&value_) - 1; - } - } - - //! Atomically increment this variable and return its previous value. - typename std::remove_reference::type operator ++ (int) - { - if (std::is_pointer::value) { - value_type inc = static_cast( - sizeof(typename std::remove_pointer::type)); - return AtomicOperation::add(inc, &value_); - } - else { - return AtomicOperation::increment(&value_); - } - } - - //! Atomically decrement this variable and return its previous value. - T operator -- (int) - { - if (std::is_pointer::value) { - value_type inc = static_cast(- - static_cast::type>( - sizeof(typename std::remove_pointer::type))); - return AtomicOperation::add(inc, &value_); - } - else { - return AtomicOperation::decrement(&value_); - } - } - - /*! \brief Atomically compare this variable with \a compare and set - * to value if equals - */ - bool compareAndSet(T compare, T value) - { - return compare == AtomicOperation::compareAndSwap( - compare, &value_, value); - } - - //! Atomically set this variable to \a value and return its previous value. - T swap(T value) - { - return AtomicOperation::swap(value, &value_); - } - - /*! \brief Execute a stores fence followed by a store to this variable. - * - * This storeRelease operation ensures that all store to memory operations - * preceding this function will be globally visible before the update to - * this variable's value. - */ - void storeRelease(T value) - { - std::atomic_thread_fence(std::memory_order_release); - value_ = value; - } - - /*! \brief Execute a load from this variable followed by a loads fence. - * - * This loadAcquire operation ensures that all load from memory operations - * following this function will be globally visible after the read from - * this variable's value. - */ - T loadAcquire() const - { - T value = value_; - std::atomic_thread_fence(std::memory_order_acquire); - return value; - } -}; - -//! Helper function to tie an Atomic to a variable of type T. -template -inline Atomic -make_atomic(T& t) -{ - return Atomic(t); -} - - -/*! @} - * @} - */ - -} // namespace amd - -#endif /*ATOMIC_HPP_*/ diff --git a/rocclr/compiler/lib/promotions/oclutils/thread/monitor.cpp b/rocclr/compiler/lib/promotions/oclutils/thread/monitor.cpp deleted file mode 100644 index 9a3d7de433..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/thread/monitor.cpp +++ /dev/null @@ -1,321 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#include "thread/monitor.hpp" -#include "thread/atomic.hpp" -#include "thread/semaphore.hpp" -#include "thread/thread.hpp" -#include "utils/util.hpp" - -#include -#include -#include - -namespace amd { - -Monitor::Monitor(const char* name, bool recursive) : - contendersList_(0), onDeck_(0), waitersList_(NULL), - owner_(NULL), recursive_(recursive) -{ - const size_t maxNameLen = sizeof(name_); - if (name == NULL) { - const char* unknownName = "@unknown@"; - assert(sizeof(unknownName) < maxNameLen && "just checking"); - strcpy(name_, unknownName); - } - else { - strncpy(name_, name, maxNameLen - 1); - name_[maxNameLen - 1] = '\0'; - } -} - -bool -Monitor::trySpinLock() -{ - if (tryLock()) { - return true; - } - - for (int s = kMaxSpinIter; s > 0; --s) { - // First, be SMT friendly - if (s >= (kMaxSpinIter - kMaxReadSpinIter)) { - Os::spinPause(); - } - // and then SMP friendly - else { - Thread::yield(); - } - if (!isLocked()) { - return tryLock(); - } - } - - // We could not acquire the lock in the spin loop. - return false; -} - -void -Monitor::finishLock() -{ - Thread* thread = Thread::current(); - assert(thread != NULL && "cannot lock() from (null)"); - - if (trySpinLock()) { - return; // We succeeded, we are done. - } - - /* The lock is contended. Push the thread's semaphore onto - * the contention list. - */ - Semaphore& semaphore = thread->lockSemaphore(); - semaphore.reset(); - - LinkedNode newHead; - newHead.setItem(&semaphore); - - intptr_t head = contendersList_.load(std::memory_order_acquire); - for (;;) { - // The assumption is that lockWord is locked. Make sure we do not - // continue unless the lock bit is set. - if ((head & kLockBit) == 0) { - if (tryLock()) { - return; - } - continue; - } - - // Set the new contention list head if lockWord is unchanged. - newHead.setNext(reinterpret_cast(head & ~kLockBit)); - if (contendersList_.compare_exchange_weak(head, - reinterpret_cast(&newHead) | kLockBit, - std::memory_order_acq_rel, std::memory_order_acquire)) { - break; - } - - // We failed the CAS. yield/pause before trying again. - Thread::yield(); - } - - int32_t spinCount = 0; - // Go to sleep until we become the on-deck thread. - while ((onDeck_ & ~kLockBit) != reinterpret_cast(&semaphore)) { - // First, be SMT friendly - if (spinCount < kMaxReadSpinIter) { - Os::spinPause(); - } - // and then SMP friendly - else if (spinCount < kMaxSpinIter) { - Thread::yield(); - } - // now go to sleep - else { - semaphore.wait(); - } - spinCount++; - } - - spinCount = 0; - // - // From now-on, we are the on-deck thread. It will stay that way until - // we successfuly acquire the lock. - // - for (;;) { - assert((onDeck_ & ~kLockBit) == reinterpret_cast(&semaphore) - && "just checking"); - if (tryLock()) { - break; - } - - // Somebody beat us to it. Since we are on-deck, we can just go - // back to sleep. - // First, be SMT friendly - if (spinCount < kMaxReadSpinIter) { - Os::spinPause(); - } - // and then SMP friendly - else if (spinCount < kMaxSpinIter) { - Thread::yield(); - } - // now go to sleep - else { - semaphore.wait(); - } - spinCount++; - } - - assert(newHead.next() == NULL && "Should not be linked"); - onDeck_ = 0; -} - -void -Monitor::finishUnlock() -{ - // If we get here, it means that there might be a thread in the contention - // list waiting to acquire the lock. We need to select a successor and - // place it on-deck. - - for (;;) { - // Grab the onDeck_ microlock to protect the next loop (make sure only - // one semaphore is removed from the contention list). - // - intptr_t ptr = 0; - if (!onDeck_.compare_exchange_strong(ptr, ptr | kLockBit, - std::memory_order_acq_rel, std::memory_order_acquire)) { - return; // Somebody else has the microlock, let him select onDeck_ - } - - intptr_t head = contendersList_.load(std::memory_order_acquire); - for (;;) { - if (head == 0) { - break; // There's nothing else to do. - } - - if ((head & kLockBit) != 0) { - // Somebody could have acquired then released the lock - // and failed to grab the onDeck_ microlock. - head = 0; - break; - } - - if (contendersList_.compare_exchange_weak( - head, reinterpret_cast( - reinterpret_cast(head)->next()), - std::memory_order_acq_rel, std::memory_order_acquire)) { - #ifdef ASSERT - reinterpret_cast(head)->setNext(NULL); - #endif // ASSERT - break; - } - } - - Semaphore* semaphore = (head != 0) - ? reinterpret_cast(head)->item() - : NULL; - - onDeck_.store(reinterpret_cast(semaphore), - std::memory_order_release); - // - // Release the onDeck_ microlock (end of critical region); - - if (semaphore != NULL) { - semaphore->post(); - return; - } - - // We do not have an on-deck thread (semaphore == NULL). Return if - // the contention list is empty or if the lock got acquired again. - head = contendersList_; - if (head == 0 || (head & kLockBit) != 0) { - return; - } - } -} - -void -Monitor::wait() -{ - Thread* thread = Thread::current(); - assert(isLocked() && owner_ == thread && "just checking"); - - // Add the thread's resume semaphore to the list. - Semaphore& suspend = thread->suspendSemaphore(); - suspend.reset(); - - LinkedNode newHead; - newHead.setItem(&suspend); - newHead.setNext(waitersList_); - waitersList_ = &newHead; - - // Preserve the lock count (for recursive mutexes) - uint32_t lockCount = lockCount_; - lockCount_ = 1; - - // Release the lock and go to sleep. - unlock(); - - // Go to sleep until we become the on-deck thread. - int32_t spinCount = 0; - while ((onDeck_ & ~kLockBit) != reinterpret_cast(&suspend)) { - // First, be SMT friendly - if (spinCount < kMaxReadSpinIter) { - Os::spinPause(); - } - // and then SMP friendly - else if (spinCount < kMaxSpinIter) { - Thread::yield(); - } - // now go to sleep - else { - suspend.wait(); - } - spinCount++; - } - - spinCount = 0; - for (;;) { - assert((onDeck_ & ~kLockBit) == reinterpret_cast(&suspend) - && "just checking"); - - if (trySpinLock()) { - break; - } - - // Somebody beat us to it. Since we are on-deck, we can just go - // back to sleep. - // First, be SMT friendly - if (spinCount < kMaxReadSpinIter) { - Os::spinPause(); - } - // and then SMP friendly - else if (spinCount < kMaxSpinIter) { - Thread::yield(); - } - // now go to sleep - else { - suspend.wait(); - } - spinCount++; - } - - // Restore the lock count (for recursive mutexes) - lockCount_ = lockCount; - - onDeck_.store(0, std::memory_order_release); -} - -void -Monitor::notify() -{ - assert(isLocked() && owner_ == Thread::current() && "just checking"); - - LinkedNode* waiter = waitersList_; - if (waiter == NULL) { - return; - } - - // Dequeue a waiter from the wait list and add it to the contention list. - waitersList_ = waiter->next(); - - intptr_t node = contendersList_.load(std::memory_order_acquire); - for (;;) { - waiter->setNext(reinterpret_cast(node & ~kLockBit)); - if (contendersList_.compare_exchange_weak(node, - reinterpret_cast(waiter) | kLockBit, - std::memory_order_acq_rel, std::memory_order_acquire)) { - break; - } - } -} - -void -Monitor::notifyAll() -{ - // NOTE: We could CAS the whole list in 1 shot but this is - // not critical code. Optimize this if it becomes hot. - while (waitersList_ != NULL) { - notify(); - } -} - -} // namespace amd diff --git a/rocclr/compiler/lib/promotions/oclutils/thread/monitor.hpp b/rocclr/compiler/lib/promotions/oclutils/thread/monitor.hpp deleted file mode 100644 index fac75b72d8..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/thread/monitor.hpp +++ /dev/null @@ -1,263 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef MONITOR_HPP_ -#define MONITOR_HPP_ - -#include "top.hpp" -#include "thread/atomic.hpp" -#include "thread/semaphore.hpp" -#include "thread/thread.hpp" - -#include -#include -#include - -namespace amd { - -/*! \addtogroup Threads - * @{ - * - * \addtogroup Synchronization - * @{ - */ - -namespace details { - -template -struct SimplyLinkedNode : public AllocClass -{ - typedef SimplyLinkedNode Node; - -protected: - std::atomic next_; /*!< \brief The next element. */ - T volatile item_; - -public: - //! \brief Return the next element in the linked-list. - Node* next() const { return next_; } - //! \brief Return the item. - T item() const { return item_; } - - //! \brief Set the next element pointer. - void setNext(Node* next) { next_ = next; } - //! \brief Set the item. - void setItem(T item) { item_ = item; } - - //! \brief Swap the next element pointer. - Node* swapNext(Node* next) { return next_.swap(next); } - - //! \brief Compare and set the next element pointer. - bool compareAndSetNext(Node* compare, Node* next) - { - return next_.compare_exchange_strong(compare, next); - } -}; - -} // namespace details - -class Monitor : public HeapObject -{ - typedef details::SimplyLinkedNode LinkedNode; - -private: - static const intptr_t kLockBit = 0x1; - - static const int kMaxSpinIter = 55; //!< Total number of spin iterations. - static const int kMaxReadSpinIter = 50; //!< Read iterations before yielding - - /*! Linked list of semaphores the contending threads are waiting on - * and main lock. - */ - std::atomic_intptr_t contendersList_; - //! The Mutex's name - char name_[64]; - - //! Semaphore of the next thread to contend for the lock. - std::atomic_intptr_t onDeck_; - //! Linked list of the suspended threads resume semaphores. - LinkedNode* volatile waitersList_; - - //! Thread owning this monitor. - Thread* volatile owner_; - //! The amount of times this monitor was acquired by the owner. - uint32_t lockCount_; - //! True if this is a recursive mutex, false otherwise. - const bool recursive_; - -private: - //! Finish locking the mutex (contented case). - void finishLock(); - //! Finish unlocking the mutex (contented case). - void finishUnlock(); - -protected: - //! Try to spin-acquire the lock, return true if successful. - bool trySpinLock(); - - /*! \brief Return true if the lock is owned. - * - * \note The user is responsible for the memory ordering. - */ - bool isLocked() const { return (contendersList_ & kLockBit) != 0; } - - //! Return this monitor's owner thread (NULL if unlocked). - Thread* owner() const { return owner_; } - - //! Set the owner. - void setOwner(Thread* thread) { owner_ = thread; } - -public: - explicit Monitor(const char* name = NULL, bool recursive = false); - ~Monitor() {} - - //! Try to acquire the lock, return true if successful. - inline bool tryLock(); - - //! Acquire the lock or suspend the calling thread. - inline void lock(); - - //! Release the lock and wake a single waiting thread if any. - inline void unlock(); - - /*! \brief Give up the lock and go to sleep. - * - * Calling wait() causes the current thread to go to sleep until - * another thread calls notify()/notifyAll(). - * - * \note The monitor must be owned before calling wait(). - */ - void wait(); - /*! \brief Wake up a single thread waiting on this monitor. - * - * \note The monitor must be owned before calling notify(). - */ - void notify(); - /*! \brief Wake up all threads that are waiting on this monitor. - * - * \note The monitor must be owned before calling notifyAll(). - */ - void notifyAll(); - - //! Return this lock's name. - const char* name() const { return name_; } -}; - -class ScopedLock : StackObject -{ -private: - Monitor* lock_; - -public: - ScopedLock(Monitor& lock) - : lock_(&lock) - { - lock_->lock(); - } - - ScopedLock(Monitor* lock) - : lock_(lock) - { - if (lock_) lock_->lock(); - } - - ~ScopedLock() - { - if (lock_) lock_->unlock(); - } -}; - -/*! @} - * @} - */ - -inline bool -Monitor::tryLock() -{ - Thread* thread = Thread::current(); - assert(thread != NULL && "cannot lock() from (null)"); - - intptr_t ptr = contendersList_.load(std::memory_order_acquire); - - if (unlikely((ptr & kLockBit) != 0)) { - if (recursive_ && thread == owner_) { - // Recursive lock: increment the lock count and return. - ++lockCount_; - return true; - } - return false; // Already locked! - } - - if (unlikely(!contendersList_.compare_exchange_weak(ptr, ptr | kLockBit, - std::memory_order_acq_rel, std::memory_order_acquire))) { - return false; // We failed the CAS from unlocked to locked. - } - - setOwner(thread); // cannot move above the CAS. - lockCount_ = 1; - - return true; -} - -inline void -Monitor::lock() -{ - if (unlikely(!tryLock())) { - // The lock is contented. - finishLock(); - } - - // This is the beginning of the critical region. From now-on, everything - // executes single-threaded! - // -} - -inline void -Monitor::unlock() -{ - assert(isLocked() && owner_ == Thread::current() && "invariant"); - - if (recursive_ && --lockCount_ > 0) { - // was a recursive lock case, simply return. - return; - } - - setOwner(NULL); - - // Clear the lock bit. - intptr_t ptr = contendersList_.load(std::memory_order_acquire); - while (!contendersList_.compare_exchange_weak(ptr, ptr & ~kLockBit, - std::memory_order_acq_rel, std::memory_order_acquire)) - ; - // - // We succeeded the CAS from locked to unlocked. - // This is the end of the critical region. - - // Check if we have an on-deck thread that needs signaling. - intptr_t onDeck = onDeck_; - if (onDeck != 0) { - if ((onDeck & kLockBit) == 0) { - // Only signal if it is unmarked. - reinterpret_cast(onDeck)->post(); - } - return; // We are done. - } - - // We do not have an on-deck thread yet, we might have to walk the list in - // order to select the next onDeck_. Only one thread needs to fill onDeck_, - // so return if the list is empty or if the lock got acquired again (it's - // somebody else's problem now!) - - intptr_t head = contendersList_; - if (head == 0 || (head & kLockBit) != 0) { - return; - } - - // Finish the unlock operation: find a thread to wake up. - finishUnlock(); -} - -} // namespace amd - -#endif /*MONITOR_HPP_*/ diff --git a/rocclr/compiler/lib/promotions/oclutils/thread/semaphore.cpp b/rocclr/compiler/lib/promotions/oclutils/thread/semaphore.cpp deleted file mode 100644 index 235ca45d9a..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/thread/semaphore.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright (c) 2008,2010 Advanced Micro Devices, Inc. All rights reserved. -// - -#include "thread/semaphore.hpp" -#include "thread/thread.hpp" - -#if defined(_WIN32) || defined(__CYGWIN__) -# include -#else // !_WIN32 -# include -# include -#endif // !_WIN32 - -namespace amd { - -Semaphore::Semaphore() -{ - std::atomic_init(&state_, 0); -#ifdef _WIN32 - handle_ = static_cast(CreateSemaphore(NULL, 0, LONG_MAX, NULL)); - assert(handle_ != NULL && "CreateSemaphore failed"); -#else // !_WIN32 - if (sem_init(&sem_, 0, 0) != 0) { - fatal("sem_init() failed"); - } -#endif // !_WIN32 -} - -Semaphore::~Semaphore() -{ -#ifdef _WIN32 - if (!CloseHandle(static_cast(handle_))) { - fatal("CloseHandle() failed"); - } -#else // !_WIN32 - if (sem_destroy(&sem_) != 0) { - fatal("sem_destroy() failed"); - } -#endif // !WIN32 -} - -void -Semaphore::post() -{ - int state = state_.load(std::memory_order_relaxed); - for (;;) { - if (state > 0) { - int newstate = state_.load(std::memory_order_acquire); - if (state == newstate) { - return; - } - state = newstate; - continue; - } - if (state_.compare_exchange_weak(state, state+1, - std::memory_order_acq_rel, std::memory_order_acquire)) { - break; - } - } - - if (state < 0) { - // We have threads waiting on this event. -#ifdef _WIN32 - ReleaseSemaphore(static_cast(handle_), 1, NULL); -#else // !_WIN32 - if (0 != sem_post(&sem_)) { - fatal("sem_post() failed"); - } -#endif // !_WIN32 - } -} - -void -Semaphore::wait() -{ - if (state_-- > 0) { - return; - } - -#ifdef _WIN32 - if (WAIT_OBJECT_0 != WaitForSingleObject( - static_cast(handle_), INFINITE)) { - fatal("WaitForSingleObject failed"); - } -#else // !_WIN32 - while (0 != sem_wait(&sem_)) { - if (EINTR != errno) { - fatal("sem_wait() failed"); - } - } -#endif // !_WIN32 -} - -} // namespace amd diff --git a/rocclr/compiler/lib/promotions/oclutils/thread/semaphore.hpp b/rocclr/compiler/lib/promotions/oclutils/thread/semaphore.hpp deleted file mode 100644 index 93c8c0f209..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/thread/semaphore.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) 2008,2010 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef SEMAPHORE_HPP_ -#define SEMAPHORE_HPP_ - -#include "top.hpp" -#include "utils/util.hpp" - -#include -#if defined(__linux__) -# include -#endif /*linux*/ - - -namespace amd { - -/*! \addtogroup Threads - * @{ - * - * \addtogroup Synchronization - * @{ - */ - -class Thread; - -//! \brief Counting semaphore -class Semaphore : public HeapObject -{ -private: - std::atomic_int state_; //!< This semaphore's value. - -#ifdef _WIN32 - void* handle_; //!< The semaphore object's handle. - char padding_[64-sizeof(void*)-sizeof(std::atomic_int)]; -#else // !_WIN32 - sem_t sem_; //!< The semaphore object's identifier. - char padding_[64-sizeof(sem_t)-sizeof(std::atomic_int)]; -#endif /*!_WIN32*/ - -public: - Semaphore(); - ~Semaphore(); - - //! \brief Decrement this semaphore - void wait(); - - //! \brief Increment this semaphore - void post(); - - //! \brief Reset this semaphore. - void reset() - { - state_.store(0, std::memory_order_release); - } -}; - -/*! @} - * @} - */ - -} // namespace amd - -#endif /*SEMAPHORE_HPP_*/ diff --git a/rocclr/compiler/lib/promotions/oclutils/thread/thread.cpp b/rocclr/compiler/lib/promotions/oclutils/thread/thread.cpp deleted file mode 100644 index ee1e6abde3..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/thread/thread.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#include "thread/thread.hpp" -#include "thread/semaphore.hpp" -#include "thread/monitor.hpp" -#include "os/os.hpp" - -#if defined(_WIN32) || defined(__CYGWIN__) -# include -#endif // _WIN32 - -namespace amd { - -HostThread::HostThread() - : Thread("HostThread", 0, false) -{ - setCurrent(); - Os::currentStackInfo(&stackBase_, &stackSize_); - setState(RUNNABLE); -} - -void -Thread::create() -{ - created_ = new Semaphore(); - lock_ = new Semaphore(); - suspend_ = new Semaphore(); - - selfSuspendLock_ = new Monitor(); - - data_ = NULL; - handle_ = NULL; - setState(CREATED); -} - -Thread::Thread(const std::string& name, size_t stackSize, bool spawn) - : handle_(NULL), name_(name), stackSize_(stackSize) -{ - create(); - - if (!spawn) return; - - if ((handle_ = Os::createOsThread(this))) { - // Now we need to wait for Thread::main to report back. - while (state() != Thread::INITIALIZED) { - created_->wait(); - } - } -} - -Thread::~Thread() -{ -#if defined(_WIN32) - if (handle_ != NULL) { - ::CloseHandle((HANDLE) handle_); - } -#endif - delete created_; - delete lock_; - delete suspend_; - - delete selfSuspendLock_; -} - -void* -Thread::main() -{ -#ifdef DEBUG - Os::setCurrentThreadName(name().c_str()); -#endif // DEBUG - Os::currentStackInfo(&stackBase_, &stackSize_); - setCurrent(); - - // Notify the parent thread that we are up and running. - { - ScopedLock sl(selfSuspendLock_); - setState(INITIALIZED); - created_->post(); - selfSuspendLock_->wait(); - } - - if (state() == RUNNABLE) { - run(data_); - } - - setState(FINISHED); - return NULL; -} - -bool -Thread::start(void* data) -{ - if (state() != INITIALIZED) { - return false; - } - - data_ = data; - { - ScopedLock sl(selfSuspendLock_); - setState(RUNNABLE); - selfSuspendLock_->notify(); - } - - return true; -} - -void -Thread::resume() -{ - ScopedLock sl(selfSuspendLock_); - selfSuspendLock_->notify(); -} - -#if defined(__linux__) - -namespace details { - -__thread Thread* thread_ __attribute__((tls_model("initial-exec"))); - -} // namespace details - -void -Thread::registerStack(address base, address top) -{ - // Nothing to do. -} - -void -Thread::setCurrent() -{ - details::thread_ = this; -} - -#elif defined(_WIN32) - -namespace details { - -#if defined(USE_DECLSPEC_THREAD) -__declspec(thread) Thread* thread_; -#else // !USE_DECLSPEC_THREAD -DWORD threadIndex_ = TlsAlloc(); -#endif // !USE_DECLSPEC_THREAD - -} // namespace details - -void -Thread::registerStack(address base, address top) -{ - // Nothing to do. -} - -void -Thread::setCurrent() -{ -#if defined(USE_DECLSPEC_THREAD) - details::thread_ = this; -#else // !USE_DECLSPEC_THREAD - TlsSetValue(details::threadIndex_, this); -#endif // !USE_DECLSPEC_THREAD -} - -#endif - -bool -Thread::init() -{ - static bool initialized_ = false; - - // We could use InitOnceExecuteOnce/pthread_once here: - if (initialized_) { - return true; - } - initialized_ = true; - - // Register the main thread - return NULL != new HostThread(); -} - -void -Thread::tearDown() -{ -#if defined(_WIN32) && !defined(USE_DECLSPEC_THREAD) - if (details::threadIndex_ != TLS_OUT_OF_INDEXES) { - TlsFree(threadIndex_); - } -#endif // _WIN32 && !USE_DECLSPEC_THREAD -} - -} // namespace amd diff --git a/rocclr/compiler/lib/promotions/oclutils/thread/thread.hpp b/rocclr/compiler/lib/promotions/oclutils/thread/thread.hpp deleted file mode 100644 index c2b5ca274c..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/thread/thread.hpp +++ /dev/null @@ -1,231 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef THREAD_HPP_ -#define THREAD_HPP_ - -#include "top.hpp" -#include "thread/semaphore.hpp" -#include "os/os.hpp" - -#include - -#if defined(_WIN32) -# define USE_DECLSPEC_THREAD 1 -# if !defined(USE_DECLSPEC_THREAD) -# include -# endif /*!USE_DECLSPEC_THREAD*/ -#endif /*_WIN32*/ - -namespace amd { - -/*! \addtogroup Threads Threading package - * @{ - * - * \addtogroup OsThread Native Threads - * @{ - */ - -class Monitor; - -class Thread : public HeapObject -{ - friend const void* Os::createOsThread(Thread*); - -public: - enum ThreadState - { - CREATED, - INITIALIZED, - RUNNABLE, - SUSPENDED, - FINISHED, - FAILED - }; - -private: - //! System thread handle. - const void* handle_; - //! The thread's name. - const std::string name_; - //! Current running state. - volatile ThreadState state_; - //! The argument passed to run() - void* data_; - - //! \cond ignore - Semaphore* created_; //!< To notify the parent thread. - Semaphore* lock_; //!< For mutex support (during contention). - Semaphore* suspend_; //!< For wait/suspend support. - //! \endcond - - Monitor* selfSuspendLock_; //!< For self suspend/resume. - -protected: - address stackBase_; //!< Main stack base. - size_t stackSize_; //!< Main stack size. - -private: - - /*! \brief The start wrapper for all newly create threads. - * This is called from the pthread_create start_thread. - */ - static void* entry(Thread* thread); - - /*! \brief Thread main (called from the main function). - * Setup the thread for running and wait for the semaphore to be signaled. - */ - void* main(); - - //! The entry point for this thread. - virtual void run(void* data) = 0; - -protected: - //! Bring this thread to the created state. - void create(); - - //! Set the current thread state. - void setState(ThreadState state) { state_ = state; } - - //! Set the thread-local _thread variable (used by current()). - void setCurrent(); - - //! Register the given memory region as a valid stack. - void registerStack(address base, address top); - - /*! \brief Construct a new thread. - * If \a spawn is false, do not create a new OS thread, instead, - * bind to the currently running on. - */ - explicit Thread( - const std::string& name, - size_t stackSize = 0 /*use system default*/, - bool spawn = true /* create a new Os::thread */); - -public: - //! Return the currently running thread instance. - static inline Thread* current(); - - //! Initialize the OsThread package. - static bool init(); - - //! Tear down the OsThread package. - static void tearDown(); - - //! Destroy this thread. - virtual ~Thread(); - - //! Return the thread's name - const std::string& name() const { return name_; } - - //! Get the system thread handle. - const void* handle() const { return handle_; } - - //! Start the thread execution - bool start(void *data = NULL); - - //! Resume the thread - void resume(); - - //! Return true is this is the host thread. - virtual bool isHostThread() const { return false; } - - //! Return true if this is a worker thread. - virtual bool isWorkerThread() const { return false; } - - //! Get the current thread state. - ThreadState state() const { return state_; } - - //! Return this thread's stack base. - address stackBase() const { return stackBase_; } - //! Return this thread's stack size. - size_t stackSize() const { return stackSize_; } - //! Return this thread's stack bottom. - address stackBottom() const { return stackBase() - stackSize(); } - - //! Return this thread's contend semaphore. - Semaphore& lockSemaphore() const { return *lock_; } - //! Return this thread's resume semaphore. - Semaphore& suspendSemaphore() const { return *suspend_; } - - //! Set this thread's affinity to the given cpu. - void setAffinity(uint cpu_id) const - { - Os::setThreadAffinity(handle_, cpu_id); - } - - //! Set this thread's affinity to the given cpu mask. - void setAffinity(const Os::ThreadAffinityMask& mask) const - { - Os::setThreadAffinity(handle_, mask); - } - - //! Yield to threads of the same priority of higher - static void yield() - { - Os::yield(); - } -}; - -class HostThread : public Thread -{ -private: - //! A HostThread does not have a run function - virtual void run(void* data) { ShouldNotCallThis(); } - -public: - //! Construct a new HostThread - HostThread(); - - //! Return true is this is the host thread. - bool isHostThread() const { return true; }; -}; - -/*! @} - * @} - */ - -namespace details { - -#if defined(__linux__) - -extern __thread Thread* thread_ __attribute__((tls_model("initial-exec"))); - -static inline Thread* -currentThread() -{ - return thread_; -} - -#elif defined(_WIN32) - -#if defined(USE_DECLSPEC_THREAD) -extern __declspec(thread) Thread* thread_; -#else // !USE_DECLSPEC_THREAD -extern DWORD threadIndex_; -#endif // !USE_DECLSPEC_THREAD - -static inline Thread* -currentThread() -{ -#if defined(USE_DECLSPEC_THREAD) - return thread_; -#else // !USE_DECLSPEC_THREAD - return (Thread*) TlsGetValue(threadIndex_); -#endif // !USE_DECLSPEC_THREAD -} - -#endif // _WIN32 - -} // namespace details - -inline Thread* -Thread::current() -{ - return details::currentThread(); -} - -} // namespace amd - -#endif /*THREAD_HPP_*/ diff --git a/rocclr/compiler/lib/promotions/oclutils/top.hpp b/rocclr/compiler/lib/promotions/oclutils/top.hpp deleted file mode 100644 index cc95b8ae89..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/top.hpp +++ /dev/null @@ -1,221 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef TOP_HPP_ -#define TOP_HPP_ - -#if defined(ATI_ARCH_ARM) -# define __EXPORTED_HEADERS__ 1 -#endif /*ATI_ARCH_ARM*/ - -#ifdef _WIN32 -#define NOMINMAX 1 -#define WIN32_LEAN_AND_MEAN 1 -#endif /*_WIN32*/ - -#include "utils/macros.hpp" -#if 0 // FIXME_lmoriche -#include "CL/opencl.h" -#include "amdocl/cl_open_video_amd.h" -#endif - -#ifdef _WIN32 -# include -#else /*!_WIN32*/ -# include -#endif /*!_WIN32*/ - -#if !defined(ATI_ARCH_ARM) -#include -#endif /*!ATI_ARCH_ARM*/ -#include -#include - -typedef unsigned char* address; -typedef const unsigned char* const_address; -typedef void * pointer; -typedef const void * const_pointer; -typedef unsigned int uint; -typedef unsigned long ulong; -typedef const char* cstring; - - -#ifdef _WIN32 -#if _MSC_VER >= 1600 -# include -#else // _MSC_VER < 1600 -typedef signed __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef signed __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef signed __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; -#endif // _MSC_VER < 1600 -#ifndef _WIN64 -typedef int32_t ssize_t; -#else // _WIN64 -typedef int64_t ssize_t; -#endif // _WIN64 -#endif /*_WIN32*/ - -#ifdef _WIN32 -# define SIZE_T_FMT "%Iu" -# define PTR_FMT "0x%p" -# if !defined(snprintf) -# define snprintf sprintf_s -# endif -#else /*!_WIN32*/ -# define SIZE_T_FMT "%zu" -# define PTR_FMT "%p" -#endif /*!_WIN32*/ - -typedef uint32_t cl_mem_fence_flags; - -//! \cond ignore -#define _BAD_INT32 0xBAADBAAD -#define _BAD_INT64 0XBAADBAADBAADBAADLL -#define _BAD_INTPTR LP64_SWITCH(_BAD_INT32,_BAD_INT64) - -const pointer badPointer = (pointer)(intptr_t) _BAD_INTPTR; -const address badAddress = (address)(intptr_t) _BAD_INTPTR; -//! \endcond - -const size_t Ki = 1024; -const size_t Mi = Ki*Ki; -const size_t Gi = Ki*Ki*Ki; - -const size_t K = 1000; -const size_t M = K*K; -const size_t G = K*K*K; - -#include "utils/debug.hpp" - -//! \addtogroup Utils - -//! Namespace for AMD's OpenCL platform -namespace amd {/*@{*/ - -//! \brief The default Null object type (!= void*); -struct Null {}; - -//! \brief Return a const Null object (null) -inline const Null null() { return Null(); } - -/*! \brief A struct to hold 2 objects of arbitrary type. - */ -template -struct pair -{ - F first; /*!< \brief first element. */ - S second; /*!< \brief second element. */ - - pair() : first(), second() { } - pair(const F& f, const S& s) : first(f), second(s) { } - - template - pair(const pair& p) : first(p.first), second(p.second) { } -}; - -template -inline pair -make_pair(F first, S second) -{ - return pair(first, second); -} - -/*! \brief Equivalent to a namespace (All member functions are static). - */ -class AllStatic -{ -WINDOWS_SWITCH(public,private): - AllStatic() { ShouldNotCallThis(); } - AllStatic(const AllStatic&) { ShouldNotCallThis(); } - ~AllStatic() { ShouldNotCallThis(); } -}; - -/*! \brief For embedded objects. - */ -class EmbeddedObject -{ -WINDOWS_SWITCH(public,private): - void* operator new(size_t) { ShouldNotCallThis(); return badPointer; } - void operator delete(void *) { ShouldNotCallThis(); } -}; - -/*! \brief For stack allocated objects. - */ -class StackObject -{ -WINDOWS_SWITCH(public,private): - void* operator new(size_t) { ShouldNotCallThis(); return badPointer; } - void operator delete(void *) { ShouldNotCallThis(); } -}; - -/*! \brief for objects allocated in a dedicate memory pool. - the standard 'new' should not be called, - only the in place version 'new (allocation_pointer) ()' - , delete should only invoke the destructors and not release memory - */ -class MemoryPoolObject -{ -public: - void* operator new(size_t) { ShouldNotCallThis(); return badPointer; } - void* operator new(size_t size,void * address) { return address; } - void operator delete(void *) { } - void operator delete( void *,void * address) { } -}; - -/*! \brief For objects allocated on the C-heap. - */ -class HeapObject -{ -public: - void* operator new(size_t size); - void operator delete(void* obj); -}; - -/*! \brief For all reference counted objects. - */ -class ReferenceCountedObject -{ - volatile uint referenceCount_; - -protected: - virtual ~ReferenceCountedObject() { } - virtual bool terminate() { return true; } - -public: - ReferenceCountedObject() : referenceCount_(1) { } - - void* operator new(size_t size) { return ::operator new(size); } - void operator delete(void* p) { return ::operator delete(p); } - - uint referenceCount() const { return referenceCount_; } - - uint retain(); - uint release(); -}; - -/*@}*/} // namespace amd - -#ifdef FOR_DOXYGEN_ONLY -namespace std -{ -template struct pair { F first; S second; }; -template struct vector { public: T data; }; -template class deque { public: T data; }; -template class list { public: T data; }; -template class slist { public: T data; }; -template class set { public: T data; }; -template class map { public: Key key; Data data; }; -} -#endif // FOR_DOXYGEN_ONLY - -#undef min // using std::min -#undef max // using std::max - -#endif /*TOP_HPP_*/ - diff --git a/rocclr/compiler/lib/promotions/oclutils/utils/debug.cpp b/rocclr/compiler/lib/promotions/oclutils/utils/debug.cpp deleted file mode 100644 index ef532eb8e2..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/utils/debug.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#include "top.hpp" -#include "utils/debug.hpp" -#include "os/os.hpp" - -#if !defined(LOG_LEVEL) -# include "utils/flags.hpp" -#endif - -#include -#include -#include - -#ifdef _WIN32 -#include -#endif // _WIN32 - -namespace amd { - -//! \cond ignore -extern "C" void -breakpoint(void) -{ -#ifdef _MSC_VER - DebugBreak(); -#endif // _MSC_VER -} -//! \endcond - -bool -ShouldBreak(LogLevel level) -{ - if ((level == LOG_WARNING && BREAK_ON_LOG_WARNING) - || (level == LOG_ERROR && BREAK_ON_LOG_ERROR)) { - return true; - } - return false; -} - -void -report_fatal(const char* file, int line, const char* message) -{ - // FIXME_lmoriche: Obfuscate the message string - fprintf(stderr, "%s:%d: %s\n", file, line, message); - ::abort(); -} - -void -report_warning(const char* message) -{ - fprintf(stderr, "Warning: %s\n", message); -} - -void -log_entry(LogLevel level, const char* file, int line, const char* message) -{ - if (level == LOG_NONE) { - return; - } - fprintf(stderr, ":%d:%s:%d: %s\n", level, file, line, message); -} - -void -log_timestamped(LogLevel level, const char* file, int line, const char* message) -{ - static bool gotstart = false; // not thread-safe, but not scary if fails - static uint64_t start; - - if (!gotstart) { - start = Os::timeNanos(); - gotstart = true; - } - - uint64_t time = Os::timeNanos() - start; - if (level == LOG_NONE) { - return; - } -#if 0 - fprintf(stderr, ":%d:%s:%d: (%010lld) %s\n", level, file, line, time, message); -#else // if you prefer fixed-width fields - fprintf(stderr, ":% 2d:%15s:% 5d: (%010lld) %s\n", - level, file, line, time/100ULL, message); // timestamp is 100ns units -#endif -} - -void -log_printf(LogLevel level, const char* file, int line, const char* format, ...) -{ - va_list ap; - - va_start(ap, format); - char message[1024]; - vsprintf(message, format, ap); - va_end(ap); - - fprintf(stderr, ":%d:%s:%d: %s\n", level, file, line, message); -} - -} // namespace amd diff --git a/rocclr/compiler/lib/promotions/oclutils/utils/debug.hpp b/rocclr/compiler/lib/promotions/oclutils/utils/debug.hpp deleted file mode 100644 index c5cb91f8f0..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/utils/debug.hpp +++ /dev/null @@ -1,182 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef DEBUG_HPP_ -#define DEBUG_HPP_ - - -#include - -//! \addtogroup Utils - -namespace amd {/*@{*/ - -enum LogLevel { - LOG_NONE = 0, - LOG_ERROR = 1, - LOG_WARNING = 2, - LOG_INFO = 3, - LOG_DEBUG = 4 -}; - -//! \cond ignore -extern "C" void -breakpoint(); -//! \endcond - -//! \brief Report a Fatal exception message and abort. -extern void -report_fatal(const char* file, int line, const char* message); - -//! \brief Display a warning message. -extern void -report_warning(const char* message); - -//! \brief Insert a log entry. -extern void -log_entry(LogLevel level, const char* file, int line, const char* messsage); - -//! \brief Insert a timestamped log entry. -extern void -log_timestamped(LogLevel level, const char* file, int line, const char* messsage); - -//! \brief Insert a printf-style log entry. -extern void -log_printf( - LogLevel level, - const char* file, - int line, - const char* format, - ...); - -/*@}*/} // namespace amd - -#if __INTEL_COMPILER - -// Disable ICC's warning #279: controlling expression is constant -// (0!=1 && "msg") -// ^ -#pragma warning ( disable : 279 ) - -#endif // __INTEL_COMPILER - -//! \brief Abort the program if the invariant \a cond is false. -#define guarantee(cond) \ - if (!(cond)) \ - { \ - amd::report_fatal(__FILE__, __LINE__, \ - "guarantee(" XSTR(cond) ")"); \ - amd::breakpoint(); \ - } - -#define fixme_guarantee(cond) guarantee(cond) - -//! \brief Abort the program with a fatal error message. -#define fatal(msg) do { assert(false && msg); } while (0) - - -//! \brief Display a warning message. -inline void -warning(const char* msg) -{ - amd::report_warning(msg); -} - -/*! \brief Abort the program with a "ShouldNotReachHere" message. - * \hideinitializer - */ -#define ShouldNotReachHere() fatal("ShouldNotReachHere()") - -/*! \brief Abort the program with a "ShouldNotCallThis" message. - * \hideinitializer - */ -#define ShouldNotCallThis() fatal("ShouldNotCallThis()") - -/*! \brief Abort the program with an "Unimplemented" message. - * \hideinitializer - */ -#define Unimplemented() fatal("Unimplemented()") - -/*! \brief Display an "Untested" warning message. - * \hideinitializer - */ -#ifndef NDEBUG -# define Untested(msg) \ - warning("Untested(\"" msg "\")") -#else /*NDEBUG*/ -# define Untested(msg) (void)(0) -#endif /*NDEBUG*/ - -#ifdef DEBUG -namespace amd { -extern bool ShouldBreak(LogLevel level); -} // namespace amd -#endif // DEBUG - -#ifdef DEBUG -# define Log(level,msg) \ -do \ -{ \ - if (LOG_LEVEL >= level) { \ - amd::log_entry(level, __FILE__, __LINE__, msg); \ - if (amd::ShouldBreak(level)) { \ - amd::breakpoint(); \ - } \ - } \ -} while (false) -#else // !DEBUG -# define Log(level,msg) (void)(0) -#endif // !DEBUG - -#ifdef DEBUG -# define LogTS(level,msg) \ -do \ -{ \ - if (LOG_LEVEL >= level) { \ - amd::log_timestamped(level, __FILE__, __LINE__, msg); \ - if (amd::ShouldBreak(level)) { \ - amd::breakpoint(); \ - } \ - } \ -} while (false) -#else // !DEBUG -# define Log(level,msg) (void)(0) -#endif // !DEBUG - -#ifdef DEBUG -# define Logf(level, format, ...) \ -do \ -{ \ - if (LOG_LEVEL >= level) { \ - amd::log_printf(level, __FILE__, __LINE__, format, __VA_ARGS__); \ - if (amd::ShouldBreak(level)) { \ - amd::breakpoint(); \ - } \ - } \ -} while (false) -#else // !DEBUG -# define Logf(level, format, ...) (void)(0) -#endif // !DEBUG - -#define CondLog(cond,msg) \ -do { \ - if (false DEBUG_ONLY(|| (cond))) { \ - Log(amd::LOG_INFO,msg); \ - } \ -} while (false) - -#define LogInfo(msg) Log(amd::LOG_INFO,msg) -#define LogError(msg) Log(amd::LOG_ERROR,msg) -#define LogWarning(msg) Log(amd::LOG_WARNING,msg) - -#define LogTSInfo(msg) LogTS(amd::LOG_INFO,msg) -#define LogTSError(msg) LogTS(amd::LOG_ERROR,msg) -#define LogTSWarning(msg) LogTS(amd::LOG_WARNING,msg) - -#define LogPrintfDebug(format, ...) Logf(amd::LOG_DEBUG, format, __VA_ARGS__) -#define LogPrintfError(format, ...) Logf(amd::LOG_ERROR, format, __VA_ARGS__) -#define LogPrintfWarning(format, ...) Logf(amd::LOG_WARNING, format, __VA_ARGS__) -#define LogPrintfInfo(format, ...) Logf(amd::LOG_INFO, format, __VA_ARGS__) - -#endif /*DEBUG_HPP_*/ diff --git a/rocclr/compiler/lib/promotions/oclutils/utils/macros.hpp b/rocclr/compiler/lib/promotions/oclutils/utils/macros.hpp deleted file mode 100644 index d3cb6a2b60..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/utils/macros.hpp +++ /dev/null @@ -1,177 +0,0 @@ -// -// Copyright (c) 2011 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef MACROS_HPP_ -#define MACROS_HPP_ - -#ifndef OPENCL_EXPORTS -# define OPENCL_EXPORTS 1 -#endif // OPENCL_EXPORTS - -#if defined(NDEBUG) -# define RELEASE 1 -#else// !NDEBUG -# define ASSERT 1 -# define DEBUG 1 -#endif // !NDEBUG - -#if defined(_WIN64) && !defined(_LP64) -# define _LP64 1 -#endif - -#if defined(_DEBUG) && !defined(DEBUG) -# define DEBUG 1 -#endif // _DEBUG && !DEBUG - -#if defined(DEBUG) && defined(RELEASE) -# error "Build Error: cannot have both -DDEBUG and -DRELEASE" -#endif /*DEBUG && RELEASE*/ - -#if !defined(DEBUG) && !defined(RELEASE) -# error "Build Error: must have either -DDEBUG or -DRELEASE" -#endif /*DEBUG && RELEASE*/ - -#ifdef DEBUG -# define DEBUG_ONLY(x) x -# define RELEASE_ONLY(x) -# define IS_DEBUG true -#else // !DEBUG -# define DEBUG_ONLY(x) -# define RELEASE_ONLY(x) x -# define IS_DEBUG false -#endif /*!DEBUG*/ -#define DEBUG_SWITCH(d,r) DEBUG_ONLY(d)RELEASE_ONLY(r) -#define RELEASE_SWITCH(r,d) RELEASE_ONLY(r)DEBUG_ONLY(d) - -//! \brief Make a c-string of __macro__ -#define STR(__macro__) #__macro__ -//! \brief Make a c-string of the expansion of __macro__ -#define XSTR(__macro__) STR(__macro__) -//! \brief Concatenate 2 symbols -#define CONCAT(a,b) a##b -#define XCONCAT(a,b) CONCAT(a,b) - - -//! \cond ignore -#ifdef _LP64 -# define LP64_ONLY(x) x -# define NOT_LP64(x) -#else // !_LP64 -# define LP64_ONLY(x) -# define NOT_LP64(x) x -#endif /*!_LP64*/ -#define LP64_SWITCH(lp32,lp64) NOT_LP64(lp32)LP64_ONLY(lp64) - -#ifdef __linux__ -# define IS_LINUX true -# define LINUX_ONLY(x) x -# define NOT_LINUX(x) -#else // !__linux__ -# define LINUX_ONLY(x) -# define NOT_LINUX(x) x -#endif /*!__linux__*/ - -#ifdef __APPLE__ -# define IS_MACOS true -# define MACOS_ONLY(x) x -# define NOT_MACOS(x) -#else // !__APPLE__ -# define MACOS_ONLY(x) -# define NOT_MACOS(x) x -#endif /*!__APPLE__*/ - -#ifdef _WIN32 -# define IS_WINDOWS true -# define WINDOWS_ONLY(x) x -# define NOT_WINDOWS(x) -#else // !_WIN32 -# define WINDOWS_ONLY(x) -# define NOT_WINDOWS(x) x -#endif /*!_WIN32*/ - -#ifdef _WIN64 -# define WIN64_ONLY(x) x -# define NOT_WIN64(x) -#else // !_WIN64 -# define WIN64_ONLY(x) -# define NOT_WIN64(x) x -#endif /*!_WIN64*/ - -#ifndef IS_LINUX -# define IS_LINUX false -#endif -#ifndef IS_MACOS -# define IS_MACOS false -#endif -#ifndef IS_WINDOWS -# define IS_WINDOWS false -#endif - -#define IF_LEFT_true(x) x -#define IF_LEFT_false(x) -#define IF_RIGHT_true(x) -#define IF_RIGHT_false(x) x - -#define IF_LEFT(cond,x) IF_LEFT_##cond(x) -#define IF_RIGHT(cond,x) IF_RIGHT_##cond(x) -#define IF(cond,x,y) IF_LEFT(cond,x)IF_RIGHT(cond,y) - -#define LINUX_SWITCH(x,other) LINUX_ONLY(x)NOT_LINUX(other) -#define MACOS_SWITCH(x,other) MACOS_ONLY(x)NOT_MACOS(other) -#define WINDOWS_SWITCH(x,other) WINDOWS_ONLY(x)NOT_WINDOWS(other) - -#ifdef OPENCL_MAINLINE -# define IS_MAINLINE true -#else // OPENCL_STAGING -# define IS_MAINLINE false -#endif - -#ifdef OPTIMIZED -# define OPTIMIZED_ONLY(x) x -# define NOT_OPTIMIZED(x) -# define IS_OPTIMIZED true -#else -# define OPTIMIZED_ONLY(x) -# define NOT_OPTIMIZED(x) x -# define IS_OPTIMIZED false -#endif - -#if defined(__GNUC__) -# define __ALIGNED__(x) __attribute__((aligned(x))) -#elif defined(_MSC_VER) -# define __ALIGNED__(x) __declspec(align(x)) -#elif defined(RC_INVOKED) -# define __ALIGNED__(x) -#else -# error -#endif /*_MSC_VER*/ - -#if defined(__GNUC__) -# define likely(cond) __builtin_expect(!!(cond), 1) -# define unlikely(cond) __builtin_expect(!!(cond), 0) -#else // !__GNUC__ -# define likely(cond) (cond) -# define unlikely(cond) (cond) -#endif // !__GNUC__ - -#if defined(__GNUC__) -# define NOINLINE __attribute__((noinline)) -# define ALWAYSINLINE __attribute__ ((always_inline)) -#elif defined(_MSC_VER) -# define NOINLINE __declspec(noinline) -# define ALWAYSINLINE __forceinline -#else // !_MSC_VER -# define NOINLINE -# define ALWAYSINLINE -#endif // !_MSC_VER - -#ifdef BRAHMA -# define IS_BRAHMA true -#else -# define IS_BRAHMA false -#endif - -//! \endcond - -#endif // MACROS_HPP_ diff --git a/rocclr/compiler/lib/promotions/oclutils/utils/util.hpp b/rocclr/compiler/lib/promotions/oclutils/utils/util.hpp deleted file mode 100644 index efe0d41288..0000000000 --- a/rocclr/compiler/lib/promotions/oclutils/utils/util.hpp +++ /dev/null @@ -1,281 +0,0 @@ -// -// Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. -// - -#ifndef UTIL_HPP_ -#define UTIL_HPP_ - -#include "top.hpp" - -#include -#include - -namespace amd { - -/*! \addtogroup Utils Utilities - * @{ - */ - -//! \brief Check if the given value \a val is a power of 2. -template -static inline bool -isPowerOfTwo(T val) -{ - return (val & (val - 1)) == 0; -} - -//! \cond ignore - -// Compute the next power of 2 helper. -template -struct NextPowerOfTwoFunction -{ - template - static T compute(T val) - { - val = NextPowerOfTwoFunction::compute(val); - return (val >> N) | val; - } -}; - -// Specialized version for <1> to break the recursion. -template <> -struct NextPowerOfTwoFunction<1> -{ - template - static T compute(T val) { return (val >> 1) | val; } -}; - -template -struct NextPowerOfTwoHelper -{ - static const uint prev = NextPowerOfTwoHelper::value; - static const uint value = (prev >> S) | prev; -}; -template -struct NextPowerOfTwoHelper -{ - static const int value = (N >> 1) | N; -}; - -template -struct NextPowerOfTwo -{ - static const uint value = NextPowerOfTwoHelper::value + 1; -}; - -//! \endcond - -/*! \brief Return the next power of two for a value of type T. - * - * The compute function is (with n = sizeof(T)*8): - * - * val = (val >> 1) | val; - * val = (val >> 2) | val; - * ... - * val = (val >> n/4) | val; - * val = (val >> n/2) | val; - * - * The next power of two is: 1+compute(val-1) - */ -template -inline T -nextPowerOfTwo(T val) -{ - return NextPowerOfTwoFunction::compute(val - 1) + 1; -} - -// Compute log2(N) -template -struct Log2 -{ - static const uint value = Log2::value + 1; -}; - -// Break the recursion -template <> -struct Log2<1> -{ - static const uint value = 0; -}; - -/*! \brief Return the log2 for a value of type T. - * - * The compute function is (with n = sizeof(T)*8): - * - * uint l = 0; - * if (val >= 1 << n/2) { val >>= n/2; l |= n/2; } - * if (val >= 1 << n/4) { val >>= n/4; l |= n/4; } - * ... - * if (val >= 1 << 2) { val >>= 2; l |= 2; } - * if (val >= 1 << 1) { l |= 1; } - * return l; - */ -template -struct Log2Function -{ - template - static uint compute(T val) - { - uint l = 0; - if (val >= T(1) << N) { - val >>= N; l = N; - } - return l + Log2Function::compute(val); - } -}; - -template <> -struct Log2Function<1> -{ - template - static uint compute(T val) { - return (val >= T(1)<<1) ? 1 : 0; - } -}; - -// log2 helper function -template -inline uint -log2(T val) -{ - return Log2Function::compute(val); -} - -template -inline T -alignDown(T value, size_t alignment) -{ - return (T) (value & ~(alignment - 1)); -} - -template -inline T* -alignDown(T* value, size_t alignment) -{ - return (T*) alignDown((intptr_t) value, alignment); -} - -template -inline T -alignUp(T value, size_t alignment) -{ - return alignDown((T) (value + alignment - 1), alignment); -} - -template -inline T* -alignUp(T* value, size_t alignment) -{ - return (T*) alignDown((intptr_t) (value + alignment - 1), alignment); -} - -template -inline bool isMultipleOf(T value, size_t alignment) -{ - if (isPowerOfTwo(alignment)) { - // fast path, using logical operators - return alignUp(value, alignment) == value; - } - return value % alignment == 0; -} - -template -inline bool isMultipleOf(T* value, size_t alignment) -{ - intptr_t ptr = reinterpret_cast(value); - return isMultipleOf(ptr, alignment); -} - -template -struct DeviceMap { - Reference ref_; - Value value_; -}; - - -inline uint -countBitsSet32(uint32_t value) -{ -#if __GNUC__ >= 4 - return (uint)__builtin_popcount(value); -#else - value = value - ((value >> 1) & 0x55555555); - value = (value & 0x33333333) + ((value >> 2) & 0x33333333); - return (uint)(((value + (value >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); -#endif -} - -inline uint -countBitsSet64(uint64_t value) -{ -#if __GNUC__ >= 4 - return (uint)__builtin_popcountll(value); -#else - value = value - ((value >> 1) & 0x5555555555555555ULL); - value = (value & 0x3333333333333333ULL) + ((value >> 2) & 0x3333333333333333ULL); - value = (value + (value >> 4)) & 0x0F0F0F0F0F0F0F0FULL; - return (uint)((uint64_t)(value * 0x0101010101010101ULL) >> 56); -#endif -} - -inline uint -leastBitSet32(uint32_t value) -{ -#if defined(_WIN32) - unsigned long idx; - return _BitScanForward(&idx, (unsigned long)value) ? idx : (uint)-1; -#else - return value ? __builtin_ctz(value) : (uint)-1; -#endif -} - -inline uint -leastBitSet64(uint64_t value) -{ -#if defined(_WIN64) - unsigned long idx; - return _BitScanForward64(&idx, (unsigned __int64)value) ? idx : (uint)-1; -#elif defined (__GNUC__) - return value ? __builtin_ctzll(value) : (uint)-1; -#else - static const uint8_t lookup67[67+1] = { - 64, 0, 1, 39, 2, 15, 40, 23, - 3, 12, 16, 59, 41, 19, 24, 54, - 4, -1, 13, 10, 17, 62, 60, 28, - 42, 30, 20, 51, 25, 44, 55, 47, - 5, 32, -1, 38, 14, 22, 11, 58, - 18, 53, 63, 9, 61, 27, 29, 50, - 43, 46, 31, 37, 21, 57, 52, 8, - 26, 49, 45, 36, 56, 7, 48, 35, - 6, 34, 33, -1 - }; - - return (uint)lookup67[((int64_t)value & -(int64_t)value) % 67]; -#endif -} - -template -inline uint countBitsSet(T value) -{ - return (sizeof(T) == 8) ? countBitsSet64((uint64_t)value) : - countBitsSet32((uint32_t)value); -} - -template -inline uint leastBitSet(T value) -{ - return (sizeof(T) == 8) ? leastBitSet64((uint64_t)value) : - leastBitSet32((uint32_t)value); -} - -static inline bool Is32Bits() { - return LP64_SWITCH(true, false); -} - -static inline bool Is64Bits() { - return LP64_SWITCH(false, true); -} -/*@}*/} // namespace amd - -#endif /*UTIL_HPP_*/ diff --git a/rocclr/runtime/utils/debug.cpp b/rocclr/runtime/utils/debug.cpp index ef532eb8e2..c8a4ada784 100644 --- a/rocclr/runtime/utils/debug.cpp +++ b/rocclr/runtime/utils/debug.cpp @@ -30,16 +30,6 @@ breakpoint(void) } //! \endcond -bool -ShouldBreak(LogLevel level) -{ - if ((level == LOG_WARNING && BREAK_ON_LOG_WARNING) - || (level == LOG_ERROR && BREAK_ON_LOG_ERROR)) { - return true; - } - return false; -} - void report_fatal(const char* file, int line, const char* message) { diff --git a/rocclr/runtime/utils/debug.hpp b/rocclr/runtime/utils/debug.hpp index c5cb91f8f0..cb7dbb7b99 100644 --- a/rocclr/runtime/utils/debug.hpp +++ b/rocclr/runtime/utils/debug.hpp @@ -108,21 +108,12 @@ warning(const char* msg) # define Untested(msg) (void)(0) #endif /*NDEBUG*/ -#ifdef DEBUG -namespace amd { -extern bool ShouldBreak(LogLevel level); -} // namespace amd -#endif // DEBUG - #ifdef DEBUG # define Log(level,msg) \ do \ { \ if (LOG_LEVEL >= level) { \ amd::log_entry(level, __FILE__, __LINE__, msg); \ - if (amd::ShouldBreak(level)) { \ - amd::breakpoint(); \ - } \ } \ } while (false) #else // !DEBUG @@ -135,9 +126,6 @@ do \ { \ if (LOG_LEVEL >= level) { \ amd::log_timestamped(level, __FILE__, __LINE__, msg); \ - if (amd::ShouldBreak(level)) { \ - amd::breakpoint(); \ - } \ } \ } while (false) #else // !DEBUG @@ -150,9 +138,6 @@ do \ { \ if (LOG_LEVEL >= level) { \ amd::log_printf(level, __FILE__, __LINE__, format, __VA_ARGS__); \ - if (amd::ShouldBreak(level)) { \ - amd::breakpoint(); \ - } \ } \ } while (false) #else // !DEBUG diff --git a/rocclr/runtime/utils/flags.hpp b/rocclr/runtime/utils/flags.hpp index 4957ff304a..22de406d47 100644 --- a/rocclr/runtime/utils/flags.hpp +++ b/rocclr/runtime/utils/flags.hpp @@ -10,10 +10,6 @@ \ debug(int, LOG_LEVEL, 0, \ "The default log level") \ -debug(bool, BREAK_ON_LOG_WARNING, false, \ - "Break each time an error is logged") \ -debug(bool, BREAK_ON_LOG_ERROR, false, \ - "Break each time an error is logged") \ debug(uint, DEBUG_GPU_FLAGS, 0, \ "The debug options for GPU device") \ debug(uint, GPU_MAX_COMMAND_QUEUES, 70, \