mtklein | 50ffd99 | 2015-03-30 08:13:33 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | // This file is not part of the public Skia API. |
| 9 | |
| 10 | #ifndef SkSpinlock_DEFINED |
| 11 | #define SkSpinlock_DEFINED |
| 12 | |
herb | e6e41a8 | 2015-09-28 11:24:13 -0700 | [diff] [blame] | 13 | #include "../private/SkAtomics.h" |
mtklein | 50ffd99 | 2015-03-30 08:13:33 -0700 | [diff] [blame] | 14 | |
| 15 | #define SK_DECLARE_STATIC_SPINLOCK(name) namespace {} static SkPODSpinlock name |
| 16 | |
| 17 | // This class has no constructor and must be zero-initialized (the macro above does this). |
dongseong.hwang | 5ce8b43 | 2015-07-10 08:32:23 -0700 | [diff] [blame] | 18 | class SK_API SkPODSpinlock { |
mtklein | 828877d | 2015-07-09 10:51:36 -0700 | [diff] [blame] | 19 | public: |
mtklein | 50ffd99 | 2015-03-30 08:13:33 -0700 | [diff] [blame] | 20 | void acquire() { |
mtklein | 828877d | 2015-07-09 10:51:36 -0700 | [diff] [blame] | 21 | // To act as a mutex, we need an acquire barrier if we take the lock. |
| 22 | if (sk_atomic_exchange(&fLocked, true, sk_memory_order_acquire)) { |
| 23 | // Lock was contended. Fall back to an out-of-line spin loop. |
| 24 | this->contendedAcquire(); |
| 25 | } |
mtklein | 50ffd99 | 2015-03-30 08:13:33 -0700 | [diff] [blame] | 26 | } |
mtklein | 828877d | 2015-07-09 10:51:36 -0700 | [diff] [blame] | 27 | |
mtklein | 50ffd99 | 2015-03-30 08:13:33 -0700 | [diff] [blame] | 28 | void release() { |
| 29 | // To act as a mutex, we need a release barrier. |
| 30 | sk_atomic_store(&fLocked, false, sk_memory_order_release); |
| 31 | } |
| 32 | |
mtklein | 828877d | 2015-07-09 10:51:36 -0700 | [diff] [blame] | 33 | private: |
| 34 | void contendedAcquire(); |
mtklein | 50ffd99 | 2015-03-30 08:13:33 -0700 | [diff] [blame] | 35 | bool fLocked; |
| 36 | }; |
| 37 | |
| 38 | // For non-global-static use cases, this is normally what you want. |
| 39 | class SkSpinlock : public SkPODSpinlock { |
| 40 | public: |
| 41 | SkSpinlock() { this->release(); } |
| 42 | }; |
| 43 | |
| 44 | #endif//SkSpinlock_DEFINED |