00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __RWLOCK_H__
00018 #define __RWLOCK_H__
00019
00020 #include <cstdio>
00021
00022 #include "Lock.h"
00023 #include "SpinLock.h"
00024 #include "Mutex.h"
00025
00026 namespace oasys {
00027
00033 class SXLock {
00034 public:
00035 SXLock(Lock* lock)
00036 : lock_(lock),
00037 scount_(0),
00038 xcount_(0)
00039 {}
00040
00045 void shared_lock() {
00046 lock_->lock();
00047 while (xcount_ > 0) {
00048 lock_->unlock();
00049 Thread::spin_yield();
00050 lock_->lock();
00051 }
00052 ++scount_;
00053 lock_->unlock();
00054 }
00055
00057 void shared_unlock() {
00058 lock_->lock();
00059 --scount_;
00060 lock_->unlock();
00061 }
00062
00068 void exclusive_lock() {
00069 lock_->lock();
00070 while (xcount_ > 0 && scount_ > 0) {
00071 lock_->unlock();
00072 Thread::spin_yield();
00073 lock_->lock();
00074 }
00075 ++xcount_;
00076
00077 if (xcount_ != 1) {
00078 fprintf(stderr, "more than 1 writer (%d writers) entered lock!!",
00079 xcount_);
00080 exit(-1);
00081 }
00082
00083 lock_->unlock();
00084 }
00085
00087 void exclusive_unlock() {
00088 lock_->lock();
00089
00090 --xcount_;
00091 if (xcount_ != 0) {
00092 fprintf(stderr, "more than 1 writer (%d writers) entered lock!!",
00093 xcount_);
00094 exit(-1);
00095 }
00096
00097 lock_->unlock();
00098 }
00099
00100 private:
00101 Lock* lock_;
00102
00103 int scount_;
00104 int xcount_;
00105 };
00106
00107 #define SCOPE_LOCK_DEFUN(_name, _fcn) \
00108 class ScopeLock_ ## _name { \
00109 ScopeLock_ ## _name (SXLock* rw_lock, \
00110 const char* lock_user) \
00111 : rw_lock_(rw_lock) \
00112 { \
00113 do_lock(lock_user); \
00114 } \
00115 \
00116 ScopeLock_ ## _name (ScopePtr<SXLock> rw_lock, \
00117 const char* lock_user) \
00118 : rw_lock_(rw_lock.ptr()) \
00119 { \
00120 do_lock(lock_user); \
00121 } \
00122 \
00123 ~ScopeLock_ ## _name () \
00124 { \
00125 if (rw_lock_) { \
00126 do_unlock(); \
00127 } \
00128 } \
00129 \
00130 private: \
00131 SXLock* rw_lock_; \
00132 \
00133 void do_lock(const char* lock_user) { \
00134 rw_lock_->_fcn ## _lock(); \
00135 } \
00136 \
00137 void do_unlock() { \
00138 rw_lock_->_fcn ## _unlock(); \
00139 } \
00140 };
00141
00145 SCOPE_LOCK_DEFUN(Shared, shared);
00146 SCOPE_LOCK_DEFUN(Exclusive, exclusive);
00148 #undef SCOPE_LOCK_DEFUN
00149
00150 }
00151
00152 #endif