OLD | NEW |
1 #include "SkTaskGroup.h" | 1 #include "SkTaskGroup.h" |
2 | 2 |
3 #include "SkCondVar.h" | 3 #include "SkCondVar.h" |
4 #include "SkTDArray.h" | 4 #include "SkTDArray.h" |
5 #include "SkThread.h" | 5 #include "SkThread.h" |
6 #include "SkThreadUtils.h" | 6 #include "SkThreadUtils.h" |
7 | 7 |
8 #if defined(SK_BUILD_FOR_WIN32) | 8 #if defined(SK_BUILD_FOR_WIN32) |
9 static inline int num_cores() { | 9 static inline int num_cores() { |
10 SYSTEM_INFO sysinfo; | 10 SYSTEM_INFO sysinfo; |
11 GetSystemInfo(&sysinfo); | 11 GetSystemInfo(&sysinfo); |
12 return sysinfo.dwNumberOfProcessors; | 12 return sysinfo.dwNumberOfProcessors; |
13 } | 13 } |
14 #else | 14 #else |
15 #include <unistd.h> | 15 #include <unistd.h> |
16 static inline int num_cores() { | 16 static inline int num_cores() { |
17 return (int) sysconf(_SC_NPROCESSORS_ONLN); | 17 return (int) sysconf(_SC_NPROCESSORS_ONLN); |
18 } | 18 } |
19 #endif | 19 #endif |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 class ThreadPool : SkNoncopyable { | 23 class ThreadPool : SkNoncopyable { |
24 public: | 24 public: |
25 static void Add(SkRunnable* task, int32_t* pending) { | 25 static void Add(SkRunnable* task, int32_t* pending) { |
26 SkASSERT(gGlobal); // If this fails, see SkTaskGroup::Enabler. | 26 if (!gGlobal) { // If we have no threads, run synchronously. |
| 27 return task->run(); |
| 28 } |
27 gGlobal->add(task, pending); | 29 gGlobal->add(task, pending); |
28 } | 30 } |
29 | 31 |
30 static void Wait(int32_t* pending) { | 32 static void Wait(int32_t* pending) { |
31 SkASSERT(gGlobal); // If this fails, see SkTaskGroup::Enabler. | 33 if (!gGlobal) { // If we have no threads, the work must already be done
. |
| 34 SkASSERT(*pending == 0); |
| 35 return; |
| 36 } |
32 while (sk_acquire_load(pending) > 0) { // Pairs with sk_atomic_dec here
or in Loop. | 37 while (sk_acquire_load(pending) > 0) { // Pairs with sk_atomic_dec here
or in Loop. |
33 // Lend a hand until our SkTaskGroup of interest is done. | 38 // Lend a hand until our SkTaskGroup of interest is done. |
34 Work work; | 39 Work work; |
35 { | 40 { |
36 AutoLock lock(&gGlobal->fReady); | 41 AutoLock lock(&gGlobal->fReady); |
37 if (gGlobal->fWork.isEmpty()) { | 42 if (gGlobal->fWork.isEmpty()) { |
38 // Someone has picked up all the work (including ours). How
nice of them! | 43 // Someone has picked up all the work (including ours). How
nice of them! |
39 // (They may still be working on it, so we can't assert *pen
ding == 0 here.) | 44 // (They may still be working on it, so we can't assert *pen
ding == 0 here.) |
40 continue; | 45 continue; |
41 } | 46 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 SkTaskGroup::Enabler::~Enabler() { | 139 SkTaskGroup::Enabler::~Enabler() { |
135 SkASSERT(ThreadPool::gGlobal != NULL); | 140 SkASSERT(ThreadPool::gGlobal != NULL); |
136 SkDELETE(ThreadPool::gGlobal); | 141 SkDELETE(ThreadPool::gGlobal); |
137 } | 142 } |
138 | 143 |
139 SkTaskGroup::SkTaskGroup() : fPending(0) {} | 144 SkTaskGroup::SkTaskGroup() : fPending(0) {} |
140 | 145 |
141 void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPending); } | 146 void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPending); } |
142 void SkTaskGroup::wait() { ThreadPool::Wait(&fPending); } | 147 void SkTaskGroup::wait() { ThreadPool::Wait(&fPending); } |
143 | 148 |
OLD | NEW |