audio_mutex: Update mutex order
Add new mutex attributes template class to configure
mutex from generated audio mutex information.
Test: validated through dynamic mutex order checking on CTS tests
Bug: 306277363
Bug: 307629326
Change-Id: If35fae81ed1f4e20e758a1cd4ee51cbd27414e1c
diff --git a/audio_utils/include/audio_utils/mutex.h b/audio_utils/include/audio_utils/mutex.h
index 38afadb..8e9b5a6 100644
--- a/audio_utils/include/audio_utils/mutex.h
+++ b/audio_utils/include/audio_utils/mutex.h
@@ -28,6 +28,267 @@
namespace android::audio_utils {
+// Define global capabilities for thread-safety annotation.
+//
+// These can be manually modified, or
+// compile generate_mutex_order.cpp in the tests directory
+// to generate this.
+
+// --- Begin generated section
+
+// Lock order
+enum class MutexOrder : uint32_t {
+ kEffectHandle_Mutex = 0,
+ kEffectBase_PolicyMutex = 1,
+ kAudioFlinger_Mutex = 2,
+ kAudioFlinger_HardwareMutex = 3,
+ kDeviceEffectManager_Mutex = 4,
+ kPatchCommandThread_Mutex = 5,
+ kThreadBase_Mutex = 6,
+ kAudioFlinger_ClientMutex = 7,
+ kMelReporter_Mutex = 8,
+ kEffectChain_Mutex = 9,
+ kDeviceEffectProxy_ProxyMutex = 10,
+ kEffectBase_Mutex = 11,
+ kAudioFlinger_UnregisteredWritersMutex = 12,
+ kAsyncCallbackThread_Mutex = 13,
+ kConfigEvent_Mutex = 14,
+ kOutputTrack_TrackMetadataMutex = 15,
+ kPassthruPatchRecord_ReadMutex = 16,
+ kPatchCommandThread_ListenerMutex = 17,
+ kPlaybackThread_AudioTrackCbMutex = 18,
+ kMediaLogNotifier_Mutex = 19,
+ kOtherMutex = 20,
+ kSize = 21,
+};
+
+// Lock by name
+inline constexpr const char* const gMutexNames[] = {
+ "EffectHandle_Mutex",
+ "EffectBase_PolicyMutex",
+ "AudioFlinger_Mutex",
+ "AudioFlinger_HardwareMutex",
+ "DeviceEffectManager_Mutex",
+ "PatchCommandThread_Mutex",
+ "ThreadBase_Mutex",
+ "AudioFlinger_ClientMutex",
+ "MelReporter_Mutex",
+ "EffectChain_Mutex",
+ "DeviceEffectProxy_ProxyMutex",
+ "EffectBase_Mutex",
+ "AudioFlinger_UnregisteredWritersMutex",
+ "AsyncCallbackThread_Mutex",
+ "ConfigEvent_Mutex",
+ "OutputTrack_TrackMetadataMutex",
+ "PassthruPatchRecord_ReadMutex",
+ "PatchCommandThread_ListenerMutex",
+ "PlaybackThread_AudioTrackCbMutex",
+ "MediaLogNotifier_Mutex",
+ "OtherMutex",
+};
+
+// Forward declarations
+class AudioMutexAttributes;
+template <typename T> class mutex_impl;
+using mutex = mutex_impl<AudioMutexAttributes>;
+
+// Capabilities in priority order
+// (declaration only, value is nullptr)
+inline mutex* EffectHandle_Mutex;
+inline mutex* EffectBase_PolicyMutex
+ ACQUIRED_AFTER(android::audio_utils::EffectHandle_Mutex);
+inline mutex* AudioFlinger_Mutex
+ ACQUIRED_AFTER(android::audio_utils::EffectBase_PolicyMutex);
+inline mutex* AudioFlinger_HardwareMutex
+ ACQUIRED_AFTER(android::audio_utils::AudioFlinger_Mutex);
+inline mutex* DeviceEffectManager_Mutex
+ ACQUIRED_AFTER(android::audio_utils::AudioFlinger_HardwareMutex);
+inline mutex* PatchCommandThread_Mutex
+ ACQUIRED_AFTER(android::audio_utils::DeviceEffectManager_Mutex);
+inline mutex* ThreadBase_Mutex
+ ACQUIRED_AFTER(android::audio_utils::PatchCommandThread_Mutex);
+inline mutex* AudioFlinger_ClientMutex
+ ACQUIRED_AFTER(android::audio_utils::ThreadBase_Mutex);
+inline mutex* MelReporter_Mutex
+ ACQUIRED_AFTER(android::audio_utils::AudioFlinger_ClientMutex);
+inline mutex* EffectChain_Mutex
+ ACQUIRED_AFTER(android::audio_utils::MelReporter_Mutex);
+inline mutex* DeviceEffectProxy_ProxyMutex
+ ACQUIRED_AFTER(android::audio_utils::EffectChain_Mutex);
+inline mutex* EffectBase_Mutex
+ ACQUIRED_AFTER(android::audio_utils::DeviceEffectProxy_ProxyMutex);
+inline mutex* AudioFlinger_UnregisteredWritersMutex
+ ACQUIRED_AFTER(android::audio_utils::EffectBase_Mutex);
+inline mutex* AsyncCallbackThread_Mutex
+ ACQUIRED_AFTER(android::audio_utils::AudioFlinger_UnregisteredWritersMutex);
+inline mutex* ConfigEvent_Mutex
+ ACQUIRED_AFTER(android::audio_utils::AsyncCallbackThread_Mutex);
+inline mutex* OutputTrack_TrackMetadataMutex
+ ACQUIRED_AFTER(android::audio_utils::ConfigEvent_Mutex);
+inline mutex* PassthruPatchRecord_ReadMutex
+ ACQUIRED_AFTER(android::audio_utils::OutputTrack_TrackMetadataMutex);
+inline mutex* PatchCommandThread_ListenerMutex
+ ACQUIRED_AFTER(android::audio_utils::PassthruPatchRecord_ReadMutex);
+inline mutex* PlaybackThread_AudioTrackCbMutex
+ ACQUIRED_AFTER(android::audio_utils::PatchCommandThread_ListenerMutex);
+inline mutex* MediaLogNotifier_Mutex
+ ACQUIRED_AFTER(android::audio_utils::PlaybackThread_AudioTrackCbMutex);
+inline mutex* OtherMutex
+ ACQUIRED_AFTER(android::audio_utils::MediaLogNotifier_Mutex);
+
+// Exclusion by capability
+#define EXCLUDES_BELOW_OtherMutex
+#define EXCLUDES_OtherMutex \
+ EXCLUDES(android::audio_utils::OtherMutex) \
+ EXCLUDES_BELOW_OtherMutex
+
+#define EXCLUDES_BELOW_MediaLogNotifier_Mutex \
+ EXCLUDES_OtherMutex
+#define EXCLUDES_MediaLogNotifier_Mutex \
+ EXCLUDES(android::audio_utils::MediaLogNotifier_Mutex) \
+ EXCLUDES_BELOW_MediaLogNotifier_Mutex
+
+#define EXCLUDES_BELOW_PlaybackThread_AudioTrackCbMutex \
+ EXCLUDES_MediaLogNotifier_Mutex
+#define EXCLUDES_PlaybackThread_AudioTrackCbMutex \
+ EXCLUDES(android::audio_utils::PlaybackThread_AudioTrackCbMutex) \
+ EXCLUDES_BELOW_PlaybackThread_AudioTrackCbMutex
+
+#define EXCLUDES_BELOW_PatchCommandThread_ListenerMutex \
+ EXCLUDES_PlaybackThread_AudioTrackCbMutex
+#define EXCLUDES_PatchCommandThread_ListenerMutex \
+ EXCLUDES(android::audio_utils::PatchCommandThread_ListenerMutex) \
+ EXCLUDES_BELOW_PatchCommandThread_ListenerMutex
+
+#define EXCLUDES_BELOW_PassthruPatchRecord_ReadMutex \
+ EXCLUDES_PatchCommandThread_ListenerMutex
+#define EXCLUDES_PassthruPatchRecord_ReadMutex \
+ EXCLUDES(android::audio_utils::PassthruPatchRecord_ReadMutex) \
+ EXCLUDES_BELOW_PassthruPatchRecord_ReadMutex
+
+#define EXCLUDES_BELOW_OutputTrack_TrackMetadataMutex \
+ EXCLUDES_PassthruPatchRecord_ReadMutex
+#define EXCLUDES_OutputTrack_TrackMetadataMutex \
+ EXCLUDES(android::audio_utils::OutputTrack_TrackMetadataMutex) \
+ EXCLUDES_BELOW_OutputTrack_TrackMetadataMutex
+
+#define EXCLUDES_BELOW_ConfigEvent_Mutex \
+ EXCLUDES_OutputTrack_TrackMetadataMutex
+#define EXCLUDES_ConfigEvent_Mutex \
+ EXCLUDES(android::audio_utils::ConfigEvent_Mutex) \
+ EXCLUDES_BELOW_ConfigEvent_Mutex
+
+#define EXCLUDES_BELOW_AsyncCallbackThread_Mutex \
+ EXCLUDES_ConfigEvent_Mutex
+#define EXCLUDES_AsyncCallbackThread_Mutex \
+ EXCLUDES(android::audio_utils::AsyncCallbackThread_Mutex) \
+ EXCLUDES_BELOW_AsyncCallbackThread_Mutex
+
+#define EXCLUDES_BELOW_AudioFlinger_UnregisteredWritersMutex \
+ EXCLUDES_AsyncCallbackThread_Mutex
+#define EXCLUDES_AudioFlinger_UnregisteredWritersMutex \
+ EXCLUDES(android::audio_utils::AudioFlinger_UnregisteredWritersMutex) \
+ EXCLUDES_BELOW_AudioFlinger_UnregisteredWritersMutex
+
+#define EXCLUDES_BELOW_EffectBase_Mutex \
+ EXCLUDES_AudioFlinger_UnregisteredWritersMutex
+#define EXCLUDES_EffectBase_Mutex \
+ EXCLUDES(android::audio_utils::EffectBase_Mutex) \
+ EXCLUDES_BELOW_EffectBase_Mutex
+
+#define EXCLUDES_BELOW_DeviceEffectProxy_ProxyMutex \
+ EXCLUDES_EffectBase_Mutex
+#define EXCLUDES_DeviceEffectProxy_ProxyMutex \
+ EXCLUDES(android::audio_utils::DeviceEffectProxy_ProxyMutex) \
+ EXCLUDES_BELOW_DeviceEffectProxy_ProxyMutex
+
+#define EXCLUDES_BELOW_EffectChain_Mutex \
+ EXCLUDES_DeviceEffectProxy_ProxyMutex
+#define EXCLUDES_EffectChain_Mutex \
+ EXCLUDES(android::audio_utils::EffectChain_Mutex) \
+ EXCLUDES_BELOW_EffectChain_Mutex
+
+#define EXCLUDES_BELOW_MelReporter_Mutex \
+ EXCLUDES_EffectChain_Mutex
+#define EXCLUDES_MelReporter_Mutex \
+ EXCLUDES(android::audio_utils::MelReporter_Mutex) \
+ EXCLUDES_BELOW_MelReporter_Mutex
+
+#define EXCLUDES_BELOW_AudioFlinger_ClientMutex \
+ EXCLUDES_MelReporter_Mutex
+#define EXCLUDES_AudioFlinger_ClientMutex \
+ EXCLUDES(android::audio_utils::AudioFlinger_ClientMutex) \
+ EXCLUDES_BELOW_AudioFlinger_ClientMutex
+
+#define EXCLUDES_BELOW_ThreadBase_Mutex \
+ EXCLUDES_AudioFlinger_ClientMutex
+#define EXCLUDES_ThreadBase_Mutex \
+ EXCLUDES(android::audio_utils::ThreadBase_Mutex) \
+ EXCLUDES_BELOW_ThreadBase_Mutex
+
+#define EXCLUDES_BELOW_PatchCommandThread_Mutex \
+ EXCLUDES_ThreadBase_Mutex
+#define EXCLUDES_PatchCommandThread_Mutex \
+ EXCLUDES(android::audio_utils::PatchCommandThread_Mutex) \
+ EXCLUDES_BELOW_PatchCommandThread_Mutex
+
+#define EXCLUDES_BELOW_DeviceEffectManager_Mutex \
+ EXCLUDES_PatchCommandThread_Mutex
+#define EXCLUDES_DeviceEffectManager_Mutex \
+ EXCLUDES(android::audio_utils::DeviceEffectManager_Mutex) \
+ EXCLUDES_BELOW_DeviceEffectManager_Mutex
+
+#define EXCLUDES_BELOW_AudioFlinger_HardwareMutex \
+ EXCLUDES_DeviceEffectManager_Mutex
+#define EXCLUDES_AudioFlinger_HardwareMutex \
+ EXCLUDES(android::audio_utils::AudioFlinger_HardwareMutex) \
+ EXCLUDES_BELOW_AudioFlinger_HardwareMutex
+
+#define EXCLUDES_BELOW_AudioFlinger_Mutex \
+ EXCLUDES_AudioFlinger_HardwareMutex
+#define EXCLUDES_AudioFlinger_Mutex \
+ EXCLUDES(android::audio_utils::AudioFlinger_Mutex) \
+ EXCLUDES_BELOW_AudioFlinger_Mutex
+
+#define EXCLUDES_BELOW_EffectBase_PolicyMutex \
+ EXCLUDES_AudioFlinger_Mutex
+#define EXCLUDES_EffectBase_PolicyMutex \
+ EXCLUDES(android::audio_utils::EffectBase_PolicyMutex) \
+ EXCLUDES_BELOW_EffectBase_PolicyMutex
+
+#define EXCLUDES_BELOW_EffectHandle_Mutex \
+ EXCLUDES_EffectBase_PolicyMutex
+#define EXCLUDES_EffectHandle_Mutex \
+ EXCLUDES(android::audio_utils::EffectHandle_Mutex) \
+ EXCLUDES_BELOW_EffectHandle_Mutex
+
+#define EXCLUDES_AUDIO_ALL \
+ EXCLUDES_EffectHandle_Mutex
+
+// --- End generated section
+
+/**
+ * AudioMutexAttributes is a collection of types and constexpr configuration
+ * used for the Android audio mutex.
+ *
+ * A different AudioMutexAttributes configuration will instantiate a completely
+ * independent set of mutex strategies, statics and thread locals,
+ * for a different type of mutexes.
+ */
+
+class AudioMutexAttributes {
+public:
+ // Order types, name arrays.
+ using order_t = MutexOrder;
+ static constexpr auto& order_names_ = gMutexNames;
+ static constexpr size_t order_size_ = (size_t)MutexOrder::kSize;
+ static constexpr order_t order_default_ = MutexOrder::kOtherMutex;
+
+ // verify order information
+ static_assert(std::size(order_names_) == order_size_);
+ static_assert((size_t)order_default_ < order_size_);
+};
+
// audio_utils::mutex, audio_utils::lock_guard, audio_utils::unique_lock,
// and audio_utils::condition_variable are method compatible versions
// of std::mutex, std::lock_guard, std::unique_lock, and std::condition_variable
@@ -37,12 +298,21 @@
// is inefficient. One is better off making a custom timed implementation using
// pthread_mutex_timedlock() on the mutex::native_handle().
-class CAPABILITY("mutex") mutex {
+extern bool mutex_get_enable_flag();
+
+template <typename Attributes>
+class CAPABILITY("mutex") mutex_impl {
public:
// We use composition here.
// No copy/move ctors as the member std::mutex has it deleted.
- mutex() {
- if (!get_enable_flag()) return;
+ mutex_impl(typename Attributes::order_t order = Attributes::order_default_)
+ : order_(order)
+ {
+ LOG_ALWAYS_FATAL_IF((size_t)order >= Attributes::order_size_,
+ "mutex order %u is equal to or greater than order limit:%zu",
+ order, Attributes::order_size_);
+
+ if (!mutex_get_enable_flag()) return;
pthread_mutexattr_t attr;
int ret = pthread_mutexattr_init(&attr);
@@ -58,12 +328,16 @@
}
// use of the native_handle() is implementation defined.
- auto handle = m_.native_handle();
+ const auto handle = m_.native_handle();
ret = pthread_mutex_init(handle, &attr);
if (ret != 0) {
ALOGW("%s, pthread_mutex_init returned %d", __func__, ret);
}
- ALOGV("%s: audio_mutex initialized: %d", __func__, ret);
+ ALOGV("%s: audio_mutex initialized: ret:%d order:%u", __func__, ret, order_);
+ }
+
+ ~mutex_impl() {
+ // Note: std::mutex behavior is undefined if released holding ownership.
}
auto native_handle() {
@@ -98,8 +372,9 @@
}
private:
- static bool get_enable_flag();
+
std::mutex m_;
+ const typename Attributes::order_t order_;
};
// audio_utils::lock_guard only works with the defined mutex.
@@ -278,157 +553,6 @@
lock_guard_no_thread_safety_analysis(Mutex1& m) : std::lock_guard<Mutex1>(m) {}
};
-// Define global capabilities for thread-safety annotation.
-//
-// These can be manually modified, or
-// compile generate_mutex_order.cpp in the tests directory
-// to generate this.
-
-// --- Begin generated section
-
-// Capabilities in priority order
-// (declaration only, value is nullptr)
-inline mutex* AudioFlinger_Mutex;
-inline mutex* EffectHandle_Mutex
- ACQUIRED_AFTER(android::audio_utils::AudioFlinger_Mutex);
-inline mutex* AudioFlinger_HardwareMutex
- ACQUIRED_AFTER(android::audio_utils::EffectHandle_Mutex);
-inline mutex* DeviceEffectManager_Mutex
- ACQUIRED_AFTER(android::audio_utils::AudioFlinger_HardwareMutex);
-inline mutex* PatchCommandThread_Mutex
- ACQUIRED_AFTER(android::audio_utils::DeviceEffectManager_Mutex);
-inline mutex* ThreadBase_Mutex
- ACQUIRED_AFTER(android::audio_utils::PatchCommandThread_Mutex);
-inline mutex* AudioFlinger_ClientMutex
- ACQUIRED_AFTER(android::audio_utils::ThreadBase_Mutex);
-inline mutex* MelReporter_Mutex
- ACQUIRED_AFTER(android::audio_utils::AudioFlinger_ClientMutex);
-inline mutex* EffectChain_Mutex
- ACQUIRED_AFTER(android::audio_utils::MelReporter_Mutex);
-inline mutex* EffectBase_Mutex
- ACQUIRED_AFTER(android::audio_utils::EffectChain_Mutex);
-inline mutex* AudioFlinger_UnregisteredWritersMutex
- ACQUIRED_AFTER(android::audio_utils::EffectBase_Mutex);
-inline mutex* AsyncCallbackThread_Mutex
- ACQUIRED_AFTER(android::audio_utils::AudioFlinger_UnregisteredWritersMutex);
-inline mutex* ConfigEvent_Mutex
- ACQUIRED_AFTER(android::audio_utils::AsyncCallbackThread_Mutex);
-inline mutex* OutputTrack_TrackMetadataMutex
- ACQUIRED_AFTER(android::audio_utils::ConfigEvent_Mutex);
-inline mutex* PassthruPatchRecord_ReadMutex
- ACQUIRED_AFTER(android::audio_utils::OutputTrack_TrackMetadataMutex);
-inline mutex* PatchCommandThread_ListenerMutex
- ACQUIRED_AFTER(android::audio_utils::PassthruPatchRecord_ReadMutex);
-inline mutex* PlaybackThread_AudioTrackCbMutex
- ACQUIRED_AFTER(android::audio_utils::PatchCommandThread_ListenerMutex);
-
-// Exclusion by capability
-#define EXCLUDES_BELOW_PlaybackThread_AudioTrackCbMutex
-#define EXCLUDES_PlaybackThread_AudioTrackCbMutex \
- EXCLUDES(android::audio_utils::PlaybackThread_AudioTrackCbMutex) \
- EXCLUDES_BELOW_PlaybackThread_AudioTrackCbMutex
-
-#define EXCLUDES_BELOW_PatchCommandThread_ListenerMutex \
- EXCLUDES_PlaybackThread_AudioTrackCbMutex
-#define EXCLUDES_PatchCommandThread_ListenerMutex \
- EXCLUDES(android::audio_utils::PatchCommandThread_ListenerMutex) \
- EXCLUDES_BELOW_PatchCommandThread_ListenerMutex
-
-#define EXCLUDES_BELOW_PassthruPatchRecord_ReadMutex \
- EXCLUDES_PatchCommandThread_ListenerMutex
-#define EXCLUDES_PassthruPatchRecord_ReadMutex \
- EXCLUDES(android::audio_utils::PassthruPatchRecord_ReadMutex) \
- EXCLUDES_BELOW_PassthruPatchRecord_ReadMutex
-
-#define EXCLUDES_BELOW_OutputTrack_TrackMetadataMutex \
- EXCLUDES_PassthruPatchRecord_ReadMutex
-#define EXCLUDES_OutputTrack_TrackMetadataMutex \
- EXCLUDES(android::audio_utils::OutputTrack_TrackMetadataMutex) \
- EXCLUDES_BELOW_OutputTrack_TrackMetadataMutex
-
-#define EXCLUDES_BELOW_ConfigEvent_Mutex \
- EXCLUDES_OutputTrack_TrackMetadataMutex
-#define EXCLUDES_ConfigEvent_Mutex \
- EXCLUDES(android::audio_utils::ConfigEvent_Mutex) \
- EXCLUDES_BELOW_ConfigEvent_Mutex
-
-#define EXCLUDES_BELOW_AsyncCallbackThread_Mutex \
- EXCLUDES_ConfigEvent_Mutex
-#define EXCLUDES_AsyncCallbackThread_Mutex \
- EXCLUDES(android::audio_utils::AsyncCallbackThread_Mutex) \
- EXCLUDES_BELOW_AsyncCallbackThread_Mutex
-
-#define EXCLUDES_BELOW_AudioFlinger_UnregisteredWritersMutex \
- EXCLUDES_AsyncCallbackThread_Mutex
-#define EXCLUDES_AudioFlinger_UnregisteredWritersMutex \
- EXCLUDES(android::audio_utils::AudioFlinger_UnregisteredWritersMutex) \
- EXCLUDES_BELOW_AudioFlinger_UnregisteredWritersMutex
-
-#define EXCLUDES_BELOW_EffectBase_Mutex \
- EXCLUDES_AudioFlinger_UnregisteredWritersMutex
-#define EXCLUDES_EffectBase_Mutex \
- EXCLUDES(android::audio_utils::EffectBase_Mutex) \
- EXCLUDES_BELOW_EffectBase_Mutex
-
-#define EXCLUDES_BELOW_EffectChain_Mutex \
- EXCLUDES_EffectBase_Mutex
-#define EXCLUDES_EffectChain_Mutex \
- EXCLUDES(android::audio_utils::EffectChain_Mutex) \
- EXCLUDES_BELOW_EffectChain_Mutex
-
-#define EXCLUDES_BELOW_MelReporter_Mutex \
- EXCLUDES_EffectChain_Mutex
-#define EXCLUDES_MelReporter_Mutex \
- EXCLUDES(android::audio_utils::MelReporter_Mutex) \
- EXCLUDES_BELOW_MelReporter_Mutex
-
-#define EXCLUDES_BELOW_AudioFlinger_ClientMutex \
- EXCLUDES_MelReporter_Mutex
-#define EXCLUDES_AudioFlinger_ClientMutex \
- EXCLUDES(android::audio_utils::AudioFlinger_ClientMutex) \
- EXCLUDES_BELOW_AudioFlinger_ClientMutex
-
-#define EXCLUDES_BELOW_ThreadBase_Mutex \
- EXCLUDES_AudioFlinger_ClientMutex
-#define EXCLUDES_ThreadBase_Mutex \
- EXCLUDES(android::audio_utils::ThreadBase_Mutex) \
- EXCLUDES_BELOW_ThreadBase_Mutex
-
-#define EXCLUDES_BELOW_PatchCommandThread_Mutex \
- EXCLUDES_ThreadBase_Mutex
-#define EXCLUDES_PatchCommandThread_Mutex \
- EXCLUDES(android::audio_utils::PatchCommandThread_Mutex) \
- EXCLUDES_BELOW_PatchCommandThread_Mutex
-
-#define EXCLUDES_BELOW_DeviceEffectManager_Mutex \
- EXCLUDES_PatchCommandThread_Mutex
-#define EXCLUDES_DeviceEffectManager_Mutex \
- EXCLUDES(android::audio_utils::DeviceEffectManager_Mutex) \
- EXCLUDES_BELOW_DeviceEffectManager_Mutex
-
-#define EXCLUDES_BELOW_AudioFlinger_HardwareMutex \
- EXCLUDES_DeviceEffectManager_Mutex
-#define EXCLUDES_AudioFlinger_HardwareMutex \
- EXCLUDES(android::audio_utils::AudioFlinger_HardwareMutex) \
- EXCLUDES_BELOW_AudioFlinger_HardwareMutex
-
-#define EXCLUDES_BELOW_EffectHandle_Mutex \
- EXCLUDES_AudioFlinger_HardwareMutex
-#define EXCLUDES_EffectHandle_Mutex \
- EXCLUDES(android::audio_utils::EffectHandle_Mutex) \
- EXCLUDES_BELOW_EffectHandle_Mutex
-
-#define EXCLUDES_BELOW_AudioFlinger_Mutex \
- EXCLUDES_EffectHandle_Mutex
-#define EXCLUDES_AudioFlinger_Mutex \
- EXCLUDES(android::audio_utils::AudioFlinger_Mutex) \
- EXCLUDES_BELOW_AudioFlinger_Mutex
-
-#define EXCLUDES_AUDIO_ALL \
- EXCLUDES_AudioFlinger_Mutex
-
-// --- End generated section
-
} // namespace android::audio_utils
#pragma pop_macro("LOG_TAG")
diff --git a/audio_utils/mutex.cpp b/audio_utils/mutex.cpp
index 98a062e..a3fed47 100644
--- a/audio_utils/mutex.cpp
+++ b/audio_utils/mutex.cpp
@@ -15,14 +15,13 @@
*/
#define LOG_TAG "audio_utils::mutex"
+#include <utils/Log.h>
-#include <audio_utils/mutex.h>
#include <com_android_media_audio_flags.h>
namespace android::audio_utils {
-/*static*/
-bool mutex::get_enable_flag() {
+bool mutex_get_enable_flag() {
static const bool enable = []() {
const bool flag = com::android::media::audio::flags::mutex_priority_inheritance();
ALOGD("get_enable_flag: mutex_priority_inheritance: %s", flag ? "true" : "false");
diff --git a/audio_utils/tests/generate_mutex_order.cpp b/audio_utils/tests/generate_mutex_order.cpp
index 29cea79..0f9f45d 100644
--- a/audio_utils/tests/generate_mutex_order.cpp
+++ b/audio_utils/tests/generate_mutex_order.cpp
@@ -41,8 +41,10 @@
// 4) AudioFlinger -> ThreadBase -> EffectChain -> EffectBase(EffectModule)
// 5) EffectHandle -> ThreadBase -> EffectChain -> EffectBase(EffectModule)
- "AudioFlinger_Mutex",
"EffectHandle_Mutex",
+ "EffectBase_PolicyMutex", // held for AudioSystem::registerEffect, must come
+ // after EffectHandle_Mutex.
+ "AudioFlinger_Mutex",
"AudioFlinger_HardwareMutex",
"DeviceEffectManager_Mutex",
"PatchCommandThread_Mutex",
@@ -50,6 +52,7 @@
"AudioFlinger_ClientMutex",
"MelReporter_Mutex",
"EffectChain_Mutex",
+ "DeviceEffectProxy_ProxyMutex", // used for device effects (which have no chain).
"EffectBase_Mutex",
// These mutexes are in leaf objects
@@ -62,6 +65,10 @@
"PassthruPatchRecord_ReadMutex",
"PatchCommandThread_ListenerMutex",
"PlaybackThread_AudioTrackCbMutex",
+ "MediaLogNotifier_Mutex",
+ "OtherMutex", // DO NOT CHANGE THIS: OtherMutex is used for mutexes without a specified order.
+ // An OtherMutex will always be the lowest order mutex and cannot acquire
+ // another named mutex while being held.
};
using namespace std;
@@ -70,7 +77,28 @@
// ordering and exclusion as listed above.
int main() {
- cout << "// Capabilities in priority order\n"
+ cout << "// Lock order\n";
+ cout << "enum class MutexOrder : uint32_t {\n";
+
+ for (size_t i = 0; i < size(mutexes); ++i) {
+ cout << " k" << mutexes[i] << " = " << i << ",\n";
+ }
+ cout << " kSize = " << size(mutexes) << ",\n";
+ cout << "};\n";
+
+ cout << "\n// Lock by name\n";
+ cout << "inline constexpr const char* const gMutexNames[] = {\n";
+ for (size_t i = 0; i < size(mutexes); ++i) {
+ cout << " \"" << mutexes[i] << "\",\n";
+ }
+ cout << "};\n";
+
+ cout << "\n// Forward declarations\n";
+ cout << "class AudioMutexAttributes;\n";
+ cout << "template <typename T> class mutex_impl;\n";
+ cout << "using mutex = mutex_impl<AudioMutexAttributes>;\n";
+
+ cout << "\n// Capabilities in priority order\n"
<< "// (declaration only, value is nullptr)\n";
const char *last = nullptr;
for (auto mutex : mutexes) {