From dc1f0c4c0096013799416664894c5194dc7e1f52 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Fri, 28 Feb 2025 23:13:39 +0800 Subject: chore(store): move everything to store. --- .../life/operating-system-experiment/Thread.cpp | 158 +++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 store/works/life/operating-system-experiment/Thread.cpp (limited to 'store/works/life/operating-system-experiment/Thread.cpp') diff --git a/store/works/life/operating-system-experiment/Thread.cpp b/store/works/life/operating-system-experiment/Thread.cpp new file mode 100644 index 0000000..0bc4c18 --- /dev/null +++ b/store/works/life/operating-system-experiment/Thread.cpp @@ -0,0 +1,158 @@ +#include "Thread.h" + +#include +#include +#include + +namespace cru { +Thread::Thread(Thread &&other) noexcept + : detached_(other.detached_), joined_(other.joined_), +#ifdef CRU_WINDOWS + thread_handle_(other.thread_handle_) +#else + thread_(std::move(other.thread_)) +#endif +{ + other.joined_ = false; +#ifdef CRU_WINDOWS + other.thread_handle_ = nullptr; +#endif +} // namespace cru + +Thread &Thread::operator=(Thread &&other) noexcept { + if (this != &other) { + detached_ = other.detached_; + joined_ = other.joined_; +#ifdef CRU_WINDOWS + thread_handle_ = other.thread_handle_; + other.thread_handle_ = nullptr; +#else + thread_ = std::move(other.thread_); +#endif + other.detached_ = false; + other.joined_ = false; + } + + return *this; +} + +Thread::~Thread() { Destroy(); } + +void Thread::Join() { + joined_ = true; +#ifdef CRU_WINDOWS + assert(thread_handle_); + WaitForSingleObject(thread_handle_, INFINITE); +#else + assert(thread_); + auto c = pthread_join(*thread_, nullptr); + assert(c == 0); +#endif +} + +void Thread::Detach() { +#ifdef CRU_WINDOWS + assert(thread_handle_); +#else + assert(thread_); +#endif + detached_ = true; +} + +#ifdef CRU_WINDOWS +DWORD +#else +pthread_t +#endif +Thread::GetNativeID() { +#ifdef CRU_WINDOWS + assert(thread_handle_); + return thread_id_; +#else + assert(thread_); + return *thread_; +#endif +} + +#ifdef CRU_WINDOWS +HANDLE +#else +pthread_t +#endif +Thread::GetNativeHandle() { +#ifdef CRU_WINDOWS + assert(thread_handle_); + return thread_handle_; +#else + assert(thread_); + return *thread_; +#endif +} + +void Thread::swap(Thread &other) noexcept { +#ifdef CRU_WINDOWS + Thread temp = std::move(*this); + *this = std::move(other); + other = std::move(temp); +#else +#endif +} + +void Thread::Destroy() noexcept { + if (!detached_ && !joined_ && +#ifdef CRU_WINDOWS + thread_handle_ != nullptr +#else + thread_ != nullptr +#endif + ) { + std::terminate(); + } else { + detached_ = false; + joined_ = false; +#ifdef CRU_WINDOWS + thread_id_ = 0; + if (thread_handle_ != nullptr) { + auto c = CloseHandle(thread_handle_); + assert(c); + thread_handle_ = nullptr; + } +#else + thread_ = nullptr; +#endif + } +} + +namespace { +#ifdef CRU_WINDOWS +DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter) { + auto p = static_cast *>(lpParameter); + (*p)(); + delete p; + return 0; +} +#else +void *ThreadProc(void *data) { + auto p = static_cast *>(data); + (*p)(); + delete p; + return nullptr; +} + +#endif +} // namespace + +void Thread::CreateThread(std::function *proc) { +#ifdef CRU_WINDOWS + thread_handle_ = ::CreateThread(nullptr, 0, ThreadProc, + static_cast(proc), 0, &thread_id_); + assert(thread_handle_); +#else + thread_.reset(new pthread_t()); + auto c = pthread_create(thread_.get(), nullptr, ThreadProc, + static_cast(proc)); + assert(c == 0); +#endif +}; + +} // namespace cru \ No newline at end of file -- cgit v1.2.3