diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/WordLock.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/WordLock.h')
-rw-r--r-- | Source/WTF/wtf/WordLock.h | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/Source/WTF/wtf/WordLock.h b/Source/WTF/wtf/WordLock.h new file mode 100644 index 000000000..52191ee01 --- /dev/null +++ b/Source/WTF/wtf/WordLock.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WTF_WordLock_h +#define WTF_WordLock_h + +#include <wtf/Atomics.h> +#include <wtf/Compiler.h> +#include <wtf/Locker.h> +#include <wtf/Noncopyable.h> + +namespace TestWebKitAPI { +struct LockInspector; +}; + +namespace WTF { + +// A WordLock is a fully adaptive mutex that uses sizeof(void*) storage. It has a fast path that is +// similar to a spinlock, and a slow path that is similar to std::mutex. In most cases, you should use +// Lock instead. WordLock sits lower in the stack and is used to implement Lock, so Lock is the main +// client of WordLock. + +// NOTE: This is also a great lock to use if you are very low in the stack. For example, +// PrintStream uses this so that ParkingLot and Lock can use PrintStream. This means that if you +// try to use dataLog to debug this code, you will have a bad time. + +struct WordLockBase { + void lock() + { + if (LIKELY(m_word.compareExchangeWeak(0, isLockedBit, std::memory_order_acquire))) { + // WordLock acquired! + return; + } + + lockSlow(); + } + + void unlock() + { + if (LIKELY(m_word.compareExchangeWeak(isLockedBit, 0, std::memory_order_release))) { + // WordLock released, and nobody was waiting! + return; + } + + unlockSlow(); + } + + bool isHeld() const + { + return m_word.load(std::memory_order_acquire) & isLockedBit; + } + + bool isLocked() const + { + return isHeld(); + } + +protected: + friend struct TestWebKitAPI::LockInspector; + + static const uintptr_t isLockedBit = 1; + static const uintptr_t isQueueLockedBit = 2; + static const uintptr_t queueHeadMask = 3; + + WTF_EXPORT_PRIVATE void lockSlow(); + WTF_EXPORT_PRIVATE void unlockSlow(); + + // Method used for testing only. + bool isFullyReset() const + { + return !m_word.load(); + } + + Atomic<uintptr_t> m_word; +}; + +class WordLock : public WordLockBase { + WTF_MAKE_NONCOPYABLE(WordLock); +public: + WordLock() + { + m_word.store(0, std::memory_order_relaxed); + } +}; + +typedef WordLockBase StaticWordLock; +typedef Locker<WordLockBase> WordLockHolder; + +} // namespace WTF + +using WTF::WordLock; +using WTF::WordLockHolder; +using WTF::StaticWordLock; + +#endif // WTF_WordLock_h + |