| // Copyright 2018 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef BASE_TASK_SEQUENCE_MANAGER_ENQUEUE_ORDER_H_ | |
| #define BASE_TASK_SEQUENCE_MANAGER_ENQUEUE_ORDER_H_ | |
| #include <atomic> | |
| #ifdef STARBOARD | |
| #include "base/atomicops.h" | |
| #endif | |
| #include "base/base_export.h" | |
| #include "base/macros.h" | |
| #include "starboard/types.h" | |
| namespace base { | |
| namespace sequence_manager { | |
| namespace internal { | |
| // 64-bit number which is used to order tasks. | |
| // SequenceManager assumes this number will never overflow. | |
| class EnqueueOrder { | |
| public: | |
| EnqueueOrder() : value_(kNone) {} | |
| ~EnqueueOrder() = default; | |
| static EnqueueOrder none() { return EnqueueOrder(kNone); } | |
| static EnqueueOrder blocking_fence() { return EnqueueOrder(kBlockingFence); } | |
| // It's okay to use EnqueueOrder in boolean expressions keeping in mind | |
| // that some non-zero values have a special meaning. | |
| operator uint64_t() const { return value_; } | |
| static EnqueueOrder FromIntForTesting(uint64_t value) { | |
| return EnqueueOrder(value); | |
| } | |
| // EnqueueOrder can't be created from a raw number in non-test code. | |
| // Generator is used to create it with strictly monotonic guarantee. | |
| class BASE_EXPORT Generator { | |
| public: | |
| Generator(); | |
| ~Generator(); | |
| // Can be called from any thread. | |
| EnqueueOrder GenerateNext() { | |
| #ifdef STARBOARD | |
| // subtle::NoBarrier_AtomicIncrement returns the new value | |
| // while std::atomic_fetch_add_explicit returns the old one, so let's | |
| // subtract 1 back. | |
| return EnqueueOrder( | |
| subtle::NoBarrier_AtomicIncrement(&counter_, subtle::Atomic32(1)) - | |
| 1); | |
| } | |
| private: | |
| subtle::Atomic32 counter_; | |
| #else | |
| return EnqueueOrder(std::atomic_fetch_add_explicit( | |
| &counter_, uint64_t(1), std::memory_order_relaxed)); | |
| } | |
| private: | |
| std::atomic<uint64_t> counter_; | |
| #endif | |
| DISALLOW_COPY_AND_ASSIGN(Generator); | |
| }; | |
| private: | |
| explicit EnqueueOrder(uint64_t value) : value_(value) {} | |
| enum SpecialValues : uint64_t { | |
| kNone = 0, | |
| kBlockingFence = 1, | |
| kFirst = 2, | |
| }; | |
| uint64_t value_; | |
| }; | |
| } // namespace internal | |
| } // namespace sequence_manager | |
| } // namespace base | |
| #endif // BASE_TASK_SEQUENCE_MANAGER_ENQUEUE_ORDER_H_ |