commit 452ed80b7f5495543049e0a7fc729919564abdb5 Author: Sky Johnson Date: Thu Jul 31 22:45:27 2025 -0500 first commit diff --git a/mutex.hpp b/mutex.hpp new file mode 100644 index 0000000..c6c466f --- /dev/null +++ b/mutex.hpp @@ -0,0 +1,140 @@ +#pragma once + +#include +#include + +#define MUTEX_ATTRIBUTE_FAST 1 +#define MUTEX_ATTRIBUTE_RECURSIVE 2 +#define MUTEX_ATTRIBUTE_ERRORCHK 3 + +class CriticalSection +{ +public: + explicit CriticalSection(int attribute = MUTEX_ATTRIBUTE_FAST) + : is_recursive(attribute == MUTEX_ATTRIBUTE_RECURSIVE) {} + + void lock() { + if (is_recursive) { + recursive_mutex.lock(); + } else { + regular_mutex.lock(); + } + } + + void unlock() { + if (is_recursive) { + recursive_mutex.unlock(); + } else { + regular_mutex.unlock(); + } + } + + bool trylock() { + return is_recursive ? recursive_mutex.try_lock() : regular_mutex.try_lock(); + } + +private: + std::mutex regular_mutex; + std::recursive_mutex recursive_mutex; + bool is_recursive; +}; + +class Mutex +{ +public: + Mutex() = default; + + void lock() { main_mutex.lock(); } + void unlock() { main_mutex.unlock(); } + bool trylock() { return main_mutex.try_lock(); } + + void readlock(const char* = nullptr, int = 0) { + while (true) { + std::unique_lock read_lock(read_mutex); + if (!writing.load()) { + readers.fetch_add(1); + return; + } + } + } + + void releasereadlock(const char* = nullptr, int = 0) { + readers.fetch_sub(1); + } + + bool tryreadlock(const char* = nullptr) { + std::lock_guard read_lock(read_mutex); + if (!writing.load()) { + readers.fetch_add(1); + return true; + } + return false; + } + + void writelock(const char* = nullptr, int = 0) { + write_mutex.lock(); + waitReaders(); + } + + void releasewritelock(const char* = nullptr, int = 0) { + writing.store(false); + write_mutex.unlock(); + } + + bool trywritelock(const char* = nullptr) { + if (!write_mutex.try_lock()) return false; + + if (readers.load() == 0) { + writing.store(true); + return true; + } + + write_mutex.unlock(); + return false; + } + + void waitReaders(const char* = nullptr, int = 0) { + while (readers.load() > 0) {} + writing.store(true); + } + + void SetName(const std::string&) {} + +private: + std::mutex read_mutex; + std::mutex write_mutex; + std::mutex main_mutex; + std::atomic readers{0}; + std::atomic writing{false}; +}; + +class LockMutex +{ +public: + explicit LockMutex(Mutex* mutex, bool lock_immediately = true) + : mut(mutex), locked(lock_immediately) { + if (locked) mut->lock(); + } + + ~LockMutex() { + if (locked) mut->unlock(); + } + + void unlock() { + if (locked) { + mut->unlock(); + locked = false; + } + } + + void lock() { + if (!locked) { + mut->lock(); + locked = true; + } + } + +private: + Mutex* mut; + bool locked; +}; \ No newline at end of file