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

Side by Side Diff: src/core/SkSharedMutex.cpp

Issue 1371303003: Unify ThreadID. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: use kIllegalThreadID Created 5 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 #include "SkSharedMutex.h" 8 #include "SkSharedMutex.h"
9 9
10 #include "SkAtomics.h" 10 #include "SkAtomics.h"
11 #include "SkTypes.h" 11 #include "SkTypes.h"
12 #include "../private/SkSemaphore.h" 12 #include "SkSemaphore.h"
13 13
14 #if defined(THREAD_SANITIZER) 14 #if defined(THREAD_SANITIZER)
15 15
16 /* Report that a lock has been created at address "lock". */ 16 /* Report that a lock has been created at address "lock". */
17 #define ANNOTATE_RWLOCK_CREATE(lock) \ 17 #define ANNOTATE_RWLOCK_CREATE(lock) \
18 AnnotateRWLockCreate(__FILE__, __LINE__, lock) 18 AnnotateRWLockCreate(__FILE__, __LINE__, lock)
19 19
20 /* Report that the lock at address "lock" is about to be destroyed. */ 20 /* Report that the lock at address "lock" is about to be destroyed. */
21 #define ANNOTATE_RWLOCK_DESTROY(lock) \ 21 #define ANNOTATE_RWLOCK_DESTROY(lock) \
22 AnnotateRWLockDestroy(__FILE__, __LINE__, lock) 22 AnnotateRWLockDestroy(__FILE__, __LINE__, lock)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 #define ANNOTATE_RWLOCK_CREATE(lock) 62 #define ANNOTATE_RWLOCK_CREATE(lock)
63 #define ANNOTATE_RWLOCK_DESTROY(lock) 63 #define ANNOTATE_RWLOCK_DESTROY(lock)
64 #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) 64 #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w)
65 #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) 65 #define ANNOTATE_RWLOCK_RELEASED(lock, is_w)
66 66
67 #endif 67 #endif
68 68
69 #ifdef SK_DEBUG 69 #ifdef SK_DEBUG
70 70
71 #include "SkThreadID.h"
71 #include "SkTDArray.h" 72 #include "SkTDArray.h"
72 #ifdef SK_BUILD_FOR_WIN
73 #include <windows.h>
74 static int64_t get_thread_id() { return GetCurrentThreadId(); }
75 #else
76 #include <pthread.h>
77 static int64_t get_thread_id() { return (int64_t)pthread_self(); }
78 #endif
79
80 typedef int64_t ThreadID;
81 73
82 class SkSharedMutex::ThreadIDSet { 74 class SkSharedMutex::ThreadIDSet {
83 public: 75 public:
84 // Returns true if threadID is in the set. 76 // Returns true if threadID is in the set.
85 bool find(ThreadID threadID) const { 77 bool find(SkThreadID threadID) const {
86 for (auto& t : fThreadIDs) { 78 for (auto& t : fThreadIDs) {
87 if (t == threadID) return true; 79 if (t == threadID) return true;
88 } 80 }
89 return false; 81 return false;
90 } 82 }
91 83
92 // Returns true if did not already exist. 84 // Returns true if did not already exist.
93 bool tryAdd(ThreadID threadID) { 85 bool tryAdd(SkThreadID threadID) {
94 for (auto& t : fThreadIDs) { 86 for (auto& t : fThreadIDs) {
95 if (t == threadID) return false; 87 if (t == threadID) return false;
96 } 88 }
97 fThreadIDs.append(1, &threadID); 89 fThreadIDs.append(1, &threadID);
98 return true; 90 return true;
99 } 91 }
100 // Returns true if already exists in Set. 92 // Returns true if already exists in Set.
101 bool tryRemove(ThreadID threadID) { 93 bool tryRemove(SkThreadID threadID) {
102 for (int i = 0; i < fThreadIDs.count(); ++i) { 94 for (int i = 0; i < fThreadIDs.count(); ++i) {
103 if (fThreadIDs[i] == threadID) { 95 if (fThreadIDs[i] == threadID) {
104 fThreadIDs.remove(i); 96 fThreadIDs.remove(i);
105 return true; 97 return true;
106 } 98 }
107 } 99 }
108 return false; 100 return false;
109 } 101 }
110 102
111 void swap(ThreadIDSet& other) { 103 void swap(ThreadIDSet& other) {
112 fThreadIDs.swap(other.fThreadIDs); 104 fThreadIDs.swap(other.fThreadIDs);
113 } 105 }
114 106
115 int count() const { 107 int count() const {
116 return fThreadIDs.count(); 108 return fThreadIDs.count();
117 } 109 }
118 110
119 private: 111 private:
120 SkTDArray<ThreadID> fThreadIDs; 112 SkTDArray<SkThreadID> fThreadIDs;
121 }; 113 };
122 114
123 SkSharedMutex::SkSharedMutex() 115 SkSharedMutex::SkSharedMutex()
124 : fCurrentShared(new ThreadIDSet) 116 : fCurrentShared(new ThreadIDSet)
125 , fWaitingExclusive(new ThreadIDSet) 117 , fWaitingExclusive(new ThreadIDSet)
126 , fWaitingShared(new ThreadIDSet){ 118 , fWaitingShared(new ThreadIDSet){
127 ANNOTATE_RWLOCK_CREATE(this); 119 ANNOTATE_RWLOCK_CREATE(this);
128 } 120 }
129 121
130 SkSharedMutex::~SkSharedMutex() { ANNOTATE_RWLOCK_DESTROY(this); } 122 SkSharedMutex::~SkSharedMutex() { ANNOTATE_RWLOCK_DESTROY(this); }
131 123
132 void SkSharedMutex::acquire() { 124 void SkSharedMutex::acquire() {
133 ThreadID threadID(get_thread_id()); 125 SkThreadID threadID(SkGetThreadID());
134 int currentSharedCount; 126 int currentSharedCount;
135 int waitingExclusiveCount; 127 int waitingExclusiveCount;
136 { 128 {
137 SkAutoMutexAcquire l(&fMu); 129 SkAutoMutexAcquire l(&fMu);
138 130
139 if (!fWaitingExclusive->tryAdd(threadID)) { 131 if (!fWaitingExclusive->tryAdd(threadID)) {
140 SkDEBUGFAILF("Thread %lx already has an exclusive lock\n", threa dID); 132 SkDEBUGFAILF("Thread %lx already has an exclusive lock\n", threa dID);
141 } 133 }
142 134
143 currentSharedCount = fCurrentShared->count(); 135 currentSharedCount = fCurrentShared->count();
144 waitingExclusiveCount = fWaitingExclusive->count(); 136 waitingExclusiveCount = fWaitingExclusive->count();
145 } 137 }
146 138
147 if (currentSharedCount > 0 || waitingExclusiveCount > 1) { 139 if (currentSharedCount > 0 || waitingExclusiveCount > 1) {
148 fExclusiveQueue.wait(); 140 fExclusiveQueue.wait();
149 } 141 }
150 142
151 ANNOTATE_RWLOCK_ACQUIRED(this, 1); 143 ANNOTATE_RWLOCK_ACQUIRED(this, 1);
152 } 144 }
153 145
154 // Implementation Detail: 146 // Implementation Detail:
155 // The shared threads need two seperate queues to keep the threads that were added after the 147 // The shared threads need two seperate queues to keep the threads that were added after the
156 // exclusive lock separate from the threads added before. 148 // exclusive lock separate from the threads added before.
157 void SkSharedMutex::release() { 149 void SkSharedMutex::release() {
158 ANNOTATE_RWLOCK_RELEASED(this, 1); 150 ANNOTATE_RWLOCK_RELEASED(this, 1);
159 ThreadID threadID(get_thread_id()); 151 SkThreadID threadID(SkGetThreadID());
160 int sharedWaitingCount; 152 int sharedWaitingCount;
161 int exclusiveWaitingCount; 153 int exclusiveWaitingCount;
162 int sharedQueueSelect; 154 int sharedQueueSelect;
163 { 155 {
164 SkAutoMutexAcquire l(&fMu); 156 SkAutoMutexAcquire l(&fMu);
165 SkASSERT(0 == fCurrentShared->count()); 157 SkASSERT(0 == fCurrentShared->count());
166 if (!fWaitingExclusive->tryRemove(threadID)) { 158 if (!fWaitingExclusive->tryRemove(threadID)) {
167 SkDEBUGFAILF("Thread %lx did not have the lock held.\n", threadI D); 159 SkDEBUGFAILF("Thread %lx did not have the lock held.\n", threadI D);
168 } 160 }
169 exclusiveWaitingCount = fWaitingExclusive->count(); 161 exclusiveWaitingCount = fWaitingExclusive->count();
170 sharedWaitingCount = fWaitingShared->count(); 162 sharedWaitingCount = fWaitingShared->count();
171 fWaitingShared.swap(fCurrentShared); 163 fWaitingShared.swap(fCurrentShared);
172 sharedQueueSelect = fSharedQueueSelect; 164 sharedQueueSelect = fSharedQueueSelect;
173 if (sharedWaitingCount > 0) { 165 if (sharedWaitingCount > 0) {
174 fSharedQueueSelect = 1 - fSharedQueueSelect; 166 fSharedQueueSelect = 1 - fSharedQueueSelect;
175 } 167 }
176 } 168 }
177 169
178 if (sharedWaitingCount > 0) { 170 if (sharedWaitingCount > 0) {
179 fSharedQueue[sharedQueueSelect].signal(sharedWaitingCount); 171 fSharedQueue[sharedQueueSelect].signal(sharedWaitingCount);
180 } else if (exclusiveWaitingCount > 0) { 172 } else if (exclusiveWaitingCount > 0) {
181 fExclusiveQueue.signal(); 173 fExclusiveQueue.signal();
182 } 174 }
183 } 175 }
184 176
185 void SkSharedMutex::assertHeld() const { 177 void SkSharedMutex::assertHeld() const {
186 ThreadID threadID(get_thread_id()); 178 SkThreadID threadID(SkGetThreadID());
187 SkAutoMutexAcquire l(&fMu); 179 SkAutoMutexAcquire l(&fMu);
188 SkASSERT(0 == fCurrentShared->count()); 180 SkASSERT(0 == fCurrentShared->count());
189 SkASSERT(fWaitingExclusive->find(threadID)); 181 SkASSERT(fWaitingExclusive->find(threadID));
190 } 182 }
191 183
192 void SkSharedMutex::acquireShared() { 184 void SkSharedMutex::acquireShared() {
193 ThreadID threadID(get_thread_id()); 185 SkThreadID threadID(SkGetThreadID());
194 int exclusiveWaitingCount; 186 int exclusiveWaitingCount;
195 int sharedQueueSelect; 187 int sharedQueueSelect;
196 { 188 {
197 SkAutoMutexAcquire l(&fMu); 189 SkAutoMutexAcquire l(&fMu);
198 exclusiveWaitingCount = fWaitingExclusive->count(); 190 exclusiveWaitingCount = fWaitingExclusive->count();
199 if (exclusiveWaitingCount > 0) { 191 if (exclusiveWaitingCount > 0) {
200 if (!fWaitingShared->tryAdd(threadID)) { 192 if (!fWaitingShared->tryAdd(threadID)) {
201 SkDEBUGFAILF("Thread %lx was already waiting!\n", threadID); 193 SkDEBUGFAILF("Thread %lx was already waiting!\n", threadID);
202 } 194 }
203 } else { 195 } else {
204 if (!fCurrentShared->tryAdd(threadID)) { 196 if (!fCurrentShared->tryAdd(threadID)) {
205 SkDEBUGFAILF("Thread %lx already holds a shared lock!\n", th readID); 197 SkDEBUGFAILF("Thread %lx already holds a shared lock!\n", th readID);
206 } 198 }
207 } 199 }
208 sharedQueueSelect = fSharedQueueSelect; 200 sharedQueueSelect = fSharedQueueSelect;
209 } 201 }
210 202
211 if (exclusiveWaitingCount > 0) { 203 if (exclusiveWaitingCount > 0) {
212 fSharedQueue[sharedQueueSelect].wait(); 204 fSharedQueue[sharedQueueSelect].wait();
213 } 205 }
214 206
215 ANNOTATE_RWLOCK_ACQUIRED(this, 0); 207 ANNOTATE_RWLOCK_ACQUIRED(this, 0);
216 } 208 }
217 209
218 void SkSharedMutex::releaseShared() { 210 void SkSharedMutex::releaseShared() {
219 ANNOTATE_RWLOCK_RELEASED(this, 0); 211 ANNOTATE_RWLOCK_RELEASED(this, 0);
220 ThreadID threadID(get_thread_id()); 212 SkThreadID threadID(SkGetThreadID());
221 213
222 int currentSharedCount; 214 int currentSharedCount;
223 int waitingExclusiveCount; 215 int waitingExclusiveCount;
224 { 216 {
225 SkAutoMutexAcquire l(&fMu); 217 SkAutoMutexAcquire l(&fMu);
226 if (!fCurrentShared->tryRemove(threadID)) { 218 if (!fCurrentShared->tryRemove(threadID)) {
227 SkDEBUGFAILF("Thread %lx does not hold a shared lock.\n", thread ID); 219 SkDEBUGFAILF("Thread %lx does not hold a shared lock.\n", thread ID);
228 } 220 }
229 currentSharedCount = fCurrentShared->count(); 221 currentSharedCount = fCurrentShared->count();
230 waitingExclusiveCount = fWaitingExclusive->count(); 222 waitingExclusiveCount = fWaitingExclusive->count();
231 } 223 }
232 224
233 if (0 == currentSharedCount && waitingExclusiveCount > 0) { 225 if (0 == currentSharedCount && waitingExclusiveCount > 0) {
234 fExclusiveQueue.signal(); 226 fExclusiveQueue.signal();
235 } 227 }
236 } 228 }
237 229
238 void SkSharedMutex::assertHeldShared() const { 230 void SkSharedMutex::assertHeldShared() const {
239 ThreadID threadID(get_thread_id()); 231 SkThreadID threadID(SkGetThreadID());
240 SkAutoMutexAcquire l(&fMu); 232 SkAutoMutexAcquire l(&fMu);
241 SkASSERT(fCurrentShared->find(threadID)); 233 SkASSERT(fCurrentShared->find(threadID));
242 } 234 }
243 235
244 #else 236 #else
245 237
246 // The fQueueCounts fields holds many counts in an int32_t in order to make managing them atomic. 238 // The fQueueCounts fields holds many counts in an int32_t in order to make managing them atomic.
247 // These three counts must be the same size, so each gets 10 bits. The 10 bi ts represent 239 // These three counts must be the same size, so each gets 10 bits. The 10 bi ts represent
248 // the log of the count which is 1024. 240 // the log of the count which is 1024.
249 // 241 //
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 341
350 // If shared count is going to zero (because the old count == 1) and the re are exclusive 342 // If shared count is going to zero (because the old count == 1) and the re are exclusive
351 // waiters, then run a single exclusive waiter. 343 // waiters, then run a single exclusive waiter.
352 if (((oldQueueCounts & kSharedMask) >> kSharedOffset) == 1 344 if (((oldQueueCounts & kSharedMask) >> kSharedOffset) == 1
353 && (oldQueueCounts & kWaitingExclusiveMask) > 0) { 345 && (oldQueueCounts & kWaitingExclusiveMask) > 0) {
354 fExclusiveQueue.signal(); 346 fExclusiveQueue.signal();
355 } 347 }
356 } 348 }
357 349
358 #endif 350 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698