Created
January 10, 2013 11:45
-
-
Save wesen/4501463 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef MUTEX_H__ | |
| #define MUTEX_H__ | |
| #include "common.h" | |
| #include <wirish/wirish_time.h> | |
| /** | |
| * Simple atomic swap memory mutex | |
| */ | |
| class Mutex { | |
| private: | |
| volatile unsigned char lock; | |
| public: | |
| Mutex(): lock(0) { | |
| } | |
| bool acquire() { | |
| return __sync_bool_compare_and_swap(&lock, 0, 1); | |
| } | |
| bool acquireWait(uint32_t waitUs = 10, uint32_t timeoutUs = 0) { | |
| uint32_t _timeout; | |
| while (timeoutUs == 0 || _timeout < timeoutUs) { | |
| if (acquire()) { | |
| return true; | |
| } | |
| delayMicroseconds(timeoutUs); | |
| _timeout += waitUs; | |
| } | |
| return false; | |
| } | |
| void release() { | |
| // do we need the synchronized variant here? we can assume we are locked ?? XXX | |
| lock = 0; | |
| } | |
| bool isLocked() { | |
| return lock == 1; | |
| } | |
| }; | |
| /** | |
| * blocking RAII mutex getter | |
| */ | |
| class MutexResource { | |
| protected: | |
| Mutex *mutex; | |
| public: | |
| MutexResource(Mutex *_m) : mutex(_m) { | |
| mutex->acquire(); | |
| } | |
| bool isLocked() { | |
| return mutex->isLocked(); | |
| } | |
| virtual ~MutexResource() { | |
| mutex->release(); | |
| } | |
| }; | |
| class MutexResourceWait { | |
| protected: | |
| Mutex *mutex; | |
| public: | |
| MutexResourceWait(Mutex *_m, uint32_t waitUs = 10, uint32_t timeoutUs = 0) : mutex(_m) { | |
| mutex->acquireWait(waitUs, timeoutUs); | |
| } | |
| bool isLocked() { | |
| return mutex->isLocked(); | |
| } | |
| virtual ~MutexResourceWait() { | |
| mutex->release(); | |
| } | |
| }; | |
| /** | |
| * Mutex protecting a resource | |
| */ | |
| template<typename T> class ResourceMutex : public Mutex { | |
| private: | |
| T resource; | |
| public: | |
| ResourceMutex() : Mutex() { | |
| } | |
| ResourceMutex(T init) : Mutex(), resource(init) { | |
| } | |
| volatile T *getResource() { | |
| if (acquire()) { | |
| return &resource; | |
| } else { | |
| return NULL; | |
| } | |
| } | |
| volatile T *getResourceWait(uint32_t waitUs = 10, uint32_t timeoutUs = 0) { | |
| if (acquireWait(waitUs, timeoutUs)) { | |
| return &resource; | |
| } else { | |
| return NULL; | |
| } | |
| } | |
| }; | |
| /** | |
| * RAII style allocators | |
| */ | |
| template<typename T> class ResourceMutexResource { | |
| protected: | |
| ResourceMutex<T> *mutex; | |
| public: | |
| volatile T *resource; | |
| ResourceMutexResource(ResourceMutex<T> *_m) : mutex(_m) { | |
| resource = mutex->getResource(); | |
| } | |
| virtual ~ResourceMutexResource() { | |
| if (resource != NULL) { | |
| mutex->release(); | |
| } | |
| } | |
| }; | |
| template<typename T> class ResourceMutexResourceWait { | |
| protected: | |
| ResourceMutex<T> *mutex; | |
| public: | |
| volatile T *resource; | |
| ResourceMutexResourceWait(ResourceMutex<T> *_m, uint32_t waitUs = 10, uint32_t timeoutUs = 0) : mutex(_m) { | |
| resource = mutex->getResourceWait(waitUs, timeoutUs); | |
| } | |
| virtual ~ResourceMutexResourceWait() { | |
| if (resource != NULL) { | |
| mutex->release(); | |
| } | |
| } | |
| }; | |
| #endif /* MUTEX_H__ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment