15dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy/* 25dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * Copyright (C) 2013 The Android Open Source Project 35dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * 45dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 55dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * you may not use this file except in compliance with the License. 65dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * You may obtain a copy of the License at 75dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * 85dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 95dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * 105dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * Unless required by applicable law or agreed to in writing, software 115dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 125dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * See the License for the specific language governing permissions and 145dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy * limitations under the License. 155dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy */ 165dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 175dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy#include <sys/sysinfo.h> 185dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 195dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy#include "Task.h" 205dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy#include "TaskProcessor.h" 215dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy#include "TaskManager.h" 225dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 235dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guynamespace android { 245dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guynamespace uirenderer { 255dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 265dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy/////////////////////////////////////////////////////////////////////////////// 275dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy// Manager 285dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy/////////////////////////////////////////////////////////////////////////////// 295dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 305dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain GuyTaskManager::TaskManager() { 315dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy // Get the number of available CPUs. This value does not change over time. 320a8c51b1d0d66d6060afcec1eab33091d49332aeRomain Guy int cpuCount = sysconf(_SC_NPROCESSORS_CONF); 335dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 345dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy for (int i = 0; i < cpuCount / 2; i++) { 355dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy String8 name; 365dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy name.appendFormat("hwuiTask%d", i + 1); 375dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy mThreads.add(new WorkerThread(name)); 385dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 395dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 405dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 415dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain GuyTaskManager::~TaskManager() { 425dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy for (size_t i = 0; i < mThreads.size(); i++) { 435dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy mThreads[i]->exit(); 445dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 455dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 465dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 475dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guybool TaskManager::canRunTasks() const { 485dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy return mThreads.size() > 0; 495dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 505dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 51c5cbee7d78513527e89450e6369a30a04b2d5e7aRomain Guyvoid TaskManager::stop() { 52c5cbee7d78513527e89450e6369a30a04b2d5e7aRomain Guy for (size_t i = 0; i < mThreads.size(); i++) { 53c5cbee7d78513527e89450e6369a30a04b2d5e7aRomain Guy mThreads[i]->exit(); 54c5cbee7d78513527e89450e6369a30a04b2d5e7aRomain Guy } 55c5cbee7d78513527e89450e6369a30a04b2d5e7aRomain Guy} 56c5cbee7d78513527e89450e6369a30a04b2d5e7aRomain Guy 575dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guybool TaskManager::addTaskBase(const sp<TaskBase>& task, const sp<TaskProcessorBase>& processor) { 585dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy if (mThreads.size() > 0) { 595dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy TaskWrapper wrapper(task, processor); 605dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 615dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy size_t minQueueSize = INT_MAX; 625dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy sp<WorkerThread> thread; 635dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 645dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy for (size_t i = 0; i < mThreads.size(); i++) { 655dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy if (mThreads[i]->getTaskCount() < minQueueSize) { 665dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy thread = mThreads[i]; 675dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy minQueueSize = mThreads[i]->getTaskCount(); 685dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 695dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 705dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 715dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy return thread->addTask(wrapper); 725dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 735dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy return false; 745dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 755dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 765dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy/////////////////////////////////////////////////////////////////////////////// 775dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy// Thread 785dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy/////////////////////////////////////////////////////////////////////////////// 795dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 805dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guybool TaskManager::WorkerThread::threadLoop() { 815dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy mSignal.wait(); 825dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy Vector<TaskWrapper> tasks; 835dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy { 845dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy Mutex::Autolock l(mLock); 855dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy tasks = mTasks; 865dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy mTasks.clear(); 875dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 885dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 895dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy for (size_t i = 0; i < tasks.size(); i++) { 905dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy const TaskWrapper& task = tasks.itemAt(i); 915dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy task.mProcessor->process(task.mTask); 925dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 935dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 945dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy return true; 955dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 965dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 975dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guybool TaskManager::WorkerThread::addTask(TaskWrapper task) { 985dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy if (!isRunning()) { 995dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy run(mName.string(), PRIORITY_DEFAULT); 1005dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 1015dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 1025dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy Mutex::Autolock l(mLock); 1035dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy ssize_t index = mTasks.add(task); 1045dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy mSignal.signal(); 1055dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 1065dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy return index >= 0; 1075dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 1085dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 1095dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guysize_t TaskManager::WorkerThread::getTaskCount() const { 1105dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy Mutex::Autolock l(mLock); 1115dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy return mTasks.size(); 1125dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 1135dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 1145dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guyvoid TaskManager::WorkerThread::exit() { 1155dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy { 1165dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy Mutex::Autolock l(mLock); 1175dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy mTasks.clear(); 1185dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy } 1195dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy requestExit(); 1205dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy mSignal.signal(); 1215dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy} 1225dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy 1235dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy}; // namespace uirenderer 1245dc7fa709646799a5207a5d217f70aa02bf4a3aaRomain Guy}; // namespace android 125