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 |