| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/worker_pool_posix.h" | 5 #include "base/threading/worker_pool_posix.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 14 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
| 15 #include "base/threading/thread_local.h" |
| 15 #include "base/threading/worker_pool.h" | 16 #include "base/threading/worker_pool.h" |
| 16 #include "base/tracked_objects.h" | 17 #include "base/tracked_objects.h" |
| 17 | 18 |
| 18 using tracked_objects::TrackedTime; | 19 using tracked_objects::TrackedTime; |
| 19 | 20 |
| 20 namespace base { | 21 namespace base { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 25 base::LazyInstance<ThreadLocalBoolean>::Leaky |
| 26 g_worker_pool_running_on_this_thread = LAZY_INSTANCE_INITIALIZER; |
| 27 |
| 24 const int kIdleSecondsBeforeExit = 10 * 60; | 28 const int kIdleSecondsBeforeExit = 10 * 60; |
| 25 // A stack size of 64 KB is too small for the CERT_PKIXVerifyCert | 29 // A stack size of 64 KB is too small for the CERT_PKIXVerifyCert |
| 26 // function of NSS because of NSS bug 439169. | 30 // function of NSS because of NSS bug 439169. |
| 27 const int kWorkerThreadStackSize = 128 * 1024; | 31 const int kWorkerThreadStackSize = 128 * 1024; |
| 28 | 32 |
| 29 class WorkerPoolImpl { | 33 class WorkerPoolImpl { |
| 30 public: | 34 public: |
| 31 WorkerPoolImpl(); | 35 WorkerPoolImpl(); |
| 32 ~WorkerPoolImpl(); | 36 ~WorkerPoolImpl(); |
| 33 | 37 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 virtual void ThreadMain() OVERRIDE; | 69 virtual void ThreadMain() OVERRIDE; |
| 66 | 70 |
| 67 private: | 71 private: |
| 68 const std::string name_prefix_; | 72 const std::string name_prefix_; |
| 69 scoped_refptr<base::PosixDynamicThreadPool> pool_; | 73 scoped_refptr<base::PosixDynamicThreadPool> pool_; |
| 70 | 74 |
| 71 DISALLOW_COPY_AND_ASSIGN(WorkerThread); | 75 DISALLOW_COPY_AND_ASSIGN(WorkerThread); |
| 72 }; | 76 }; |
| 73 | 77 |
| 74 void WorkerThread::ThreadMain() { | 78 void WorkerThread::ThreadMain() { |
| 79 g_worker_pool_running_on_this_thread.Get().Set(true); |
| 75 const std::string name = base::StringPrintf( | 80 const std::string name = base::StringPrintf( |
| 76 "%s/%d", name_prefix_.c_str(), PlatformThread::CurrentId()); | 81 "%s/%d", name_prefix_.c_str(), PlatformThread::CurrentId()); |
| 77 // Note |name.c_str()| must remain valid for for the whole life of the thread. | 82 // Note |name.c_str()| must remain valid for for the whole life of the thread. |
| 78 PlatformThread::SetName(name.c_str()); | 83 PlatformThread::SetName(name.c_str()); |
| 79 | 84 |
| 80 for (;;) { | 85 for (;;) { |
| 81 PendingTask pending_task = pool_->WaitForTask(); | 86 PendingTask pending_task = pool_->WaitForTask(); |
| 82 if (pending_task.task.is_null()) | 87 if (pending_task.task.is_null()) |
| 83 break; | 88 break; |
| 84 TRACE_EVENT2("task", "WorkerThread::ThreadMain::Run", | 89 TRACE_EVENT2("task", "WorkerThread::ThreadMain::Run", |
| 85 "src_file", pending_task.posted_from.file_name(), | 90 "src_file", pending_task.posted_from.file_name(), |
| 86 "src_func", pending_task.posted_from.function_name()); | 91 "src_func", pending_task.posted_from.function_name()); |
| 87 | 92 |
| 88 TrackedTime start_time = | 93 TrackedTime start_time = |
| 89 tracked_objects::ThreadData::NowForStartOfRun(pending_task.birth_tally); | 94 tracked_objects::ThreadData::NowForStartOfRun(pending_task.birth_tally); |
| 90 | 95 |
| 91 pending_task.task.Run(); | 96 pending_task.task.Run(); |
| 92 | 97 |
| 93 tracked_objects::ThreadData::TallyRunOnWorkerThreadIfTracking( | 98 tracked_objects::ThreadData::TallyRunOnWorkerThreadIfTracking( |
| 94 pending_task.birth_tally, TrackedTime(pending_task.time_posted), | 99 pending_task.birth_tally, TrackedTime(pending_task.time_posted), |
| 95 start_time, tracked_objects::ThreadData::NowForEndOfRun()); | 100 start_time, tracked_objects::ThreadData::NowForEndOfRun()); |
| 96 } | 101 } |
| 97 | 102 |
| 98 // The WorkerThread is non-joinable, so it deletes itself. | 103 // The WorkerThread is non-joinable, so it deletes itself. |
| 99 delete this; | 104 delete this; |
| 100 } | 105 } |
| 101 | 106 |
| 102 } // namespace | 107 } // namespace |
| 103 | 108 |
| 109 // static |
| 104 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, | 110 bool WorkerPool::PostTask(const tracked_objects::Location& from_here, |
| 105 const base::Closure& task, bool task_is_slow) { | 111 const base::Closure& task, bool task_is_slow) { |
| 106 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); | 112 g_lazy_worker_pool.Pointer()->PostTask(from_here, task, task_is_slow); |
| 107 return true; | 113 return true; |
| 108 } | 114 } |
| 109 | 115 |
| 116 // static |
| 117 bool WorkerPool::RunsTasksOnCurrentThread() { |
| 118 return g_worker_pool_running_on_this_thread.Get().Get(); |
| 119 } |
| 120 |
| 110 PosixDynamicThreadPool::PosixDynamicThreadPool( | 121 PosixDynamicThreadPool::PosixDynamicThreadPool( |
| 111 const std::string& name_prefix, | 122 const std::string& name_prefix, |
| 112 int idle_seconds_before_exit) | 123 int idle_seconds_before_exit) |
| 113 : name_prefix_(name_prefix), | 124 : name_prefix_(name_prefix), |
| 114 idle_seconds_before_exit_(idle_seconds_before_exit), | 125 idle_seconds_before_exit_(idle_seconds_before_exit), |
| 115 pending_tasks_available_cv_(&lock_), | 126 pending_tasks_available_cv_(&lock_), |
| 116 num_idle_threads_(0), | 127 num_idle_threads_(0), |
| 117 terminated_(false), | 128 terminated_(false), |
| 118 num_idle_threads_cv_(NULL) {} | 129 num_idle_threads_cv_(NULL) {} |
| 119 | 130 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 return PendingTask(FROM_HERE, base::Closure()); | 190 return PendingTask(FROM_HERE, base::Closure()); |
| 180 } | 191 } |
| 181 } | 192 } |
| 182 | 193 |
| 183 PendingTask pending_task = pending_tasks_.front(); | 194 PendingTask pending_task = pending_tasks_.front(); |
| 184 pending_tasks_.pop(); | 195 pending_tasks_.pop(); |
| 185 return pending_task; | 196 return pending_task; |
| 186 } | 197 } |
| 187 | 198 |
| 188 } // namespace base | 199 } // namespace base |
| OLD | NEW |