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

Side by Side Diff: include/core/SkOnce.h

Issue 247813005: teach TSAN about SkSpinlock, SkRefCnt, and SkOnce (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: unused Created 6 years, 8 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 2013 Google Inc. 2 * Copyright 2013 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 SkOnce_DEFINED 8 #ifndef SkOnce_DEFINED
9 #define SkOnce_DEFINED 9 #define SkOnce_DEFINED
10 10
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 // ---------------------- Implementation details below here. ----------------- ------------ 47 // ---------------------- Implementation details below here. ----------------- ------------
48 48
49 // This is POD and must be zero-initialized. 49 // This is POD and must be zero-initialized.
50 struct SkSpinlock { 50 struct SkSpinlock {
51 void acquire() { 51 void acquire() {
52 SkASSERT(shouldBeZero == 0); 52 SkASSERT(shouldBeZero == 0);
53 // No memory barrier needed, but sk_atomic_cas gives us at least release anyway. 53 // No memory barrier needed, but sk_atomic_cas gives us at least release anyway.
54 while (!sk_atomic_cas(&thisIsPrivate, 0, 1)) { 54 while (!sk_atomic_cas(&thisIsPrivate, 0, 1)) {
55 // spin 55 // spin
56 } 56 }
57 SK_ANNOTATE_RWLOCK_ACQUIRED(this, true);
57 } 58 }
58 59
59 void release() { 60 void release() {
60 SkASSERT(shouldBeZero == 0); 61 SkASSERT(shouldBeZero == 0);
62 SK_ANNOTATE_RWLOCK_RELEASED(this, true);
61 // This requires a release memory barrier before storing, which sk_atomi c_cas guarantees. 63 // This requires a release memory barrier before storing, which sk_atomi c_cas guarantees.
62 SkAssertResult(sk_atomic_cas(&thisIsPrivate, 1, 0)); 64 SkAssertResult(sk_atomic_cas(&thisIsPrivate, 1, 0));
63 } 65 }
64 66
65 int32_t thisIsPrivate; 67 int32_t thisIsPrivate;
66 SkDEBUGCODE(int32_t shouldBeZero;) 68 SkDEBUGCODE(int32_t shouldBeZero;)
67 }; 69 };
68 70
69 struct SkOnceFlag { 71 struct SkOnceFlag {
70 bool done; 72 bool done;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 // done before here---in particular, those done by calling f(arg)---are observable 140 // done before here---in particular, those done by calling f(arg)---are observable
139 // before the writes after the line, *done = true. 141 // before the writes after the line, *done = true.
140 // 142 //
141 // In version control terms this is like saying, "check in the work up 143 // In version control terms this is like saying, "check in the work up
142 // to and including f(arg), then check in *done=true as a subsequent cha nge". 144 // to and including f(arg), then check in *done=true as a subsequent cha nge".
143 // 145 //
144 // We'll use this in the fast path to make sure f(arg)'s effects are 146 // We'll use this in the fast path to make sure f(arg)'s effects are
145 // observable whenever we observe *done == true. 147 // observable whenever we observe *done == true.
146 release_barrier(); 148 release_barrier();
147 *done = true; 149 *done = true;
150 SK_ANNOTATE_HAPPENS_BEFORE(done);
148 } 151 }
149 } 152 }
150 153
151 // This is our fast path, called all the time. We do really want it to be inlin ed. 154 // This is our fast path, called all the time. We do really want it to be inlin ed.
152 template <typename Lock, typename Func, typename Arg> 155 template <typename Lock, typename Func, typename Arg>
153 inline void SkOnce(bool* done, Lock* lock, Func f, Arg arg, void(*atExit)()) { 156 inline void SkOnce(bool* done, Lock* lock, Func f, Arg arg, void(*atExit)()) {
154 if (!SK_ANNOTATE_UNPROTECTED_READ(*done)) { 157 if (!SK_ANNOTATE_UNPROTECTED_READ(*done)) {
155 sk_once_slow(done, lock, f, arg, atExit); 158 sk_once_slow(done, lock, f, arg, atExit);
156 } 159 }
157 // Also known as a load-load/load-store barrier, this acquire barrier makes 160 // Also known as a load-load/load-store barrier, this acquire barrier makes
158 // sure that anything we read from memory---in particular, memory written by 161 // sure that anything we read from memory---in particular, memory written by
159 // calling f(arg)---is at least as current as the value we read from once->d one. 162 // calling f(arg)---is at least as current as the value we read from once->d one.
160 // 163 //
161 // In version control terms, this is a lot like saying "sync up to the 164 // In version control terms, this is a lot like saying "sync up to the
162 // commit where we wrote once->done = true". 165 // commit where we wrote once->done = true".
163 // 166 //
164 // The release barrier in sk_once_slow guaranteed that once->done = true 167 // The release barrier in sk_once_slow guaranteed that once->done = true
165 // happens after f(arg), so by syncing to once->done = true here we're 168 // happens after f(arg), so by syncing to once->done = true here we're
166 // forcing ourselves to also wait until the effects of f(arg) are readble. 169 // forcing ourselves to also wait until the effects of f(arg) are readble.
167 acquire_barrier(); 170 acquire_barrier();
171 SK_ANNOTATE_HAPPENS_AFTER(done);
168 } 172 }
169 173
170 template <typename Func, typename Arg> 174 template <typename Func, typename Arg>
171 inline void SkOnce(SkOnceFlag* once, Func f, Arg arg, void(*atExit)()) { 175 inline void SkOnce(SkOnceFlag* once, Func f, Arg arg, void(*atExit)()) {
172 return SkOnce(&once->done, &once->lock, f, arg, atExit); 176 return SkOnce(&once->done, &once->lock, f, arg, atExit);
173 } 177 }
174 178
175 #undef SK_ANNOTATE_BENIGN_RACE 179 #undef SK_ANNOTATE_BENIGN_RACE
176 180
177 #endif // SkOnce_DEFINED 181 #endif // SkOnce_DEFINED
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698