xref: /aosp_15_r20/external/harfbuzz_ng/src/hb-atomic.hh (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker  * Copyright © 2007  Chris Wilson
3*2d1272b8SAndroid Build Coastguard Worker  * Copyright © 2009,2010  Red Hat, Inc.
4*2d1272b8SAndroid Build Coastguard Worker  * Copyright © 2011,2012  Google, Inc.
5*2d1272b8SAndroid Build Coastguard Worker  *
6*2d1272b8SAndroid Build Coastguard Worker  *  This is part of HarfBuzz, a text shaping library.
7*2d1272b8SAndroid Build Coastguard Worker  *
8*2d1272b8SAndroid Build Coastguard Worker  * Permission is hereby granted, without written agreement and without
9*2d1272b8SAndroid Build Coastguard Worker  * license or royalty fees, to use, copy, modify, and distribute this
10*2d1272b8SAndroid Build Coastguard Worker  * software and its documentation for any purpose, provided that the
11*2d1272b8SAndroid Build Coastguard Worker  * above copyright notice and the following two paragraphs appear in
12*2d1272b8SAndroid Build Coastguard Worker  * all copies of this software.
13*2d1272b8SAndroid Build Coastguard Worker  *
14*2d1272b8SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
15*2d1272b8SAndroid Build Coastguard Worker  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16*2d1272b8SAndroid Build Coastguard Worker  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17*2d1272b8SAndroid Build Coastguard Worker  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18*2d1272b8SAndroid Build Coastguard Worker  * DAMAGE.
19*2d1272b8SAndroid Build Coastguard Worker  *
20*2d1272b8SAndroid Build Coastguard Worker  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
21*2d1272b8SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22*2d1272b8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
23*2d1272b8SAndroid Build Coastguard Worker  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24*2d1272b8SAndroid Build Coastguard Worker  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25*2d1272b8SAndroid Build Coastguard Worker  *
26*2d1272b8SAndroid Build Coastguard Worker  * Contributor(s):
27*2d1272b8SAndroid Build Coastguard Worker  *	Chris Wilson <[email protected]>
28*2d1272b8SAndroid Build Coastguard Worker  * Red Hat Author(s): Behdad Esfahbod
29*2d1272b8SAndroid Build Coastguard Worker  * Google Author(s): Behdad Esfahbod
30*2d1272b8SAndroid Build Coastguard Worker  */
31*2d1272b8SAndroid Build Coastguard Worker 
32*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_ATOMIC_HH
33*2d1272b8SAndroid Build Coastguard Worker #define HB_ATOMIC_HH
34*2d1272b8SAndroid Build Coastguard Worker 
35*2d1272b8SAndroid Build Coastguard Worker #include "hb.hh"
36*2d1272b8SAndroid Build Coastguard Worker #include "hb-meta.hh"
37*2d1272b8SAndroid Build Coastguard Worker 
38*2d1272b8SAndroid Build Coastguard Worker 
39*2d1272b8SAndroid Build Coastguard Worker /*
40*2d1272b8SAndroid Build Coastguard Worker  * Atomic integers and pointers.
41*2d1272b8SAndroid Build Coastguard Worker  */
42*2d1272b8SAndroid Build Coastguard Worker 
43*2d1272b8SAndroid Build Coastguard Worker 
44*2d1272b8SAndroid Build Coastguard Worker /* We need external help for these */
45*2d1272b8SAndroid Build Coastguard Worker 
46*2d1272b8SAndroid Build Coastguard Worker #if defined(hb_atomic_int_impl_add) \
47*2d1272b8SAndroid Build Coastguard Worker  && defined(hb_atomic_ptr_impl_get) \
48*2d1272b8SAndroid Build Coastguard Worker  && defined(hb_atomic_ptr_impl_cmpexch)
49*2d1272b8SAndroid Build Coastguard Worker 
50*2d1272b8SAndroid Build Coastguard Worker /* Defined externally, i.e. in config.h. */
51*2d1272b8SAndroid Build Coastguard Worker 
52*2d1272b8SAndroid Build Coastguard Worker 
53*2d1272b8SAndroid Build Coastguard Worker #elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
54*2d1272b8SAndroid Build Coastguard Worker 
55*2d1272b8SAndroid Build Coastguard Worker /* C++11-style GCC primitives. We prefer these as they don't require linking to libstdc++ / libc++. */
56*2d1272b8SAndroid Build Coastguard Worker 
57*2d1272b8SAndroid Build Coastguard Worker #define _hb_memory_barrier()			__sync_synchronize ()
58*2d1272b8SAndroid Build Coastguard Worker 
59*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_add(AI, V)		__atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL)
60*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_set_relaxed(AI, V)	__atomic_store_n ((AI), (V), __ATOMIC_RELAXED)
61*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_set(AI, V)		__atomic_store_n ((AI), (V), __ATOMIC_RELEASE)
62*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_get_relaxed(AI)	__atomic_load_n ((AI), __ATOMIC_RELAXED)
63*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_get(AI)		__atomic_load_n ((AI), __ATOMIC_ACQUIRE)
64*2d1272b8SAndroid Build Coastguard Worker 
65*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_set_relaxed(P, V)	__atomic_store_n ((P), (V), __ATOMIC_RELAXED)
66*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_get_relaxed(P)	__atomic_load_n ((P), __ATOMIC_RELAXED)
67*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_get(P)		__atomic_load_n ((P), __ATOMIC_ACQUIRE)
68*2d1272b8SAndroid Build Coastguard Worker static inline bool
_hb_atomic_ptr_impl_cmplexch(const void ** P,const void * O_,const void * N)69*2d1272b8SAndroid Build Coastguard Worker _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
70*2d1272b8SAndroid Build Coastguard Worker {
71*2d1272b8SAndroid Build Coastguard Worker   const void *O = O_; // Need lvalue
72*2d1272b8SAndroid Build Coastguard Worker   return __atomic_compare_exchange_n ((void **) P, (void **) &O, (void *) N, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
73*2d1272b8SAndroid Build Coastguard Worker }
74*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_cmpexch(P,O,N)	_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
75*2d1272b8SAndroid Build Coastguard Worker 
76*2d1272b8SAndroid Build Coastguard Worker 
77*2d1272b8SAndroid Build Coastguard Worker #elif !defined(HB_NO_MT)
78*2d1272b8SAndroid Build Coastguard Worker 
79*2d1272b8SAndroid Build Coastguard Worker /* C++11 atomics. */
80*2d1272b8SAndroid Build Coastguard Worker 
81*2d1272b8SAndroid Build Coastguard Worker #include <atomic>
82*2d1272b8SAndroid Build Coastguard Worker 
83*2d1272b8SAndroid Build Coastguard Worker #define _hb_memory_barrier()			std::atomic_thread_fence(std::memory_order_ack_rel)
84*2d1272b8SAndroid Build Coastguard Worker #define _hb_memory_r_barrier()			std::atomic_thread_fence(std::memory_order_acquire)
85*2d1272b8SAndroid Build Coastguard Worker #define _hb_memory_w_barrier()			std::atomic_thread_fence(std::memory_order_release)
86*2d1272b8SAndroid Build Coastguard Worker 
87*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_add(AI, V)		(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
88*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_set_relaxed(AI, V)	(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_relaxed))
89*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_set(AI, V)		(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_release))
90*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_get_relaxed(AI)	(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_relaxed))
91*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_get(AI)		(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_acquire))
92*2d1272b8SAndroid Build Coastguard Worker 
93*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_set_relaxed(P, V)	(reinterpret_cast<std::atomic<void*> *> (P)->store ((V), std::memory_order_relaxed))
94*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_get_relaxed(P)	(reinterpret_cast<std::atomic<void*> const *> (P)->load (std::memory_order_relaxed))
95*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_get(P)		(reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_acquire))
96*2d1272b8SAndroid Build Coastguard Worker static inline bool
_hb_atomic_ptr_impl_cmplexch(const void ** P,const void * O_,const void * N)97*2d1272b8SAndroid Build Coastguard Worker _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
98*2d1272b8SAndroid Build Coastguard Worker {
99*2d1272b8SAndroid Build Coastguard Worker   const void *O = O_; // Need lvalue
100*2d1272b8SAndroid Build Coastguard Worker   return reinterpret_cast<std::atomic<const void*> *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed);
101*2d1272b8SAndroid Build Coastguard Worker }
102*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_cmpexch(P,O,N)	_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
103*2d1272b8SAndroid Build Coastguard Worker 
104*2d1272b8SAndroid Build Coastguard Worker 
105*2d1272b8SAndroid Build Coastguard Worker #else /* defined(HB_NO_MT) */
106*2d1272b8SAndroid Build Coastguard Worker 
107*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_add(AI, V)		((*(AI) += (V)) - (V))
108*2d1272b8SAndroid Build Coastguard Worker #define _hb_memory_barrier()			do {} while (0)
109*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_cmpexch(P,O,N)	(* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
110*2d1272b8SAndroid Build Coastguard Worker 
111*2d1272b8SAndroid Build Coastguard Worker #endif
112*2d1272b8SAndroid Build Coastguard Worker 
113*2d1272b8SAndroid Build Coastguard Worker 
114*2d1272b8SAndroid Build Coastguard Worker /* This should never be disabled, even under HB_NO_MT.
115*2d1272b8SAndroid Build Coastguard Worker  * except that MSVC gives me an internal compiler error, so disabled there.
116*2d1272b8SAndroid Build Coastguard Worker  *
117*2d1272b8SAndroid Build Coastguard Worker  * https://github.com/harfbuzz/harfbuzz/pull/4119
118*2d1272b8SAndroid Build Coastguard Worker  */
119*2d1272b8SAndroid Build Coastguard Worker #ifndef _hb_compiler_memory_r_barrier
120*2d1272b8SAndroid Build Coastguard Worker #if defined(__ATOMIC_ACQUIRE) // gcc-like
_hb_compiler_memory_r_barrier()121*2d1272b8SAndroid Build Coastguard Worker static inline void _hb_compiler_memory_r_barrier () { asm volatile("": : :"memory"); }
122*2d1272b8SAndroid Build Coastguard Worker #elif !defined(_MSC_VER)
123*2d1272b8SAndroid Build Coastguard Worker #include <atomic>
124*2d1272b8SAndroid Build Coastguard Worker #define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire)
125*2d1272b8SAndroid Build Coastguard Worker #else
_hb_compiler_memory_r_barrier()126*2d1272b8SAndroid Build Coastguard Worker static inline void _hb_compiler_memory_r_barrier () {}
127*2d1272b8SAndroid Build Coastguard Worker #endif
128*2d1272b8SAndroid Build Coastguard Worker #endif
129*2d1272b8SAndroid Build Coastguard Worker 
130*2d1272b8SAndroid Build Coastguard Worker 
131*2d1272b8SAndroid Build Coastguard Worker 
132*2d1272b8SAndroid Build Coastguard Worker #ifndef _hb_memory_r_barrier
133*2d1272b8SAndroid Build Coastguard Worker #define _hb_memory_r_barrier()			_hb_memory_barrier ()
134*2d1272b8SAndroid Build Coastguard Worker #endif
135*2d1272b8SAndroid Build Coastguard Worker #ifndef _hb_memory_w_barrier
136*2d1272b8SAndroid Build Coastguard Worker #define _hb_memory_w_barrier()			_hb_memory_barrier ()
137*2d1272b8SAndroid Build Coastguard Worker #endif
138*2d1272b8SAndroid Build Coastguard Worker #ifndef hb_atomic_int_impl_set_relaxed
139*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_set_relaxed(AI, V)	(*(AI) = (V))
140*2d1272b8SAndroid Build Coastguard Worker #endif
141*2d1272b8SAndroid Build Coastguard Worker #ifndef hb_atomic_int_impl_get_relaxed
142*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_int_impl_get_relaxed(AI)	(*(AI))
143*2d1272b8SAndroid Build Coastguard Worker #endif
144*2d1272b8SAndroid Build Coastguard Worker 
145*2d1272b8SAndroid Build Coastguard Worker #ifndef hb_atomic_ptr_impl_set_relaxed
146*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_set_relaxed(P, V)	(*(P) = (V))
147*2d1272b8SAndroid Build Coastguard Worker #endif
148*2d1272b8SAndroid Build Coastguard Worker #ifndef hb_atomic_ptr_impl_get_relaxed
149*2d1272b8SAndroid Build Coastguard Worker #define hb_atomic_ptr_impl_get_relaxed(P)	(*(P))
150*2d1272b8SAndroid Build Coastguard Worker #endif
151*2d1272b8SAndroid Build Coastguard Worker #ifndef hb_atomic_int_impl_set
hb_atomic_int_impl_set(int * AI,int v)152*2d1272b8SAndroid Build Coastguard Worker inline void hb_atomic_int_impl_set (int *AI, int v)	{ _hb_memory_w_barrier (); *AI = v; }
hb_atomic_int_impl_set(short * AI,short v)153*2d1272b8SAndroid Build Coastguard Worker inline void hb_atomic_int_impl_set (short *AI, short v)	{ _hb_memory_w_barrier (); *AI = v; }
154*2d1272b8SAndroid Build Coastguard Worker #endif
155*2d1272b8SAndroid Build Coastguard Worker #ifndef hb_atomic_int_impl_get
hb_atomic_int_impl_get(const int * AI)156*2d1272b8SAndroid Build Coastguard Worker inline int hb_atomic_int_impl_get (const int *AI)	{ int v = *AI; _hb_memory_r_barrier (); return v; }
hb_atomic_int_impl_get(const short * AI)157*2d1272b8SAndroid Build Coastguard Worker inline short hb_atomic_int_impl_get (const short *AI)	{ short v = *AI; _hb_memory_r_barrier (); return v; }
158*2d1272b8SAndroid Build Coastguard Worker #endif
159*2d1272b8SAndroid Build Coastguard Worker #ifndef hb_atomic_ptr_impl_get
hb_atomic_ptr_impl_get(void ** const P)160*2d1272b8SAndroid Build Coastguard Worker inline void *hb_atomic_ptr_impl_get (void ** const P)	{ void *v = *P; _hb_memory_r_barrier (); return v; }
161*2d1272b8SAndroid Build Coastguard Worker #endif
162*2d1272b8SAndroid Build Coastguard Worker 
163*2d1272b8SAndroid Build Coastguard Worker 
164*2d1272b8SAndroid Build Coastguard Worker struct hb_atomic_short_t
165*2d1272b8SAndroid Build Coastguard Worker {
166*2d1272b8SAndroid Build Coastguard Worker   hb_atomic_short_t () = default;
hb_atomic_short_thb_atomic_short_t167*2d1272b8SAndroid Build Coastguard Worker   constexpr hb_atomic_short_t (short v) : v (v) {}
168*2d1272b8SAndroid Build Coastguard Worker 
operator =hb_atomic_short_t169*2d1272b8SAndroid Build Coastguard Worker   hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; }
operator shorthb_atomic_short_t170*2d1272b8SAndroid Build Coastguard Worker   operator short () const { return get_relaxed (); }
171*2d1272b8SAndroid Build Coastguard Worker 
set_relaxedhb_atomic_short_t172*2d1272b8SAndroid Build Coastguard Worker   void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
set_releasehb_atomic_short_t173*2d1272b8SAndroid Build Coastguard Worker   void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); }
get_relaxedhb_atomic_short_t174*2d1272b8SAndroid Build Coastguard Worker   short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
get_acquirehb_atomic_short_t175*2d1272b8SAndroid Build Coastguard Worker   short get_acquire () const { return hb_atomic_int_impl_get (&v); }
inchb_atomic_short_t176*2d1272b8SAndroid Build Coastguard Worker   short inc () { return hb_atomic_int_impl_add (&v,  1); }
dechb_atomic_short_t177*2d1272b8SAndroid Build Coastguard Worker   short dec () { return hb_atomic_int_impl_add (&v, -1); }
178*2d1272b8SAndroid Build Coastguard Worker 
179*2d1272b8SAndroid Build Coastguard Worker   short v = 0;
180*2d1272b8SAndroid Build Coastguard Worker };
181*2d1272b8SAndroid Build Coastguard Worker 
182*2d1272b8SAndroid Build Coastguard Worker struct hb_atomic_int_t
183*2d1272b8SAndroid Build Coastguard Worker {
184*2d1272b8SAndroid Build Coastguard Worker   hb_atomic_int_t () = default;
hb_atomic_int_thb_atomic_int_t185*2d1272b8SAndroid Build Coastguard Worker   constexpr hb_atomic_int_t (int v) : v (v) {}
186*2d1272b8SAndroid Build Coastguard Worker 
operator =hb_atomic_int_t187*2d1272b8SAndroid Build Coastguard Worker   hb_atomic_int_t& operator = (int v_) { set_relaxed (v_); return *this; }
operator inthb_atomic_int_t188*2d1272b8SAndroid Build Coastguard Worker   operator int () const { return get_relaxed (); }
189*2d1272b8SAndroid Build Coastguard Worker 
set_relaxedhb_atomic_int_t190*2d1272b8SAndroid Build Coastguard Worker   void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
set_releasehb_atomic_int_t191*2d1272b8SAndroid Build Coastguard Worker   void set_release (int v_) { hb_atomic_int_impl_set (&v, v_); }
get_relaxedhb_atomic_int_t192*2d1272b8SAndroid Build Coastguard Worker   int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
get_acquirehb_atomic_int_t193*2d1272b8SAndroid Build Coastguard Worker   int get_acquire () const { return hb_atomic_int_impl_get (&v); }
inchb_atomic_int_t194*2d1272b8SAndroid Build Coastguard Worker   int inc () { return hb_atomic_int_impl_add (&v,  1); }
dechb_atomic_int_t195*2d1272b8SAndroid Build Coastguard Worker   int dec () { return hb_atomic_int_impl_add (&v, -1); }
196*2d1272b8SAndroid Build Coastguard Worker 
197*2d1272b8SAndroid Build Coastguard Worker   int v = 0;
198*2d1272b8SAndroid Build Coastguard Worker };
199*2d1272b8SAndroid Build Coastguard Worker 
200*2d1272b8SAndroid Build Coastguard Worker template <typename P>
201*2d1272b8SAndroid Build Coastguard Worker struct hb_atomic_ptr_t
202*2d1272b8SAndroid Build Coastguard Worker {
203*2d1272b8SAndroid Build Coastguard Worker   typedef hb_remove_pointer<P> T;
204*2d1272b8SAndroid Build Coastguard Worker 
205*2d1272b8SAndroid Build Coastguard Worker   hb_atomic_ptr_t () = default;
hb_atomic_ptr_thb_atomic_ptr_t206*2d1272b8SAndroid Build Coastguard Worker   constexpr hb_atomic_ptr_t (T* v) : v (v) {}
207*2d1272b8SAndroid Build Coastguard Worker   hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete;
208*2d1272b8SAndroid Build Coastguard Worker 
inithb_atomic_ptr_t209*2d1272b8SAndroid Build Coastguard Worker   void init (T* v_ = nullptr) { set_relaxed (v_); }
set_relaxedhb_atomic_ptr_t210*2d1272b8SAndroid Build Coastguard Worker   void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
get_relaxedhb_atomic_ptr_t211*2d1272b8SAndroid Build Coastguard Worker   T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); }
get_acquirehb_atomic_ptr_t212*2d1272b8SAndroid Build Coastguard Worker   T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); }
cmpexchhb_atomic_ptr_t213*2d1272b8SAndroid Build Coastguard Worker   bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); }
214*2d1272b8SAndroid Build Coastguard Worker 
operator ->hb_atomic_ptr_t215*2d1272b8SAndroid Build Coastguard Worker   T * operator -> () const                    { return get_acquire (); }
operator C*hb_atomic_ptr_t216*2d1272b8SAndroid Build Coastguard Worker   template <typename C> operator C * () const { return get_acquire (); }
217*2d1272b8SAndroid Build Coastguard Worker 
218*2d1272b8SAndroid Build Coastguard Worker   T *v = nullptr;
219*2d1272b8SAndroid Build Coastguard Worker };
220*2d1272b8SAndroid Build Coastguard Worker 
hb_barrier()221*2d1272b8SAndroid Build Coastguard Worker static inline bool hb_barrier ()
222*2d1272b8SAndroid Build Coastguard Worker {
223*2d1272b8SAndroid Build Coastguard Worker   _hb_compiler_memory_r_barrier ();
224*2d1272b8SAndroid Build Coastguard Worker   return true;
225*2d1272b8SAndroid Build Coastguard Worker }
226*2d1272b8SAndroid Build Coastguard Worker 
227*2d1272b8SAndroid Build Coastguard Worker 
228*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_ATOMIC_HH */
229