SXLock.h

Go to the documentation of this file.
00001 #ifndef __RWLOCK_H__
00002 #define __RWLOCK_H__
00003 
00004 #include <cstdio>
00005 
00006 #include "Lock.h"
00007 #include "SpinLock.h"
00008 #include "Mutex.h"
00009 
00010 namespace oasys {
00011 
00017 class SXLock {
00018 public:
00019     SXLock(Lock* lock)
00020         : lock_(lock),
00021           scount_(0),
00022           xcount_(0)
00023     {}
00024 
00029     void shared_lock() {
00030         lock_->lock();
00031         while (xcount_ > 0) {
00032             lock_->unlock();
00033             Thread::spin_yield();
00034             lock_->lock();
00035         }
00036         ++scount_;
00037         lock_->unlock();
00038     }
00039 
00041     void shared_unlock() {
00042         lock_->lock();
00043         --scount_;
00044         lock_->unlock();
00045     }
00046 
00052     void exclusive_lock() {
00053         lock_->lock();
00054         while (xcount_ > 0 && scount_ > 0) {
00055             lock_->unlock();
00056             Thread::spin_yield();
00057             lock_->lock();
00058         }
00059         ++xcount_;
00060 
00061         if (xcount_ != 1) {
00062             fprintf(stderr, "more than 1 writer (%d writers) entered lock!!", 
00063                     xcount_);
00064             exit(-1);
00065         }
00066 
00067         lock_->unlock();
00068     }
00069 
00071     void exclusive_unlock() {
00072         lock_->lock();
00073 
00074         --xcount_;
00075         if (xcount_ != 0) {
00076             fprintf(stderr, "more than 1 writer (%d writers) entered lock!!", 
00077                     xcount_);
00078             exit(-1);
00079         }
00080 
00081         lock_->unlock();        
00082     }
00083     
00084 private:
00085     Lock* lock_;
00086 
00087     int scount_;
00088     int xcount_;
00089 };
00090 
00091 #define SCOPE_LOCK_DEFUN(_name, _fcn)                   \
00092 class ScopeLock_ ## _name {                             \
00093     ScopeLock_ ## _name (SXLock*     rw_lock,           \
00094                          const char* lock_user)         \
00095         : rw_lock_(rw_lock)                             \
00096     {                                                   \
00097         do_lock(lock_user);                             \
00098     }                                                   \
00099                                                         \
00100     ScopeLock_ ## _name (ScopePtr<SXLock> rw_lock,      \
00101                          const char*      lock_user)    \
00102         : rw_lock_(rw_lock.ptr())                       \
00103     {                                                   \
00104         do_lock(lock_user);                             \
00105     }                                                   \
00106                                                         \
00107     ScopeLock_ ## _name (auto_ptr<SXLock> rw_lock,      \
00108                          const char*      lock_user)    \
00109         : rw_lock_(rw_lock.get())                       \
00110     {                                                   \
00111         do_lock(lock_user);                             \
00112     }                                                   \
00113                                                         \
00114     ~ScopeLock_ ## _name ()                             \
00115     {                                                   \
00116         if (rw_lock_) {                                 \
00117             do_unlock();                                \
00118         }                                               \
00119     }                                                   \
00120                                                         \
00121 private:                                                \
00122     SXLock* rw_lock_;                                   \
00123                                                         \
00124     void do_lock(const char* lock_user) {               \
00125         rw_lock_->_fcn ## _lock();                      \
00126     }                                                   \
00127                                                         \
00128     void do_unlock() {                                  \
00129         rw_lock_->_fcn ## _unlock();                    \
00130     }                                                   \
00131 };
00132 
00136 SCOPE_LOCK_DEFUN(Shared,    shared);
00137 SCOPE_LOCK_DEFUN(Exclusive, exclusive);
00139 #undef SCOPE_LOCK_DEFUN
00140 
00141 } // namespace oasys
00142 
00143 #endif /* __RWLOCK_H__ */

Generated on Fri Dec 22 14:48:00 2006 for DTN Reference Implementation by  doxygen 1.5.1