SXLock.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
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 } // namespace oasys
00151 
00152 #endif /* __RWLOCK_H__ */

Generated on Thu Jun 7 16:56:52 2007 for DTN Reference Implementation by  doxygen 1.5.1