diff options
author | crupest <crupest@outlook.com> | 2021-06-09 22:28:01 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-06-09 22:28:01 +0800 |
commit | 8bdb5db67fa3eeda755511f91fd257bde548a18f (patch) | |
tree | 2f8bdc79c6106c8cd4500113b8dd764316bf9896 | |
parent | d42dfdf4b903763997d47b6e2214c2ce33b9bf8e (diff) | |
download | crupest-8bdb5db67fa3eeda755511f91fd257bde548a18f.tar.gz crupest-8bdb5db67fa3eeda755511f91fd257bde548a18f.tar.bz2 crupest-8bdb5db67fa3eeda755511f91fd257bde548a18f.zip |
import(life): ...
-rw-r--r-- | works/life/operating-system-experiment/Base.h | 4 | ||||
-rw-r--r-- | works/life/operating-system-experiment/CMakeLists.txt | 4 | ||||
-rw-r--r-- | works/life/operating-system-experiment/Thread.cpp | 53 | ||||
-rw-r--r-- | works/life/operating-system-experiment/Thread.h | 17 |
4 files changed, 69 insertions, 9 deletions
diff --git a/works/life/operating-system-experiment/Base.h b/works/life/operating-system-experiment/Base.h index b3ac1ee..6964c1c 100644 --- a/works/life/operating-system-experiment/Base.h +++ b/works/life/operating-system-experiment/Base.h @@ -6,10 +6,6 @@ #endif
#ifdef CRU_WINDOWS
-#include <Windows.h>
-#endif
-
-#ifdef CRU_WINDOWS
#ifdef CRU_EXPORT_API
#define CRU_API __declspec(dllexport)
#else
diff --git a/works/life/operating-system-experiment/CMakeLists.txt b/works/life/operating-system-experiment/CMakeLists.txt index 2c46b0f..540574b 100644 --- a/works/life/operating-system-experiment/CMakeLists.txt +++ b/works/life/operating-system-experiment/CMakeLists.txt @@ -12,6 +12,10 @@ find_package(Microsoft.GSL CONFIG REQUIRED) add_library(cru_system SHARED Thread.cpp)
target_link_libraries(cru_system PUBLIC Microsoft.GSL::GSL fmt::fmt)
target_compile_definitions(cru_system PUBLIC CRU_EXPORT_API)
+if(UNIX)
+target_link_libraries(cru_system PUBLIC pthread)
+endif()
+
add_executable(main main.cpp)
target_link_libraries(main PRIVATE cru_system)
\ No newline at end of file diff --git a/works/life/operating-system-experiment/Thread.cpp b/works/life/operating-system-experiment/Thread.cpp index b91ca69..8230c1c 100644 --- a/works/life/operating-system-experiment/Thread.cpp +++ b/works/life/operating-system-experiment/Thread.cpp @@ -2,21 +2,36 @@ #include <cassert>
#include <exception>
+#include <pthread.h>
#include <utility>
namespace cru {
Thread::Thread(Thread &&other) noexcept
- : joined_(other.joined_), thread_handle_(other.thread_handle_) {
+ : 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.joined_ = false;
other.thread_handle_ = nullptr;
+#else
+ thread_ = std::move(other.thread_);
+#endif
+ other.detached_ = false;
+ other.joined_ = false;
}
return *this;
@@ -25,13 +40,23 @@ Thread &Thread::operator=(Thread &&other) noexcept { Thread::~Thread() { Destroy(); }
void Thread::Join() {
- assert(thread_handle_);
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;
}
@@ -45,11 +70,22 @@ void Thread::swap(Thread &other) noexcept { }
void Thread::Destroy() noexcept {
- if (!detached_ && !joined_ && thread_handle_ != nullptr) {
+ if (!detached_ && !joined_ &&
+#ifdef CRU_WINDOWS
+ thread_handle_ != nullptr
+#else
+ thread_ != nullptr
+#endif
+ ) {
std::terminate();
} else {
+ detached_ = false;
joined_ = false;
+#ifdef CRU_WINDOWS
thread_handle_ = nullptr;
+#else
+ thread_ = nullptr;
+#endif
}
}
@@ -62,6 +98,13 @@ DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter) { return 0;
}
#else
+void *ThreadProc(void *data) {
+ auto p = static_cast<std::function<void()> *>(data);
+ (*p)();
+ delete p;
+ return nullptr;
+}
+
#endif
} // namespace details
} // namespace cru
\ No newline at end of file diff --git a/works/life/operating-system-experiment/Thread.h b/works/life/operating-system-experiment/Thread.h index c71c11f..79c1728 100644 --- a/works/life/operating-system-experiment/Thread.h +++ b/works/life/operating-system-experiment/Thread.h @@ -3,9 +3,17 @@ #include "Base.h"
+#ifdef CRU_WINDOWS
+#include <Windows.h>
+#else
+#include <pthread.h>
+#endif
+
#ifdef __cplusplus
+#include <cassert>
#include <functional>
+#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
@@ -38,6 +46,8 @@ private: #ifdef CRU_WINDOWS
DWORD thread_id_ = 0;
HANDLE thread_handle_ = nullptr;
+#else
+ std::unique_ptr<pthread_t> thread_;
#endif
};
@@ -45,6 +55,7 @@ namespace details { #ifdef CRU_WINDOWS
CRU_API DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter);
#else
+void *ThreadProc(void *data);
#endif
} // namespace details
@@ -59,6 +70,12 @@ Thread::Thread(Fn &&process, Args &&...args) { #ifdef CRU_WINDOWS
thread_handle_ = ::CreateThread(nullptr, 0, &::cru::details::ThreadProc,
static_cast<void *>(p), 0, &thread_id_);
+ assert(thread_handle_);
+#else
+ thread_.reset(new pthread_t());
+ auto c = pthread_create(thread_.get(), nullptr, details::ThreadProc,
+ static_cast<void *>(p));
+ assert(c == 0);
#endif
};
} // namespace cru
|