Home | History | Annotate | Download | only in private
      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 #ifndef SkSpinlock_DEFINED
      9 #define SkSpinlock_DEFINED
     10 
     11 #include "SkTypes.h"
     12 #include <atomic>
     13 
     14 class SkSpinlock {
     15 public:
     16     constexpr SkSpinlock() = default;
     17 
     18     void acquire() {
     19         // To act as a mutex, we need an acquire barrier when we acquire the lock.
     20         if (fLocked.exchange(true, std::memory_order_acquire)) {
     21             // Lock was contended.  Fall back to an out-of-line spin loop.
     22             this->contendedAcquire();
     23         }
     24     }
     25 
     26     // Acquire the lock or fail (quickly). Lets the caller decide to do something other than wait.
     27     bool tryAcquire() {
     28         // To act as a mutex, we need an acquire barrier when we acquire the lock.
     29         if (fLocked.exchange(true, std::memory_order_acquire)) {
     30             // Lock was contended. Let the caller decide what to do.
     31             return false;
     32         }
     33         return true;
     34     }
     35 
     36     void release() {
     37         // To act as a mutex, we need a release barrier when we release the lock.
     38         fLocked.store(false, std::memory_order_release);
     39     }
     40 
     41 private:
     42     SK_API void contendedAcquire();
     43 
     44     std::atomic<bool> fLocked{false};
     45 };
     46 
     47 #endif//SkSpinlock_DEFINED
     48