Changeset 28979 in webkit
- Timestamp:
- Dec 24, 2007 10:55:23 PM (16 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r28977 r28979 1 2007-12-25 Mark Rowe <mrowe@apple.com> 2 3 Reviewed by Sam Weinig. 4 5 Implement a lock-free ThreadSafeShared for i386, x86_64, ppc and ppc64. 6 http://bugs.webkit.org/show_bug.cgi?id=16596 7 8 This is a 1.7x as fast as the lock-based implementation on x86 for a single-threaded use 9 of ThreadSafeShared but is closer to 280x as fast when there is heavy concurrent multi-threaded 10 access to a single ThreadSafeShared object. 11 12 The atomic operations are based on those used by the Boost C++ library's shared_ptr implementation. 13 14 * platform/Threading.h: 15 (WebCore::atomicIncrement): 16 (WebCore::atomicDecrement): 17 (WebCore::ThreadSafeShared::ThreadSafeShared): 18 (WebCore::ThreadSafeShared::ref): Use lock-free operations if available. 19 (WebCore::ThreadSafeShared::deref): Ditto. 20 (WebCore::ThreadSafeShared::hasOneRef): 21 (WebCore::ThreadSafeShared::refCount): 22 (WebCore::ThreadSafeShared::isThreadSafe): 23 1 24 2007-12-24 Darin Adler <darin@apple.com> 2 25 -
trunk/WebCore/platform/Threading.h
r28835 r28979 26 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * 30 * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based 31 * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license 32 * is virtually identical to the Apple license above but is included here for completeness. 33 * 34 * Boost Software License - Version 1.0 - August 17th, 2003 35 * 36 * Permission is hereby granted, free of charge, to any person or organization 37 * obtaining a copy of the software and accompanying documentation covered by 38 * this license (the "Software") to use, reproduce, display, distribute, 39 * execute, and transmit the Software, and to prepare derivative works of the 40 * Software, and to permit third-parties to whom the Software is furnished to 41 * do so, all subject to the following: 42 * 43 * The copyright notices in the Software and this entire statement, including 44 * the above license grant, this restriction and the following disclaimer, 45 * must be included in all copies of the Software, in whole or in part, and 46 * all derivative works of the Software, unless such copies or derivative 47 * works are solely in the form of machine-executable object code generated by 48 * a source language processor. 49 * 50 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 52 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 53 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 54 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 55 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 56 * DEALINGS IN THE SOFTWARE. 28 57 */ 29 58 … … 33 62 #include <wtf/Assertions.h> 34 63 #include <wtf/Noncopyable.h> 64 65 #if PLATFORM(WIN_OS) 66 #include <windows.h> 67 #endif 35 68 36 69 #if USE(PTHREADS) … … 124 157 PlatformCondition m_condition; 125 158 }; 126 159 160 #if PLATFORM(WIN_OS) 161 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 162 163 inline void atomicIncrement(int volatile* addened) { InterlockedIncrement(addened); } 164 inline int atomicDecrement(int volatile* addened) { return InterlockedDecrement(addened); } 165 166 #elif COMPILER(GCC) && (PLATFORM(X86) || PLATFORM(X86_64) || PLATFORM(PPC) || PLATFORM(PPC64)) 167 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 168 169 inline void atomicIncrement(int volatile* addend) 170 { 171 #if PLATFORM(X86) || PLATFORM(X86_64) 172 __asm__( 173 "lock\n\t" 174 "incl %0": 175 "=m"(*addend): // output (%0) 176 "m"(*addend): // input (%1) 177 "cc" 178 ); 179 #else 180 int tmp; 181 __asm__( 182 "0:\n\t" 183 "lwarx %1, 0, %2\n\t" 184 "addi %1, %1, 1\n\t" 185 "stwcx. %1, 0, %2\n\t" 186 "bne- 0b": 187 188 "=m"(*addend), "=&b"(tmp): 189 "r"(addend), "m"(*addend): 190 "cc" 191 ); 192 #endif 193 } 194 195 inline int atomicDecrement(int volatile* addend) 196 { 197 #if PLATFORM(X86) || PLATFORM(X86_64) 198 int readval = 0; 199 __asm__ __volatile__ 200 ( 201 "lock\n\t" 202 "xadd %1, %0": 203 "=m"(*addend), "=r"(readval): // outputs (%0, %1) 204 "m"(*addend), "1"(-1): // inputs (%2, %3 == %1) 205 "memory", "cc" // clobbers 206 ); 207 return readval - 1; 208 #else 209 int readval; 210 __asm__ __volatile__( 211 "sync\n\t" 212 "0:\n\t" 213 "lwarx %1, 0, %2\n\t" 214 "addi %1, %1, -1\n\t" 215 "stwcx. %1, 0, %2\n\t" 216 "bne- 0b\n\t" 217 "isync": 218 219 "=m"(*addend), "=&b"(readval): 220 "r"(addend), "m"(*addend): 221 "memory", "cc" 222 ); 223 return readval; 224 #endif 225 } 226 #endif 227 127 228 template<class T> class ThreadSafeShared : Noncopyable { 128 229 public: 129 230 ThreadSafeShared() 130 231 : m_refCount(0) 131 #ifndef NDEBUG132 , m_inDestructor(0)133 #endif134 232 { 135 233 } … … 137 235 void ref() 138 236 { 237 #if USE(LOCKFREE_THREADSAFESHARED) 238 atomicIncrement(&m_refCount); 239 #else 139 240 MutexLocker locker(m_mutex); 140 ASSERT(!m_inDestructor);141 241 ++m_refCount; 242 #endif 142 243 } 143 244 144 245 void deref() 145 246 { 247 #if USE(LOCKFREE_THREADSAFESHARED) 248 if (atomicDecrement(&m_refCount) <= 0) 249 #else 146 250 { 147 251 MutexLocker locker(m_mutex); 148 ASSERT(!m_inDestructor);149 252 --m_refCount; 150 253 } 151 152 if (m_refCount <= 0) { 153 #ifndef NDEBUG 154 m_inDestructor = true; 254 if (m_refCount <= 0) 155 255 #endif 156 256 delete static_cast<T*>(this); 157 }158 257 } 159 258 160 259 bool hasOneRef() 161 260 { 261 return refCount() == 1; 262 } 263 264 int refCount() const 265 { 266 #if !USE(LOCKFREE_THREADSAFESHARED) 162 267 MutexLocker locker(m_mutex); 163 ASSERT(!m_inDestructor); 164 return m_refCount == 1; 165 } 166 167 int refCount() const 168 { 169 MutexLocker locker(m_mutex); 170 return m_refCount; 171 } 172 173 bool isThreadSafe() { return true; } 174 175 private: 268 #endif 269 return static_cast<int const volatile &>(m_refCount); 270 } 271 272 private: 273 int m_refCount; 274 #if !USE(LOCKFREE_THREADSAFESHARED) 176 275 mutable Mutex m_mutex; 177 int m_refCount;178 #ifndef NDEBUG179 bool m_inDestructor;180 276 #endif 181 277 };
Note: See TracChangeset
for help on using the changeset viewer.