aboutsummaryrefslogtreecommitdiff
path: root/operating-system-experiment/Semaphore.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-06-11 10:43:00 +0800
committercrupest <crupest@outlook.com>2021-06-11 10:43:00 +0800
commit864c09033f17904640fc17e571a50ab64f8f225d (patch)
tree0023bef179062292cb9e9fd3b455a7af8f4f5d91 /operating-system-experiment/Semaphore.cpp
parent10b7a5e29e48b874dbec2732c0396160bdcd5b01 (diff)
downloadlife-864c09033f17904640fc17e571a50ab64f8f225d.tar.gz
life-864c09033f17904640fc17e571a50ab64f8f225d.tar.bz2
life-864c09033f17904640fc17e571a50ab64f8f225d.zip
...
Diffstat (limited to 'operating-system-experiment/Semaphore.cpp')
-rw-r--r--operating-system-experiment/Semaphore.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/operating-system-experiment/Semaphore.cpp b/operating-system-experiment/Semaphore.cpp
new file mode 100644
index 0000000..e8221fd
--- /dev/null
+++ b/operating-system-experiment/Semaphore.cpp
@@ -0,0 +1,78 @@
+#include "Semaphore.h"
+
+#include <cassert>
+
+#ifndef CRU_WINDOWS
+#include <errno.h>
+#endif
+
+namespace cru {
+Semaphore::Semaphore(unsigned init_value) {
+#ifdef CRU_WINDOWS
+#else
+ semaphore_ = std::make_unique<sem_t>();
+ auto c = sem_init(semaphore_.get(), 0, init_value);
+ assert(c == 0);
+#endif
+}
+
+Semaphore::Semaphore(Semaphore &&other)
+#ifdef CRU_WINDOWS
+#else
+ : semaphore_(std::move(other.semaphore_))
+#endif
+{
+}
+
+Semaphore &Semaphore::operator=(Semaphore &&other) {
+ if (this != &other) {
+ Destroy();
+#ifdef CRU_WINDOWS
+#else
+ semaphore_ = std::move(other.semaphore_);
+#endif
+ }
+ return *this;
+}
+
+Semaphore::~Semaphore() { Destroy(); }
+
+void Semaphore::P() { Acquire(); }
+void Semaphore::V() { Release(); }
+
+void Semaphore::Acquire() {
+#ifdef CRU_WINDOWS
+#else
+ auto c = sem_wait(semaphore_.get());
+ assert(c == 0);
+#endif
+}
+
+bool Semaphore::TryAcquire() {
+#ifdef CRU_WINDOWS
+#else
+ auto c = sem_trywait(semaphore_.get());
+ assert((c == 0) || (c == -1 && errno == EAGAIN));
+ return c == 0 ? true : false;
+#endif
+}
+
+void Semaphore::Release() {
+#ifdef CRU_WINDOWS
+#else
+ auto c = sem_post(semaphore_.get());
+ assert(c == 0);
+#endif
+}
+
+void Semaphore::Destroy() {
+#ifdef CRU_WINDOWS
+#else
+ if (semaphore_ != nullptr) {
+ auto c = sem_destroy(semaphore_.get());
+ assert(c == 0);
+ semaphore_ = nullptr;
+ }
+#endif
+}
+} // namespace cru \ No newline at end of file