GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID)
- return sysconf(_SC_NPROCESSORS_ONLN);
+ return (int) sysconf(_SC_NPROCESSORS_ONLN);
#else
return 1;
#endif
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();
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;
} // namespace SkThreadPoolPrivate
template <typename T>
-void SkTThreadPool<T>::add(SkTRunnable<T>* r) {
+void SkTThreadPool<T>::addSomewhere(SkTRunnable<T>* r,
+ void (SkTInternalLList<LinkedRunnable>::* f)(LinkedRunnable*)) {
if (r == NULL) {
return;
}
linkedRunnable->fRunnable = r;
fReady.lock();
SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when we're halting.
- fQueue.addToHead(linkedRunnable);
+ (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() {
// 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.tail();
+ LinkedRunnable* r = pool->fQueue.head();
pool->fQueue.remove(r);