xref: /aosp_15_r20/system/media/audio_utils/include/audio_utils/mutex.h (revision b9df5ad1c9ac98a7fefaac271a55f7ae3db05414)
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <android-base/thread_annotations.h>
20 #include <audio_utils/safe_math.h>
21 #include <audio_utils/threads.h>
22 #include <utils/Log.h>
23 #include <utils/Timers.h>
24 
25 #include <algorithm>
26 #include <array>
27 #include <cmath>
28 #include <map>
29 #include <memory>
30 #include <mutex>
31 #include <sys/syscall.h>
32 #include <unordered_map>
33 #include <unordered_set>
34 #include <utility>
35 #include <vector>
36 
37 #pragma push_macro("LOG_TAG")
38 #undef LOG_TAG
39 #define LOG_TAG "audio_utils::mutex"
40 
41 namespace android::audio_utils {
42 
43 // Define global capabilities for thread-safety annotation.
44 //
45 // These can be manually modified, or
46 // compile generate_mutex_order.cpp in the tests directory
47 // to generate this.
48 
49 // --- Begin generated section
50 
51 // Lock order
52 enum class MutexOrder : uint32_t {
53     kSpatializer_Mutex = 0,
54     kAudioPolicyEffects_Mutex = 1,
55     kEffectHandle_Mutex = 2,
56     kEffectBase_PolicyMutex = 3,
57     kAudioPolicyService_Mutex = 4,
58     kCommandThread_Mutex = 5,
59     kAudioCommand_Mutex = 6,
60     kUidPolicy_Mutex = 7,
61     kAudioFlinger_Mutex = 8,
62     kDeviceEffectManager_Mutex = 9,
63     kDeviceEffectProxy_ProxyMutex = 10,
64     kDeviceEffectHandle_Mutex = 11,
65     kPatchCommandThread_Mutex = 12,
66     kThreadBase_Mutex = 13,
67     kAudioFlinger_ClientMutex = 14,
68     kEffectChain_Mutex = 15,
69     kEffectBase_Mutex = 16,
70     kAudioFlinger_HardwareMutex = 17,
71     kMelReporter_Mutex = 18,
72     kAudioFlinger_UnregisteredWritersMutex = 19,
73     kAsyncCallbackThread_Mutex = 20,
74     kConfigEvent_Mutex = 21,
75     kOutputTrack_TrackMetadataMutex = 22,
76     kPassthruPatchRecord_ReadMutex = 23,
77     kPatchCommandThread_ListenerMutex = 24,
78     kPlaybackThread_AudioTrackCbMutex = 25,
79     kAudioPolicyService_NotificationClientsMutex = 26,
80     kMediaLogNotifier_Mutex = 27,
81     kOtherMutex = 28,
82     kSize = 29,
83 };
84 
85 // Lock by name
86 inline constexpr const char* const gMutexNames[] = {
87     "Spatializer_Mutex",
88     "AudioPolicyEffects_Mutex",
89     "EffectHandle_Mutex",
90     "EffectBase_PolicyMutex",
91     "AudioPolicyService_Mutex",
92     "CommandThread_Mutex",
93     "AudioCommand_Mutex",
94     "UidPolicy_Mutex",
95     "AudioFlinger_Mutex",
96     "DeviceEffectManager_Mutex",
97     "DeviceEffectProxy_ProxyMutex",
98     "DeviceEffectHandle_Mutex",
99     "PatchCommandThread_Mutex",
100     "ThreadBase_Mutex",
101     "AudioFlinger_ClientMutex",
102     "EffectChain_Mutex",
103     "EffectBase_Mutex",
104     "AudioFlinger_HardwareMutex",
105     "MelReporter_Mutex",
106     "AudioFlinger_UnregisteredWritersMutex",
107     "AsyncCallbackThread_Mutex",
108     "ConfigEvent_Mutex",
109     "OutputTrack_TrackMetadataMutex",
110     "PassthruPatchRecord_ReadMutex",
111     "PatchCommandThread_ListenerMutex",
112     "PlaybackThread_AudioTrackCbMutex",
113     "AudioPolicyService_NotificationClientsMutex",
114     "MediaLogNotifier_Mutex",
115     "OtherMutex",
116 };
117 
118 // Forward declarations
119 class AudioMutexAttributes;
120 template <typename T> class mutex_impl;
121 using mutex = mutex_impl<AudioMutexAttributes>;
122 
123 // Capabilities in priority order
124 // (declaration only, value is nullptr)
125 inline mutex* Spatializer_Mutex;
126 inline mutex* AudioPolicyEffects_Mutex
127         ACQUIRED_AFTER(android::audio_utils::Spatializer_Mutex);
128 inline mutex* EffectHandle_Mutex
129         ACQUIRED_AFTER(android::audio_utils::AudioPolicyEffects_Mutex);
130 inline mutex* EffectBase_PolicyMutex
131         ACQUIRED_AFTER(android::audio_utils::EffectHandle_Mutex);
132 inline mutex* AudioPolicyService_Mutex
133         ACQUIRED_AFTER(android::audio_utils::EffectBase_PolicyMutex);
134 inline mutex* CommandThread_Mutex
135         ACQUIRED_AFTER(android::audio_utils::AudioPolicyService_Mutex);
136 inline mutex* AudioCommand_Mutex
137         ACQUIRED_AFTER(android::audio_utils::CommandThread_Mutex);
138 inline mutex* UidPolicy_Mutex
139         ACQUIRED_AFTER(android::audio_utils::AudioCommand_Mutex);
140 inline mutex* AudioFlinger_Mutex
141         ACQUIRED_AFTER(android::audio_utils::UidPolicy_Mutex);
142 inline mutex* DeviceEffectManager_Mutex
143         ACQUIRED_AFTER(android::audio_utils::AudioFlinger_Mutex);
144 inline mutex* DeviceEffectProxy_ProxyMutex
145         ACQUIRED_AFTER(android::audio_utils::DeviceEffectManager_Mutex);
146 inline mutex* DeviceEffectHandle_Mutex
147         ACQUIRED_AFTER(android::audio_utils::DeviceEffectProxy_ProxyMutex);
148 inline mutex* PatchCommandThread_Mutex
149         ACQUIRED_AFTER(android::audio_utils::DeviceEffectHandle_Mutex);
150 inline mutex* ThreadBase_Mutex
151         ACQUIRED_AFTER(android::audio_utils::PatchCommandThread_Mutex);
152 inline mutex* AudioFlinger_ClientMutex
153         ACQUIRED_AFTER(android::audio_utils::ThreadBase_Mutex);
154 inline mutex* EffectChain_Mutex
155         ACQUIRED_AFTER(android::audio_utils::AudioFlinger_ClientMutex);
156 inline mutex* EffectBase_Mutex
157         ACQUIRED_AFTER(android::audio_utils::EffectChain_Mutex);
158 inline mutex* AudioFlinger_HardwareMutex
159         ACQUIRED_AFTER(android::audio_utils::EffectBase_Mutex);
160 inline mutex* MelReporter_Mutex
161         ACQUIRED_AFTER(android::audio_utils::AudioFlinger_HardwareMutex);
162 inline mutex* AudioFlinger_UnregisteredWritersMutex
163         ACQUIRED_AFTER(android::audio_utils::MelReporter_Mutex);
164 inline mutex* AsyncCallbackThread_Mutex
165         ACQUIRED_AFTER(android::audio_utils::AudioFlinger_UnregisteredWritersMutex);
166 inline mutex* ConfigEvent_Mutex
167         ACQUIRED_AFTER(android::audio_utils::AsyncCallbackThread_Mutex);
168 inline mutex* OutputTrack_TrackMetadataMutex
169         ACQUIRED_AFTER(android::audio_utils::ConfigEvent_Mutex);
170 inline mutex* PassthruPatchRecord_ReadMutex
171         ACQUIRED_AFTER(android::audio_utils::OutputTrack_TrackMetadataMutex);
172 inline mutex* PatchCommandThread_ListenerMutex
173         ACQUIRED_AFTER(android::audio_utils::PassthruPatchRecord_ReadMutex);
174 inline mutex* PlaybackThread_AudioTrackCbMutex
175         ACQUIRED_AFTER(android::audio_utils::PatchCommandThread_ListenerMutex);
176 inline mutex* AudioPolicyService_NotificationClientsMutex
177         ACQUIRED_AFTER(android::audio_utils::PlaybackThread_AudioTrackCbMutex);
178 inline mutex* MediaLogNotifier_Mutex
179         ACQUIRED_AFTER(android::audio_utils::AudioPolicyService_NotificationClientsMutex);
180 inline mutex* OtherMutex
181         ACQUIRED_AFTER(android::audio_utils::MediaLogNotifier_Mutex);
182 
183 // Exclusion by capability
184 #define EXCLUDES_BELOW_OtherMutex
185 #define EXCLUDES_OtherMutex \
186     EXCLUDES(android::audio_utils::OtherMutex) \
187     EXCLUDES_BELOW_OtherMutex
188 
189 #define EXCLUDES_BELOW_MediaLogNotifier_Mutex \
190     EXCLUDES_OtherMutex
191 #define EXCLUDES_MediaLogNotifier_Mutex \
192     EXCLUDES(android::audio_utils::MediaLogNotifier_Mutex) \
193     EXCLUDES_BELOW_MediaLogNotifier_Mutex
194 
195 #define EXCLUDES_BELOW_AudioPolicyService_NotificationClientsMutex \
196     EXCLUDES_MediaLogNotifier_Mutex
197 #define EXCLUDES_AudioPolicyService_NotificationClientsMutex \
198     EXCLUDES(android::audio_utils::AudioPolicyService_NotificationClientsMutex) \
199     EXCLUDES_BELOW_AudioPolicyService_NotificationClientsMutex
200 
201 #define EXCLUDES_BELOW_PlaybackThread_AudioTrackCbMutex \
202     EXCLUDES_AudioPolicyService_NotificationClientsMutex
203 #define EXCLUDES_PlaybackThread_AudioTrackCbMutex \
204     EXCLUDES(android::audio_utils::PlaybackThread_AudioTrackCbMutex) \
205     EXCLUDES_BELOW_PlaybackThread_AudioTrackCbMutex
206 
207 #define EXCLUDES_BELOW_PatchCommandThread_ListenerMutex \
208     EXCLUDES_PlaybackThread_AudioTrackCbMutex
209 #define EXCLUDES_PatchCommandThread_ListenerMutex \
210     EXCLUDES(android::audio_utils::PatchCommandThread_ListenerMutex) \
211     EXCLUDES_BELOW_PatchCommandThread_ListenerMutex
212 
213 #define EXCLUDES_BELOW_PassthruPatchRecord_ReadMutex \
214     EXCLUDES_PatchCommandThread_ListenerMutex
215 #define EXCLUDES_PassthruPatchRecord_ReadMutex \
216     EXCLUDES(android::audio_utils::PassthruPatchRecord_ReadMutex) \
217     EXCLUDES_BELOW_PassthruPatchRecord_ReadMutex
218 
219 #define EXCLUDES_BELOW_OutputTrack_TrackMetadataMutex \
220     EXCLUDES_PassthruPatchRecord_ReadMutex
221 #define EXCLUDES_OutputTrack_TrackMetadataMutex \
222     EXCLUDES(android::audio_utils::OutputTrack_TrackMetadataMutex) \
223     EXCLUDES_BELOW_OutputTrack_TrackMetadataMutex
224 
225 #define EXCLUDES_BELOW_ConfigEvent_Mutex \
226     EXCLUDES_OutputTrack_TrackMetadataMutex
227 #define EXCLUDES_ConfigEvent_Mutex \
228     EXCLUDES(android::audio_utils::ConfigEvent_Mutex) \
229     EXCLUDES_BELOW_ConfigEvent_Mutex
230 
231 #define EXCLUDES_BELOW_AsyncCallbackThread_Mutex \
232     EXCLUDES_ConfigEvent_Mutex
233 #define EXCLUDES_AsyncCallbackThread_Mutex \
234     EXCLUDES(android::audio_utils::AsyncCallbackThread_Mutex) \
235     EXCLUDES_BELOW_AsyncCallbackThread_Mutex
236 
237 #define EXCLUDES_BELOW_AudioFlinger_UnregisteredWritersMutex \
238     EXCLUDES_AsyncCallbackThread_Mutex
239 #define EXCLUDES_AudioFlinger_UnregisteredWritersMutex \
240     EXCLUDES(android::audio_utils::AudioFlinger_UnregisteredWritersMutex) \
241     EXCLUDES_BELOW_AudioFlinger_UnregisteredWritersMutex
242 
243 #define EXCLUDES_BELOW_MelReporter_Mutex \
244     EXCLUDES_AudioFlinger_UnregisteredWritersMutex
245 #define EXCLUDES_MelReporter_Mutex \
246     EXCLUDES(android::audio_utils::MelReporter_Mutex) \
247     EXCLUDES_BELOW_MelReporter_Mutex
248 
249 #define EXCLUDES_BELOW_AudioFlinger_HardwareMutex \
250     EXCLUDES_MelReporter_Mutex
251 #define EXCLUDES_AudioFlinger_HardwareMutex \
252     EXCLUDES(android::audio_utils::AudioFlinger_HardwareMutex) \
253     EXCLUDES_BELOW_AudioFlinger_HardwareMutex
254 
255 #define EXCLUDES_BELOW_EffectBase_Mutex \
256     EXCLUDES_AudioFlinger_HardwareMutex
257 #define EXCLUDES_EffectBase_Mutex \
258     EXCLUDES(android::audio_utils::EffectBase_Mutex) \
259     EXCLUDES_BELOW_EffectBase_Mutex
260 
261 #define EXCLUDES_BELOW_EffectChain_Mutex \
262     EXCLUDES_EffectBase_Mutex
263 #define EXCLUDES_EffectChain_Mutex \
264     EXCLUDES(android::audio_utils::EffectChain_Mutex) \
265     EXCLUDES_BELOW_EffectChain_Mutex
266 
267 #define EXCLUDES_BELOW_AudioFlinger_ClientMutex \
268     EXCLUDES_EffectChain_Mutex
269 #define EXCLUDES_AudioFlinger_ClientMutex \
270     EXCLUDES(android::audio_utils::AudioFlinger_ClientMutex) \
271     EXCLUDES_BELOW_AudioFlinger_ClientMutex
272 
273 #define EXCLUDES_BELOW_ThreadBase_Mutex \
274     EXCLUDES_AudioFlinger_ClientMutex
275 #define EXCLUDES_ThreadBase_Mutex \
276     EXCLUDES(android::audio_utils::ThreadBase_Mutex) \
277     EXCLUDES_BELOW_ThreadBase_Mutex
278 
279 #define EXCLUDES_BELOW_PatchCommandThread_Mutex \
280     EXCLUDES_ThreadBase_Mutex
281 #define EXCLUDES_PatchCommandThread_Mutex \
282     EXCLUDES(android::audio_utils::PatchCommandThread_Mutex) \
283     EXCLUDES_BELOW_PatchCommandThread_Mutex
284 
285 #define EXCLUDES_BELOW_DeviceEffectHandle_Mutex \
286     EXCLUDES_PatchCommandThread_Mutex
287 #define EXCLUDES_DeviceEffectHandle_Mutex \
288     EXCLUDES(android::audio_utils::DeviceEffectHandle_Mutex) \
289     EXCLUDES_BELOW_DeviceEffectHandle_Mutex
290 
291 #define EXCLUDES_BELOW_DeviceEffectProxy_ProxyMutex \
292     EXCLUDES_DeviceEffectHandle_Mutex
293 #define EXCLUDES_DeviceEffectProxy_ProxyMutex \
294     EXCLUDES(android::audio_utils::DeviceEffectProxy_ProxyMutex) \
295     EXCLUDES_BELOW_DeviceEffectProxy_ProxyMutex
296 
297 #define EXCLUDES_BELOW_DeviceEffectManager_Mutex \
298     EXCLUDES_DeviceEffectProxy_ProxyMutex
299 #define EXCLUDES_DeviceEffectManager_Mutex \
300     EXCLUDES(android::audio_utils::DeviceEffectManager_Mutex) \
301     EXCLUDES_BELOW_DeviceEffectManager_Mutex
302 
303 #define EXCLUDES_BELOW_AudioFlinger_Mutex \
304     EXCLUDES_DeviceEffectManager_Mutex
305 #define EXCLUDES_AudioFlinger_Mutex \
306     EXCLUDES(android::audio_utils::AudioFlinger_Mutex) \
307     EXCLUDES_BELOW_AudioFlinger_Mutex
308 
309 #define EXCLUDES_BELOW_UidPolicy_Mutex \
310     EXCLUDES_AudioFlinger_Mutex
311 #define EXCLUDES_UidPolicy_Mutex \
312     EXCLUDES(android::audio_utils::UidPolicy_Mutex) \
313     EXCLUDES_BELOW_UidPolicy_Mutex
314 
315 #define EXCLUDES_BELOW_AudioCommand_Mutex \
316     EXCLUDES_UidPolicy_Mutex
317 #define EXCLUDES_AudioCommand_Mutex \
318     EXCLUDES(android::audio_utils::AudioCommand_Mutex) \
319     EXCLUDES_BELOW_AudioCommand_Mutex
320 
321 #define EXCLUDES_BELOW_CommandThread_Mutex \
322     EXCLUDES_AudioCommand_Mutex
323 #define EXCLUDES_CommandThread_Mutex \
324     EXCLUDES(android::audio_utils::CommandThread_Mutex) \
325     EXCLUDES_BELOW_CommandThread_Mutex
326 
327 #define EXCLUDES_BELOW_AudioPolicyService_Mutex \
328     EXCLUDES_CommandThread_Mutex
329 #define EXCLUDES_AudioPolicyService_Mutex \
330     EXCLUDES(android::audio_utils::AudioPolicyService_Mutex) \
331     EXCLUDES_BELOW_AudioPolicyService_Mutex
332 
333 #define EXCLUDES_BELOW_EffectBase_PolicyMutex \
334     EXCLUDES_AudioPolicyService_Mutex
335 #define EXCLUDES_EffectBase_PolicyMutex \
336     EXCLUDES(android::audio_utils::EffectBase_PolicyMutex) \
337     EXCLUDES_BELOW_EffectBase_PolicyMutex
338 
339 #define EXCLUDES_BELOW_EffectHandle_Mutex \
340     EXCLUDES_EffectBase_PolicyMutex
341 #define EXCLUDES_EffectHandle_Mutex \
342     EXCLUDES(android::audio_utils::EffectHandle_Mutex) \
343     EXCLUDES_BELOW_EffectHandle_Mutex
344 
345 #define EXCLUDES_BELOW_AudioPolicyEffects_Mutex \
346     EXCLUDES_EffectHandle_Mutex
347 #define EXCLUDES_AudioPolicyEffects_Mutex \
348     EXCLUDES(android::audio_utils::AudioPolicyEffects_Mutex) \
349     EXCLUDES_BELOW_AudioPolicyEffects_Mutex
350 
351 #define EXCLUDES_BELOW_Spatializer_Mutex \
352     EXCLUDES_AudioPolicyEffects_Mutex
353 #define EXCLUDES_Spatializer_Mutex \
354     EXCLUDES(android::audio_utils::Spatializer_Mutex) \
355     EXCLUDES_BELOW_Spatializer_Mutex
356 
357 #define EXCLUDES_AUDIO_ALL \
358     EXCLUDES_Spatializer_Mutex
359 
360 // --- End generated section
361 
362 /**
363  * AudioMutexAttributes is a collection of types and constexpr configuration
364  * used for the Android audio mutex.
365  *
366  * A different AudioMutexAttributes configuration will instantiate a completely
367  * independent set of mutex strategies, statics and thread locals,
368  * for a different type of mutexes.
369  */
370 
371 class AudioMutexAttributes {
372 public:
373     // Order types, name arrays.
374     using order_t = MutexOrder;
375     static constexpr auto& order_names_ = gMutexNames;
376     static constexpr size_t order_size_ = static_cast<size_t>(MutexOrder::kSize);
377     static constexpr order_t order_default_ = MutexOrder::kOtherMutex;
378 
379     // verify order information
380     static_assert(std::size(order_names_) == order_size_);
381     static_assert(static_cast<size_t>(order_default_) < order_size_);
382 
383     // Set mutex_tracking_enabled_ to true to enable mutex
384     // statistics and debugging (order checking) features.
385     static constexpr bool mutex_tracking_enabled_ = true;
386 
387     // Control the depth of the mutex stack per thread (the mutexes
388     // we track).  Set this to the maximum expected
389     // number of mutexes held by a thread.  If the depth is too small,
390     // deadlock detection, order checking, and recursion checking
391     // may result in a false negative.  This is a static configuration
392     // because reallocating memory for the stack requires a lock for
393     // the reader.
394     static constexpr size_t mutex_stack_depth_ = 16;
395 
396     // Enable or disable log always fatal.
397     // This also requires the mutex feature flag to be set.
398     static constexpr bool abort_on_order_check_ = true;
399     static constexpr bool abort_on_recursion_check_ = true;
400     static constexpr bool abort_on_invalid_unlock_ = true;
401 };
402 
403 // relaxed_atomic implements the same features as std::atomic<T> but using
404 // std::memory_order_relaxed as default.
405 //
406 // This is the minimum consistency for the multiple writer multiple reader case.
407 
408 template <typename T>
409 class relaxed_atomic : private std::atomic<T> {
410 public:
411     constexpr relaxed_atomic(T desired = {}) : std::atomic<T>(desired) {}
T()412     operator T() const { return std::atomic<T>::load(std::memory_order_relaxed); }
413     T operator=(T desired) {
414         std::atomic<T>::store(desired, std::memory_order_relaxed); return desired;
415     }
416 
417     T operator--() { return std::atomic<T>::fetch_sub(1, std::memory_order_relaxed) - 1; }
418     T operator++() { return std::atomic<T>::fetch_add(1, std::memory_order_relaxed) + 1;  }
419     T operator+=(const T value) {
420         return std::atomic<T>::fetch_add(value, std::memory_order_relaxed) + value;
421     }
422 
423     T load(std::memory_order order = std::memory_order_relaxed) const {
424         return std::atomic<T>::load(order);
425     }
426     T fetch_add(T arg, std::memory_order order =std::memory_order_relaxed) {
427         return std::atomic<T>::fetch_add(arg, order);
428     }
429     bool compare_exchange_weak(
430             T& expected, T desired, std::memory_order order = std::memory_order_relaxed) {
431         return std::atomic<T>::compare_exchange_weak(expected, desired, order);
432     }
433 };
434 
435 // unordered_atomic implements data storage such that memory reads have a value
436 // consistent with a memory write in some order, i.e. not having values
437 // "out of thin air".
438 //
439 // Unordered memory reads and writes may not actually take place but be implicitly cached.
440 // Nevertheless, a memory read should return at least as contemporaneous a value
441 // as the last memory write before the write thread memory barrier that
442 // preceded the most recent read thread memory barrier.
443 //
444 // This is weaker than relaxed_atomic and has no equivalent C++ terminology.
445 // unordered_atomic would be used for a single writer, multiple reader case,
446 // where data access of type T would be a implemented by the compiler and
447 // hw architecture with a single "uninterruptible" memory operation.
448 // (The current implementation holds true for general realized CPU architectures).
449 // Note that multiple writers would cause read-modify-write unordered_atomic
450 // operations to have inconsistent results.
451 //
452 // unordered_atomic is implemented with normal operations such that compiler
453 // optimizations can take place which would otherwise be discouraged for atomics.
454 // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0062r1.html
455 
456 // VT may be volatile qualified, if desired, or a normal arithmetic type.
457 template <typename VT>
458 class unordered_atomic {
459     using T = std::decay_t<VT>;
460     static_assert(std::atomic<T>::is_always_lock_free);
461 public:
t_(desired)462     constexpr unordered_atomic(T desired = {}) : t_(desired) {}
T()463     operator T() const { return t_; }
464     T operator=(T desired) { t_ = desired; return desired; }
465 
466     // a volatile ++t_ or t_ += 1 is deprecated in C++20.
467     T operator--() { return operator=(t_ - 1); }
468     T operator++() { return operator=(t_ + 1); }
469     T operator+=(const T value) { return operator=(t_ + value); }
470 
471     T load(std::memory_order order = std::memory_order_relaxed) const { (void)order; return t_; }
472 
473 private:
474     VT t_;
475 };
476 
477 inline constexpr pid_t kInvalidTid = -1;
478 
479 // While std::atomic with the default std::memory_order_seq_cst
480 // access could be used, it results in performance loss over less
481 // restrictive memory access.
482 
483 // stats_atomic is a multiple writer multiple reader object.
484 //
485 // This is normally used to increment statistics counters on
486 // mutex priority categories.
487 //
488 // We used relaxed_atomic instead of std::atomic/memory_order_seq_cst here.
489 template <typename T>
490 using stats_atomic = relaxed_atomic<T>;
491 
492 // thread_atomic is a single writer multiple reader object.
493 //
494 // This is normally accessed as a thread local (hence single writer)
495 // but may be accessed (rarely) by multiple readers on deadlock
496 // detection which does not modify the data.
497 //
498 // We use unordered_atomic instead of std::atomic/memory_order_seq_cst here.
499 template <typename T>
500 using thread_atomic = unordered_atomic<T>;
501 
compiler_memory_barrier()502 inline void compiler_memory_barrier() {
503     // Reads or writes are not migrated or cached by the compiler across this barrier.
504     asm volatile("" ::: "memory");
505 
506     // if not using gnu / clang, compare with compiler-only barrier generated by
507     // std::atomic_signal_fence(std::memory_order_seq_cst);
508     // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0124r7.html
509 }
510 
511 // The mutex locking is thread-safe.
512 //
513 // However, the mutex metadata (statistics and thread info) updates are not locked
514 // by an internal mutex for efficiency reasons. Instead, they use atomics, with
515 // the possibility of false negatives since they are not sampled synchronously.
516 //
517 // To prevent the compiler from excessively caching the statistics and thread metadata
518 // which makes this asynchronous atomic sampling worse, as unordered or relaxed atomics
519 // do not implicitly impose any memory barriers,
520 // we can elect to explicitly issue compiler memory barriers to ensure
521 // metadata visibility across threads. This is optional, and only useful if
522 // the compiler does aggressive inlining.
523 //
metadata_memory_barrier_if_needed()524 inline void metadata_memory_barrier_if_needed() {
525     // check the level of atomicity used for thread metadata to alter the
526     // use of a barrier here.
527     if constexpr (std::is_same_v<thread_atomic<int32_t>, unordered_atomic<int32_t>>
528             || std::is_same_v<thread_atomic<int32_t>, relaxed_atomic<int32_t>>) {
529         compiler_memory_barrier();
530     }
531 }
532 
533 /**
534  * Helper method to accumulate floating point values to an atomic
535  * prior to C++23 support of atomic<float> atomic<double> accumulation.
536  */
537 template <typename AccumulateType, typename ValueType>
538 requires std::is_floating_point<AccumulateType>::value
539 void atomic_add_to(std::atomic<AccumulateType> &dst, ValueType src,
540         std::memory_order order = std::memory_order_seq_cst) {
541     static_assert(std::atomic<AccumulateType>::is_always_lock_free);
542     AccumulateType expected;
543     do {
544         expected = dst;
545     } while (!dst.compare_exchange_weak(expected, expected + src, order));
546 }
547 
548 template <typename AccumulateType, typename ValueType>
549 requires std::is_integral<AccumulateType>::value
550 void atomic_add_to(std::atomic<AccumulateType> &dst, ValueType src,
551         std::memory_order order = std::memory_order_seq_cst) {
552     dst.fetch_add(src, order);
553 }
554 
555 template <typename AccumulateType, typename ValueType>
556 requires std::is_floating_point<AccumulateType>::value
557 void atomic_add_to(relaxed_atomic<AccumulateType> &dst, ValueType src,
558         std::memory_order order = std::memory_order_relaxed) {
559     AccumulateType expected;
560     do {
561         expected = dst;
562     } while (!dst.compare_exchange_weak(expected, expected + src, order));
563 }
564 
565 template <typename AccumulateType, typename ValueType>
566 requires std::is_integral<AccumulateType>::value
567 void atomic_add_to(relaxed_atomic<AccumulateType> &dst, ValueType src,
568         std::memory_order order = std::memory_order_relaxed) {
569     dst.fetch_add(src, order);
570 }
571 
572 template <typename AccumulateType, typename ValueType>
573 void atomic_add_to(unordered_atomic<AccumulateType> &dst, ValueType src,
574         std::memory_order order = std::memory_order_relaxed) {
575     (void)order; // unused
576     dst = dst + src;
577 }
578 
579 /**
580  * mutex_stat is a struct composed of atomic members associated
581  * with usage of a particular mutex order.
582  *
583  * Access of a snapshot of this does not have a global lock, so the reader
584  * may experience temporal shear. Use of this by a different reader thread
585  * is for informative purposes only.
586  */
587 
588 // CounterType == uint64_t, AccumulatorType == double
589 template <typename CounterType, typename AccumulatorType>
590 struct mutex_stat {
591     static_assert(std::is_floating_point_v<AccumulatorType>);
592     static_assert(std::is_integral_v<CounterType>);
593     static_assert(std::atomic<CounterType>::is_always_lock_free);
594     static_assert(std::atomic<AccumulatorType>::is_always_lock_free);
595     stats_atomic<CounterType> locks = 0;        // number of times locked
596     stats_atomic<CounterType> unlocks = 0;      // number of times unlocked
597     stats_atomic<CounterType> waits = 0;         // number of locks that waited
598     stats_atomic<AccumulatorType> wait_sum_ns = 0.;    // sum of time waited.
599     stats_atomic<AccumulatorType> wait_sumsq_ns = 0.;  // sumsq of time waited.
600 
601     template <typename WaitTimeType>
add_wait_timemutex_stat602     void add_wait_time(WaitTimeType wait_ns) {
603         AccumulatorType value_ns = wait_ns;
604         atomic_add_to(wait_sum_ns, value_ns);
605         atomic_add_to(wait_sumsq_ns, value_ns * value_ns);
606     }
607 
to_stringmutex_stat608     std::string to_string() const {
609         CounterType uncontested = locks - waits;
610         AccumulatorType recip = waits == 0 ? 0. : 1. / waits;
611         AccumulatorType avg_wait_ms = waits == 0 ? 0. : wait_sum_ns * 1e-6 * recip;
612         AccumulatorType std_wait_ms = waits < 2 ? 0. :
613                 std::sqrt(std::max(wait_sumsq_ns * recip * 1e-12 - avg_wait_ms * avg_wait_ms,
614                         0.));
615         return std::string("locks: ").append(std::to_string(locks))
616             .append("\nuncontested: ").append(std::to_string(uncontested))
617             .append("\nwaits: ").append(std::to_string(waits))
618             .append("\nunlocks: ").append(std::to_string(unlocks))
619             .append("\navg_wait_ms: ").append(std::to_string(avg_wait_ms))
620             .append("\nstd_wait_ms: ").append(std::to_string(std_wait_ms))
621             .append("\n");
622     }
623 };
624 
625 /**
626  * atomic_stack is a single writer, multiple reader object.
627  * Readers not on the same thread as the writer may experience temporal shear,
628  * but individual members are accessed atomic-safe, i.e. no partial member
629  * reads or delayed writes due to caching.
630  *
631  * For use with mutex checking, the atomic_stack maintains an ordering on
632  * P (payload) such that the top item pushed must always be greater than or
633  * equal to the P (payload) of items below it.
634  *
635  * Pushes always go to the top of the stack.  Removes can occur
636  * from any place in the stack, but typically near the top.
637  *
638  * The atomic_stack never reallocates beyond its fixed capacity of N.
639  * This prevents a lockless reader from accessing invalid memory because
640  * the address region does not change.
641  *
642  * If the number of pushes exceed the capacity N, then items may be discarded.
643  * In that case, the stack is a subset stack of the "true" unlimited
644  * capacity stack.  Nevertheless, a subset of an ordered stack
645  * with items deleted is also ordered.
646  *
647  * The size() of the atomic_stack is the size of the subset stack of tracked items.
648  * The true_size() is the size of the number of items pushed minus the
649  * number of items removed (the "true" size if capacity were unlimited).
650  * Since the capacity() is constant the true_size() may include
651  * items we don't track except by count.  If true_size() == size() then
652  * the subset stack is complete.
653  *
654  * In this single writer, multiple reader model, we could get away with
655  * memory_order_relaxed as the reader is purely informative,
656  * but we choose memory_order_seq_cst which imposes the most
657  * restrictions on the compiler (variable access reordering) and the
658  * processor (memory access reordering).  This means operations take effect
659  * in the order written.  However, this isn't strictly needed - as there is
660  * only one writer, a read-modify-write operation is safe (no need for special
661  * memory instructions), and there isn't the acquire-release semantics with
662  * non-atomic memory access needed for a lockless fifo, for example.
663  */
664 
665  /*
666   * For audio mutex purposes, one question arises - why don't we use
667   * a bitmask to represent the capabilities taken by a thread
668   * instead of a stack?
669   *
670   * A bitmask arrangement works if there exists a one-to-one relationship
671   * from a physical mutex to its capability.  That may exist for some
672   * projects, but not AudioFlinger.
673   *
674   * As a consequence, we need the actual count and handle:
675   *
676   * 1) A single thread may hold multiple instances of some capabilities
677   * (e.g. ThreadBase_Mutex and EffectChain_Mutex).
678   * For example there may be multiple effect chains locked during mixing.
679   * There may be multiple PlaybackThreads locked during effect chain movement.
680   * A bit per capability can't count beyond 1.
681   *
682   * 2) Deadlock detection requires tracking the actual MutexHandle (a void*)
683   * to form a cycle, because there may be many mutexes associated with a
684   * given capability order.
685   * For example, each PlaybackThread or RecordThread will have its own mutex
686   * with the ThreadBase_Mutex capability.
687   *
688   */
689 
690 template <typename Item, typename Payload, size_t N>
691 class atomic_stack {
692 public:
693     using item_payload_pair_t = std::pair<thread_atomic<Item>, thread_atomic<Payload>>;
694 
695     /**
696      * Puts the item at the top of the stack.
697      *
698      * If the stack depth is exceeded the item
699      * replaces the top.
700      *
701      * Mutexes when locked are always placed on the top of the stack;
702      * however, they may be unlocked in a non last-in-first-out (LIFO)
703      * order.  It is rare to see a non LIFO order, but it can happen.
704      */
push(const Item & item,const Payload & payload)705     void push(const Item& item, const Payload& payload) {
706         size_t location = top_;
707         size_t increment = 1;
708         if (location >= N) {
709             // we exceed the top of stack.
710             //
711             // although we could ignore this item (subset is the oldest),
712             // the better solution is to replace the topmost entry as
713             // it allows quicker removal.
714             location = N - 1;
715             increment = 0;
716         }
717         // issue the operations close together.
718         pairs_[location].first = item;
719         pairs_[location].second = payload;
720         ++true_top_;
721         top_ += increment;
722     }
723 
724     /**
725      * Removes the item which is expected at the top of the stack
726      * but may be lower.  Mutexes are generally unlocked in stack
727      * order (LIFO), but this is not a strict requirement.
728      */
remove(const Item & item)729     bool remove(const Item& item) {
730         if (true_top_ == 0) {
731             return false;  // cannot remove.
732         }
733         // there is a temporary benign read race here where true_top_ != top_.
734         --true_top_;
735         for (size_t i = top_; i > 0; ) {
736             if (item == pairs_[--i].first) {
737                 // We shift to preserve order.
738                 // A reader may temporarily see a "duplicate" entry
739                 // but that is preferable to a "missing" entry
740                 // for the purposes of deadlock detection.
741                 const size_t limit = top_ - 1;
742                 while (i < limit) {  // using atomics, we need to assign first, second separately.
743                     pairs_[i].first = pairs_[i + 1].first.load();
744                     pairs_[i].second = pairs_[i + 1].second.load();
745                     ++i;
746                 }
747                 --top_; // now we restrict our range.
748                 // on relaxed semantics, it might be better to clear out the last
749                 // pair, but we are seq_cst.
750                 return true;
751             }
752         }
753         // not found in our subset.
754         //
755         // we return true upon correct removal (true_top_ must always be >= top_).
756         if (true_top_ >= top_) return true;
757 
758         // else recover and return false to notify that removal was invalid.
759         true_top_ = top_.load();
760         return false;
761     }
762 
763     /**
764      * return the top of our atomic subset stack
765      * or the invalid_ (zero-initialized) entry if it doesn't exist.
766      */
767     // Consideration of using std::optional<> is a possibility
768     // but as std::atomic doesn't have a copy ctor (and does not make sense),
769     // we would want to directly return an optional on the non-atomic values,
770     // in a custom pair.
771     const item_payload_pair_t& top(size_t offset = 0) const {
772         const ssize_t top = static_cast<ssize_t>(top_) - static_cast<ssize_t>(offset);
773         if (top > 0 && top <= static_cast<ssize_t>(N)) return pairs_[top - 1];
774         return invalid_;  // we don't know anything.
775     }
776 
777     /**
778      * return the bottom (or base) of our atomic subset stack
779      * or the invalid_ (zero-initialized) entry if it doesn't exist.
780      */
781     const item_payload_pair_t& bottom(size_t offset = 0) const {
782         if (offset < top_) return pairs_[offset];
783         return invalid_;  // we don't know anything.
784     }
785 
786     /**
787      * prints the contents of the stack starting from the most recent first.
788      *
789      * If the thread is not the same as the writer thread, there could be
790      * temporal shear in the data printed.
791      */
to_string()792     std::string to_string() const {
793         std::string s("size: ");
794         s.append(std::to_string(size()))
795             .append(" true_size: ").append(std::to_string(true_size()))
796             .append(" items: [");
797         for (size_t i = 0; i < top_; ++i) {
798             s.append("{ ")
799             .append(std::to_string(reinterpret_cast<uintptr_t>(pairs_[i].first.load())))
800             .append(", ")
801             .append(std::to_string(static_cast<size_t>(pairs_[i].second.load())))
802             .append(" } ");
803         }
804         s.append("]");
805         return s;
806     }
807 
808    /*
809     * stack configuration
810     */
capacity()811     static consteval size_t capacity() { return N; }
true_size()812     size_t true_size() const { return true_top_; }
size()813     size_t size() const { return top_; }
invalid()814     const auto& invalid() const { return invalid_; }
815 
816 private:
817     thread_atomic<size_t> top_ = 0;       // ranges from 0 to N - 1
818     thread_atomic<size_t> true_top_ = 0;  // always >= top_.
819     // if true_top_ == top_ the subset stack is complete.
820 
821     /*
822      * The subset stack entries are a pair of atomics rather than an atomic<pair>
823      * to prevent lock requirements if T and P are small enough, i.e. <= sizeof(size_t).
824      *
825      * As atomics are not composable from smaller atomics, there may be some
826      * temporary inconsistencies when reading from a different thread than the writer.
827      */
828     item_payload_pair_t pairs_[N]{};
829 
830     /*
831      * The invalid pair is returned when top() is called without a tracked item.
832      * This might occur with an empty subset of the "true" stack.
833      */
834     static inline const item_payload_pair_t invalid_{};  // volatile != constexpr, if so qualified
835 };
836 
837 // A list of reasons why we might have an inter-thread wait besides a mutex.
838 enum class other_wait_reason_t {
839     none = 0,
840     cv = 1,
841     join = 2,
842     queue = 3,
843 };
844 
reason_to_string(other_wait_reason_t reason)845 inline constexpr const char* reason_to_string(other_wait_reason_t reason) {
846     switch (reason) {
847         case other_wait_reason_t::none: return "none";
848         case other_wait_reason_t::cv: return "cv";
849         case other_wait_reason_t::join: return "join";
850         case other_wait_reason_t::queue: return "queue";
851         default: return "invalid";
852     }
853 }
854 
855 /**
856  * thread_mutex_info is a struct that is associated with every
857  * thread the first time a mutex is used on it.  Writing will be through
858  * a single thread (essentially thread_local), but the thread_registry
859  * debug methods may access this through a different reader thread.
860  *
861  * If the thread does not use the audio_utils mutex, the allocation of this
862  * struct never occurs, although there is approx 16 bytes for a shared ptr and
863  * 1 byte for a thread local once bool.
864  *
865  * Here, we use for the MutexHandle a void*, which is used as an opaque unique ID
866  * representing the mutex.
867  *
868  * Since there is no global locking, the validity of the mutex* associated to
869  * the void* is unknown -- the mutex* could be deallocated in a different
870  * thread.  Nevertheless the opaque ID can still be used to check deadlocks
871  * realizing there could be a false positive on a potential reader race
872  * where a new mutex is created at the same storage location.
873  */
874 template <typename MutexHandle, typename Order, size_t N>
875 class thread_mutex_info {
876 public:
877     using atomic_stack_t = atomic_stack<MutexHandle, Order, N>;
878 
879     class other_wait_info {
880     public:
881         thread_atomic<pid_t> tid_ = kInvalidTid;
882         thread_atomic<other_wait_reason_t> reason_ = other_wait_reason_t::none;
883         thread_atomic<Order> order_ = (Order)-1;
884 
to_string()885         std::string to_string() const {
886             const pid_t tid = tid_.load();
887             const other_wait_reason_t reason = reason_.load();
888             const Order order = order_.load();
889 
890             std::string s;
891             if (tid != kInvalidTid) {
892                 switch (reason) {
893                 case other_wait_reason_t::none:
894                 default:
895                     break;
896                 case other_wait_reason_t::cv:
897                     s.append("cv_tid: ").append(std::to_string(tid))
898                             .append("  cv_order: ").append(std::to_string(
899                                     static_cast<size_t>(order)));
900                     break;
901                 case other_wait_reason_t::join:
902                     s.append("join_tid: ").append(std::to_string(tid));
903                     break;
904                 case other_wait_reason_t::queue:
905                     s.append("queue_tid: ").append(std::to_string(tid));
906                     break;
907                 }
908             }
909             return s;
910         }
911     };
912 
thread_mutex_info(pid_t tid)913     thread_mutex_info(pid_t tid) : tid_(tid) {}
914 
915     // the destructor releases the thread_mutex_info.
916     // declared here, defined below due to use of thread_registry.
917     ~thread_mutex_info();
918 
919     void reset_waiter(MutexHandle waiter = nullptr) {
920         mutex_wait_ = waiter;
921     }
922 
923     /**
924      * check_held returns the stack pair that conflicts
925      * with the existing mutex handle and order, or the invalid
926      * stack pair (empty mutex handle and empty order).
927      */
928     const typename atomic_stack_t::item_payload_pair_t&
check_held(MutexHandle mutex,Order order)929     check_held(MutexHandle mutex, Order order) const {
930         // validate mutex order.
931         const size_t size = mutexes_held_.size();
932         for (size_t i = 0; i < size; ++i) {
933             const auto& top = mutexes_held_.top(i);
934             const auto top_order = top.second.load();
935 
936             if (top_order < order) break;              // ok
937             if (top_order > order) return top;         // inverted order
938             if (top.first.load() == mutex) return top; // recursive mutex
939         }
940         return mutexes_held_.invalid();
941     }
942 
943     /*
944      * This is unverified push.  Use check_held() prior to this to
945      * verify no lock inversion or replication.
946      */
push_held(MutexHandle mutex,Order order)947     void push_held(MutexHandle mutex, Order order) {
948         mutexes_held_.push(mutex, order);
949     }
950 
remove_held(MutexHandle mutex)951     bool remove_held(MutexHandle mutex) {
952         return mutexes_held_.remove(mutex);
953     }
954 
955     // Variants used by condition_variable on wait() that handle
956     // hint metadata. This is used by deadlock detection algorithm to inform we
957     // are waiting on a worker thread identified by notifier_tid.
958 
push_held_for_cv(MutexHandle mutex,Order order)959     void push_held_for_cv(MutexHandle mutex, Order order) {
960         push_held(mutex, order);
961         // condition wait has expired.  always invalidate.
962         other_wait_info_.tid_ = kInvalidTid;
963     }
964 
remove_held_for_cv(MutexHandle mutex,Order order,pid_t notifier_tid)965     bool remove_held_for_cv(MutexHandle mutex, Order order, pid_t notifier_tid) {
966         // last condition on the mutex overwrites.
967         other_wait_info_.order_ = order;
968         other_wait_info_.reason_ = other_wait_reason_t::cv;
969         other_wait_info_.tid_ = notifier_tid;
970         return remove_held(mutex);
971     }
972 
973     // Add waiting state for join.
add_wait_join(pid_t waiting_tid)974     void add_wait_join(pid_t waiting_tid) {
975         other_wait_info_.reason_ = other_wait_reason_t::join;
976         other_wait_info_.tid_ = waiting_tid;
977     }
978 
remove_wait_join()979     void remove_wait_join() {
980         other_wait_info_.tid_ = kInvalidTid;
981     }
982 
983     // Add waiting state for queue.
add_wait_queue(pid_t waiting_tid)984     void add_wait_queue(pid_t waiting_tid) {
985         other_wait_info_.reason_ = other_wait_reason_t::queue;
986         other_wait_info_.tid_ = waiting_tid;
987     }
988 
remove_wait_queue()989     void remove_wait_queue() {
990         other_wait_info_.tid_ = kInvalidTid;
991     }
992 
993     /*
994      * Due to the fact that the thread_mutex_info contents are not globally locked,
995      * there may be temporal shear.  The string representation is
996      * informative only.
997      */
to_string()998     std::string to_string() const {
999         std::string s;
1000         s.append("tid: ").append(std::to_string(static_cast<int>(tid_)));
1001         s.append("\nwaiting: ").append(std::to_string(
1002                 reinterpret_cast<uintptr_t>(mutex_wait_.load())));
1003         // inform if there is a condition variable wait associated with a known thread.
1004         if (other_wait_info_.tid_ != kInvalidTid) {
1005             s.append("\n").append(other_wait_info_.to_string());
1006         }
1007         s.append("\nheld: ").append(mutexes_held_.to_string());
1008         return s;
1009     }
1010 
1011     /*
1012      * empty() indicates that the thread is not waiting for or
1013      * holding any mutexes.
1014      */
empty()1015     bool empty() const {
1016         return mutex_wait_ == nullptr && mutexes_held_.size() == 0;
1017     }
1018 
stack()1019     const auto& stack() const {
1020         return mutexes_held_;
1021     }
1022 
1023     const pid_t tid_;                                   // me
1024     thread_atomic<MutexHandle> mutex_wait_{};           // mutex waiting for
1025     other_wait_info other_wait_info_;
1026     atomic_stack_t mutexes_held_;  // mutexes held
1027 };
1028 
1029 
1030 /**
1031  * deadlock_info_t encapsulates the mutex wait / cycle information from
1032  * thread_registry::deadlock_detection().
1033  *
1034  * If a cycle is detected, the last element of the vector chain represents
1035  * a tid that is repeated somewhere earlier in the vector.
1036  */
1037 struct deadlock_info_t {
1038 public:
deadlock_info_tdeadlock_info_t1039     explicit deadlock_info_t(pid_t tid_param) : tid(tid_param) {}
1040 
emptydeadlock_info_t1041     bool empty() const {
1042         return chain.empty();
1043     }
1044 
to_stringdeadlock_info_t1045     std::string to_string() const {
1046         std::string description;
1047 
1048         if (has_cycle) {
1049             description.append("mutex cycle found (last tid repeated) ");
1050         } else {
1051             description.append("mutex wait chain ");
1052         }
1053         description.append("[ ").append(std::to_string(tid));
1054         // Note: when we dump here, we add the timeout tid to the start of the wait chain.
1055         for (const auto& [ tid2, name ] : chain) {
1056             description.append(", ").append(std::to_string(tid2))
1057                     .append(" (by ").append(name).append(")");
1058         }
1059         description.append(" ]");
1060         return description;
1061     }
1062 
1063     const pid_t tid;         // tid for which the deadlock was checked
1064     bool has_cycle = false;  // true if there is a cycle detected
1065     other_wait_reason_t other_wait_reason = other_wait_reason_t::none;
1066     std::vector<std::pair<pid_t, std::string>> chain;  // wait chain of tids and mutexes.
1067 };
1068 
1069 /**
1070  * The thread_registry is a thread-safe locked structure that
1071  * maintains a list of the threads that contain thread_mutex_info.
1072  *
1073  * Only first mutex access from a new thread and the destruction of that
1074  * thread will trigger an access to the thread_registry map.
1075  *
1076  * The debug methods to_string() and deadlock_detection() will also lock the struct
1077  * long enough to copy the map and safely obtain the weak pointers,
1078  * and then deal with the thread local data afterwards.
1079  *
1080  * It is recommended to keep a static singleton of the thread_registry for the
1081  * type desired.  The singleton should be associated properly with the object
1082  * it should be unique for, which in this case is the mutex_impl template.
1083  * This enables access to the elements as needed.
1084  */
1085 template <typename ThreadInfo>
1086 class thread_registry {
1087 public:
add_to_registry(const std::shared_ptr<ThreadInfo> & tminfo)1088     bool add_to_registry(const std::shared_ptr<ThreadInfo>& tminfo) EXCLUDES(mutex_) {
1089         ALOGV("%s: registered for %d", __func__, tminfo->tid_);
1090         std::lock_guard l(mutex_);
1091         if (registry_.count(tminfo->tid_) > 0) {
1092             ALOGW_IF("%s: tid %d already exists", __func__, tminfo->tid_);
1093             return false;
1094         }
1095         registry_[tminfo->tid_] = tminfo;
1096         return true;
1097     }
1098 
remove_from_registry(pid_t tid)1099     bool remove_from_registry(pid_t tid) EXCLUDES(mutex_) {
1100         ALOGV("%s: unregistered for %d", __func__, tid);
1101         std::lock_guard l(mutex_);
1102         // don't crash here because it might be a test app.
1103         const bool success = registry_.erase(tid) == 1;
1104         ALOGW_IF(!success, "%s: Cannot find entry for tid:%d", __func__, tid);
1105         return success;
1106     }
1107 
1108     // Returns a std::unordered_map for easy access on tid.
copy_map()1109     auto copy_map() EXCLUDES(mutex_) {
1110         std::lock_guard l(mutex_);
1111         return registry_;
1112     }
1113 
1114     // Returns a std::map sorted on tid for easy debug reading.
copy_ordered_map()1115     auto copy_ordered_map() EXCLUDES(mutex_) {
1116         std::lock_guard l(mutex_);
1117         std::map<pid_t, std::weak_ptr<ThreadInfo>> sorted(registry_.begin(), registry_.end());
1118         return sorted;
1119     }
1120 
1121     /**
1122      * Returns a string containing the thread mutex info for each
1123      * thread that has accessed the audio_utils mutex.
1124      */
to_string()1125     std::string to_string() {
1126         // for debug purposes it is much easier to see the tids in numeric order.
1127         const auto registry_map = copy_ordered_map();
1128         ALOGV("%s: dumping tids: %zu", __func__, registry_map.size());
1129         std::string s("thread count: ");
1130         s.append(std::to_string(registry_map.size())).append("\n");
1131 
1132         std::vector<pid_t> empty;
1133         for (const auto& [tid, weak_info] : registry_map) {
1134             const auto info = weak_info.lock();
1135             if (info) {
1136                 if (info->empty()) {
1137                     empty.push_back(tid);
1138                 } else {
1139                     s.append(info->to_string()).append("\n");
1140                 }
1141             }
1142         }
1143 
1144         // dump remaining empty tids out
1145         s.append("tids without current activity [ ");
1146         for (const auto tid : empty) {
1147             s.append(std::to_string(tid)).append(" ");
1148         }
1149         s.append("]\n");
1150         return s;
1151     }
1152 
1153     /**
1154      * Returns the thread info for a pid_t.
1155      *
1156      * It should use a copy of the registry map which is not changing
1157      * as it does not take any lock.
1158      */
tid_to_info(const std::unordered_map<pid_t,std::weak_ptr<ThreadInfo>> & registry_map,pid_t tid)1159     static std::shared_ptr<ThreadInfo> tid_to_info(
1160             const std::unordered_map<pid_t, std::weak_ptr<ThreadInfo>>& registry_map,
1161             pid_t tid) {
1162         const auto it = registry_map.find(tid);
1163         if (it == registry_map.end()) return {};
1164         const auto& weak_info = it->second;  // unmapped returns empty weak_ptr.
1165         return weak_info.lock();
1166     }
1167 
1168     /**
1169      * Returns a deadlock_info_t struct describing the mutex wait / cycle information.
1170      *
1171      * The deadlock_detection() method is not exceptionally fast
1172      * and is not designed to be called for every mutex locked (and contended).
1173      * It is designed to run as a diagnostic routine to enhance
1174      * dumping for watchdogs, like TimeCheck, when a tid is believed blocked.
1175      *
1176      * Access of state is through atomics, so has minimal overhead on
1177      * concurrent execution, with the possibility of (mostly) false
1178      * negatives due to race.
1179      *
1180      * \param tid target tid which may be in a cycle or blocked.
1181      * \param mutex_names a string array of mutex names indexed on capability order.
1182      * \return a deadlock_info_t struct, which contains whether a cycle was found and
1183      *         a vector of tids and mutex names in the mutex wait chain.
1184      */
1185     template <typename StringArray>
deadlock_detection(pid_t tid,const StringArray & mutex_names)1186     deadlock_info_t deadlock_detection(pid_t tid, const StringArray& mutex_names) {
1187         const auto registry_map = copy_map();
1188         deadlock_info_t deadlock_info{tid};
1189 
1190         // if tid not waiting, return.
1191 
1192         const auto tinfo_original_tid = tid_to_info(registry_map, tid);
1193         if (tinfo_original_tid == nullptr) return deadlock_info;
1194 
1195         void* m = tinfo_original_tid->mutex_wait_.load();
1196         pid_t other_wait_tid = tinfo_original_tid->other_wait_info_.tid_.load();
1197         if (m == nullptr && other_wait_tid == kInvalidTid) return deadlock_info;
1198         other_wait_reason_t other_wait_reason =
1199                 tinfo_original_tid->other_wait_info_.reason_.load();
1200         size_t other_wait_order =
1201                 static_cast<size_t>(tinfo_original_tid->other_wait_info_.order_.load());
1202 
1203         bool subset = false; // do we have missing mutex data per thread?
1204 
1205         // Create helper map from mutex to tid.
1206         //
1207         // The helper map is built up from thread_local info rather than from
1208         // a global mutex list.
1209         //
1210         // There are multiple reasons behind this.
1211         // 1) There are many mutexes (mostly not held). We don't want to keep and
1212         //    manage a "global" list of them.
1213         // 2) The mutex pointer itself may be deallocated from a different thread
1214         //    from the reader. To keep it alive requires either a mutex, or a
1215         //    weak_ptr to shared_ptr promotion.
1216         //    Lifetime management is expensive on a per-mutex basis as there are many
1217         //    of them, but cheaper on a per-thread basis as the threads are fewer.
1218         // 3) The thread_local lookup is very inexpensive for thread info (special
1219         //    acceleration by C++ and the OS), but more complex for a mutex list
1220         //    which at best is a static concurrent hash map.
1221         //
1222         // Note that the mutex_ptr handle is opaque -- it may be deallocated from
1223         // a different thread, so we use the tid from the thread registry map.
1224         //
1225         using pid_order_index_pair_t = std::pair<pid_t, size_t>;
1226         std::unordered_map<void*, pid_order_index_pair_t> mutex_to_tid;
1227         for (const auto& [tid2, weak_info] : registry_map) {
1228             const auto info = weak_info.lock();
1229             if (info == nullptr) continue;
1230             const auto& stack = info->mutexes_held_;
1231             static constinit size_t capacity = std::decay_t<decltype(stack)>::capacity();
1232             const size_t size = std::min(stack.size(), capacity);
1233             subset = subset || size != stack.true_size();
1234             for (size_t i = 0; i < size; ++i) {
1235                 const auto& mutex_order_pair = stack.bottom(i);
1236                 // if this method is not called by the writer thread
1237                 // it is possible for data to change.
1238                 const auto mutex_ptr = mutex_order_pair.first.load();
1239                 const auto order = static_cast<size_t>(mutex_order_pair.second.load());
1240                 if (mutex_ptr != nullptr) {
1241                     mutex_to_tid[mutex_ptr] = pid_order_index_pair_t{tid2, order};
1242                 }
1243             }
1244         }
1245         ALOGD_IF(subset, "%s: mutex info only subset, deadlock detection may be inaccurate",
1246                 __func__);
1247 
1248         // traverse from tid -> waiting mutex, then
1249         // mutex -> tid holding
1250         // until we get no more tids, or a tid cycle.
1251         std::unordered_set<pid_t> visited;
1252         visited.insert(tid);  // mark the original tid, we start there for cycle detection.
1253         for (pid_t tid2 = tid; true;) {
1254             size_t order;
1255             other_wait_reason_t reason = other_wait_reason_t::none;
1256 
1257             if (m != nullptr && mutex_to_tid.count(m)) {
1258                 // waiting on mutex held by another tid.
1259                 std::tie(tid2, order) = mutex_to_tid[m];
1260             }  else if (other_wait_tid != kInvalidTid) {
1261                 // condition variable waiting on tid.
1262                 tid2 = other_wait_tid;
1263                 order = other_wait_order;
1264                 reason = other_wait_reason;
1265                 deadlock_info.other_wait_reason = reason;
1266             } else {
1267                 // no mutex or cv info.
1268                 return deadlock_info;
1269             }
1270 
1271             // add to chain.
1272             // if waiting through a condition variable, we prefix with "cv-".
1273             const auto name = order < std::size(mutex_names) ? mutex_names[order] : "unknown";
1274             deadlock_info.chain.emplace_back(tid2,
1275                     reason == other_wait_reason_t::cv
1276                             ? std::string("cv-").append(name).c_str()
1277                     : reason == other_wait_reason_t::join ? "join"
1278                     : reason == other_wait_reason_t::queue ? "queue" : name);
1279 
1280             // cycle detected
1281             if (visited.count(tid2)) {
1282                 deadlock_info.has_cycle = true;
1283                 return deadlock_info;
1284             }
1285             visited.insert(tid2);
1286 
1287             // if tid not waiting return (could be blocked on binder).
1288             const auto tinfo = tid_to_info(registry_map, tid2);
1289             if (tinfo == nullptr) {
1290                 // thread may have disappeared.
1291                 return deadlock_info;
1292             }
1293             m = tinfo->mutex_wait_.load();
1294             other_wait_tid = tinfo->other_wait_info_.tid_.load();
1295             other_wait_reason = tinfo->other_wait_info_.reason_.load();
1296             other_wait_order = static_cast<size_t>(tinfo->other_wait_info_.order_.load());
1297         }
1298     }
1299 
1300 private:
1301     mutable std::mutex mutex_;
1302     std::unordered_map<pid_t, std::weak_ptr<ThreadInfo>> registry_ GUARDED_BY(mutex_);
1303 };
1304 
1305 // audio_utils::mutex, audio_utils::lock_guard, audio_utils::unique_lock,
1306 // and audio_utils::condition_variable are method compatible versions
1307 // of std::mutex, std::lock_guard, std::unique_lock, and std::condition_variable
1308 // for optimizing audio thread performance and debugging.
1309 //
1310 // Note: we do not use std::timed_mutex as its Clang library implementation
1311 // is inefficient.  One is better off making a custom timed implementation using
1312 // pthread_mutex_timedlock() on the mutex::native_handle().
1313 
1314 extern bool mutex_get_enable_flag();
1315 
1316 // Returns true if the mutex was locked within the timeout_ns.
1317 //
1318 // std::timed_mutex is implemented using a condition variable and doesn't
1319 // have complete thread safety annotations.
1320 //
1321 // Here, we add the flexibility of a timed lock on an existing std::mutex.
1322 //
std_mutex_timed_lock(std::mutex & m,int64_t timeout_ns)1323 inline bool std_mutex_timed_lock(std::mutex& m, int64_t timeout_ns) TRY_ACQUIRE(true, m) {
1324     const int64_t deadline_ns =
1325             safe_add_sat(timeout_ns, systemTime(SYSTEM_TIME_REALTIME));
1326     const struct timespec ts = {
1327             .tv_sec = static_cast<time_t>(deadline_ns / 1'000'000'000),
1328             .tv_nsec = static_cast<long>(deadline_ns % 1'000'000'000),
1329     };
1330     if (pthread_mutex_timedlock(m.native_handle(), &ts) != 0) {
1331         metadata_memory_barrier_if_needed();
1332         return false;
1333     }
1334     return true;
1335 }
1336 
1337 template <typename Attributes>
1338 class CAPABILITY("mutex") [[nodiscard]] mutex_impl {
1339 public:
1340     using attributes_t = Attributes;
1341 
1342     // We use composition here.
1343     // No copy/move ctors as the member std::mutex has it deleted.
1344 
1345     // Constructor selects priority inheritance based on the platform default.
1346     mutex_impl(typename Attributes::order_t order = Attributes::order_default_)
mutex_impl(mutex_get_enable_flag (),order)1347         : mutex_impl(mutex_get_enable_flag(), order)
1348     {}
1349 
1350     // Constructor selects priority inheritance based on input argument.
1351     mutex_impl(bool priority_inheritance,
1352             typename Attributes::order_t order = Attributes::order_default_)
order_(order)1353         : order_(order)
1354         , stat_{get_mutex_stat_array()[static_cast<size_t>(order)]}
1355     {
1356         LOG_ALWAYS_FATAL_IF(static_cast<size_t>(order) >= Attributes::order_size_,
1357                 "mutex order %zu is equal to or greater than order limit:%zu",
1358                 static_cast<size_t>(order), Attributes::order_size_);
1359 
1360         if (!priority_inheritance) return;
1361 
1362         pthread_mutexattr_t attr;
1363         int ret = pthread_mutexattr_init(&attr);
1364         if (ret != 0) {
1365             ALOGW("%s, pthread_mutexattr_init returned %d", __func__, ret);
1366             return;
1367         }
1368 
1369         ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
1370         if (ret != 0) {
1371             ALOGW("%s, pthread_mutexattr_setprotocol returned %d", __func__, ret);
1372             return;
1373         }
1374 
1375         // use of the native_handle() is implementation defined.
1376         const auto handle = m_.native_handle();
1377         ret = pthread_mutex_init(handle, &attr);
1378         if (ret != 0) {
1379             ALOGW("%s, pthread_mutex_init returned %d", __func__, ret);
1380         }
1381         ALOGV("%s: audio_mutex initialized: ret:%d  order:%zu",
1382                 __func__, ret, static_cast<size_t>(order_));
1383     }
1384 
~mutex_impl()1385     ~mutex_impl() {
1386         // Note: std::mutex behavior is undefined if released holding ownership.
1387     }
1388 
native_handle()1389     auto native_handle() {
1390         return m_.native_handle();
1391     }
1392 
lock()1393     void lock() ACQUIRE() {
1394         lock_scoped_stat_t::pre_lock(*this);
1395         if (!m_.try_lock()) {  // if we directly use futex, we can optimize this with m_.lock().
1396             // lock_scoped_stat_t accumulates waiting time for the mutex lock call.
1397             lock_scoped_stat_t ls(*this);
1398             m_.lock();
1399         }
1400         lock_scoped_stat_t::post_lock(*this);
1401         metadata_memory_barrier_if_needed();
1402     }
1403 
unlock()1404     void unlock() RELEASE() {
1405         lock_scoped_stat_t::pre_unlock(*this);
1406         m_.unlock();
1407         metadata_memory_barrier_if_needed();
1408     }
1409 
TRY_ACQUIRE(true)1410     bool try_lock(int64_t timeout_ns = 0) TRY_ACQUIRE(true) {
1411         lock_scoped_stat_t::pre_lock(*this);
1412         if (timeout_ns <= 0) {
1413             if (!m_.try_lock()) return false;
1414         } else {
1415             const int64_t deadline_ns =
1416                     safe_add_sat(timeout_ns, systemTime(SYSTEM_TIME_REALTIME));
1417             const struct timespec ts = {
1418                 .tv_sec = static_cast<time_t>(deadline_ns / 1'000'000'000),
1419                 .tv_nsec = static_cast<long>(deadline_ns % 1'000'000'000),
1420             };
1421             lock_scoped_stat_t ls(*this);
1422             if (pthread_mutex_timedlock(m_.native_handle(), &ts) != 0) {
1423                 ls.ignoreWaitTime();  // didn't get lock, don't count wait time
1424                 metadata_memory_barrier_if_needed();
1425                 return false;
1426             }
1427         }
1428         lock_scoped_stat_t::post_lock(*this);
1429         metadata_memory_barrier_if_needed();
1430         return true;
1431     }
1432 
1433     // additional method to obtain the underlying std::mutex.
std_mutex()1434     std::mutex& std_mutex() {
1435         return m_;
1436     }
1437 
1438     using mutex_stat_t = mutex_stat<uint64_t, double>;
1439 
get_stat()1440     mutex_stat_t& get_stat() const {
1441         return stat_;
1442     }
1443 
1444     /**
1445      * Returns the locking statistics per mutex capability category.
1446      */
all_stats_to_string()1447     static std::string all_stats_to_string() {
1448         std::string out("mutex stats: priority inheritance ");
1449         out.append(mutex_get_enable_flag() ? "enabled" : "disabled")
1450             .append("\n");
1451         const auto& stat_array = get_mutex_stat_array();
1452         for (size_t i = 0; i < stat_array.size(); ++i) {
1453             if (stat_array[i].locks != 0) {
1454                 out.append("Capability: ").append(Attributes::order_names_[i]).append("\n")
1455                     .append(stat_array[i].to_string());
1456             }
1457         }
1458         return out;
1459     }
1460 
1461     /**
1462      * Returns the thread locks held per tid.
1463      */
all_threads_to_string()1464     static std::string all_threads_to_string() {
1465         return get_registry().to_string();
1466     }
1467 
1468     /**
1469      * Returns a pair of bool (whether a cycle is detected) and a vector
1470      * of mutex wait dependencies.
1471      *
1472      * If a cycle is detected, the last element of the vector represents
1473      * a tid that is repeated somewhere earlier in the vector.
1474      *
1475      * The deadlock_detection() method is not exceptionally fast
1476      * and is not designed to be called for every mutex locked (and contended).
1477      * It is designed to run as a diagnostic routine to enhance
1478      * dumping for watchdogs, like TimeCheck, when a tid is believed blocked.
1479      *
1480      * Access of state is through atomics, so has minimal overhead on
1481      * concurrent execution, with the possibility of (mostly) false
1482      * negatives due to race.
1483      */
1484     static deadlock_info_t
deadlock_detection(pid_t tid)1485     deadlock_detection(pid_t tid) {
1486         return get_registry().deadlock_detection(tid, Attributes::order_names_);
1487     }
1488 
1489     using thread_mutex_info_t = thread_mutex_info<
1490             void* /* mutex handle */, MutexOrder, Attributes::mutex_stack_depth_>;
1491 
1492     // get_thread_mutex_info is a thread-local "singleton".
1493     //
1494     // We write it like a Meyer's singleton with a single thread_local
1495     // assignment that is guaranteed to be called on first time initialization.
1496     // Since the variables are thread_local, there is no thread contention
1497     // for initialization that would happen with a traditional Meyer's singleton,
1498     // so really a simple thread-local bool will do for a once_flag.
get_thread_mutex_info()1499     static const std::shared_ptr<thread_mutex_info_t>& get_thread_mutex_info() {
1500         thread_local std::shared_ptr<thread_mutex_info_t> tminfo = []() {
1501             auto info = std::make_shared<thread_mutex_info_t>(gettid_wrapper());
1502             get_registry().add_to_registry(info);
1503             return info;
1504         }();
1505         return tminfo;
1506     }
1507 
1508     // helper class for registering statistics for a mutex lock.
1509 
1510     class [[nodiscard]] lock_scoped_stat_enabled {
1511     public:
lock_scoped_stat_enabled(mutex & m)1512         explicit lock_scoped_stat_enabled(mutex& m)
1513             : mutex_(m)
1514             , time_(systemTime()) {
1515            ++mutex_.stat_.waits;
1516            mutex_.get_thread_mutex_info()->reset_waiter(&mutex_);
1517         }
1518 
~lock_scoped_stat_enabled()1519         ~lock_scoped_stat_enabled() {
1520            if (!discard_wait_time_) mutex_.stat_.add_wait_time(systemTime() - time_);
1521            mutex_.get_thread_mutex_info()->reset_waiter();
1522         }
1523 
ignoreWaitTime()1524         void ignoreWaitTime() {
1525             discard_wait_time_ = true;
1526         }
1527 
pre_unlock(mutex & m)1528         static void pre_unlock(mutex& m) {
1529             ++m.stat_.unlocks;
1530             const bool success = m.get_thread_mutex_info()->remove_held(&m);
1531             LOG_ALWAYS_FATAL_IF(Attributes::abort_on_invalid_unlock_
1532                     && !success,
1533                     "%s: invalid mutex unlock when not previously held", __func__);
1534         }
1535 
1536         // before we lock, we check order and recursion.
pre_lock(mutex & m)1537         static void pre_lock(mutex& m) {
1538             if constexpr (!Attributes::abort_on_order_check_ &&
1539                     !Attributes::abort_on_recursion_check_) return;
1540 
1541             const auto& p = m.get_thread_mutex_info()->check_held(&m, m.order_);
1542             if (p.first == nullptr) return;  // no problematic mutex.
1543 
1544             // problem!
1545             const size_t p_order = static_cast<size_t>(p.second.load());
1546             const size_t m_order = static_cast<size_t>(m.order_);
1547 
1548             // lock inversion
1549             LOG_ALWAYS_FATAL_IF(Attributes::abort_on_order_check_
1550                     && p_order > m_order,
1551                     "%s: invalid mutex order (previous) %zu %s> (new) %zu %s",
1552                     __func__, p_order, Attributes::order_names_[p_order],
1553                     m_order, Attributes::order_names_[m_order]);
1554 
1555             // lock recursion
1556             LOG_ALWAYS_FATAL_IF(Attributes::abort_on_recursion_check_
1557                     && p_order == m_order,
1558                     "%s: recursive mutex access detected (order: %zu %s)",
1559                     __func__, p_order, Attributes::order_names_[p_order]);
1560         }
1561 
post_lock(mutex & m)1562         static void post_lock(mutex& m) {
1563             ++m.stat_.locks;
1564             m.get_thread_mutex_info()->push_held(&m, m.order_);
1565         }
1566 
1567     private:
1568         mutex& mutex_;
1569         const int64_t time_;
1570         bool discard_wait_time_ = false;
1571     };
1572 
1573     // A RAII class that implements thread join wait detection
1574     // for the deadlock check.
1575     //
1576     // During the lifetime of this class object, the current thread
1577     // is assumed blocked on the thread tid due to a
1578     // thread join.
1579     //
1580     // {
1581     //   scoped_join_wait_check sjw(tid_of_thread);
1582     //   thread.join();
1583     // }
1584     //
1585 
1586     class [[nodiscard]] scoped_join_wait_check {
1587     public:
scoped_join_wait_check(pid_t tid)1588         explicit scoped_join_wait_check(pid_t tid) {
1589            get_thread_mutex_info()->add_wait_join(tid);
1590         }
~scoped_join_wait_check()1591         ~scoped_join_wait_check() {
1592            get_thread_mutex_info()->remove_wait_join();
1593         }
1594     };
1595 
1596     // A RAII class that implements queue wait detection
1597     // for the deadlock check.
1598     //
1599     // During the lifetime of this class object, the current thread
1600     // is assumed blocked on the thread tid due to a
1601     // cross-thread communication via a queue.
1602     //
1603     // {
1604     //   scoped_queue_wait_check sjw(tid_of_thread);
1605     //   queue.add(...);
1606     // }
1607     //
1608 
1609     class [[nodiscard]] scoped_queue_wait_check {
1610     public:
scoped_queue_wait_check(pid_t tid)1611         explicit scoped_queue_wait_check(pid_t tid) {
1612             get_thread_mutex_info()->add_wait_queue(tid);
1613         }
~scoped_queue_wait_check()1614         ~scoped_queue_wait_check() {
1615             get_thread_mutex_info()->remove_wait_queue();
1616         }
1617     };
1618 
1619     class lock_scoped_stat_disabled {
1620     public:
lock_scoped_stat_disabled(mutex &)1621         explicit lock_scoped_stat_disabled(mutex&) {}
1622 
ignoreWaitTime()1623         void ignoreWaitTime() {}
1624 
pre_unlock(mutex &)1625         static void pre_unlock(mutex&) {}
1626 
pre_lock(mutex &)1627         static void pre_lock(mutex&) {}
1628 
post_lock(mutex &)1629         static void post_lock(mutex&) {}
1630     };
1631 
1632     using lock_scoped_stat_t = std::conditional_t<Attributes::mutex_tracking_enabled_,
1633             lock_scoped_stat_enabled, lock_scoped_stat_disabled>;
1634 
1635     // helper class for registering statistics for a cv wait.
1636     class [[nodiscard]] cv_wait_scoped_stat_enabled {
1637     public:
1638         explicit cv_wait_scoped_stat_enabled(mutex& m, pid_t notifier_tid = kInvalidTid)
mutex_(m)1639             : mutex_(m) {
1640             ++mutex_.stat_.unlocks;
1641             // metadata that we relinquish lock.
1642             const bool success = mutex_.get_thread_mutex_info()->remove_held_for_cv(
1643                     &mutex_, mutex_.order_, notifier_tid);
1644             LOG_ALWAYS_FATAL_IF(Attributes::abort_on_invalid_unlock_
1645                     && !success,
1646                     "%s: invalid mutex unlock when not previously held", __func__);
1647         }
1648 
~cv_wait_scoped_stat_enabled()1649         ~cv_wait_scoped_stat_enabled() {
1650             ++mutex_.stat_.locks;
1651             // metadata that we are reacquiring lock.
1652             mutex_.get_thread_mutex_info()->push_held_for_cv(&mutex_, mutex_.order_);
1653         }
1654     private:
1655         mutex& mutex_;
1656     };
1657 
1658     class [[nodiscard]] cv_wait_scoped_stat_disabled {
cv_wait_scoped_stat_disabled(mutex &)1659         explicit cv_wait_scoped_stat_disabled(mutex&) {}
1660     };
1661 
1662     using cv_wait_scoped_stat_t = std::conditional_t<Attributes::mutex_tracking_enabled_,
1663             cv_wait_scoped_stat_enabled, cv_wait_scoped_stat_disabled>;
1664 
1665     using thread_registry_t = thread_registry<thread_mutex_info_t>;
1666 
1667     // One per-process thread registry, one instance per template typename.
1668     // Declared here but must be defined in a .cpp otherwise there will be multiple
1669     // instances if the header is included into different shared libraries.
1670     static thread_registry_t& get_registry();
1671 
1672     using stat_array_t = std::array<mutex_stat_t, Attributes::order_size_>;
1673 
1674     // One per-process mutex statistics array, one instance per template typename.
1675     // Declared here but must be defined in a .cpp otherwise there will be multiple
1676     // instances if the header is included into different shared libraries.
1677     static stat_array_t& get_mutex_stat_array();
1678 
1679 private:
1680 
1681     std::mutex m_;
1682     const typename Attributes::order_t order_;
1683     mutex_stat_t& stat_;  // set in ctor
1684 };
1685 
1686 // define the destructor to remove from registry.
1687 template <typename MutexHandle, typename Order, size_t N>
~thread_mutex_info()1688 inline thread_mutex_info<MutexHandle, Order, N>::~thread_mutex_info() {
1689     if (tid_ != 0) {
1690         mutex::get_registry().remove_from_registry(tid_);
1691     }
1692 }
1693 
1694 
1695 namespace details {
1696 
1697 // Discovery of the audio_utils::mutex vs std::mutex.
1698 template<typename T>
requires(T & a)1699 concept IsAudioMutex = requires (T& a) {
1700     a.std_mutex();  // std::mutex does not have this method.
1701 };
1702 
1703 } // details
1704 
1705 
1706 // audio_utils::lock_guard only works with the defined mutex.
1707 //
1708 // We add [[nodiscard]] to prevent accidentally ignoring construction.
1709 class [[nodiscard]] SCOPED_CAPABILITY lock_guard {
1710 public:
lock_guard(mutex & m)1711     explicit lock_guard(mutex& m) ACQUIRE(m)
1712         : mutex_(m) {
1713         mutex_.lock();
1714     }
1715 
RELEASE()1716     ~lock_guard() RELEASE() {
1717         mutex_.unlock();
1718     }
1719 
1720     lock_guard(const lock_guard&) = delete;
1721 
1722     // Note: a member reference will also delete this.
1723     lock_guard& operator=(const lock_guard&) = delete;
1724 
1725 private:
1726     mutex& mutex_;
1727 };
1728 
1729 // audio_utils::unique_lock is based on std::unique_lock<std::mutex>
1730 // because std::condition_variable is optimized for std::unique_lock<std::mutex>
1731 //
1732 // Note: std::unique_lock **does not** have thread safety annotations.
1733 // We annotate correctly here.  Essentially, this is the same as an annotated
1734 // using unique_lock = std::unique_lock<std::mutex>;
1735 //
1736 // We omit swap(), release() and move methods which don't have thread
1737 // safety annotations.
1738 //
1739 // We add [[nodiscard]] to prevent accidentally ignoring construction.
1740 
1741 // The generic unique_lock.  This works for std::mutex.
1742 template <typename Mutex>
1743 class [[nodiscard]] SCOPED_CAPABILITY unique_lock : public std::unique_lock<Mutex> {
1744 public:
unique_lock(Mutex & m)1745     explicit unique_lock(Mutex& m) ACQUIRE(m)
1746         : std::unique_lock<Mutex>(m) {}
RELEASE()1747     ~unique_lock() RELEASE() {}
1748 
lock()1749     void lock() ACQUIRE() { std::unique_lock<Mutex>::lock(); }
unlock()1750     void unlock() RELEASE() { std::unique_lock<Mutex>::unlock(); }
1751 
try_lock()1752     bool try_lock() TRY_ACQUIRE(true) { return std::unique_lock<Mutex>::try_lock(); }
1753 
1754     template<class Rep, class Period>
try_lock_for(const std::chrono::duration<Rep,Period> & timeout_duration)1755     bool try_lock_for(const std::chrono::duration<Rep, Period>& timeout_duration)
1756             TRY_ACQUIRE(true) {
1757         return std::unique_lock<Mutex>::try_lock_for(timeout_duration);
1758     }
1759 
1760     template<class Clock, class Duration>
try_lock_until(const std::chrono::time_point<Clock,Duration> & timeout_time)1761     bool try_lock_until(const std::chrono::time_point<Clock, Duration>& timeout_time)
1762             TRY_ACQUIRE(true) {
1763         return std::unique_lock<Mutex>::try_lock_until(timeout_time);
1764     }
1765 };
1766 
1767 // Specialized unique_lock for the audio_utlis::mutex.
1768 //
1769 // the requires() clause selects this over the generic case upon match.
1770 //
1771 template <typename Mutex>
1772 requires details::IsAudioMutex<Mutex>
1773 class [[nodiscard]] SCOPED_CAPABILITY unique_lock<Mutex> {
1774 public:
unique_lock(Mutex & m)1775     explicit unique_lock(Mutex& m) ACQUIRE(m)
1776         : ul_(m.std_mutex(), std::defer_lock)
1777         , mutex_(m) {
1778         lock();
1779     }
1780 
RELEASE()1781     ~unique_lock() RELEASE() {
1782         if (owns_lock()) unlock();
1783     }
1784 
lock()1785     void lock() ACQUIRE() {
1786         mutex::lock_scoped_stat_t::pre_lock(mutex_);
1787         if (!ul_.try_lock()) {
1788             typename Mutex::lock_scoped_stat_t ls(mutex_);
1789             ul_.lock();
1790         }
1791         mutex::lock_scoped_stat_t::post_lock(mutex_);
1792         metadata_memory_barrier_if_needed();
1793     }
1794 
unlock()1795     void unlock() RELEASE() {
1796         mutex::lock_scoped_stat_t::pre_unlock(mutex_);
1797         ul_.unlock();
1798         metadata_memory_barrier_if_needed();
1799     }
1800 
try_lock()1801     bool try_lock() TRY_ACQUIRE(true) {
1802         mutex::lock_scoped_stat_t::pre_lock(mutex_);
1803         if (!ul_.try_lock()) return false;
1804         mutex::lock_scoped_stat_t::post_lock(mutex_);
1805         metadata_memory_barrier_if_needed();
1806         return true;
1807     }
1808 
1809     template<class Rep, class Period>
try_lock_for(const std::chrono::duration<Rep,Period> & timeout_duration)1810     bool try_lock_for(const std::chrono::duration<Rep, Period>& timeout_duration)
1811             TRY_ACQUIRE(true) {
1812         mutex::lock_scoped_stat_t::pre_lock(mutex_);
1813         if (!ul_.try_lock_for(timeout_duration)) return false;
1814         mutex::lock_scoped_stat_t::post_lock(mutex_);
1815         metadata_memory_barrier_if_needed();
1816         return true;
1817     }
1818 
1819     template<class Clock, class Duration>
try_lock_until(const std::chrono::time_point<Clock,Duration> & timeout_time)1820     bool try_lock_until(const std::chrono::time_point<Clock, Duration>& timeout_time)
1821             TRY_ACQUIRE(true) {
1822         mutex::lock_scoped_stat_t::pre_lock(mutex_);
1823         if (!ul_.try_lock_until(timeout_time)) return false;
1824         mutex::lock_scoped_stat_t::post_lock(mutex_);
1825         metadata_memory_barrier_if_needed();
1826         return true;
1827     }
1828 
owns_lock()1829     bool owns_lock() const {
1830         return ul_.owns_lock();
1831     }
1832 
1833     explicit operator bool() const {
1834         return owns_lock();
1835     }
1836 
1837     // additional method to obtain the underlying std::unique_lock
std_unique_lock()1838     std::unique_lock<std::mutex>& std_unique_lock() {
1839         return ul_;
1840     }
1841 
1842     // additional method to obtain the underlying mutex
native_mutex()1843     mutex& native_mutex() {
1844         return mutex_;
1845     }
1846 
1847 private:
1848     std::unique_lock<std::mutex> ul_;
1849     mutex& mutex_;
1850 };
1851 
1852 // audio_utils::condition_variable uses the optimized version of
1853 // std::condition_variable for std::unique_lock<std::mutex>
1854 // It is possible to use std::condition_variable_any for a generic mutex type,
1855 // but it is less efficient.
1856 
1857 // The audio_utils condition_variable permits speicifying a "notifier_tid"
1858 // metadata in the wait() methods, which states the expected tid of the
1859 // notification thread for deadlock / wait detection purposes.
1860 class [[nodiscard]] condition_variable {
1861 public:
notify_one()1862     void notify_one() noexcept {
1863         cv_.notify_one();
1864     }
1865 
notify_all()1866     void notify_all() noexcept {
1867         cv_.notify_all();
1868     }
1869 
1870     template <typename Mutex>
1871     void wait(unique_lock<Mutex>& lock, pid_t notifier_tid = kInvalidTid) {
1872         typename Mutex::cv_wait_scoped_stat_t ws(lock.native_mutex(), notifier_tid);
1873         cv_.wait(lock.std_unique_lock());
1874     }
1875 
1876     template<typename Mutex, typename Predicate>
1877     void wait(unique_lock<Mutex>& lock, Predicate stop_waiting, pid_t notifier_tid = kInvalidTid) {
1878         typename Mutex::cv_wait_scoped_stat_t ws(lock.native_mutex(), notifier_tid);
1879         cv_.wait(lock.std_unique_lock(), std::move(stop_waiting));
1880     }
1881 
1882     template<typename Mutex, typename Rep, typename Period>
1883     std::cv_status wait_for(unique_lock<Mutex>& lock,
1884             const std::chrono::duration<Rep, Period>& rel_time,
1885             pid_t notifier_tid = kInvalidTid) {
1886         typename Mutex::cv_wait_scoped_stat_t ws(lock.native_mutex(), notifier_tid);
1887         return cv_.wait_for(lock.std_unique_lock(), rel_time);
1888     }
1889 
1890     template<typename Mutex, typename Rep, typename Period, typename Predicate>
1891     bool wait_for(unique_lock<Mutex>& lock,
1892             const std::chrono::duration<Rep, Period>& rel_time,
1893             Predicate stop_waiting, pid_t notifier_tid = kInvalidTid) {
1894         typename Mutex::cv_wait_scoped_stat_t ws(lock.native_mutex(), notifier_tid);
1895         return cv_.wait_for(lock.std_unique_lock(), rel_time, std::move(stop_waiting));
1896     }
1897 
1898     template<typename Mutex, typename Clock, typename Duration>
1899     std::cv_status wait_until(unique_lock<Mutex>& lock,
1900             const std::chrono::time_point<Clock, Duration>& timeout_time,
1901             pid_t notifier_tid = kInvalidTid) {
1902         typename Mutex::cv_wait_scoped_stat_t ws(lock.native_mutex(), notifier_tid);
1903         return cv_.wait_until(lock.std_unique_lock(), timeout_time);
1904     }
1905 
1906     template<typename Mutex, typename Clock, typename Duration, typename Predicate>
1907     bool wait_until(unique_lock<Mutex>& lock,
1908             const std::chrono::time_point<Clock, Duration>& timeout_time,
1909             Predicate stop_waiting, pid_t notifier_tid = kInvalidTid) {
1910         typename Mutex::cv_wait_scoped_stat_t ws(lock.native_mutex(), notifier_tid);
1911         return cv_.wait_until(lock.std_unique_lock(), timeout_time, std::move(stop_waiting));
1912     }
1913 
native_handle()1914     auto native_handle() {
1915         return cv_.native_handle();
1916     }
1917 
1918 private:
1919     std::condition_variable cv_;
1920 };
1921 
1922 // audio_utils::scoped_lock has proper thread safety annotations.
1923 // std::scoped_lock does not have thread safety annotations for greater than 1 lock
1924 // since the variadic template doesn't convert to the variadic macro def.
1925 //
1926 // We add [[nodiscard]] to prevent accidentally ignoring construction.
1927 template <typename ...Mutexes>
1928 class scoped_lock;
1929 
1930 template <typename Mutex1>
1931 class [[nodiscard]] SCOPED_CAPABILITY scoped_lock<Mutex1>
1932     : private std::scoped_lock<Mutex1> {
1933 public:
scoped_lock(Mutex1 & m)1934     explicit scoped_lock(Mutex1& m) ACQUIRE(m) : std::scoped_lock<Mutex1>(m) {}
1935     ~scoped_lock() RELEASE() = default;
1936 };
1937 
1938 template <typename Mutex1, typename Mutex2>
1939 class [[nodiscard]] SCOPED_CAPABILITY scoped_lock<Mutex1, Mutex2>
1940     : private std::scoped_lock<Mutex1, Mutex2> {
1941 public:
scoped_lock(Mutex1 & m1,Mutex2 & m2)1942     scoped_lock(Mutex1& m1, Mutex2& m2) ACQUIRE(m1, m2)
1943         : std::scoped_lock<Mutex1, Mutex2>(m1, m2) {}
1944     ~scoped_lock() RELEASE() = default;
1945 };
1946 
1947 template <typename Mutex1, typename Mutex2, typename Mutex3>
1948 class [[nodiscard]] SCOPED_CAPABILITY scoped_lock<Mutex1, Mutex2, Mutex3>
1949     : private std::scoped_lock<Mutex1, Mutex2, Mutex3> {
1950 public:
scoped_lock(Mutex1 & m1,Mutex2 & m2,Mutex3 & m3)1951     scoped_lock(Mutex1& m1, Mutex2& m2, Mutex3& m3) ACQUIRE(m1, m2, m3)
1952         : std::scoped_lock<Mutex1, Mutex2, Mutex3>(m1, m2, m3) {}
1953     ~scoped_lock() RELEASE() = default;
1954 };
1955 
1956 template <typename ...Mutexes>
1957 class [[nodiscard]] scoped_lock : private std::scoped_lock<Mutexes...> {
1958 public:
scoped_lock(Mutexes &...mutexes)1959     scoped_lock(Mutexes&... mutexes)
1960       : std::scoped_lock<Mutexes...>(mutexes...) {}
1961 };
1962 
1963 // audio_utils::lock_guard_no_thread_safety_analysis is used to lock
1964 // the second mutex when the same global capability is aliased
1965 // to 2 (or more) different mutexes.
1966 //
1967 // Example usage:
1968 //
1969 // // Suppose the interface IAfThreadBase::mutex() returns a global capability
1970 // // ThreadBase_Mutex.
1971 //
1972 // sp<IAfThreadBase> srcThread, dstThread;
1973 //
1974 // lock_guard(srcThread->mutex());  // acquires global capability ThreadBase_Mutex;
1975 // ...
1976 // lock_guard_no_thread_safety_analysis(  // lock_guard would fail here as
1977 //         dstThread->mutex());           // the same global capability is assigned to
1978 //                                        // dstThread->mutex().
1979 //                                        // lock_guard_no_thread_safety_analysis
1980 //                                        // prevents a thread safety error.
1981 
1982 template<typename Mutex1>
1983 class lock_guard_no_thread_safety_analysis : private std::lock_guard<Mutex1> {
1984 public:
lock_guard_no_thread_safety_analysis(Mutex1 & m)1985     lock_guard_no_thread_safety_analysis(Mutex1& m) : std::lock_guard<Mutex1>(m) {}
1986 };
1987 
1988 } // namespace android::audio_utils
1989 
1990 #pragma pop_macro("LOG_TAG")
1991