| 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; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 gGlobal->add(&CallRunnable, task, pending); | 29 gGlobal->add(&CallRunnable, task, pending); |
| 30 } | 30 } |
| 31 | 31 |
| 32 static void Add(void (*fn)(void*), void* arg, int32_t* pending) { | 32 static void Add(void (*fn)(void*), void* arg, int32_t* pending) { |
| 33 if (!gGlobal) { | 33 if (!gGlobal) { |
| 34 return fn(arg); | 34 return fn(arg); |
| 35 } | 35 } |
| 36 gGlobal->add(fn, arg, pending); | 36 gGlobal->add(fn, arg, pending); |
| 37 } | 37 } |
| 38 | 38 |
| 39 static void Batch(void (*fn)(void*), void* args, int N, size_t stride, int32
_t* pending) { |
| 40 if (!gGlobal) { |
| 41 for (int i = 0; i < N; i++) { fn((char*)args + i*stride); } |
| 42 return; |
| 43 } |
| 44 gGlobal->batch(fn, args, N, stride, pending); |
| 45 } |
| 46 |
| 39 static void Wait(int32_t* pending) { | 47 static void Wait(int32_t* pending) { |
| 40 if (!gGlobal) { // If we have no threads, the work must already be done
. | 48 if (!gGlobal) { // If we have no threads, the work must already be done
. |
| 41 SkASSERT(*pending == 0); | 49 SkASSERT(*pending == 0); |
| 42 return; | 50 return; |
| 43 } | 51 } |
| 44 while (sk_acquire_load(pending) > 0) { // Pairs with sk_atomic_dec here
or in Loop. | 52 while (sk_acquire_load(pending) > 0) { // Pairs with sk_atomic_dec here
or in Loop. |
| 45 // Lend a hand until our SkTaskGroup of interest is done. | 53 // Lend a hand until our SkTaskGroup of interest is done. |
| 46 Work work; | 54 Work work; |
| 47 { | 55 { |
| 48 AutoLock lock(&gGlobal->fReady); | 56 AutoLock lock(&gGlobal->fReady); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 void add(void (*fn)(void*), void* arg, int32_t* pending) { | 111 void add(void (*fn)(void*), void* arg, int32_t* pending) { |
| 104 Work work = { fn, arg, pending }; | 112 Work work = { fn, arg, pending }; |
| 105 sk_atomic_inc(pending); // No barrier needed. | 113 sk_atomic_inc(pending); // No barrier needed. |
| 106 { | 114 { |
| 107 AutoLock lock(&fReady); | 115 AutoLock lock(&fReady); |
| 108 fWork.push(work); | 116 fWork.push(work); |
| 109 fReady.signal(); | 117 fReady.signal(); |
| 110 } | 118 } |
| 111 } | 119 } |
| 112 | 120 |
| 121 void batch(void (*fn)(void*), void* arg, int N, size_t stride, int32_t* pend
ing) { |
| 122 sk_atomic_add(pending, N); // No barrier needed. |
| 123 { |
| 124 AutoLock lock(&fReady); |
| 125 Work* batch = fWork.append(N); |
| 126 for (int i = 0; i < N; i++) { |
| 127 Work work = { fn, (char*)arg + i*stride, pending }; |
| 128 batch[i] = work; |
| 129 } |
| 130 fReady.broadcast(); |
| 131 } |
| 132 } |
| 133 |
| 113 static void Loop(void* arg) { | 134 static void Loop(void* arg) { |
| 114 ThreadPool* pool = (ThreadPool*)arg; | 135 ThreadPool* pool = (ThreadPool*)arg; |
| 115 Work work; | 136 Work work; |
| 116 while (true) { | 137 while (true) { |
| 117 { | 138 { |
| 118 AutoLock lock(&pool->fReady); | 139 AutoLock lock(&pool->fReady); |
| 119 while (pool->fWork.isEmpty()) { | 140 while (pool->fWork.isEmpty()) { |
| 120 if (pool->fDraining) { | 141 if (pool->fDraining) { |
| 121 return; | 142 return; |
| 122 } | 143 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 147 ThreadPool::gGlobal = SkNEW_ARGS(ThreadPool, (threads)); | 168 ThreadPool::gGlobal = SkNEW_ARGS(ThreadPool, (threads)); |
| 148 } | 169 } |
| 149 } | 170 } |
| 150 | 171 |
| 151 SkTaskGroup::Enabler::~Enabler() { | 172 SkTaskGroup::Enabler::~Enabler() { |
| 152 SkDELETE(ThreadPool::gGlobal); | 173 SkDELETE(ThreadPool::gGlobal); |
| 153 } | 174 } |
| 154 | 175 |
| 155 SkTaskGroup::SkTaskGroup() : fPending(0) {} | 176 SkTaskGroup::SkTaskGroup() : fPending(0) {} |
| 156 | 177 |
| 178 void SkTaskGroup::wait() { ThreadPool::Wait(&fPending
); } |
| 157 void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPe
nding); } | 179 void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPe
nding); } |
| 158 void SkTaskGroup::add(void (*fn)(void*), void* arg) { ThreadPool::Add(fn, arg, &
fPending); } | 180 void SkTaskGroup::add(void (*fn)(void*), void* arg) { ThreadPool::Add(fn, arg, &
fPending); } |
| 159 void SkTaskGroup::wait() { ThreadPool::Wait(&fPending
); } | 181 void SkTaskGroup::batch (void (*fn)(void*), void* args, int N, size_t stride) { |
| 182 ThreadPool::Batch(fn, args, N, stride, &fPending); |
| 183 } |
| 160 | 184 |
| OLD | NEW |