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

Side by Side Diff: third_party/libc++abi/src/cxa_guard.cpp

Issue 75213003: Add libc++ and libc++abi to third-party. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 //===---------------------------- cxa_guard.cpp ---------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "abort_message.h"
11
12 #include <pthread.h>
13 #include <stdint.h>
14
15 /*
16 This implementation must be careful to not call code external to this file
17 which will turn around and try to call __cxa_guard_acquire reentrantly.
18 For this reason, the headers of this file are as restricted as possible.
19 Previous implementations of this code for __APPLE__ have used
20 pthread_mutex_lock and the abort_message utility without problem. This
21 implementation also uses pthread_cond_wait which has tested to not be a
22 problem.
23 */
24
25 namespace __cxxabiv1
26 {
27
28 namespace
29 {
30
31 #if __arm__
32
33 // A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must
34 // be statically initialized to 0.
35 typedef uint32_t guard_type;
36
37 // Test the lowest bit.
38 inline bool is_initialized(guard_type* guard_object) {
39 return (*guard_object) & 1;
40 }
41
42 inline void set_initialized(guard_type* guard_object) {
43 *guard_object |= 1;
44 }
45
46 #else
47
48 typedef uint64_t guard_type;
49
50 bool is_initialized(guard_type* guard_object) {
51 char* initialized = (char*)guard_object;
52 return *initialized;
53 }
54
55 void set_initialized(guard_type* guard_object) {
56 char* initialized = (char*)guard_object;
57 *initialized = 1;
58 }
59
60 #endif
61
62 pthread_mutex_t guard_mut = PTHREAD_MUTEX_INITIALIZER;
63 pthread_cond_t guard_cv = PTHREAD_COND_INITIALIZER;
64
65 #if defined(__APPLE__) && !defined(__arm__)
66
67 typedef uint32_t lock_type;
68
69 #if __LITTLE_ENDIAN__
70
71 inline
72 lock_type
73 get_lock(uint64_t x)
74 {
75 return static_cast<lock_type>(x >> 32);
76 }
77
78 inline
79 void
80 set_lock(uint64_t& x, lock_type y)
81 {
82 x = static_cast<uint64_t>(y) << 32;
83 }
84
85 #else // __LITTLE_ENDIAN__
86
87 inline
88 lock_type
89 get_lock(uint64_t x)
90 {
91 return static_cast<lock_type>(x);
92 }
93
94 inline
95 void
96 set_lock(uint64_t& x, lock_type y)
97 {
98 x = y;
99 }
100
101 #endif // __LITTLE_ENDIAN__
102
103 #else // !__APPLE__ || __arm__
104
105 typedef bool lock_type;
106
107 inline
108 lock_type
109 get_lock(uint64_t x)
110 {
111 union
112 {
113 uint64_t guard;
114 uint8_t lock[2];
115 } f = {x};
116 return f.lock[1] != 0;
117 }
118
119 inline
120 void
121 set_lock(uint64_t& x, lock_type y)
122 {
123 union
124 {
125 uint64_t guard;
126 uint8_t lock[2];
127 } f = {0};
128 f.lock[1] = y;
129 x = f.guard;
130 }
131
132 inline
133 lock_type
134 get_lock(uint32_t x)
135 {
136 union
137 {
138 uint32_t guard;
139 uint8_t lock[2];
140 } f = {x};
141 return f.lock[1] != 0;
142 }
143
144 inline
145 void
146 set_lock(uint32_t& x, lock_type y)
147 {
148 union
149 {
150 uint32_t guard;
151 uint8_t lock[2];
152 } f = {0};
153 f.lock[1] = y;
154 x = f.guard;
155 }
156
157 #endif // __APPLE__
158
159 } // unnamed namespace
160
161 extern "C"
162 {
163
164 int __cxa_guard_acquire(guard_type* guard_object)
165 {
166 char* initialized = (char*)guard_object;
167 if (pthread_mutex_lock(&guard_mut))
168 abort_message("__cxa_guard_acquire failed to acquire mutex");
169 int result = *initialized == 0;
170 if (result)
171 {
172 #if defined(__APPLE__) && !defined(__arm__)
173 const lock_type id = pthread_mach_thread_np(pthread_self());
174 lock_type lock = get_lock(*guard_object);
175 if (lock)
176 {
177 // if this thread set lock for this same guard_object, abort
178 if (lock == id)
179 abort_message("__cxa_guard_acquire detected deadlock");
180 do
181 {
182 if (pthread_cond_wait(&guard_cv, &guard_mut))
183 abort_message("__cxa_guard_acquire condition variable wait f ailed");
184 lock = get_lock(*guard_object);
185 } while (lock);
186 result = !is_initialized(guard_object);
187 if (result)
188 set_lock(*guard_object, id);
189 }
190 else
191 set_lock(*guard_object, id);
192 #else // !__APPLE__ || __arm__
193 while (get_lock(*guard_object))
194 if (pthread_cond_wait(&guard_cv, &guard_mut))
195 abort_message("__cxa_guard_acquire condition variable wait faile d");
196 result = *initialized == 0;
197 if (result)
198 set_lock(*guard_object, true);
199 #endif // !__APPLE__ || __arm__
200 }
201 if (pthread_mutex_unlock(&guard_mut))
202 abort_message("__cxa_guard_acquire failed to release mutex");
203 return result;
204 }
205
206 void __cxa_guard_release(guard_type* guard_object)
207 {
208 if (pthread_mutex_lock(&guard_mut))
209 abort_message("__cxa_guard_release failed to acquire mutex");
210 *guard_object = 0;
211 set_initialized(guard_object);
212 if (pthread_mutex_unlock(&guard_mut))
213 abort_message("__cxa_guard_release failed to release mutex");
214 if (pthread_cond_broadcast(&guard_cv))
215 abort_message("__cxa_guard_release failed to broadcast condition variabl e");
216 }
217
218 void __cxa_guard_abort(guard_type* guard_object)
219 {
220 if (pthread_mutex_lock(&guard_mut))
221 abort_message("__cxa_guard_abort failed to acquire mutex");
222 *guard_object = 0;
223 if (pthread_mutex_unlock(&guard_mut))
224 abort_message("__cxa_guard_abort failed to release mutex");
225 if (pthread_cond_broadcast(&guard_cv))
226 abort_message("__cxa_guard_abort failed to broadcast condition variable" );
227 }
228
229 } // extern "C"
230
231 } // __cxxabiv1
OLDNEW
« no previous file with comments | « third_party/libc++abi/src/cxa_exception_storage.cpp ('k') | third_party/libc++abi/src/cxa_handlers.hpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698