1*6777b538SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #include "base/sequence_token.h" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker #include "base/atomic_sequence_num.h" 8*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/base/attributes.h" 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker namespace base { 11*6777b538SAndroid Build Coastguard Worker namespace internal { 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker namespace { 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker base::AtomicSequenceNumber g_sequence_token_generator; 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker base::AtomicSequenceNumber g_task_token_generator; 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local SequenceToken current_sequence_token; 20*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local TaskToken current_task_token; 21*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local bool current_task_is_thread_bound = true; 22*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local bool current_task_is_running_synchronously = false; 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker } // namespace 25*6777b538SAndroid Build Coastguard Worker operator ==(const SequenceToken & other) const26*6777b538SAndroid Build Coastguard Workerbool SequenceToken::operator==(const SequenceToken& other) const { 27*6777b538SAndroid Build Coastguard Worker return token_ == other.token_ && IsValid(); 28*6777b538SAndroid Build Coastguard Worker } 29*6777b538SAndroid Build Coastguard Worker operator !=(const SequenceToken & other) const30*6777b538SAndroid Build Coastguard Workerbool SequenceToken::operator!=(const SequenceToken& other) const { 31*6777b538SAndroid Build Coastguard Worker return !(*this == other); 32*6777b538SAndroid Build Coastguard Worker } 33*6777b538SAndroid Build Coastguard Worker IsValid() const34*6777b538SAndroid Build Coastguard Workerbool SequenceToken::IsValid() const { 35*6777b538SAndroid Build Coastguard Worker return token_ != kInvalidSequenceToken; 36*6777b538SAndroid Build Coastguard Worker } 37*6777b538SAndroid Build Coastguard Worker ToInternalValue() const38*6777b538SAndroid Build Coastguard Workerint SequenceToken::ToInternalValue() const { 39*6777b538SAndroid Build Coastguard Worker return token_; 40*6777b538SAndroid Build Coastguard Worker } 41*6777b538SAndroid Build Coastguard Worker Create()42*6777b538SAndroid Build Coastguard WorkerSequenceToken SequenceToken::Create() { 43*6777b538SAndroid Build Coastguard Worker return SequenceToken(g_sequence_token_generator.GetNext()); 44*6777b538SAndroid Build Coastguard Worker } 45*6777b538SAndroid Build Coastguard Worker GetForCurrentThread()46*6777b538SAndroid Build Coastguard WorkerSequenceToken SequenceToken::GetForCurrentThread() { 47*6777b538SAndroid Build Coastguard Worker if (!current_sequence_token.IsValid()) { 48*6777b538SAndroid Build Coastguard Worker current_sequence_token = SequenceToken::Create(); 49*6777b538SAndroid Build Coastguard Worker DCHECK(current_task_is_thread_bound); 50*6777b538SAndroid Build Coastguard Worker } 51*6777b538SAndroid Build Coastguard Worker return current_sequence_token; 52*6777b538SAndroid Build Coastguard Worker } 53*6777b538SAndroid Build Coastguard Worker operator ==(const TaskToken & other) const54*6777b538SAndroid Build Coastguard Workerbool TaskToken::operator==(const TaskToken& other) const { 55*6777b538SAndroid Build Coastguard Worker return token_ == other.token_ && IsValid(); 56*6777b538SAndroid Build Coastguard Worker } 57*6777b538SAndroid Build Coastguard Worker operator !=(const TaskToken & other) const58*6777b538SAndroid Build Coastguard Workerbool TaskToken::operator!=(const TaskToken& other) const { 59*6777b538SAndroid Build Coastguard Worker return !(*this == other); 60*6777b538SAndroid Build Coastguard Worker } 61*6777b538SAndroid Build Coastguard Worker IsValid() const62*6777b538SAndroid Build Coastguard Workerbool TaskToken::IsValid() const { 63*6777b538SAndroid Build Coastguard Worker return token_ != kInvalidTaskToken; 64*6777b538SAndroid Build Coastguard Worker } 65*6777b538SAndroid Build Coastguard Worker Create()66*6777b538SAndroid Build Coastguard WorkerTaskToken TaskToken::Create() { 67*6777b538SAndroid Build Coastguard Worker return TaskToken(g_task_token_generator.GetNext()); 68*6777b538SAndroid Build Coastguard Worker } 69*6777b538SAndroid Build Coastguard Worker GetForCurrentThread()70*6777b538SAndroid Build Coastguard WorkerTaskToken TaskToken::GetForCurrentThread() { 71*6777b538SAndroid Build Coastguard Worker return current_task_token; 72*6777b538SAndroid Build Coastguard Worker } 73*6777b538SAndroid Build Coastguard Worker CurrentTaskIsThreadBound()74*6777b538SAndroid Build Coastguard Workerbool CurrentTaskIsThreadBound() { 75*6777b538SAndroid Build Coastguard Worker return current_task_is_thread_bound; 76*6777b538SAndroid Build Coastguard Worker } 77*6777b538SAndroid Build Coastguard Worker TaskScope(SequenceToken sequence_token,bool is_single_threaded,bool is_running_synchronously)78*6777b538SAndroid Build Coastguard WorkerTaskScope::TaskScope(SequenceToken sequence_token, 79*6777b538SAndroid Build Coastguard Worker bool is_single_threaded, 80*6777b538SAndroid Build Coastguard Worker bool is_running_synchronously) 81*6777b538SAndroid Build Coastguard Worker : previous_task_token_(TaskToken::GetForCurrentThread()), 82*6777b538SAndroid Build Coastguard Worker previous_sequence_token_(SequenceToken::GetForCurrentThread()), 83*6777b538SAndroid Build Coastguard Worker previous_task_is_thread_bound_(current_task_is_thread_bound), 84*6777b538SAndroid Build Coastguard Worker previous_task_is_running_synchronously_( 85*6777b538SAndroid Build Coastguard Worker current_task_is_running_synchronously) { 86*6777b538SAndroid Build Coastguard Worker current_task_token = TaskToken::Create(); 87*6777b538SAndroid Build Coastguard Worker current_sequence_token = sequence_token; 88*6777b538SAndroid Build Coastguard Worker current_task_is_thread_bound = is_single_threaded; 89*6777b538SAndroid Build Coastguard Worker current_task_is_running_synchronously = is_running_synchronously; 90*6777b538SAndroid Build Coastguard Worker } 91*6777b538SAndroid Build Coastguard Worker ~TaskScope()92*6777b538SAndroid Build Coastguard WorkerTaskScope::~TaskScope() { 93*6777b538SAndroid Build Coastguard Worker current_task_token = previous_task_token_; 94*6777b538SAndroid Build Coastguard Worker current_sequence_token = previous_sequence_token_; 95*6777b538SAndroid Build Coastguard Worker current_task_is_thread_bound = previous_task_is_thread_bound_; 96*6777b538SAndroid Build Coastguard Worker current_task_is_running_synchronously = 97*6777b538SAndroid Build Coastguard Worker previous_task_is_running_synchronously_; 98*6777b538SAndroid Build Coastguard Worker } 99*6777b538SAndroid Build Coastguard Worker 100*6777b538SAndroid Build Coastguard Worker } // namespace internal 101*6777b538SAndroid Build Coastguard Worker CurrentTaskIsRunningSynchronously()102*6777b538SAndroid Build Coastguard Workerbool CurrentTaskIsRunningSynchronously() { 103*6777b538SAndroid Build Coastguard Worker return internal::current_task_is_running_synchronously; 104*6777b538SAndroid Build Coastguard Worker } 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker } // namespace base 107