// // Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. // #include "platform/runtime.hpp" #include "os/os.hpp" #include "thread/thread.hpp" #include "device/device.hpp" #include "utils/flags.hpp" #include "utils/options.hpp" #include "platform/context.hpp" #include "platform/agent.hpp" #include "amdocl/cl_gl_amd.hpp" #ifdef _WIN32 #include #include #include "CL/cl_d3d10.h" #endif //_WIN32 #if defined(_MSC_VER) // both Win32 and Win64 #include #endif #include #include #include namespace amd { volatile bool Runtime::initialized_ = false; bool Runtime::init() { if (initialized_) { return true; } // Enter a very basic critical region. We want to prevent 2 threads // from concurrently executing the init() routines. We can't use a // Monitor since the system is not yet initialized. static std::atomic_flag lock = ATOMIC_FLAG_INIT; struct CriticalRegion { std::atomic_flag& lock_; CriticalRegion(std::atomic_flag& lock) : lock_(lock) { while (lock.test_and_set(std::memory_order_acquire)) { Os::yield(); } } ~CriticalRegion() { lock_.clear(std::memory_order_release); } } region(lock); if (initialized_) { return true; } if (!Flag::init() || !option::init() || !Device::init() // Agent initializes last || !Agent::init()) { return false; } initialized_ = true; return true; } void Runtime::tearDown() { if (!initialized_) { return; } Agent::tearDown(); Device::tearDown(); option::teardown(); Flag::tearDown(); initialized_ = false; } class RuntimeTearDown : public amd::HeapObject { public: RuntimeTearDown() {} ~RuntimeTearDown() { /*Runtime::tearDown();*/ } } runtime_tear_down; uint ReferenceCountedObject::retain() { return ++make_atomic(referenceCount_); } uint ReferenceCountedObject::release() { uint newCount = --make_atomic(referenceCount_); if (newCount == 0) { if (terminate()) { delete this; } } return newCount; } #ifdef _WIN32 #ifdef DEBUG static int reportHook(int reportType, char* message, int* returnValue) { if (returnValue) { *returnValue = 1; } std::cerr << message; ::exit(3); return TRUE; } #endif // DEBUG extern "C" BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: #ifdef DEBUG if (!::getenv("AMD_OCL_ENABLE_MESSAGE_BOX")) { _CrtSetReportHook(reportHook); _set_error_mode(_OUT_TO_STDERR); } #endif // DEBUG break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_DETACH: { amd::Thread* thread = amd::Thread::current(); delete thread; } break; default: break; } return true; } #endif } // namespace amd