1*1208bc7eSAndroid Build Coastguard Worker #ifndef JEMALLOC_INTERNAL_MUTEX_H
2*1208bc7eSAndroid Build Coastguard Worker #define JEMALLOC_INTERNAL_MUTEX_H
3*1208bc7eSAndroid Build Coastguard Worker
4*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/atomic.h"
5*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/mutex_prof.h"
6*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/tsd.h"
7*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/witness.h"
8*1208bc7eSAndroid Build Coastguard Worker
9*1208bc7eSAndroid Build Coastguard Worker typedef enum {
10*1208bc7eSAndroid Build Coastguard Worker /* Can only acquire one mutex of a given witness rank at a time. */
11*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_rank_exclusive,
12*1208bc7eSAndroid Build Coastguard Worker /*
13*1208bc7eSAndroid Build Coastguard Worker * Can acquire multiple mutexes of the same witness rank, but in
14*1208bc7eSAndroid Build Coastguard Worker * address-ascending order only.
15*1208bc7eSAndroid Build Coastguard Worker */
16*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_address_ordered
17*1208bc7eSAndroid Build Coastguard Worker } malloc_mutex_lock_order_t;
18*1208bc7eSAndroid Build Coastguard Worker
19*1208bc7eSAndroid Build Coastguard Worker typedef struct malloc_mutex_s malloc_mutex_t;
20*1208bc7eSAndroid Build Coastguard Worker struct malloc_mutex_s {
21*1208bc7eSAndroid Build Coastguard Worker union {
22*1208bc7eSAndroid Build Coastguard Worker struct {
23*1208bc7eSAndroid Build Coastguard Worker /*
24*1208bc7eSAndroid Build Coastguard Worker * prof_data is defined first to reduce cacheline
25*1208bc7eSAndroid Build Coastguard Worker * bouncing: the data is not touched by the mutex holder
26*1208bc7eSAndroid Build Coastguard Worker * during unlocking, while might be modified by
27*1208bc7eSAndroid Build Coastguard Worker * contenders. Having it before the mutex itself could
28*1208bc7eSAndroid Build Coastguard Worker * avoid prefetching a modified cacheline (for the
29*1208bc7eSAndroid Build Coastguard Worker * unlocking thread).
30*1208bc7eSAndroid Build Coastguard Worker */
31*1208bc7eSAndroid Build Coastguard Worker mutex_prof_data_t prof_data;
32*1208bc7eSAndroid Build Coastguard Worker #ifdef _WIN32
33*1208bc7eSAndroid Build Coastguard Worker # if _WIN32_WINNT >= 0x0600
34*1208bc7eSAndroid Build Coastguard Worker SRWLOCK lock;
35*1208bc7eSAndroid Build Coastguard Worker # else
36*1208bc7eSAndroid Build Coastguard Worker CRITICAL_SECTION lock;
37*1208bc7eSAndroid Build Coastguard Worker # endif
38*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
39*1208bc7eSAndroid Build Coastguard Worker os_unfair_lock lock;
40*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_OSSPIN))
41*1208bc7eSAndroid Build Coastguard Worker OSSpinLock lock;
42*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_MUTEX_INIT_CB))
43*1208bc7eSAndroid Build Coastguard Worker pthread_mutex_t lock;
44*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_t *postponed_next;
45*1208bc7eSAndroid Build Coastguard Worker #else
46*1208bc7eSAndroid Build Coastguard Worker pthread_mutex_t lock;
47*1208bc7eSAndroid Build Coastguard Worker #endif
48*1208bc7eSAndroid Build Coastguard Worker };
49*1208bc7eSAndroid Build Coastguard Worker /*
50*1208bc7eSAndroid Build Coastguard Worker * We only touch witness when configured w/ debug. However we
51*1208bc7eSAndroid Build Coastguard Worker * keep the field in a union when !debug so that we don't have
52*1208bc7eSAndroid Build Coastguard Worker * to pollute the code base with #ifdefs, while avoid paying the
53*1208bc7eSAndroid Build Coastguard Worker * memory cost.
54*1208bc7eSAndroid Build Coastguard Worker */
55*1208bc7eSAndroid Build Coastguard Worker #if !defined(JEMALLOC_DEBUG)
56*1208bc7eSAndroid Build Coastguard Worker witness_t witness;
57*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_lock_order_t lock_order;
58*1208bc7eSAndroid Build Coastguard Worker #endif
59*1208bc7eSAndroid Build Coastguard Worker };
60*1208bc7eSAndroid Build Coastguard Worker
61*1208bc7eSAndroid Build Coastguard Worker #if defined(JEMALLOC_DEBUG)
62*1208bc7eSAndroid Build Coastguard Worker witness_t witness;
63*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_lock_order_t lock_order;
64*1208bc7eSAndroid Build Coastguard Worker #endif
65*1208bc7eSAndroid Build Coastguard Worker };
66*1208bc7eSAndroid Build Coastguard Worker
67*1208bc7eSAndroid Build Coastguard Worker /*
68*1208bc7eSAndroid Build Coastguard Worker * Based on benchmark results, a fixed spin with this amount of retries works
69*1208bc7eSAndroid Build Coastguard Worker * well for our critical sections.
70*1208bc7eSAndroid Build Coastguard Worker */
71*1208bc7eSAndroid Build Coastguard Worker #define MALLOC_MUTEX_MAX_SPIN 250
72*1208bc7eSAndroid Build Coastguard Worker
73*1208bc7eSAndroid Build Coastguard Worker #ifdef _WIN32
74*1208bc7eSAndroid Build Coastguard Worker # if _WIN32_WINNT >= 0x0600
75*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_LOCK(m) AcquireSRWLockExclusive(&(m)->lock)
76*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_UNLOCK(m) ReleaseSRWLockExclusive(&(m)->lock)
77*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_TRYLOCK(m) (!TryAcquireSRWLockExclusive(&(m)->lock))
78*1208bc7eSAndroid Build Coastguard Worker # else
79*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_LOCK(m) EnterCriticalSection(&(m)->lock)
80*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_UNLOCK(m) LeaveCriticalSection(&(m)->lock)
81*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_TRYLOCK(m) (!TryEnterCriticalSection(&(m)->lock))
82*1208bc7eSAndroid Build Coastguard Worker # endif
83*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
84*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_LOCK(m) os_unfair_lock_lock(&(m)->lock)
85*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_UNLOCK(m) os_unfair_lock_unlock(&(m)->lock)
86*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_TRYLOCK(m) (!os_unfair_lock_trylock(&(m)->lock))
87*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_OSSPIN))
88*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_LOCK(m) OSSpinLockLock(&(m)->lock)
89*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_UNLOCK(m) OSSpinLockUnlock(&(m)->lock)
90*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_TRYLOCK(m) (!OSSpinLockTry(&(m)->lock))
91*1208bc7eSAndroid Build Coastguard Worker #else
92*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_LOCK(m) pthread_mutex_lock(&(m)->lock)
93*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_UNLOCK(m) pthread_mutex_unlock(&(m)->lock)
94*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_TRYLOCK(m) (pthread_mutex_trylock(&(m)->lock) != 0)
95*1208bc7eSAndroid Build Coastguard Worker #endif
96*1208bc7eSAndroid Build Coastguard Worker
97*1208bc7eSAndroid Build Coastguard Worker #define LOCK_PROF_DATA_INITIALIZER \
98*1208bc7eSAndroid Build Coastguard Worker {NSTIME_ZERO_INITIALIZER, NSTIME_ZERO_INITIALIZER, 0, 0, 0, \
99*1208bc7eSAndroid Build Coastguard Worker ATOMIC_INIT(0), 0, NULL, 0}
100*1208bc7eSAndroid Build Coastguard Worker
101*1208bc7eSAndroid Build Coastguard Worker #ifdef _WIN32
102*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_INITIALIZER
103*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
104*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_INITIALIZER \
105*1208bc7eSAndroid Build Coastguard Worker {{{LOCK_PROF_DATA_INITIALIZER, OS_UNFAIR_LOCK_INIT}}, \
106*1208bc7eSAndroid Build Coastguard Worker WITNESS_INITIALIZER("mutex", WITNESS_RANK_OMIT)}
107*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_OSSPIN))
108*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_INITIALIZER \
109*1208bc7eSAndroid Build Coastguard Worker {{{LOCK_PROF_DATA_INITIALIZER, 0}}, \
110*1208bc7eSAndroid Build Coastguard Worker WITNESS_INITIALIZER("mutex", WITNESS_RANK_OMIT)}
111*1208bc7eSAndroid Build Coastguard Worker #elif (defined(JEMALLOC_MUTEX_INIT_CB))
112*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_INITIALIZER \
113*1208bc7eSAndroid Build Coastguard Worker {{{LOCK_PROF_DATA_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, NULL}}, \
114*1208bc7eSAndroid Build Coastguard Worker WITNESS_INITIALIZER("mutex", WITNESS_RANK_OMIT)}
115*1208bc7eSAndroid Build Coastguard Worker #else
116*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
117*1208bc7eSAndroid Build Coastguard Worker # define MALLOC_MUTEX_INITIALIZER \
118*1208bc7eSAndroid Build Coastguard Worker {{{LOCK_PROF_DATA_INITIALIZER, PTHREAD_MUTEX_INITIALIZER}}, \
119*1208bc7eSAndroid Build Coastguard Worker WITNESS_INITIALIZER("mutex", WITNESS_RANK_OMIT)}
120*1208bc7eSAndroid Build Coastguard Worker #endif
121*1208bc7eSAndroid Build Coastguard Worker
122*1208bc7eSAndroid Build Coastguard Worker #ifdef JEMALLOC_LAZY_LOCK
123*1208bc7eSAndroid Build Coastguard Worker extern bool isthreaded;
124*1208bc7eSAndroid Build Coastguard Worker #else
125*1208bc7eSAndroid Build Coastguard Worker # undef isthreaded /* Undo private_namespace.h definition. */
126*1208bc7eSAndroid Build Coastguard Worker # define isthreaded true
127*1208bc7eSAndroid Build Coastguard Worker #endif
128*1208bc7eSAndroid Build Coastguard Worker
129*1208bc7eSAndroid Build Coastguard Worker bool malloc_mutex_init(malloc_mutex_t *mutex, const char *name,
130*1208bc7eSAndroid Build Coastguard Worker witness_rank_t rank, malloc_mutex_lock_order_t lock_order);
131*1208bc7eSAndroid Build Coastguard Worker void malloc_mutex_prefork(tsdn_t *tsdn, malloc_mutex_t *mutex);
132*1208bc7eSAndroid Build Coastguard Worker void malloc_mutex_postfork_parent(tsdn_t *tsdn, malloc_mutex_t *mutex);
133*1208bc7eSAndroid Build Coastguard Worker void malloc_mutex_postfork_child(tsdn_t *tsdn, malloc_mutex_t *mutex);
134*1208bc7eSAndroid Build Coastguard Worker bool malloc_mutex_boot(void);
135*1208bc7eSAndroid Build Coastguard Worker void malloc_mutex_prof_data_reset(tsdn_t *tsdn, malloc_mutex_t *mutex);
136*1208bc7eSAndroid Build Coastguard Worker
137*1208bc7eSAndroid Build Coastguard Worker void malloc_mutex_lock_slow(malloc_mutex_t *mutex);
138*1208bc7eSAndroid Build Coastguard Worker
139*1208bc7eSAndroid Build Coastguard Worker static inline void
malloc_mutex_lock_final(malloc_mutex_t * mutex)140*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_lock_final(malloc_mutex_t *mutex) {
141*1208bc7eSAndroid Build Coastguard Worker MALLOC_MUTEX_LOCK(mutex);
142*1208bc7eSAndroid Build Coastguard Worker }
143*1208bc7eSAndroid Build Coastguard Worker
144*1208bc7eSAndroid Build Coastguard Worker static inline bool
malloc_mutex_trylock_final(malloc_mutex_t * mutex)145*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_trylock_final(malloc_mutex_t *mutex) {
146*1208bc7eSAndroid Build Coastguard Worker return MALLOC_MUTEX_TRYLOCK(mutex);
147*1208bc7eSAndroid Build Coastguard Worker }
148*1208bc7eSAndroid Build Coastguard Worker
149*1208bc7eSAndroid Build Coastguard Worker static inline void
mutex_owner_stats_update(tsdn_t * tsdn,malloc_mutex_t * mutex)150*1208bc7eSAndroid Build Coastguard Worker mutex_owner_stats_update(tsdn_t *tsdn, malloc_mutex_t *mutex) {
151*1208bc7eSAndroid Build Coastguard Worker if (config_stats) {
152*1208bc7eSAndroid Build Coastguard Worker mutex_prof_data_t *data = &mutex->prof_data;
153*1208bc7eSAndroid Build Coastguard Worker data->n_lock_ops++;
154*1208bc7eSAndroid Build Coastguard Worker if (data->prev_owner != tsdn) {
155*1208bc7eSAndroid Build Coastguard Worker data->prev_owner = tsdn;
156*1208bc7eSAndroid Build Coastguard Worker data->n_owner_switches++;
157*1208bc7eSAndroid Build Coastguard Worker }
158*1208bc7eSAndroid Build Coastguard Worker }
159*1208bc7eSAndroid Build Coastguard Worker }
160*1208bc7eSAndroid Build Coastguard Worker
161*1208bc7eSAndroid Build Coastguard Worker /* Trylock: return false if the lock is successfully acquired. */
162*1208bc7eSAndroid Build Coastguard Worker static inline bool
malloc_mutex_trylock(tsdn_t * tsdn,malloc_mutex_t * mutex)163*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_trylock(tsdn_t *tsdn, malloc_mutex_t *mutex) {
164*1208bc7eSAndroid Build Coastguard Worker witness_assert_not_owner(tsdn_witness_tsdp_get(tsdn), &mutex->witness);
165*1208bc7eSAndroid Build Coastguard Worker if (isthreaded) {
166*1208bc7eSAndroid Build Coastguard Worker if (malloc_mutex_trylock_final(mutex)) {
167*1208bc7eSAndroid Build Coastguard Worker return true;
168*1208bc7eSAndroid Build Coastguard Worker }
169*1208bc7eSAndroid Build Coastguard Worker mutex_owner_stats_update(tsdn, mutex);
170*1208bc7eSAndroid Build Coastguard Worker }
171*1208bc7eSAndroid Build Coastguard Worker witness_lock(tsdn_witness_tsdp_get(tsdn), &mutex->witness);
172*1208bc7eSAndroid Build Coastguard Worker
173*1208bc7eSAndroid Build Coastguard Worker return false;
174*1208bc7eSAndroid Build Coastguard Worker }
175*1208bc7eSAndroid Build Coastguard Worker
176*1208bc7eSAndroid Build Coastguard Worker /* Aggregate lock prof data. */
177*1208bc7eSAndroid Build Coastguard Worker static inline void
malloc_mutex_prof_merge(mutex_prof_data_t * sum,mutex_prof_data_t * data)178*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_prof_merge(mutex_prof_data_t *sum, mutex_prof_data_t *data) {
179*1208bc7eSAndroid Build Coastguard Worker nstime_add(&sum->tot_wait_time, &data->tot_wait_time);
180*1208bc7eSAndroid Build Coastguard Worker if (nstime_compare(&sum->max_wait_time, &data->max_wait_time) < 0) {
181*1208bc7eSAndroid Build Coastguard Worker nstime_copy(&sum->max_wait_time, &data->max_wait_time);
182*1208bc7eSAndroid Build Coastguard Worker }
183*1208bc7eSAndroid Build Coastguard Worker
184*1208bc7eSAndroid Build Coastguard Worker sum->n_wait_times += data->n_wait_times;
185*1208bc7eSAndroid Build Coastguard Worker sum->n_spin_acquired += data->n_spin_acquired;
186*1208bc7eSAndroid Build Coastguard Worker
187*1208bc7eSAndroid Build Coastguard Worker if (sum->max_n_thds < data->max_n_thds) {
188*1208bc7eSAndroid Build Coastguard Worker sum->max_n_thds = data->max_n_thds;
189*1208bc7eSAndroid Build Coastguard Worker }
190*1208bc7eSAndroid Build Coastguard Worker uint32_t cur_n_waiting_thds = atomic_load_u32(&sum->n_waiting_thds,
191*1208bc7eSAndroid Build Coastguard Worker ATOMIC_RELAXED);
192*1208bc7eSAndroid Build Coastguard Worker uint32_t new_n_waiting_thds = cur_n_waiting_thds + atomic_load_u32(
193*1208bc7eSAndroid Build Coastguard Worker &data->n_waiting_thds, ATOMIC_RELAXED);
194*1208bc7eSAndroid Build Coastguard Worker atomic_store_u32(&sum->n_waiting_thds, new_n_waiting_thds,
195*1208bc7eSAndroid Build Coastguard Worker ATOMIC_RELAXED);
196*1208bc7eSAndroid Build Coastguard Worker sum->n_owner_switches += data->n_owner_switches;
197*1208bc7eSAndroid Build Coastguard Worker sum->n_lock_ops += data->n_lock_ops;
198*1208bc7eSAndroid Build Coastguard Worker }
199*1208bc7eSAndroid Build Coastguard Worker
200*1208bc7eSAndroid Build Coastguard Worker static inline void
malloc_mutex_lock(tsdn_t * tsdn,malloc_mutex_t * mutex)201*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_lock(tsdn_t *tsdn, malloc_mutex_t *mutex) {
202*1208bc7eSAndroid Build Coastguard Worker witness_assert_not_owner(tsdn_witness_tsdp_get(tsdn), &mutex->witness);
203*1208bc7eSAndroid Build Coastguard Worker if (isthreaded) {
204*1208bc7eSAndroid Build Coastguard Worker if (malloc_mutex_trylock_final(mutex)) {
205*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_lock_slow(mutex);
206*1208bc7eSAndroid Build Coastguard Worker }
207*1208bc7eSAndroid Build Coastguard Worker mutex_owner_stats_update(tsdn, mutex);
208*1208bc7eSAndroid Build Coastguard Worker }
209*1208bc7eSAndroid Build Coastguard Worker witness_lock(tsdn_witness_tsdp_get(tsdn), &mutex->witness);
210*1208bc7eSAndroid Build Coastguard Worker }
211*1208bc7eSAndroid Build Coastguard Worker
212*1208bc7eSAndroid Build Coastguard Worker static inline void
malloc_mutex_unlock(tsdn_t * tsdn,malloc_mutex_t * mutex)213*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_unlock(tsdn_t *tsdn, malloc_mutex_t *mutex) {
214*1208bc7eSAndroid Build Coastguard Worker witness_unlock(tsdn_witness_tsdp_get(tsdn), &mutex->witness);
215*1208bc7eSAndroid Build Coastguard Worker if (isthreaded) {
216*1208bc7eSAndroid Build Coastguard Worker MALLOC_MUTEX_UNLOCK(mutex);
217*1208bc7eSAndroid Build Coastguard Worker }
218*1208bc7eSAndroid Build Coastguard Worker }
219*1208bc7eSAndroid Build Coastguard Worker
220*1208bc7eSAndroid Build Coastguard Worker static inline void
malloc_mutex_assert_owner(tsdn_t * tsdn,malloc_mutex_t * mutex)221*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_assert_owner(tsdn_t *tsdn, malloc_mutex_t *mutex) {
222*1208bc7eSAndroid Build Coastguard Worker witness_assert_owner(tsdn_witness_tsdp_get(tsdn), &mutex->witness);
223*1208bc7eSAndroid Build Coastguard Worker }
224*1208bc7eSAndroid Build Coastguard Worker
225*1208bc7eSAndroid Build Coastguard Worker static inline void
malloc_mutex_assert_not_owner(tsdn_t * tsdn,malloc_mutex_t * mutex)226*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_assert_not_owner(tsdn_t *tsdn, malloc_mutex_t *mutex) {
227*1208bc7eSAndroid Build Coastguard Worker witness_assert_not_owner(tsdn_witness_tsdp_get(tsdn), &mutex->witness);
228*1208bc7eSAndroid Build Coastguard Worker }
229*1208bc7eSAndroid Build Coastguard Worker
230*1208bc7eSAndroid Build Coastguard Worker /* Copy the prof data from mutex for processing. */
231*1208bc7eSAndroid Build Coastguard Worker static inline void
malloc_mutex_prof_read(tsdn_t * tsdn,mutex_prof_data_t * data,malloc_mutex_t * mutex)232*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_prof_read(tsdn_t *tsdn, mutex_prof_data_t *data,
233*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_t *mutex) {
234*1208bc7eSAndroid Build Coastguard Worker mutex_prof_data_t *source = &mutex->prof_data;
235*1208bc7eSAndroid Build Coastguard Worker /* Can only read holding the mutex. */
236*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_assert_owner(tsdn, mutex);
237*1208bc7eSAndroid Build Coastguard Worker
238*1208bc7eSAndroid Build Coastguard Worker /*
239*1208bc7eSAndroid Build Coastguard Worker * Not *really* allowed (we shouldn't be doing non-atomic loads of
240*1208bc7eSAndroid Build Coastguard Worker * atomic data), but the mutex protection makes this safe, and writing
241*1208bc7eSAndroid Build Coastguard Worker * a member-for-member copy is tedious for this situation.
242*1208bc7eSAndroid Build Coastguard Worker */
243*1208bc7eSAndroid Build Coastguard Worker *data = *source;
244*1208bc7eSAndroid Build Coastguard Worker /* n_wait_thds is not reported (modified w/o locking). */
245*1208bc7eSAndroid Build Coastguard Worker atomic_store_u32(&data->n_waiting_thds, 0, ATOMIC_RELAXED);
246*1208bc7eSAndroid Build Coastguard Worker }
247*1208bc7eSAndroid Build Coastguard Worker
248*1208bc7eSAndroid Build Coastguard Worker #endif /* JEMALLOC_INTERNAL_MUTEX_H */
249