1363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/* 2363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Copyright 2012 Google Inc. 3363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * 4363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 5363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * found in the LICENSE file. 6363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 7363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 8363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#ifndef SkThreadPool_DEFINED 9363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#define SkThreadPool_DEFINED 10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkCondVar.h" 120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkRunnable.h" 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkTDArray.h" 14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkTInternalLList.h" 15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass SkThread; 17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass SkThreadPool { 19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerpublic: 21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** 227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Create a threadpool with count threads, or one thread per core if kThreadPerCore. 23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger static const int kThreadPerCore = -1; 25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger explicit SkThreadPool(int count); 26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ~SkThreadPool(); 27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** 29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Queues up an SkRunnable to run when a thread is available, or immediately if 30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * count is 0. NULL is a safe no-op. Does not take ownership. 31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */ 32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger void add(SkRunnable*); 33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger /** 350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Block until all added SkRunnables have completed. Once called, calling add() is undefined. 360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger */ 370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger void wait(); 380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger private: 40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger struct LinkedRunnable { 41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Unowned pointer. 42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkRunnable* fRunnable; 43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger private: 45363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SK_DECLARE_INTERNAL_LLIST_INTERFACE(LinkedRunnable); 46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger }; 47363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger enum State { 490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kRunning_State, // Normal case. We've been constructed and no one has called wait(). 500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kWaiting_State, // wait has been called, but there still might be work to do or being done. 510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kHalting_State, // There's no work to do and no thread is busy. All threads can shut down. 520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger }; 530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkTInternalLList<LinkedRunnable> fQueue; 550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkCondVar fReady; 560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkTDArray<SkThread*> fThreads; 570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger State fState; 580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger int fBusyThreads; 59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static void Loop(void*); // Static because we pass in this. 61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}; 62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#endif 64