• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) const25 bool SequenceToken::operator==(const SequenceToken& other) const {
26   return token_ == other.token_ && IsValid();
27 }
28 
operator !=(const SequenceToken & other) const29 bool SequenceToken::operator!=(const SequenceToken& other) const {
30   return !(*this == other);
31 }
32 
IsValid() const33 bool SequenceToken::IsValid() const {
34   return token_ != kInvalidSequenceToken;
35 }
36 
ToInternalValue() const37 int SequenceToken::ToInternalValue() const {
38   return token_;
39 }
40 
Create()41 SequenceToken SequenceToken::Create() {
42   return SequenceToken(g_sequence_token_generator.GetNext());
43 }
44 
GetForCurrentThread()45 SequenceToken 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) const53 bool TaskToken::operator==(const TaskToken& other) const {
54   return token_ == other.token_ && IsValid();
55 }
56 
operator !=(const TaskToken & other) const57 bool TaskToken::operator!=(const TaskToken& other) const {
58   return !(*this == other);
59 }
60 
IsValid() const61 bool TaskToken::IsValid() const {
62   return token_ != kInvalidTaskToken;
63 }
64 
Create()65 TaskToken TaskToken::Create() {
66   return TaskToken(g_task_token_generator.GetNext());
67 }
68 
GetForCurrentThread()69 TaskToken TaskToken::GetForCurrentThread() {
70   return current_task_token;
71 }
72 
CurrentTaskIsThreadBound()73 bool CurrentTaskIsThreadBound() {
74   return current_task_is_thread_bound;
75 }
76 
TaskScope(SequenceToken sequence_token,bool is_single_threaded,bool is_running_synchronously)77 TaskScope::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()91 TaskScope::~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()101 bool CurrentTaskIsRunningSynchronously() {
102   return internal::current_task_is_running_synchronously;
103 }
104 
105 }  // namespace base
106