1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/sequence_token.h" 6 7 #include "base/atomic_sequence_num.h" 8 9 namespace base { 10 namespace internal { 11 12 namespace { 13 14 base::AtomicSequenceNumber g_sequence_token_generator; 15 16 base::AtomicSequenceNumber g_task_token_generator; 17 18 constinit thread_local SequenceToken current_sequence_token; 19 constinit thread_local TaskToken current_task_token; 20 constinit thread_local bool current_task_is_thread_bound = true; 21 constinit thread_local bool current_task_is_running_synchronously = false; 22 23 } // namespace 24 operator ==(const SequenceToken & other) const25bool SequenceToken::operator==(const SequenceToken& other) const { 26 return token_ == other.token_ && IsValid(); 27 } 28 operator !=(const SequenceToken & other) const29bool SequenceToken::operator!=(const SequenceToken& other) const { 30 return !(*this == other); 31 } 32 IsValid() const33bool SequenceToken::IsValid() const { 34 return token_ != kInvalidSequenceToken; 35 } 36 ToInternalValue() const37int SequenceToken::ToInternalValue() const { 38 return token_; 39 } 40 Create()41SequenceToken SequenceToken::Create() { 42 return SequenceToken(g_sequence_token_generator.GetNext()); 43 } 44 GetForCurrentThread()45SequenceToken SequenceToken::GetForCurrentThread() { 46 if (!current_sequence_token.IsValid()) { 47 current_sequence_token = SequenceToken::Create(); 48 DCHECK(current_task_is_thread_bound); 49 } 50 return current_sequence_token; 51 } 52 operator ==(const TaskToken & other) const53bool TaskToken::operator==(const TaskToken& other) const { 54 return token_ == other.token_ && IsValid(); 55 } 56 operator !=(const TaskToken & other) const57bool TaskToken::operator!=(const TaskToken& other) const { 58 return !(*this == other); 59 } 60 IsValid() const61bool TaskToken::IsValid() const { 62 return token_ != kInvalidTaskToken; 63 } 64 Create()65TaskToken TaskToken::Create() { 66 return TaskToken(g_task_token_generator.GetNext()); 67 } 68 GetForCurrentThread()69TaskToken TaskToken::GetForCurrentThread() { 70 return current_task_token; 71 } 72 CurrentTaskIsThreadBound()73bool CurrentTaskIsThreadBound() { 74 return current_task_is_thread_bound; 75 } 76 TaskScope(SequenceToken sequence_token,bool is_single_threaded,bool is_running_synchronously)77TaskScope::TaskScope(SequenceToken sequence_token, 78 bool is_single_threaded, 79 bool is_running_synchronously) 80 : previous_task_token_(TaskToken::GetForCurrentThread()), 81 previous_sequence_token_(SequenceToken::GetForCurrentThread()), 82 previous_task_is_thread_bound_(current_task_is_thread_bound), 83 previous_task_is_running_synchronously_( 84 current_task_is_running_synchronously) { 85 current_task_token = TaskToken::Create(); 86 current_sequence_token = sequence_token; 87 current_task_is_thread_bound = is_single_threaded; 88 current_task_is_running_synchronously = is_running_synchronously; 89 } 90 ~TaskScope()91TaskScope::~TaskScope() { 92 current_task_token = previous_task_token_; 93 current_sequence_token = previous_sequence_token_; 94 current_task_is_thread_bound = previous_task_is_thread_bound_; 95 current_task_is_running_synchronously = 96 previous_task_is_running_synchronously_; 97 } 98 99 } // namespace internal 100 CurrentTaskIsRunningSynchronously()101bool CurrentTaskIsRunningSynchronously() { 102 return internal::current_task_is_running_synchronously; 103 } 104 105 } // namespace base 106