OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/threading/simple_thread.h" | 5 #include "base/threading/simple_thread.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/threading/platform_thread.h" | 9 #include "base/threading/platform_thread.h" |
10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
11 | 11 |
12 namespace base { | 12 namespace base { |
13 | 13 |
14 SimpleThread::SimpleThread(const std::string& name_prefix) | 14 SimpleThread::SimpleThread(const std::string& name_prefix) |
15 : name_prefix_(name_prefix), name_(name_prefix), | 15 : name_prefix_(name_prefix), |
16 thread_(), event_(true, false), tid_(0), joined_(false) { | 16 name_(name_prefix), |
17 } | 17 thread_(), |
| 18 event_(true, false), |
| 19 tid_(0), |
| 20 joined_(false), |
| 21 priority_(options_.priority()) {} |
18 | 22 |
19 SimpleThread::SimpleThread(const std::string& name_prefix, | 23 SimpleThread::SimpleThread(const std::string& name_prefix, |
20 const Options& options) | 24 const Options& options) |
21 : name_prefix_(name_prefix), name_(name_prefix), options_(options), | 25 : name_prefix_(name_prefix), |
22 thread_(), event_(true, false), tid_(0), joined_(false) { | 26 name_(name_prefix), |
23 } | 27 options_(options), |
| 28 thread_(), |
| 29 event_(true, false), |
| 30 tid_(0), |
| 31 joined_(false), |
| 32 priority_(options_.priority()) {} |
24 | 33 |
25 SimpleThread::~SimpleThread() { | 34 SimpleThread::~SimpleThread() { |
26 DCHECK(HasBeenStarted()) << "SimpleThread was never started."; | 35 DCHECK(HasBeenStarted()) << "SimpleThread was never started."; |
27 DCHECK(HasBeenJoined()) << "SimpleThread destroyed without being Join()ed."; | 36 DCHECK(HasBeenJoined()) << "SimpleThread destroyed without being Join()ed."; |
28 } | 37 } |
29 | 38 |
30 void SimpleThread::Start() { | 39 void SimpleThread::Start() { |
31 DCHECK(!HasBeenStarted()) << "Tried to Start a thread multiple times."; | 40 DCHECK(!HasBeenStarted()) << "Tried to Start a thread multiple times."; |
32 bool success; | 41 bool success; |
33 if (options_.priority() == ThreadPriority::NORMAL) { | 42 if (options_.priority() == ThreadPriority::NORMAL) { |
34 success = PlatformThread::Create(options_.stack_size(), this, &thread_); | 43 success = PlatformThread::Create(options_.stack_size(), this, &thread_); |
35 } else { | 44 } else { |
36 success = PlatformThread::CreateWithPriority(options_.stack_size(), this, | 45 success = PlatformThread::CreateWithPriority(options_.stack_size(), this, |
37 &thread_, options_.priority()); | 46 &thread_, options_.priority()); |
38 } | 47 } |
39 DCHECK(success); | 48 DCHECK(success); |
40 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 49 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
41 event_.Wait(); // Wait for the thread to complete initialization. | 50 event_.Wait(); // Wait for the thread to complete initialization. |
42 } | 51 } |
43 | 52 |
| 53 bool SimpleThread::SetThreadPriority(ThreadPriority priority) { |
| 54 if (PlatformThread::SetThreadPriority(tid_, priority)) { |
| 55 priority_ = priority; |
| 56 return true; |
| 57 } |
| 58 return false; |
| 59 } |
| 60 |
44 void SimpleThread::Join() { | 61 void SimpleThread::Join() { |
45 DCHECK(HasBeenStarted()) << "Tried to Join a never-started thread."; | 62 DCHECK(HasBeenStarted()) << "Tried to Join a never-started thread."; |
46 DCHECK(!HasBeenJoined()) << "Tried to Join a thread multiple times."; | 63 DCHECK(!HasBeenJoined()) << "Tried to Join a thread multiple times."; |
47 PlatformThread::Join(thread_); | 64 PlatformThread::Join(thread_); |
48 joined_ = true; | 65 joined_ = true; |
49 } | 66 } |
50 | 67 |
51 bool SimpleThread::HasBeenStarted() { | 68 bool SimpleThread::HasBeenStarted() { |
52 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 69 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
53 return event_.IsSignaled(); | 70 return event_.IsSignaled(); |
54 } | 71 } |
55 | 72 |
56 void SimpleThread::ThreadMain() { | 73 void SimpleThread::ThreadMain() { |
57 tid_ = PlatformThread::CurrentId(); | 74 tid_ = PlatformThread::CurrentId(); |
58 // Construct our full name of the form "name_prefix_/TID". | 75 // Construct our full name of the form "name_prefix_/TID". |
59 name_.push_back('/'); | 76 name_.push_back('/'); |
60 name_.append(IntToString(tid_)); | 77 name_.append(IntToString(tid_)); |
61 PlatformThread::SetName(name_); | 78 PlatformThread::SetName(name_); |
62 | 79 |
63 // We've initialized our new thread, signal that we're done to Start(). | 80 // We've initialized our new thread, signal that we're done to Start(). |
64 event_.Signal(); | 81 event_.Signal(); |
65 | 82 |
66 Run(); | 83 Run(); |
67 } | 84 } |
68 | 85 |
| 86 TestSimpleThread::TestSimpleThread(const PrioritySet& priorities, |
| 87 const std::string& name_prefix, |
| 88 const Options& options) |
| 89 : SimpleThread(name_prefix, options), |
| 90 priorities_(priorities), |
| 91 dynamic_prio_(false), |
| 92 changed_(false) { |
| 93 CHECK(priorities_.high_prio == priorities_.default_prio || |
| 94 priorities_.low_prio == priorities_.default_prio); |
| 95 dynamic_prio_ = priorities_.high_prio != priorities_.low_prio; |
| 96 } |
| 97 |
| 98 bool TestSimpleThread::Speedup() { |
| 99 if (dynamic_prio_ && (GetThreadPriority() != priorities_.high_prio)) { |
| 100 SetThreadPriority(priorities_.high_prio); |
| 101 changed_ = true; |
| 102 return true; |
| 103 } |
| 104 return false; |
| 105 } |
| 106 |
| 107 bool TestSimpleThread::Slowdown() { |
| 108 if (dynamic_prio_ && (GetThreadPriority() != priorities_.low_prio)) { |
| 109 SetThreadPriority(priorities_.low_prio); |
| 110 changed_ = true; |
| 111 return true; |
| 112 } |
| 113 return false; |
| 114 } |
| 115 |
| 116 bool TestSimpleThread::Restore() { |
| 117 if (dynamic_prio_ && changed_) { |
| 118 changed_ = false; |
| 119 SetThreadPriority(priorities_.default_prio); |
| 120 // LOG(ERROR) << "\nPRAS:: [" << std::hex << this << "] " |
| 121 // << GetPrioritySetForDebugging() << ". Restored to default."; |
| 122 return true; |
| 123 } |
| 124 return false; |
| 125 } |
| 126 |
| 127 std::string GetPriorityString(ThreadPriority prio) { |
| 128 std::string str; |
| 129 if (prio == base::ThreadPriority::BACKGROUND) |
| 130 str = "background"; |
| 131 else if (prio == base::ThreadPriority::NORMAL) |
| 132 str = "normal"; |
| 133 else if (prio == base::ThreadPriority::DISPLAY) |
| 134 str = "display"; |
| 135 else if (prio == base::ThreadPriority::REALTIME_AUDIO) |
| 136 str = "audio"; |
| 137 else |
| 138 str = "WRONG"; |
| 139 |
| 140 return str; |
| 141 } |
| 142 |
| 143 std::string TestSimpleThread::GetPrioritySetForDebugging() { |
| 144 static bool once = true; |
| 145 |
| 146 if (once) { |
| 147 std::ostringstream stream; |
| 148 stream << "{ Default = " << GetPriorityString(priorities_.default_prio) |
| 149 << ", Low = " << GetPriorityString(priorities_.low_prio) |
| 150 << ", High = " << GetPriorityString(priorities_.high_prio) << "}"; |
| 151 priorities_str_ = stream.str(); |
| 152 } |
| 153 |
| 154 std::string str = "Current = "; |
| 155 str += GetPriorityString(GetThreadPriority()); |
| 156 str += ", "; |
| 157 str += priorities_str_; |
| 158 |
| 159 return str; |
| 160 } |
| 161 |
69 DelegateSimpleThread::DelegateSimpleThread(Delegate* delegate, | 162 DelegateSimpleThread::DelegateSimpleThread(Delegate* delegate, |
70 const std::string& name_prefix) | 163 const std::string& name_prefix) |
71 : SimpleThread(name_prefix), | 164 : SimpleThread(name_prefix), |
72 delegate_(delegate) { | 165 delegate_(delegate) { |
73 } | 166 } |
74 | 167 |
75 DelegateSimpleThread::DelegateSimpleThread(Delegate* delegate, | 168 DelegateSimpleThread::DelegateSimpleThread(Delegate* delegate, |
76 const std::string& name_prefix, | 169 const std::string& name_prefix, |
77 const Options& options) | 170 const Options& options) |
78 : SimpleThread(name_prefix, options), | 171 : SimpleThread(name_prefix, options), |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 249 |
157 // A NULL delegate pointer signals us to quit. | 250 // A NULL delegate pointer signals us to quit. |
158 if (!work) | 251 if (!work) |
159 break; | 252 break; |
160 | 253 |
161 work->Run(); | 254 work->Run(); |
162 } | 255 } |
163 } | 256 } |
164 | 257 |
165 } // namespace base | 258 } // namespace base |
OLD | NEW |