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

Side by Side Diff: base/memory/singleton.h

Issue 9186057: Add ALIGNAS and ALIGNOF macros to ensure proper alignment of StaticMemorySingletonTraits (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: win compile Created 8 years, 11 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 | Annotate | Revision Log
OLDNEW
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 // PLEASE READ: Do you really need a singleton? 5 // PLEASE READ: Do you really need a singleton?
6 // 6 //
7 // Singletons make it hard to determine the lifetime of an object, which can 7 // Singletons make it hard to determine the lifetime of an object, which can
8 // lead to buggy code and spurious crashes. 8 // lead to buggy code and spurious crashes.
9 // 9 //
10 // Instead of adding another singleton into the mix, try to identify either: 10 // Instead of adding another singleton into the mix, try to identify either:
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 // possibility of loading briefly into someone else's process space, and 101 // possibility of loading briefly into someone else's process space, and
102 // so leaking is not an option, as that would sabotage the state of your host 102 // so leaking is not an option, as that would sabotage the state of your host
103 // process once you've unloaded. 103 // process once you've unloaded.
104 template <typename Type> 104 template <typename Type>
105 struct StaticMemorySingletonTraits { 105 struct StaticMemorySingletonTraits {
106 // WARNING: User has to deal with get() in the singleton class 106 // WARNING: User has to deal with get() in the singleton class
107 // this is traits for returning NULL. 107 // this is traits for returning NULL.
108 static Type* New() { 108 static Type* New() {
109 if (base::subtle::NoBarrier_AtomicExchange(&dead_, 1)) 109 if (base::subtle::NoBarrier_AtomicExchange(&dead_, 1))
110 return NULL; 110 return NULL;
111 Type* ptr = reinterpret_cast<Type*>(buffer_); 111
112 // Calculate aligned address for object pointer. This rounds up to the
113 // nearest address whose alignment is ALIGNOF(Type).
114 intptr_t aligned_addr =
115 (reinterpret_cast<intptr_t>(buffer_) + ALIGNOF(Type) - 1) &
116 ~(ALIGNOF(Type) - 1);
112 117
113 // We are protected by a memory barrier. 118 // We are protected by a memory barrier.
Jeffrey Yasskin (google) 2012/02/15 22:27:19 Unrelated to the current CL, but, really? I see a
jbates 2012/02/15 22:51:33 Hmm. I just assumed this code was already thread s
114 new(ptr) Type(); 119 return new(reinterpret_cast<void*>(aligned_addr)) Type();
115 return ptr;
116 } 120 }
117 121
118 static void Delete(Type* p) { 122 static void Delete(Type* p) {
119 base::subtle::NoBarrier_Store(&dead_, 1); 123 base::subtle::NoBarrier_Store(&dead_, 1);
120 base::subtle::MemoryBarrier(); 124 base::subtle::MemoryBarrier();
121 if (p != NULL) 125 if (p != NULL)
122 p->Type::~Type(); 126 p->Type::~Type();
123 } 127 }
124 128
125 static const bool kRegisterAtExit = true; 129 static const bool kRegisterAtExit = true;
126 static const bool kAllowedToAccessOnNonjoinableThread = true; 130 static const bool kAllowedToAccessOnNonjoinableThread = true;
127 131
128 // Exposed for unittesting. 132 // Exposed for unittesting.
129 static void Resurrect() { 133 static void Resurrect() {
130 base::subtle::NoBarrier_Store(&dead_, 0); 134 base::subtle::NoBarrier_Store(&dead_, 0);
131 } 135 }
132 136
133 private: 137 private:
134 static const size_t kBufferSize = (sizeof(Type) + 138 static const size_t kBufferSize = sizeof(Type) + ALIGNOF(Type) - 1;
Sigurður Ásgeirsson 2012/01/13 14:32:18 This is pretty wasteful, as many existing instance
jbates 2012/01/13 17:29:18 How so? ALIGNOF will typically be 4 or 8 for most
Jeffrey Yasskin (google) 2012/02/15 22:27:19 Does MSVC accept ALIGNED(size_t-template-argument)
jbates 2012/02/15 22:51:33 Yeah, hopefully that will work. I'll give it a try
135 sizeof(intptr_t) - 1) / sizeof(intptr_t); 139 static uint8 buffer_[kBufferSize];
136 static intptr_t buffer_[kBufferSize];
137 140
138 // Signal the object was already deleted, so it is not revived. 141 // Signal the object was already deleted, so it is not revived.
139 static base::subtle::Atomic32 dead_; 142 static base::subtle::Atomic32 dead_;
140 }; 143 };
141 144
142 template <typename Type> intptr_t 145 template <typename Type> uint8
143 StaticMemorySingletonTraits<Type>::buffer_[kBufferSize]; 146 StaticMemorySingletonTraits<Type>::buffer_[kBufferSize];
144 template <typename Type> base::subtle::Atomic32 147 template <typename Type> base::subtle::Atomic32
145 StaticMemorySingletonTraits<Type>::dead_ = 0; 148 StaticMemorySingletonTraits<Type>::dead_ = 0;
146 149
147 // The Singleton<Type, Traits, DifferentiatingType> class manages a single 150 // The Singleton<Type, Traits, DifferentiatingType> class manages a single
148 // instance of Type which will be created on first use and will be destroyed at 151 // instance of Type which will be created on first use and will be destroyed at
149 // normal process exit). The Trait::Delete function will not be called on 152 // normal process exit). The Trait::Delete function will not be called on
150 // abnormal process exit. 153 // abnormal process exit.
151 // 154 //
152 // DifferentiatingType is used as a key to differentiate two different 155 // DifferentiatingType is used as a key to differentiate two different
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 instance_ = 0; 285 instance_ = 0;
283 } 286 }
284 static base::subtle::AtomicWord instance_; 287 static base::subtle::AtomicWord instance_;
285 }; 288 };
286 289
287 template <typename Type, typename Traits, typename DifferentiatingType> 290 template <typename Type, typename Traits, typename DifferentiatingType>
288 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: 291 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::
289 instance_ = 0; 292 instance_ = 0;
290 293
291 #endif // BASE_MEMORY_SINGLETON_H_ 294 #endif // BASE_MEMORY_SINGLETON_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698