void DeterministicSchedule::join(std::thread& child) { auto sched = tls_sched; if (sched) { bool done = false; while (!done) { beforeSharedAccess(); done = !sched->active_.count(child.get_id()); if (done) { FOLLY_TEST_DSCHED_VLOG("joined " << std::hex << child.get_id()); } afterSharedAccess(); } } child.join(); }
_R sync(_Function& work, const _Args&... args) { if (std::this_thread::get_id() != thread_.get_id()) { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (!is_running_) { throw std::runtime_error("Not running"); } std::promise<_R> promise; { std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back([&promise, &work, &args...]() { try { promise.set_value(work(args...)); } catch (...) { promise.set_exception(std::current_exception()); } }); workable_.notify_all(); } // Make sync return promise.get_future().get(); } else { if (!is_running_) { throw std::runtime_error("Not running"); } return work(args...); } }
~async_message_loop() { if(thread.get_id() != std::thread::id()){ DWORD id = ::GetThreadId(thread.native_handle()); ::PostThreadMessageW(id, WM_QUIT, 0, 0); thread.join(); } }
bool start_message_loop() { if(thread.get_id() != std::thread::id()) return false; thread = std::thread([this](){ if(::CoInitialize(nullptr)) return; ::quote::win32::message_loop([this](){ if(queue.empty()){ ::Sleep(1); return; } std::shared_ptr<async_message> message; if(queue.try_pop(message)){ switch(message->message){ case async_message::message_type::create: { auto param = reinterpret_cast<creation_params*>(message->data.get()); HWND hwnd = ::CreateWindowExW( param->exstyle, param->classname, param->title, param->style, param->x, param->y, param->w, param->h, param->hparent, nullptr, ::GetModuleHandleW(nullptr), param->data); message->result = hwnd != nullptr; std::lock_guard<std::mutex> lock(message->mutex); message->cv.notify_one(); } break; case async_message::message_type::destroy: { message->result = ::DestroyWindow(reinterpret_cast<HWND>(message->data.get())) != 0; std::lock_guard<std::mutex> lock(message->mutex); message->cv.notify_one(); } break; } } }); ::CoUninitialize(); }); return true; }
// Helper function for cleaning up the thread in use inline void cleanupThread(std::thread &t) { if (t.joinable()) { t.join(); } else if (t.get_id() != std::thread::id()) { t.detach(); } }
bool IsGPUThread() { const SConfig& _CoreParameter = SConfig::GetInstance(); if (_CoreParameter.bCPUThread) { return (s_emu_thread.joinable() && (s_emu_thread.get_id() == std::this_thread::get_id())); } else { return IsCPUThread(); } }
void stop() { if (mThread.get_id() != std::thread::id()) { mQuit.store(true); mThread.join(); } alSourceRewind(mSource); alSourcei(mSource, AL_BUFFER, 0); mBufferIdx = 0; }
static inline void set_affinity(std::thread &t, int n) { if(t.get_id() == std::thread::id()) throw std::runtime_error("thread not running"); cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(n, &cpuset); auto pth = t.native_handle(); if ( ::pthread_setaffinity_np(pth, sizeof(cpuset), &cpuset) != 0) throw std::runtime_error("pthread_setaffinity_np"); }
bool IsGPUThread() { const SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; if (_CoreParameter.bCPUThread) { return (g_EmuThread.joinable() && (g_EmuThread.get_id() == std::this_thread::get_id())); } else { return IsCPUThread(); } }
void async(std::function<void(void)>&& work) { if (std::this_thread::get_id() != thread_.get_id()) { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (!is_running_) { return; } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back(work); workable_.notify_all(); } else { if (!is_running_) { return; } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back(work); workable_.notify_all(); } }
~OpenALStream() { if (mThread.get_id() != std::thread::id()) { /* Tell the thread to quit and wait for it to stop. */ mQuit.store(true); mThread.join(); } if (mSource) { /* Stop the source, remove the buffers, then put it back so it can * be used again. */ alSourceRewind(mSource); alSourcei(mSource, AL_BUFFER, 0); mManager->mFreeSources.push_front(mSource); } /* Delete the buffers used for the queue. */ alDeleteBuffers(static_cast<ALsizei>(mBuffers.size()), mBuffers.data()); }
void play() { /* If the source is already playing (thread exists and isn't stopped), * don't do anything. */ if (mThread.get_id() != std::thread::id()) { if (!mQuit.load()) return; mThread.join(); } /* Reset the source and clear any buffers that may be on it. */ alSourceRewind(mSource); alSourcei(mSource, AL_BUFFER, 0); mBufferIdx = 0; mQuit.store(false); /* Start the background thread processing. */ mThread = std::thread(std::mem_fn(&OpenALStream::backgroundProc), this); }
std::future<void> async(_Function&& work, _Args&&... args) { auto promise_ptr = std::make_shared<std::promise<void>>(); do { if (std::this_thread::get_id() != thread_.get_id()) { std::lock_guard<std::recursive_mutex> api_lock(api_mutex_); if (!is_running_) { throw std::runtime_error("Not running"); } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back([=]() { try { work(args...); promise_ptr->set_value(); } catch (...) { promise_ptr->set_exception(std::current_exception()); } }); workable_.notify_all(); } else { if (!is_running_) { throw std::runtime_error("Not running"); } std::lock_guard<std::mutex> lock(works_mutex_); works_.push_back([=]() { try { work(args...); promise_ptr->set_value(); } catch (...) { promise_ptr->set_exception(std::current_exception()); } }); workable_.notify_all(); } } while (0); return promise_ptr->get_future(); }
bool IsCPUThread() { return (s_cpu_thread.joinable() ? (s_cpu_thread.get_id() == std::this_thread::get_id()) : !s_is_started); }
bool IsCPUThread() { return (g_cpu_thread.joinable() ? (g_cpu_thread.get_id() == std::this_thread::get_id()) : !g_bStarted); }
std::thread::id get_id() const { return t_.get_id(); }