aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-06-09 22:31:11 +0800
committercrupest <crupest@outlook.com>2021-06-09 22:31:11 +0800
commit59be99aad9d7ad36e3edf648dbbd6b5b215c125c (patch)
tree73cf88107c915ed1657d6e2a6b9584cc48c52113 /works/life
parent8268724a054a42f9446736c42d8f04a0207aa12d (diff)
parent8bdb5db67fa3eeda755511f91fd257bde548a18f (diff)
downloadcrupest-59be99aad9d7ad36e3edf648dbbd6b5b215c125c.tar.gz
crupest-59be99aad9d7ad36e3edf648dbbd6b5b215c125c.tar.bz2
crupest-59be99aad9d7ad36e3edf648dbbd6b5b215c125c.zip
import(life): Merge branch 'main' of https://github.com/crupest/life
Diffstat (limited to 'works/life')
-rw-r--r--works/life/operating-system-experiment/Base.h4
-rw-r--r--works/life/operating-system-experiment/CMakeLists.txt4
-rw-r--r--works/life/operating-system-experiment/Thread.cpp53
-rw-r--r--works/life/operating-system-experiment/Thread.h17
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 cdeecac..69a402c 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>
@@ -39,6 +47,8 @@ private:
#ifdef CRU_WINDOWS
DWORD thread_id_ = 0;
HANDLE thread_handle_ = nullptr;
+#else
+ std::unique_ptr<pthread_t> thread_;
#endif
};
@@ -46,6 +56,7 @@ namespace details {
#ifdef CRU_WINDOWS
CRU_API DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter);
#else
+void *ThreadProc(void *data);
#endif
} // namespace details
@@ -60,6 +71,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