00001 00007 /* 00008 * Copyright (C) 2004 Bregmasoft 00009 * 00010 * This program is free software; you can redistribute it and/or modify it under 00011 * the terms of the GNU General Public License as published by the Free Software 00012 * Foundation; either version 2 of the License, or (at your option) any later 00013 * version. 00014 * 00015 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 00016 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 00017 * PARTICULAR PURPOSE. See the GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License along with 00020 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 * Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 #ifndef ZYGOMA_SPINLOCK_H_ 00024 #define ZYGOMA_SPINLOCK_H_ 00025 00026 #include <atomic.h> 00027 00028 namespace Zygoma 00029 { 00042 class SpinLockMutex 00043 { 00044 friend class SpinLock; 00045 00046 public: 00051 SpinLockMutex(); 00052 00056 ~SpinLockMutex(); 00057 00058 private: 00059 void acquire(); 00060 void release(); 00061 00062 protected: 00067 /* @{ */ 00071 static const AtomicWord SPIN_LOCK_AVAILABLE = 0; 00072 00076 static const AtomicWord SPIN_LOCK_UNAVAILABLE = ~SPIN_LOCK_AVAILABLE; 00077 /* @} */ 00078 00079 private: 00080 AtomicWord m_key; 00081 }; 00082 00089 inline void 00090 SpinLockMutex::acquire() 00091 { 00092 register AtomicWord lock = SPIN_LOCK_UNAVAILABLE; 00093 do 00094 { 00095 lock = atomicExchange(&m_key, lock); 00096 } while (lock != SPIN_LOCK_AVAILABLE); 00097 } 00098 00104 inline void 00105 SpinLockMutex::release() 00106 { 00107 atomicExchange(&m_key, SPIN_LOCK_AVAILABLE); 00108 } 00109 00123 class SpinLock 00124 { 00125 public: 00132 SpinLock(SpinLockMutex& mutex) 00133 : m_mutex(mutex) 00134 { m_mutex.acquire(); } 00135 00139 ~SpinLock() 00140 { m_mutex.release(); } 00141 00142 protected: 00143 SpinLock(const SpinLock&); /* unimplemented */ 00144 SpinLock& operator=(const SpinLock&); /* unimplemented */ 00145 00146 protected: 00147 SpinLockMutex& m_mutex; 00148 }; 00149 } // namespace Zygoma 00150 00151 #endif // ZYGOMA_SPINLOCK_H_