diff options
author | crupest <crupest@outlook.com> | 2021-06-10 11:12:25 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-06-10 11:12:25 +0800 |
commit | ef593ba2d445af515214d63bfd3942be9d673467 (patch) | |
tree | 6f286d3c30af2a6c74a1a60047fa25bae09fd9db /works/life | |
parent | 93d8feccd79b35fc890fc8629d6da2c2baa57762 (diff) | |
download | crupest-ef593ba2d445af515214d63bfd3942be9d673467.tar.gz crupest-ef593ba2d445af515214d63bfd3942be9d673467.tar.bz2 crupest-ef593ba2d445af515214d63bfd3942be9d673467.zip |
import(life): ...
Diffstat (limited to 'works/life')
-rw-r--r-- | works/life/operating-system-experiment/CMakeLists.txt | 8 | ||||
-rw-r--r-- | works/life/operating-system-experiment/DataRaceDemo.cpp | 27 | ||||
-rw-r--r-- | works/life/operating-system-experiment/Mutex.cpp | 78 | ||||
-rw-r--r-- | works/life/operating-system-experiment/Mutex.h | 44 | ||||
-rw-r--r-- | works/life/operating-system-experiment/Thread.cpp | 31 | ||||
-rw-r--r-- | works/life/operating-system-experiment/Thread.h | 15 |
6 files changed, 199 insertions, 4 deletions
diff --git a/works/life/operating-system-experiment/CMakeLists.txt b/works/life/operating-system-experiment/CMakeLists.txt index 540574b..806ec74 100644 --- a/works/life/operating-system-experiment/CMakeLists.txt +++ b/works/life/operating-system-experiment/CMakeLists.txt @@ -9,13 +9,15 @@ set(CMAKE_CXX_STANDARD 17) find_package(fmt CONFIG REQUIRED)
find_package(Microsoft.GSL CONFIG REQUIRED)
-add_library(cru_system SHARED Thread.cpp)
+add_library(cru_system SHARED Thread.cpp Mutex.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 +target_link_libraries(main PRIVATE cru_system)
+
+add_executable(data_race_demo DataRaceDemo.cpp)
+target_link_libraries(data_race_demo PRIVATE cru_system)
diff --git a/works/life/operating-system-experiment/DataRaceDemo.cpp b/works/life/operating-system-experiment/DataRaceDemo.cpp new file mode 100644 index 0000000..9589eb3 --- /dev/null +++ b/works/life/operating-system-experiment/DataRaceDemo.cpp @@ -0,0 +1,27 @@ +#include "Thread.h" + +#include <iostream> + +int main() { + unsigned data = 0; + + cru::Thread t1([&data] { + for (int i = 0; i < 100000; i++) + data += 10; + }); + + cru::Thread t2([&data] { + for (int i = 0; i < 100000; i++) + data += 10; + }); + + std::cout << "Created thread: " << t1.GetNativeID() << '\n'; + std::cout << "Created thread: " << t2.GetNativeID() << '\n'; + + t1.Join(); + t2.Join(); + std::cout << "Answer is " << data << ", which is " + << (data == 200000 ? "correct" : "false") << '\n'; + + return 0; +} diff --git a/works/life/operating-system-experiment/Mutex.cpp b/works/life/operating-system-experiment/Mutex.cpp new file mode 100644 index 0000000..6a91885 --- /dev/null +++ b/works/life/operating-system-experiment/Mutex.cpp @@ -0,0 +1,78 @@ +#include "Mutex.h" + +#include <cassert> +#include <pthread.h> + +#ifndef CRU_WINDOWS +#include <errno.h> +#endif + +namespace cru { +Mutex::Mutex() { +#ifdef CRU_WINDOWS +#else + mutex_ = std::make_unique<pthread_mutex_t>(); + + auto c = pthread_mutex_init(mutex_.get(), nullptr); + assert(c == 0); +#endif +} + +Mutex::Mutex(Mutex &&other) +#ifdef CRU_WINDOWS +#else + : mutex_(std::move(other.mutex_)) +#endif +{ +} + +Mutex &Mutex::operator=(Mutex &&other) { + if (this != &other) { + Destroy(); + mutex_ = std::move(other.mutex_); + } + return *this; +} + +Mutex::~Mutex() { Destroy(); } + +void Mutex::Lock() { +#ifdef CRU_WINDOWS +#else + assert(mutex_); + auto c = pthread_mutex_lock(mutex_.get()); + assert(c == 0); +#endif +} + +bool Mutex::TryLock() { +#ifdef CRU_WINDOWS +#else + assert(mutex_); + auto c = pthread_mutex_trylock(mutex_.get()); + assert(c == 0 || c == EBUSY); + return c == 0 ? true : false; +#endif +} + +void Mutex::Unlock() { +#ifdef CRU_WINDOWS +#else + assert(mutex_); + auto c = pthread_mutex_unlock(mutex_.get()); + assert(c == 0); +#endif +} + +void Mutex::Destroy() { +#ifdef CRU_WINDOWS +#else + if (mutex_ != nullptr) { + auto c = pthread_mutex_destroy(mutex_.get()); + assert(c); + mutex_ = nullptr; + } +#endif +} + +} // namespace cru diff --git a/works/life/operating-system-experiment/Mutex.h b/works/life/operating-system-experiment/Mutex.h new file mode 100644 index 0000000..163d9ca --- /dev/null +++ b/works/life/operating-system-experiment/Mutex.h @@ -0,0 +1,44 @@ +#ifndef HEADER_MUTEX_H +#define HEADER_MUTEX_H + +#include "Base.h" + +#include <memory> + +#ifdef CRU_WINDOWS +#include <Windows.h> +#else +#include <pthread.h> +#endif + +namespace cru { +class CRU_API Mutex { +public: + Mutex(); + + Mutex(const Mutex &other) = delete; + Mutex &operator=(const Mutex &other) = delete; + + Mutex(Mutex &&other); + Mutex &operator=(Mutex &&other); + + ~Mutex(); + +public: + void Lock(); + bool TryLock(); + + void Unlock(); + +private: + void Destroy(); + +private: +#ifdef CRU_WINDOWS +#else + std::unique_ptr<pthread_mutex_t> mutex_; +#endif +}; +} // namespace cru + +#endif
\ 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 9d9f5dd..7e3c784 100644 --- a/works/life/operating-system-experiment/Thread.cpp +++ b/works/life/operating-system-experiment/Thread.cpp @@ -59,6 +59,36 @@ void Thread::Detach() { 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);
@@ -81,6 +111,7 @@ void Thread::Destroy() noexcept { detached_ = false;
joined_ = false;
#ifdef CRU_WINDOWS
+ thread_id_ = 0;
thread_handle_ = nullptr;
#else
thread_ = nullptr;
diff --git a/works/life/operating-system-experiment/Thread.h b/works/life/operating-system-experiment/Thread.h index 69a402c..56fdcb0 100644 --- a/works/life/operating-system-experiment/Thread.h +++ b/works/life/operating-system-experiment/Thread.h @@ -18,7 +18,6 @@ #include <type_traits>
#include <utility>
#include <vector>
-#include <tuple>
namespace cru {
class CRU_API Thread {
@@ -35,6 +34,20 @@ public: void Join();
void Detach();
+#ifdef CRU_WINDOWS
+ DWORD
+#else
+ pthread_t
+#endif
+ GetNativeID();
+
+#ifdef CRU_WINDOWS
+ HANDLE
+#else
+ pthread_t
+#endif
+ GetNativeHandle();
+
void swap(Thread &other) noexcept;
private:
|