diff options
Diffstat (limited to 'works/life/operating-system-experiment/Semaphore.cpp')
-rw-r--r-- | works/life/operating-system-experiment/Semaphore.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/works/life/operating-system-experiment/Semaphore.cpp b/works/life/operating-system-experiment/Semaphore.cpp new file mode 100644 index 0000000..e8221fd --- /dev/null +++ b/works/life/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 |