tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

serial_utils.h (3985B)


      1 //
      2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 // serial_utils:
      7 //   Utilities for generating unique IDs for resources in ANGLE.
      8 //
      9 
     10 #ifndef LIBANGLE_RENDERER_SERIAL_UTILS_H_
     11 #define LIBANGLE_RENDERER_SERIAL_UTILS_H_
     12 
     13 #include <atomic>
     14 #include <limits>
     15 
     16 #include "common/angleutils.h"
     17 #include "common/debug.h"
     18 
     19 namespace rx
     20 {
     21 class ResourceSerial
     22 {
     23  public:
     24    constexpr ResourceSerial() : mValue(kDirty) {}
     25    explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {}
     26    constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; }
     27    constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; }
     28 
     29    void dirty() { mValue = kDirty; }
     30    void clear() { mValue = kEmpty; }
     31 
     32    constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; }
     33    constexpr bool empty() const { return mValue == kEmpty; }
     34 
     35  private:
     36    constexpr static uintptr_t kDirty = std::numeric_limits<uintptr_t>::max();
     37    constexpr static uintptr_t kEmpty = 0;
     38 
     39    uintptr_t mValue;
     40 };
     41 
     42 class Serial final
     43 {
     44  public:
     45    constexpr Serial() : mValue(kInvalid) {}
     46    constexpr Serial(const Serial &other)  = default;
     47    Serial &operator=(const Serial &other) = default;
     48 
     49    static constexpr Serial Infinite() { return Serial(std::numeric_limits<uint64_t>::max()); }
     50 
     51    constexpr bool operator==(const Serial &other) const
     52    {
     53        return mValue != kInvalid && mValue == other.mValue;
     54    }
     55    constexpr bool operator==(uint32_t value) const
     56    {
     57        return mValue != kInvalid && mValue == static_cast<uint64_t>(value);
     58    }
     59    constexpr bool operator!=(const Serial &other) const
     60    {
     61        return mValue == kInvalid || mValue != other.mValue;
     62    }
     63    constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; }
     64    constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; }
     65    constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; }
     66    constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; }
     67 
     68    constexpr bool operator<(uint32_t value) const { return mValue < static_cast<uint64_t>(value); }
     69 
     70    // Useful for serialization.
     71    constexpr uint64_t getValue() const { return mValue; }
     72    constexpr bool valid() const { return mValue != kInvalid; }
     73 
     74  private:
     75    template <typename T>
     76    friend class SerialFactoryBase;
     77    friend class AtomicQueueSerial;
     78    constexpr explicit Serial(uint64_t value) : mValue(value) {}
     79    uint64_t mValue;
     80    static constexpr uint64_t kInvalid = 0;
     81 };
     82 
     83 // Defines class to track the queue serial that can be load/store from multiple threads atomically.
     84 class AtomicQueueSerial final
     85 {
     86  public:
     87    constexpr AtomicQueueSerial() : mValue(kInvalid) { ASSERT(mValue.is_lock_free()); }
     88    AtomicQueueSerial &operator=(const Serial &other)
     89    {
     90        mValue.store(other.mValue, std::memory_order_release);
     91        return *this;
     92    }
     93    Serial getSerial() const { return Serial(mValue.load(std::memory_order_consume)); }
     94 
     95  private:
     96    std::atomic<uint64_t> mValue;
     97    static constexpr uint64_t kInvalid = 0;
     98 };
     99 
    100 // Used as default/initial serial
    101 static constexpr Serial kZeroSerial = Serial();
    102 
    103 template <typename SerialBaseType>
    104 class SerialFactoryBase final : angle::NonCopyable
    105 {
    106  public:
    107    SerialFactoryBase() : mSerial(1) {}
    108 
    109    Serial generate()
    110    {
    111        uint64_t current = mSerial++;
    112        ASSERT(mSerial > current);  // Integer overflow
    113        return Serial(current);
    114    }
    115 
    116  private:
    117    SerialBaseType mSerial;
    118 };
    119 
    120 using SerialFactory           = SerialFactoryBase<uint64_t>;
    121 using AtomicSerialFactory     = SerialFactoryBase<std::atomic<uint64_t>>;
    122 using RenderPassSerialFactory = SerialFactoryBase<uint64_t>;
    123 
    124 }  // namespace rx
    125 
    126 #endif  // LIBANGLE_RENDERER_SERIAL_UTILS_H_