aboutsummaryrefslogtreecommitdiff
path: root/store/works/life/operating-system-experiment/Mutex.cpp
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-02-28 23:13:39 +0800
committerYuqian Yang <crupest@crupest.life>2025-02-28 23:13:39 +0800
commitdc1f0c4c0096013799416664894c5194dc7e1f52 (patch)
tree2f5d235f778cd720f4c39ec3e56b77ba6d99f375 /store/works/life/operating-system-experiment/Mutex.cpp
parent7299d424d90b1effb6db69e3476ddd5af72eeba4 (diff)
downloadcrupest-dc1f0c4c0096013799416664894c5194dc7e1f52.tar.gz
crupest-dc1f0c4c0096013799416664894c5194dc7e1f52.tar.bz2
crupest-dc1f0c4c0096013799416664894c5194dc7e1f52.zip
chore(store): move everything to store.
Diffstat (limited to 'store/works/life/operating-system-experiment/Mutex.cpp')
-rw-r--r--store/works/life/operating-system-experiment/Mutex.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/store/works/life/operating-system-experiment/Mutex.cpp b/store/works/life/operating-system-experiment/Mutex.cpp
new file mode 100644
index 0000000..8acfdc5
--- /dev/null
+++ b/store/works/life/operating-system-experiment/Mutex.cpp
@@ -0,0 +1,100 @@
+#include "Mutex.h"
+
+#include <cassert>
+
+#ifndef CRU_WINDOWS
+#include <errno.h>
+#endif
+
+namespace cru {
+Mutex::Mutex() {
+#ifdef CRU_WINDOWS
+ handle_ = CreateMutexW(nullptr, FALSE, nullptr);
+ assert(handle_);
+#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
+ : handle_(other.handle_)
+#else
+ : mutex_(std::move(other.mutex_))
+#endif
+{
+#ifdef CRU_WINDOWS
+ other.handle_ = nullptr;
+#endif
+}
+
+Mutex &Mutex::operator=(Mutex &&other) {
+ if (this != &other) {
+ Destroy();
+#ifdef CRU_WINDOWS
+ handle_ = other.handle_;
+ other.handle_ = nullptr;
+#else
+ mutex_ = std::move(other.mutex_);
+#endif
+ }
+ return *this;
+}
+
+Mutex::~Mutex() { Destroy(); }
+
+void Mutex::Lock() {
+#ifdef CRU_WINDOWS
+ auto c = WaitForSingleObject(handle_, INFINITE);
+ assert(c == WAIT_OBJECT_0);
+#else
+ assert(mutex_);
+ auto c = pthread_mutex_lock(mutex_.get());
+ assert(c == 0);
+#endif
+}
+
+bool Mutex::TryLock() {
+#ifdef CRU_WINDOWS
+ auto c = WaitForSingleObject(handle_, 0);
+ assert(c == WAIT_OBJECT_0 || c == WAIT_TIMEOUT);
+ return c == WAIT_OBJECT_0 ? true : false;
+#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
+ auto c = ReleaseMutex(handle_);
+ assert(c);
+#else
+ assert(mutex_);
+ auto c = pthread_mutex_unlock(mutex_.get());
+ assert(c == 0);
+#endif
+}
+
+void Mutex::Destroy() {
+#ifdef CRU_WINDOWS
+ if (handle_ != nullptr) {
+ auto c = CloseHandle(handle_);
+ assert(c);
+ handle_ = nullptr;
+ }
+#else
+ if (mutex_ != nullptr) {
+ auto c = pthread_mutex_destroy(mutex_.get());
+ assert(c == 0);
+ mutex_ = nullptr;
+ }
+#endif
+}
+
+} // namespace cru