OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This is a low level implementation of atomic semantics for reference | 5 // This is a low level implementation of atomic semantics for reference |
6 // counting. Please use base/memory/ref_counted.h directly instead. | 6 // counting. Please use base/memory/ref_counted.h directly instead. |
7 // | 7 // |
8 // The implementation includes annotations to avoid some false positives | 8 // The implementation includes annotations to avoid some false positives |
9 // when using data race detection tools. | 9 // when using data race detection tools. |
10 | 10 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 base::AtomicRefCountIncN(ptr, 1); | 44 base::AtomicRefCountIncN(ptr, 1); |
45 } | 45 } |
46 | 46 |
47 // Decrement a reference count by 1 and return whether the result is non-zero. | 47 // Decrement a reference count by 1 and return whether the result is non-zero. |
48 // Insert barriers to ensure that state written before the reference count | 48 // Insert barriers to ensure that state written before the reference count |
49 // became zero will be visible to a thread that has just made the count zero. | 49 // became zero will be visible to a thread that has just made the count zero. |
50 inline bool AtomicRefCountDec(volatile AtomicRefCount *ptr) { | 50 inline bool AtomicRefCountDec(volatile AtomicRefCount *ptr) { |
51 return base::AtomicRefCountDecN(ptr, 1); | 51 return base::AtomicRefCountDecN(ptr, 1); |
52 } | 52 } |
53 | 53 |
| 54 // Increment a reference count by 1 and return the new value. |
| 55 inline AtomicRefCount AtomicRefCountIncAndReturnValue( |
| 56 volatile AtomicRefCount *ptr) { |
| 57 ANNOTATE_HAPPENS_BEFORE(ptr); |
| 58 AtomicRefCount res = subtle::Barrier_AtomicIncrement(ptr, 1); |
| 59 ANNOTATE_HAPPENS_AFTER(ptr); |
| 60 return res; |
| 61 } |
| 62 |
| 63 // Decrement a reference count by 1 and return the new value. |
| 64 inline AtomicRefCount AtomicRefCountDecAndReturnValue( |
| 65 volatile AtomicRefCount *ptr) { |
| 66 ANNOTATE_HAPPENS_BEFORE(ptr); |
| 67 AtomicRefCount res = subtle::Barrier_AtomicIncrement(ptr, -1); |
| 68 ANNOTATE_HAPPENS_AFTER(ptr); |
| 69 return res; |
| 70 } |
| 71 |
54 // Return whether the reference count is one. If the reference count is used | 72 // Return whether the reference count is one. If the reference count is used |
55 // in the conventional way, a refrerence count of 1 implies that the current | 73 // in the conventional way, a refrerence count of 1 implies that the current |
56 // thread owns the reference and no other thread shares it. This call performs | 74 // thread owns the reference and no other thread shares it. This call performs |
57 // the test for a reference count of one, and performs the memory barrier | 75 // the test for a reference count of one, and performs the memory barrier |
58 // needed for the owning thread to act on the object, knowing that it has | 76 // needed for the owning thread to act on the object, knowing that it has |
59 // exclusive access to the object. | 77 // exclusive access to the object. |
60 inline bool AtomicRefCountIsOne(volatile AtomicRefCount *ptr) { | 78 inline bool AtomicRefCountIsOne(volatile AtomicRefCount *ptr) { |
61 bool res = (subtle::Acquire_Load(ptr) == 1); | 79 bool res = (subtle::Acquire_Load(ptr) == 1); |
62 if (res) { | 80 if (res) { |
63 ANNOTATE_HAPPENS_AFTER(ptr); | 81 ANNOTATE_HAPPENS_AFTER(ptr); |
64 } | 82 } |
65 return res; | 83 return res; |
66 } | 84 } |
67 | 85 |
68 // Return whether the reference count is zero. With conventional object | 86 // Return whether the reference count is zero. With conventional object |
69 // referencing counting, the object will be destroyed, so the reference count | 87 // referencing counting, the object will be destroyed, so the reference count |
70 // should never be zero. Hence this is generally used for a debug check. | 88 // should never be zero. Hence this is generally used for a debug check. |
71 inline bool AtomicRefCountIsZero(volatile AtomicRefCount *ptr) { | 89 inline bool AtomicRefCountIsZero(volatile AtomicRefCount *ptr) { |
72 bool res = (subtle::Acquire_Load(ptr) == 0); | 90 bool res = (subtle::Acquire_Load(ptr) == 0); |
73 if (res) { | 91 if (res) { |
74 ANNOTATE_HAPPENS_AFTER(ptr); | 92 ANNOTATE_HAPPENS_AFTER(ptr); |
75 } | 93 } |
76 return res; | 94 return res; |
77 } | 95 } |
78 | 96 |
79 } // namespace base | 97 } // namespace base |
80 | 98 |
81 #endif // BASE_ATOMIC_REF_COUNT_H_ | 99 #endif // BASE_ATOMIC_REF_COUNT_H_ |
OLD | NEW |