Chromium Code Reviews| Index: cc/base/worker_pool.cc |
| diff --git a/cc/base/worker_pool.cc b/cc/base/worker_pool.cc |
| index 0097ad998878a5d12b05d9af3eab4c7b69ea868e..fd07e6ce1871ce2d7a00be6e0c0368987ebb2426 100644 |
| --- a/cc/base/worker_pool.cc |
| +++ b/cc/base/worker_pool.cc |
| @@ -4,6 +4,11 @@ |
| #include "cc/base/worker_pool.h" |
| +#if defined(OS_ANDROID) |
| +// TODO(epenner): Move thread priorities to base. (crbug.com/170549) |
| +#include <sys/resource.h> |
| +#endif |
| + |
| #include <algorithm> |
| #include "base/bind.h" |
| @@ -12,11 +17,6 @@ |
| #include "base/synchronization/condition_variable.h" |
| #include "base/threading/simple_thread.h" |
| -#if defined(OS_ANDROID) |
| -// TODO(epenner): Move thread priorities to base. (crbug.com/170549) |
| -#include <sys/resource.h> |
| -#endif |
| - |
| namespace cc { |
| namespace { |
| @@ -28,12 +28,6 @@ class WorkerPoolTaskImpl : public internal::WorkerPoolTask { |
| : internal::WorkerPoolTask(reply), |
| task_(task) {} |
| - virtual bool IsCheap() OVERRIDE { return false; } |
| - |
| - virtual void Run() OVERRIDE { |
| - task_.Run(); |
| - } |
| - |
| virtual void RunOnThread(unsigned thread_index) OVERRIDE { |
| task_.Run(); |
| } |
| @@ -65,33 +59,23 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate { |
| public: |
| Inner(WorkerPool* worker_pool, |
| size_t num_threads, |
| - const std::string& thread_name_prefix, |
| - bool need_on_task_completed_callback); |
| + const std::string& thread_name_prefix); |
| virtual ~Inner(); |
| void Shutdown(); |
| - void PostTask(scoped_ptr<internal::WorkerPoolTask> task, bool signal_workers); |
| + void PostTask(scoped_ptr<internal::WorkerPoolTask> task); |
| // Appends all completed tasks to worker pool's completed tasks queue |
| // and returns true if idle. |
| bool CollectCompletedTasks(); |
| - // Runs cheap tasks on caller thread until |time_limit| is reached |
| - // and returns true if idle. |
| - bool RunCheapTasksUntilTimeLimit(base::TimeTicks time_limit); |
| - |
| private: |
| // Appends all completed tasks to |completed_tasks|. Lock must |
| // already be acquired before calling this function. |
| bool AppendCompletedTasksWithLockAcquired( |
| ScopedPtrDeque<internal::WorkerPoolTask>* completed_tasks); |
| - // Schedule a OnTaskCompletedOnOriginThread callback if not already |
| - // pending. Lock must already be acquired before calling this function. |
| - void ScheduleOnTaskCompletedWithLockAcquired(); |
| - void OnTaskCompletedOnOriginThread(); |
| - |
| // Schedule an OnIdleOnOriginThread callback if not already pending. |
| // Lock must already be acquired before calling this function. |
| void ScheduleOnIdleWithLockAcquired(); |
| @@ -118,14 +102,6 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate { |
| base::WeakPtrFactory<Inner> weak_ptr_factory_; |
| - // Set to true when worker pool requires a callback for each |
| - // completed task. |
| - bool need_on_task_completed_callback_; |
| - |
| - const base::Closure on_task_completed_callback_; |
| - // Set when a OnTaskCompletedOnOriginThread() callback is pending. |
| - bool on_task_completed_pending_; |
| - |
| const base::Closure on_idle_callback_; |
| // Set when a OnIdleOnOriginThread() callback is pending. |
| bool on_idle_pending_; |
| @@ -152,18 +128,12 @@ class WorkerPool::Inner : public base::DelegateSimpleThread::Delegate { |
| WorkerPool::Inner::Inner(WorkerPool* worker_pool, |
| size_t num_threads, |
| - const std::string& thread_name_prefix, |
| - bool need_on_task_completed_callback) |
| + const std::string& thread_name_prefix) |
| : worker_pool_on_origin_thread_(worker_pool), |
| lock_(), |
| has_pending_tasks_cv_(&lock_), |
| origin_loop_(base::MessageLoopProxy::current()), |
| weak_ptr_factory_(this), |
| - need_on_task_completed_callback_(need_on_task_completed_callback), |
| - on_task_completed_callback_( |
| - base::Bind(&WorkerPool::Inner::OnTaskCompletedOnOriginThread, |
| - weak_ptr_factory_.GetWeakPtr())), |
| - on_task_completed_pending_(false), |
| on_idle_callback_(base::Bind(&WorkerPool::Inner::OnIdleOnOriginThread, |
| weak_ptr_factory_.GetWeakPtr())), |
| on_idle_pending_(false), |
| @@ -178,8 +148,8 @@ WorkerPool::Inner::Inner(WorkerPool* worker_pool, |
| this, |
| thread_name_prefix + |
| base::StringPrintf( |
| - "Worker%lu", |
| - static_cast<unsigned long>(workers_.size() + 1)).c_str())); |
| + "Worker%u", |
| + static_cast<unsigned>(workers_.size() + 1)).c_str())); |
|
vmpstr
2013/04/26 22:51:35
nit: is the static_cast required here now?
reveman
2013/04/26 23:09:42
Done.
|
| worker->Start(); |
| workers_.push_back(worker.Pass()); |
| } |
| @@ -216,15 +186,13 @@ void WorkerPool::Inner::Shutdown() { |
| } |
| } |
| -void WorkerPool::Inner::PostTask(scoped_ptr<internal::WorkerPoolTask> task, |
| - bool signal_workers) { |
| +void WorkerPool::Inner::PostTask(scoped_ptr<internal::WorkerPoolTask> task) { |
| base::AutoLock lock(lock_); |
| pending_tasks_.push_back(task.Pass()); |
| // There is more work available, so wake up worker thread. |
| - if (signal_workers) |
| - has_pending_tasks_cv_.Signal(); |
| + has_pending_tasks_cv_.Signal(); |
| } |
| bool WorkerPool::Inner::CollectCompletedTasks() { |
| @@ -234,57 +202,6 @@ bool WorkerPool::Inner::CollectCompletedTasks() { |
| &worker_pool_on_origin_thread_->completed_tasks_); |
| } |
| -bool WorkerPool::Inner::RunCheapTasksUntilTimeLimit( |
| - base::TimeTicks time_limit) { |
| - base::AutoLock lock(lock_); |
| - |
| - while (base::TimeTicks::Now() < time_limit) { |
| - scoped_ptr<internal::WorkerPoolTask> task; |
| - |
| - // Find next cheap task. |
| - for (TaskDeque::iterator iter = pending_tasks_.begin(); |
| - iter != pending_tasks_.end(); ++iter) { |
| - if ((*iter)->IsCheap()) { |
| - task = pending_tasks_.take(iter); |
| - break; |
| - } |
| - } |
| - |
| - if (!task) { |
| - // Schedule an idle callback if requested and not pending. |
| - if (!running_task_count_ && pending_tasks_.empty()) |
| - ScheduleOnIdleWithLockAcquired(); |
| - |
| - // Exit when no more cheap tasks are pending. |
| - break; |
| - } |
| - |
| - // Increment |running_task_count_| before starting to run task. |
| - running_task_count_++; |
| - |
| - { |
| - base::AutoUnlock unlock(lock_); |
| - |
| - task->Run(); |
| - |
| - // Append tasks directly to worker pool's completed tasks queue. |
| - worker_pool_on_origin_thread_->completed_tasks_.push_back(task.Pass()); |
| - if (need_on_task_completed_callback_) |
| - worker_pool_on_origin_thread_->OnTaskCompleted(); |
| - } |
| - |
| - // Decrement |running_task_count_| now that we are done running task. |
| - running_task_count_--; |
| - } |
| - |
| - if (!pending_tasks_.empty()) |
| - has_pending_tasks_cv_.Signal(); |
| - |
| - // Append any other completed tasks before releasing lock. |
| - return AppendCompletedTasksWithLockAcquired( |
| - &worker_pool_on_origin_thread_->completed_tasks_); |
| -} |
| - |
| bool WorkerPool::Inner::AppendCompletedTasksWithLockAcquired( |
| ScopedPtrDeque<internal::WorkerPoolTask>* completed_tasks) { |
| lock_.AssertAcquired(); |
| @@ -295,29 +212,6 @@ bool WorkerPool::Inner::AppendCompletedTasksWithLockAcquired( |
| return !running_task_count_ && pending_tasks_.empty(); |
| } |
| -void WorkerPool::Inner::ScheduleOnTaskCompletedWithLockAcquired() { |
| - lock_.AssertAcquired(); |
| - |
| - if (on_task_completed_pending_ || !need_on_task_completed_callback_) |
| - return; |
| - origin_loop_->PostTask(FROM_HERE, on_task_completed_callback_); |
| - on_task_completed_pending_ = true; |
| -} |
| - |
| -void WorkerPool::Inner::OnTaskCompletedOnOriginThread() { |
| - { |
| - base::AutoLock lock(lock_); |
| - |
| - DCHECK(on_task_completed_pending_); |
| - on_task_completed_pending_ = false; |
| - |
| - AppendCompletedTasksWithLockAcquired( |
| - &worker_pool_on_origin_thread_->completed_tasks_); |
| - } |
| - |
| - worker_pool_on_origin_thread_->OnTaskCompleted(); |
| -} |
| - |
| void WorkerPool::Inner::ScheduleOnIdleWithLockAcquired() { |
| lock_.AssertAcquired(); |
| @@ -351,56 +245,52 @@ void WorkerPool::Inner::Run() { |
| int nice_value = 10; // Idle priority. |
| setpriority(PRIO_PROCESS, base::PlatformThread::CurrentId(), nice_value); |
| #endif |
| - { |
| - base::AutoLock lock(lock_); |
| - // Get a unique thread index. |
| - int thread_index = next_thread_index_++; |
| - |
| - while (true) { |
| - if (pending_tasks_.empty()) { |
| - // Exit when shutdown is set and no more tasks are pending. |
| - if (shutdown_) |
| - break; |
| - |
| - // Schedule an idle callback if requested and not pending. |
| - if (!running_task_count_) |
| - ScheduleOnIdleWithLockAcquired(); |
| + base::AutoLock lock(lock_); |
| - // Wait for new pending tasks. |
| - has_pending_tasks_cv_.Wait(); |
| - continue; |
| - } |
| + // Get a unique thread index. |
| + int thread_index = next_thread_index_++; |
| - // Get next task. |
| - scoped_ptr<internal::WorkerPoolTask> task = pending_tasks_.take_front(); |
| + while (true) { |
| + if (pending_tasks_.empty()) { |
| + // Exit when shutdown is set and no more tasks are pending. |
| + if (shutdown_) |
| + break; |
| - // Increment |running_task_count_| before starting to run task. |
| - running_task_count_++; |
| + // Schedule an idle callback if requested and not pending. |
| + if (!running_task_count_) |
| + ScheduleOnIdleWithLockAcquired(); |
| - // There may be more work available, so wake up another |
| - // worker thread. |
| - has_pending_tasks_cv_.Signal(); |
| + // Wait for new pending tasks. |
| + has_pending_tasks_cv_.Wait(); |
| + continue; |
| + } |
| - { |
| - base::AutoUnlock unlock(lock_); |
| + // Get next task. |
| + scoped_ptr<internal::WorkerPoolTask> task = pending_tasks_.take_front(); |
| - task->RunOnThread(thread_index); |
| - } |
| + // Increment |running_task_count_| before starting to run task. |
| + running_task_count_++; |
| - completed_tasks_.push_back(task.Pass()); |
| + // There may be more work available, so wake up another |
| + // worker thread. |
| + has_pending_tasks_cv_.Signal(); |
| - // Decrement |running_task_count_| now that we are done running task. |
| - running_task_count_--; |
| + { |
| + base::AutoUnlock unlock(lock_); |
| - // Schedule a task completed callback if requested and not pending. |
| - ScheduleOnTaskCompletedWithLockAcquired(); |
| + task->RunOnThread(thread_index); |
| } |
| - // We noticed we should exit. Wake up the next worker so it knows it should |
| - // exit as well (because the Shutdown() code only signals once). |
| - has_pending_tasks_cv_.Signal(); |
| + completed_tasks_.push_back(task.Pass()); |
| + |
| + // Decrement |running_task_count_| now that we are done running task. |
| + running_task_count_--; |
| } |
| + |
| + // We noticed we should exit. Wake up the next worker so it knows it should |
| + // exit as well (because the Shutdown() code only signals once). |
| + has_pending_tasks_cv_.Signal(); |
| } |
| WorkerPool::WorkerPool(WorkerPoolClient* client, |
| @@ -412,18 +302,9 @@ WorkerPool::WorkerPool(WorkerPoolClient* client, |
| weak_ptr_factory_(this), |
| check_for_completed_tasks_delay_(check_for_completed_tasks_delay), |
| check_for_completed_tasks_pending_(false), |
| - run_cheap_tasks_callback_( |
| - base::Bind(&WorkerPool::RunCheapTasks, |
| - weak_ptr_factory_.GetWeakPtr())), |
| - run_cheap_tasks_pending_(false), |
| - inner_(make_scoped_ptr( |
| - new Inner( |
| - this, |
| - num_threads, |
| - thread_name_prefix, |
| - // Request OnTaskCompleted() callback when check |
| - // for completed tasks delay is 0. |
| - check_for_completed_tasks_delay == base::TimeDelta()))) { |
| + inner_(make_scoped_ptr(new Inner(this, |
| + num_threads, |
| + thread_name_prefix))) { |
| } |
| WorkerPool::~WorkerPool() { |
| @@ -447,36 +328,19 @@ void WorkerPool::PostTaskAndReply( |
| reply)).PassAs<internal::WorkerPoolTask>()); |
| } |
| -void WorkerPool::SetRunCheapTasksTimeLimit( |
| - base::TimeTicks run_cheap_tasks_time_limit) { |
| - run_cheap_tasks_time_limit_ = run_cheap_tasks_time_limit; |
| - ScheduleRunCheapTasks(); |
| -} |
| - |
| void WorkerPool::OnIdle() { |
| TRACE_EVENT0("cc", "WorkerPool::OnIdle"); |
| DispatchCompletionCallbacks(); |
| } |
| -void WorkerPool::OnTaskCompleted() { |
| - TRACE_EVENT0("cc", "WorkerPool::OnTaskCompleted"); |
| - |
| - DispatchCompletionCallbacks(); |
| -} |
| - |
| void WorkerPool::ScheduleCheckForCompletedTasks() { |
| - if (check_for_completed_tasks_pending_ || |
| - check_for_completed_tasks_delay_ == base::TimeDelta()) |
| + if (check_for_completed_tasks_pending_) |
| return; |
| - check_for_completed_tasks_callback_.Reset( |
| - base::Bind(&WorkerPool::CheckForCompletedTasks, |
| - weak_ptr_factory_.GetWeakPtr())); |
| - check_for_completed_tasks_time_ = base::TimeTicks::Now() + |
| - check_for_completed_tasks_delay_; |
| origin_loop_->PostDelayedTask( |
| FROM_HERE, |
| - check_for_completed_tasks_callback_.callback(), |
| + base::Bind(&WorkerPool::CheckForCompletedTasks, |
| + weak_ptr_factory_.GetWeakPtr()), |
| check_for_completed_tasks_delay_); |
| check_for_completed_tasks_pending_ = true; |
| } |
| @@ -493,14 +357,6 @@ void WorkerPool::CheckForCompletedTasks() { |
| DispatchCompletionCallbacks(); |
| } |
| -void WorkerPool::CancelCheckForCompletedTasks() { |
| - if (!check_for_completed_tasks_pending_) |
| - return; |
| - |
| - check_for_completed_tasks_callback_.Cancel(); |
| - check_for_completed_tasks_pending_ = false; |
| -} |
| - |
| void WorkerPool::DispatchCompletionCallbacks() { |
| TRACE_EVENT0("cc", "WorkerPool::DispatchCompletionCallbacks"); |
| @@ -516,60 +372,10 @@ void WorkerPool::DispatchCompletionCallbacks() { |
| } |
| void WorkerPool::PostTask(scoped_ptr<internal::WorkerPoolTask> task) { |
| - bool signal_workers = true; |
| - if (task->IsCheap()) { |
| - // To make cheap tasks more likely to run on the origin thread, don't wake |
| - // workers when posting them. |
| - signal_workers = false; |
| - ScheduleRunCheapTasks(); |
| - } |
| - |
| // Schedule check for completed tasks if not pending. |
| ScheduleCheckForCompletedTasks(); |
| - inner_->PostTask(task.Pass(), signal_workers); |
| -} |
| - |
| -void WorkerPool::ScheduleRunCheapTasks() { |
| - if (run_cheap_tasks_pending_) |
| - return; |
| - origin_loop_->PostTask(FROM_HERE, run_cheap_tasks_callback_); |
| - run_cheap_tasks_pending_ = true; |
| -} |
| - |
| -void WorkerPool::RunCheapTasks() { |
| - TRACE_EVENT0("cc", "WorkerPool::RunCheapTasks"); |
| - DCHECK(run_cheap_tasks_pending_); |
| - run_cheap_tasks_pending_ = false; |
| - |
| - while (true) { |
| - base::TimeTicks time_limit = run_cheap_tasks_time_limit_; |
| - |
| - if (!check_for_completed_tasks_time_.is_null()) |
| - time_limit = std::min(time_limit, check_for_completed_tasks_time_); |
| - |
| - bool is_idle = inner_->RunCheapTasksUntilTimeLimit(time_limit); |
| - |
| - base::TimeTicks now = base::TimeTicks::Now(); |
| - if (now >= run_cheap_tasks_time_limit_) { |
| - TRACE_EVENT_INSTANT0("cc", "WorkerPool::RunCheapTasks out of time", |
| - TRACE_EVENT_SCOPE_THREAD); |
| - break; |
| - } |
| - |
| - // We must be out of cheap tasks if this happens. |
| - if (!check_for_completed_tasks_pending_ || |
| - now < check_for_completed_tasks_time_) |
| - break; |
| - |
| - TRACE_EVENT_INSTANT0("cc", "WorkerPool::RunCheapTasks check time", |
| - TRACE_EVENT_SCOPE_THREAD); |
| - CancelCheckForCompletedTasks(); |
| - DispatchCompletionCallbacks(); |
| - // Schedule another check for completed tasks if not idle. |
| - if (!is_idle) |
| - ScheduleCheckForCompletedTasks(); |
| - } |
| + inner_->PostTask(task.Pass()); |
| } |
| } // namespace cc |