From 0380cd595ee05773f78751aa7f2952b6ea105f7c Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 11 Jun 2021 10:43:00 +0800 Subject: import(life): ... --- works/life/operating-system-experiment/Semaphore.h | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 works/life/operating-system-experiment/Semaphore.h (limited to 'works/life/operating-system-experiment/Semaphore.h') diff --git a/works/life/operating-system-experiment/Semaphore.h b/works/life/operating-system-experiment/Semaphore.h new file mode 100644 index 0000000..1d49b60 --- /dev/null +++ b/works/life/operating-system-experiment/Semaphore.h @@ -0,0 +1,46 @@ +#ifndef HEADER_SEMAPHORE_H +#define HEADER_SEMAPHORE_H + +#include "Base.h" + +#include + +#ifdef CRU_WINDOWS +#include +#else +#include +#endif + +namespace cru { +class CRU_API Semaphore { +public: + explicit Semaphore(unsigned init_value = 1); + + Semaphore(const Semaphore &other) = delete; + Semaphore &operator=(const Semaphore &other) = delete; + + Semaphore(Semaphore &&other); + Semaphore &operator=(Semaphore &&other); + + ~Semaphore(); + +public: + void P(); + void V(); + + void Acquire(); + bool TryAcquire(); + void Release(); + +private: + void Destroy(); + +private: +#ifdef CRU_WINDOWS +#else + std::unique_ptr semaphore_; +#endif +}; +} // namespace cru + +#endif \ No newline at end of file -- cgit v1.2.3 From fabd9692c49bad9f4f2858315f2a16501ad45d21 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 11 Jun 2021 11:02:41 +0800 Subject: import(life): ... --- works/life/operating-system-experiment/Mutex.cpp | 1 + works/life/operating-system-experiment/Semaphore.cpp | 20 ++++++++++++++++++++ works/life/operating-system-experiment/Semaphore.h | 1 + works/life/operating-system-experiment/Thread.cpp | 3 ++- 4 files changed, 24 insertions(+), 1 deletion(-) (limited to 'works/life/operating-system-experiment/Semaphore.h') diff --git a/works/life/operating-system-experiment/Mutex.cpp b/works/life/operating-system-experiment/Mutex.cpp index 4d360f1..8acfdc5 100644 --- a/works/life/operating-system-experiment/Mutex.cpp +++ b/works/life/operating-system-experiment/Mutex.cpp @@ -86,6 +86,7 @@ void Mutex::Destroy() { if (handle_ != nullptr) { auto c = CloseHandle(handle_); assert(c); + handle_ = nullptr; } #else if (mutex_ != nullptr) { diff --git a/works/life/operating-system-experiment/Semaphore.cpp b/works/life/operating-system-experiment/Semaphore.cpp index e8221fd..aceef4d 100644 --- a/works/life/operating-system-experiment/Semaphore.cpp +++ b/works/life/operating-system-experiment/Semaphore.cpp @@ -9,6 +9,8 @@ namespace cru { Semaphore::Semaphore(unsigned init_value) { #ifdef CRU_WINDOWS + handle_ = CreateSemaphoreW(nullptr, init_value, 100, nullptr); + assert(handle_); #else semaphore_ = std::make_unique(); auto c = sem_init(semaphore_.get(), 0, init_value); @@ -18,16 +20,22 @@ Semaphore::Semaphore(unsigned init_value) { Semaphore::Semaphore(Semaphore &&other) #ifdef CRU_WINDOWS + : handle_(other.handle_) #else : semaphore_(std::move(other.semaphore_)) #endif { +#ifdef CRU_WINDOWS + other.handle_ = nullptr; +#endif } Semaphore &Semaphore::operator=(Semaphore &&other) { if (this != &other) { Destroy(); #ifdef CRU_WINDOWS + handle_ = other.handle_; + other.handle_ = nullptr; #else semaphore_ = std::move(other.semaphore_); #endif @@ -42,6 +50,8 @@ void Semaphore::V() { Release(); } void Semaphore::Acquire() { #ifdef CRU_WINDOWS + auto c = WaitForSingleObject(handle_, INFINITE); + assert(c == WAIT_OBJECT_0); #else auto c = sem_wait(semaphore_.get()); assert(c == 0); @@ -50,6 +60,9 @@ void Semaphore::Acquire() { bool Semaphore::TryAcquire() { #ifdef CRU_WINDOWS + auto c = WaitForSingleObject(handle_, 0); + assert(c == WAIT_OBJECT_0 || c == WAIT_TIMEOUT); + return c == WAIT_OBJECT_0 ? true : false; #else auto c = sem_trywait(semaphore_.get()); assert((c == 0) || (c == -1 && errno == EAGAIN)); @@ -59,6 +72,8 @@ bool Semaphore::TryAcquire() { void Semaphore::Release() { #ifdef CRU_WINDOWS + auto c = ReleaseSemaphore(handle_, 1, nullptr); + assert(c); #else auto c = sem_post(semaphore_.get()); assert(c == 0); @@ -67,6 +82,11 @@ void Semaphore::Release() { void Semaphore::Destroy() { #ifdef CRU_WINDOWS + if (handle_ != nullptr) { + auto c = CloseHandle(handle_); + assert(c); + handle_ = nullptr; + } #else if (semaphore_ != nullptr) { auto c = sem_destroy(semaphore_.get()); diff --git a/works/life/operating-system-experiment/Semaphore.h b/works/life/operating-system-experiment/Semaphore.h index 1d49b60..430c036 100644 --- a/works/life/operating-system-experiment/Semaphore.h +++ b/works/life/operating-system-experiment/Semaphore.h @@ -37,6 +37,7 @@ private: private: #ifdef CRU_WINDOWS + HANDLE handle_ = nullptr; #else std::unique_ptr semaphore_; #endif diff --git a/works/life/operating-system-experiment/Thread.cpp b/works/life/operating-system-experiment/Thread.cpp index 657c69f..0bc4c18 100644 --- a/works/life/operating-system-experiment/Thread.cpp +++ b/works/life/operating-system-experiment/Thread.cpp @@ -113,7 +113,8 @@ void Thread::Destroy() noexcept { #ifdef CRU_WINDOWS thread_id_ = 0; if (thread_handle_ != nullptr) { - CloseHandle(thread_handle_); + auto c = CloseHandle(thread_handle_); + assert(c); thread_handle_ = nullptr; } #else -- cgit v1.2.3