Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(690)

Side by Side Diff: include/utils/SkThreadPool.h

Issue 263803003: DM: Push GPU-parent child tasks to the front of the queue. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: share code Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « dm/DMTaskRunner.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkThreadPool_DEFINED 8 #ifndef SkThreadPool_DEFINED
9 #define SkThreadPool_DEFINED 9 #define SkThreadPool_DEFINED
10 10
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 ~SkTThreadPool(); 43 ~SkTThreadPool();
44 44
45 /** 45 /**
46 * Queues up an SkRunnable to run when a thread is available, or synchronous ly if count is 0. 46 * Queues up an SkRunnable to run when a thread is available, or synchronous ly if count is 0.
47 * Does not take ownership. NULL is a safe no-op. If T is not void, the run nable will be passed 47 * Does not take ownership. NULL is a safe no-op. If T is not void, the run nable will be passed
48 * a reference to a T on the thread's local stack. 48 * a reference to a T on the thread's local stack.
49 */ 49 */
50 void add(SkTRunnable<T>*); 50 void add(SkTRunnable<T>*);
51 51
52 /** 52 /**
53 * Same as add, but adds the runnable as the very next to run rather than en queueing it.
54 */
55 void addNext(SkTRunnable<T>*);
56
57 /**
53 * Block until all added SkRunnables have completed. Once called, calling a dd() is undefined. 58 * Block until all added SkRunnables have completed. Once called, calling a dd() is undefined.
54 */ 59 */
55 void wait(); 60 void wait();
56 61
57 private: 62 private:
58 struct LinkedRunnable { 63 struct LinkedRunnable {
59 SkTRunnable<T>* fRunnable; // Unowned. 64 SkTRunnable<T>* fRunnable; // Unowned.
60 SK_DECLARE_INTERNAL_LLIST_INTERFACE(LinkedRunnable); 65 SK_DECLARE_INTERNAL_LLIST_INTERFACE(LinkedRunnable);
61 }; 66 };
62 67
63 enum State { 68 enum State {
64 kRunning_State, // Normal case. We've been constructed and no one has called wait(). 69 kRunning_State, // Normal case. We've been constructed and no one has called wait().
65 kWaiting_State, // wait has been called, but there still might be work to do or being done. 70 kWaiting_State, // wait has been called, but there still might be work to do or being done.
66 kHalting_State, // There's no work to do and no thread is busy. All th reads can shut down. 71 kHalting_State, // There's no work to do and no thread is busy. All th reads can shut down.
67 }; 72 };
68 73
74 void addSomewhere(SkTRunnable<T>* r,
75 void (SkTInternalLList<LinkedRunnable>::*)(LinkedRunnable* ));
76
69 SkTInternalLList<LinkedRunnable> fQueue; 77 SkTInternalLList<LinkedRunnable> fQueue;
70 SkCondVar fReady; 78 SkCondVar fReady;
71 SkTDArray<SkThread*> fThreads; 79 SkTDArray<SkThread*> fThreads;
72 State fState; 80 State fState;
73 int fBusyThreads; 81 int fBusyThreads;
74 82
75 static void Loop(void*); // Static because we pass in this. 83 static void Loop(void*); // Static because we pass in this.
76 }; 84 };
77 85
78 template <typename T> 86 template <typename T>
(...skipping 25 matching lines...) Expand all
104 }; 112 };
105 113
106 template <> 114 template <>
107 struct ThreadLocal<void> { 115 struct ThreadLocal<void> {
108 void run(SkTRunnable<void>* r) { r->run(); } 116 void run(SkTRunnable<void>* r) { r->run(); }
109 }; 117 };
110 118
111 } // namespace SkThreadPoolPrivate 119 } // namespace SkThreadPoolPrivate
112 120
113 template <typename T> 121 template <typename T>
114 void SkTThreadPool<T>::add(SkTRunnable<T>* r) { 122 void SkTThreadPool<T>::addSomewhere(SkTRunnable<T>* r,
123 void (SkTInternalLList<LinkedRunnable>::* f) (LinkedRunnable*)) {
115 if (r == NULL) { 124 if (r == NULL) {
116 return; 125 return;
117 } 126 }
118 127
119 if (fThreads.isEmpty()) { 128 if (fThreads.isEmpty()) {
120 SkThreadPoolPrivate::ThreadLocal<T> threadLocal; 129 SkThreadPoolPrivate::ThreadLocal<T> threadLocal;
121 threadLocal.run(r); 130 threadLocal.run(r);
122 return; 131 return;
123 } 132 }
124 133
125 LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable); 134 LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable);
126 linkedRunnable->fRunnable = r; 135 linkedRunnable->fRunnable = r;
127 fReady.lock(); 136 fReady.lock();
128 SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when w e're halting. 137 SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when w e're halting.
129 fQueue.addToHead(linkedRunnable); 138 (fQueue.*f)(linkedRunnable);
130 fReady.signal(); 139 fReady.signal();
131 fReady.unlock(); 140 fReady.unlock();
132 } 141 }
133 142
143 template <typename T>
144 void SkTThreadPool<T>::add(SkTRunnable<T>* r) {
145 this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToTail);
146 }
147
148 template <typename T>
149 void SkTThreadPool<T>::addNext(SkTRunnable<T>* r) {
150 this->addSomewhere(r, &SkTInternalLList<LinkedRunnable>::addToHead);
151 }
152
134 153
135 template <typename T> 154 template <typename T>
136 void SkTThreadPool<T>::wait() { 155 void SkTThreadPool<T>::wait() {
137 fReady.lock(); 156 fReady.lock();
138 fState = kWaiting_State; 157 fState = kWaiting_State;
139 fReady.broadcast(); 158 fReady.broadcast();
140 fReady.unlock(); 159 fReady.unlock();
141 160
142 // Wait for all threads to stop. 161 // Wait for all threads to stop.
143 for (int i = 0; i < fThreads.count(); i++) { 162 for (int i = 0; i < fThreads.count(); i++) {
(...skipping 23 matching lines...) Expand all
167 if (kHalting_State == pool->fState) { 186 if (kHalting_State == pool->fState) {
168 pool->fReady.unlock(); 187 pool->fReady.unlock();
169 return; 188 return;
170 } 189 }
171 // wait yields the lock while waiting, but will have it again when a woken. 190 // wait yields the lock while waiting, but will have it again when a woken.
172 pool->fReady.wait(); 191 pool->fReady.wait();
173 } 192 }
174 // We've got the lock back here, no matter if we ran wait or not. 193 // We've got the lock back here, no matter if we ran wait or not.
175 194
176 // The queue is not empty, so we have something to run. Claim it. 195 // The queue is not empty, so we have something to run. Claim it.
177 LinkedRunnable* r = pool->fQueue.tail(); 196 LinkedRunnable* r = pool->fQueue.head();
178 197
179 pool->fQueue.remove(r); 198 pool->fQueue.remove(r);
180 199
181 // Having claimed our SkRunnable, we now give up the lock while we run i t. 200 // Having claimed our SkRunnable, we now give up the lock while we run i t.
182 // Otherwise, we'd only ever do work on one thread at a time, which rath er 201 // Otherwise, we'd only ever do work on one thread at a time, which rath er
183 // defeats the point of this code. 202 // defeats the point of this code.
184 pool->fBusyThreads++; 203 pool->fBusyThreads++;
185 pool->fReady.unlock(); 204 pool->fReady.unlock();
186 205
187 // OK, now really do the work. 206 // OK, now really do the work.
188 threadLocal.run(r->fRunnable); 207 threadLocal.run(r->fRunnable);
189 SkDELETE(r); 208 SkDELETE(r);
190 209
191 // Let everyone know we're not busy. 210 // Let everyone know we're not busy.
192 pool->fReady.lock(); 211 pool->fReady.lock();
193 pool->fBusyThreads--; 212 pool->fBusyThreads--;
194 pool->fReady.unlock(); 213 pool->fReady.unlock();
195 } 214 }
196 215
197 SkASSERT(false); // Unreachable. The only exit happens when pool->fState is kHalting_State. 216 SkASSERT(false); // Unreachable. The only exit happens when pool->fState is kHalting_State.
198 } 217 }
199 218
200 typedef SkTThreadPool<void> SkThreadPool; 219 typedef SkTThreadPool<void> SkThreadPool;
201 220
202 #endif 221 #endif
OLDNEW
« no previous file with comments | « dm/DMTaskRunner.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698