aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/utils
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2014-08-06 06:55:12 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-06 06:55:12 -0700
commit847092c88be671c06bdf24aa02b5a66e7a593a15 (patch)
tree60909e9c901e0310d1e1379d8c8193fefd38cad3 /include/utils
parent70f25c1a3f5677ff582399e138a82653a5bfe7c8 (diff)
SkThreadPool and co. are not public.
BUG=skia: R=reed@google.com, mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/444583006
Diffstat (limited to 'include/utils')
-rw-r--r--include/utils/SkCondVar.h78
-rw-r--r--include/utils/SkRunnable.h25
-rw-r--r--include/utils/SkThreadPool.h221
3 files changed, 0 insertions, 324 deletions
diff --git a/include/utils/SkCondVar.h b/include/utils/SkCondVar.h
deleted file mode 100644
index 6f18e1a651..0000000000
--- a/include/utils/SkCondVar.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkCondVar_DEFINED
-#define SkCondVar_DEFINED
-
-/**
- * Import any thread model setting from configuration files.
- */
-#include "SkTypes.h"
-
-#ifdef SK_USE_POSIX_THREADS
-#include <pthread.h>
-#elif defined(SK_BUILD_FOR_WIN32)
-#include <windows.h>
-#else
-/**
- * Warn if the implementation of this class is empty, i.e. thread safety is not working.
- */
-#warning "Thread safety class SkCondVar has no implementation!"
-#endif
-
-/**
- * Condition variable for blocking access to shared data from other threads and
- * controlling which threads are awake.
- *
- * Currently only supported on platforms with posix threads and Windows Vista and
- * above.
- */
-class SkCondVar {
-public:
- SkCondVar();
- ~SkCondVar();
-
- /**
- * Lock a mutex. Must be done before calling the other functions on this object.
- */
- void lock();
-
- /**
- * Unlock the mutex.
- */
- void unlock();
-
- /**
- * Pause the calling thread. Will be awoken when signal() or broadcast() is called.
- * Must be called while lock() is held (but gives it up while waiting). Once awoken,
- * the calling thread will hold the lock once again.
- */
- void wait();
-
- /**
- * Wake one thread waiting on this condition. Must be called while lock()
- * is held.
- */
- void signal();
-
- /**
- * Wake all threads waiting on this condition. Must be called while lock()
- * is held.
- */
- void broadcast();
-
-private:
-#ifdef SK_USE_POSIX_THREADS
- pthread_mutex_t fMutex;
- pthread_cond_t fCond;
-#elif defined(SK_BUILD_FOR_WIN32)
- CRITICAL_SECTION fCriticalSection;
- CONDITION_VARIABLE fCondition;
-#endif
-};
-
-#endif
diff --git a/include/utils/SkRunnable.h b/include/utils/SkRunnable.h
deleted file mode 100644
index 5acf4dbc61..0000000000
--- a/include/utils/SkRunnable.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkRunnable_DEFINED
-#define SkRunnable_DEFINED
-
-template <typename T>
-struct SkTRunnable {
- virtual ~SkTRunnable() {};
- virtual void run(T&) = 0;
-};
-
-template <>
-struct SkTRunnable<void> {
- virtual ~SkTRunnable() {};
- virtual void run() = 0;
-};
-
-typedef SkTRunnable<void> SkRunnable;
-
-#endif
diff --git a/include/utils/SkThreadPool.h b/include/utils/SkThreadPool.h
deleted file mode 100644
index c99c5c4188..0000000000
--- a/include/utils/SkThreadPool.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkThreadPool_DEFINED
-#define SkThreadPool_DEFINED
-
-#include "SkCondVar.h"
-#include "SkRunnable.h"
-#include "SkTDArray.h"
-#include "SkTInternalLList.h"
-#include "SkThreadUtils.h"
-#include "SkTypes.h"
-
-#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID)
-# include <unistd.h>
-#endif
-
-// Returns the number of cores on this machine.
-static inline int num_cores() {
-#if defined(SK_BUILD_FOR_WIN32)
- SYSTEM_INFO sysinfo;
- GetSystemInfo(&sysinfo);
- return sysinfo.dwNumberOfProcessors;
-#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID)
- return (int) sysconf(_SC_NPROCESSORS_ONLN);
-#else
- return 1;
-#endif
-}
-
-template <typename T>
-class SkTThreadPool {
-public:
- /**
- * Create a threadpool with count threads, or one thread per core if kThreadPerCore.
- */
- static const int kThreadPerCore = -1;
- explicit SkTThreadPool(int count);
- ~SkTThreadPool();
-
- /**
- * Queues up an SkRunnable to run when a thread is available, or synchronously if count is 0.
- * Does not take ownership. NULL is a safe no-op. If T is not void, the runnable will be passed
- * a reference to a T on the thread's local stack.
- */
- void add(SkTRunnable<T>*);
-
- /**
- * Same as add, but adds the runnable as the very next to run rather than enqueueing it.
- */
- void addNext(SkTRunnable<T>*);
-
- /**
- * Block until all added SkRunnables have completed. Once called, calling add() is undefined.
- */
- void wait();
-
- private:
- struct LinkedRunnable {
- SkTRunnable<T>* fRunnable; // Unowned.
- SK_DECLARE_INTERNAL_LLIST_INTERFACE(LinkedRunnable);
- };
-
- enum State {
- kRunning_State, // Normal case. We've been constructed and no one has called wait().
- kWaiting_State, // wait has been called, but there still might be work to do or being done.
- kHalting_State, // There's no work to do and no thread is busy. All threads can shut down.
- };
-
- void addSomewhere(SkTRunnable<T>* r,
- void (SkTInternalLList<LinkedRunnable>::*)(LinkedRunnable*));
-
- SkTInternalLList<LinkedRunnable> fQueue;
- SkCondVar fReady;
- SkTDArray<SkThread*> fThreads;
- State fState;
- int fBusyThreads;
-
- static void Loop(void*); // Static because we pass in this.
-};
-
-template <typename T>
-SkTThreadPool<T>::SkTThreadPool(int count) : fState(kRunning_State), fBusyThreads(0) {
- if (count < 0) {
- count = num_cores();
- }
- // Create count threads, all running SkTThreadPool::Loop.
- for (int i = 0; i < count; i++) {
- SkThread* thread = SkNEW_ARGS(SkThread, (&SkTThreadPool::Loop, this));
- *fThreads.append() = thread;
- thread->start();
- }
-}
-
-template <typename T>
-SkTThreadPool<T>::~SkTThreadPool() {
- if (kRunning_State == fState) {
- this->wait();
- }
-}
-
-namespace SkThreadPoolPrivate {
-
-template <typename T>
-struct ThreadLocal {
- void run(SkTRunnable<T>* r) { r->run(data); }
- T data;
-};
-
-template <>
-struct ThreadLocal<void> {
- void run(SkTRunnable<void>* r) { r->run(); }
-};
-
-} // namespace SkThreadPoolPrivate
-
-template <typename T>
-void SkTThreadPool<T>::addSomewhere(SkTRunnable<T>* r,
- void (SkTInternalLList<LinkedRunnable>::* f)(LinkedRunnable*)) {
- if (r == NULL) {
- return;
- }
-
- if (fThreads.isEmpty()) {
- SkThreadPoolPrivate::ThreadLocal<T> threadLocal;
- threadLocal.run(r);
- return;
- }
-
- LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable);
- linkedRunnable->fRunnable = r;
- fReady.lock();
- SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when we're halting.
- (fQueue.*f)(linkedRunnable);
- fReady.signal();
- fReady.unlock();
-}
-
-template <typename T>
-void SkTThreadPool<T>::add(SkTRunnable<T>* r) {
- this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToTail);
-}
-
-template <typename T>
-void SkTThreadPool<T>::addNext(SkTRunnable<T>* r) {
- this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToHead);
-}
-
-
-template <typename T>
-void SkTThreadPool<T>::wait() {
- fReady.lock();
- fState = kWaiting_State;
- fReady.broadcast();
- fReady.unlock();
-
- // Wait for all threads to stop.
- for (int i = 0; i < fThreads.count(); i++) {
- fThreads[i]->join();
- SkDELETE(fThreads[i]);
- }
- SkASSERT(fQueue.isEmpty());
-}
-
-template <typename T>
-/*static*/ void SkTThreadPool<T>::Loop(void* arg) {
- // The SkTThreadPool passes itself as arg to each thread as they're created.
- SkTThreadPool<T>* pool = static_cast<SkTThreadPool<T>*>(arg);
- SkThreadPoolPrivate::ThreadLocal<T> threadLocal;
-
- while (true) {
- // We have to be holding the lock to read the queue and to call wait.
- pool->fReady.lock();
- while(pool->fQueue.isEmpty()) {
- // Does the client want to stop and are all the threads ready to stop?
- // If so, we move into the halting state, and whack all the threads so they notice.
- if (kWaiting_State == pool->fState && pool->fBusyThreads == 0) {
- pool->fState = kHalting_State;
- pool->fReady.broadcast();
- }
- // Any time we find ourselves in the halting state, it's quitting time.
- if (kHalting_State == pool->fState) {
- pool->fReady.unlock();
- return;
- }
- // wait yields the lock while waiting, but will have it again when awoken.
- pool->fReady.wait();
- }
- // We've got the lock back here, no matter if we ran wait or not.
-
- // The queue is not empty, so we have something to run. Claim it.
- LinkedRunnable* r = pool->fQueue.head();
-
- pool->fQueue.remove(r);
-
- // Having claimed our SkRunnable, we now give up the lock while we run it.
- // Otherwise, we'd only ever do work on one thread at a time, which rather
- // defeats the point of this code.
- pool->fBusyThreads++;
- pool->fReady.unlock();
-
- // OK, now really do the work.
- threadLocal.run(r->fRunnable);
- SkDELETE(r);
-
- // Let everyone know we're not busy.
- pool->fReady.lock();
- pool->fBusyThreads--;
- pool->fReady.unlock();
- }
-
- SkASSERT(false); // Unreachable. The only exit happens when pool->fState is kHalting_State.
-}
-
-typedef SkTThreadPool<void> SkThreadPool;
-
-#endif