layers: Make layer logging thread-safe
Some validation objects in the layer chassis may not need to lock
around validation/recording calls, leaving access to the debug report-
related data structures unprotected. Added a mutex to the
debug_report_data structure and the lock calls where they were
necessary.
Change-Id: I60938f73c53286808afac4df0f264c1b3bdefc25
diff --git a/layers/vk_layer_logging.h b/layers/vk_layer_logging.h
index 92146cb..02c6b42 100644
--- a/layers/vk_layer_logging.h
+++ b/layers/vk_layer_logging.h
@@ -32,6 +32,7 @@
#include "vk_object_types.h"
#include "vk_validation_error_messages.h"
#include "vk_layer_dispatch_table.h"
+#include <mutex>
#include <signal.h>
#include <cinttypes>
#include <stdarg.h>
@@ -91,8 +92,12 @@
std::unordered_map<uint64_t, std::string> debugUtilsObjectNameMap;
std::unordered_map<VkQueue, std::vector<LoggingLabelData>> debugUtilsQueueLabels;
std::unordered_map<VkCommandBuffer, std::vector<LoggingLabelData>> debugUtilsCmdBufLabels;
+ // This mutex is defined as mutable since the normal usage for a debug report object is as 'const'. The mutable keyword allows
+ // the layers to continue this pattern, but also allows them to use/change this specific member for synchronization purposes.
+ mutable std::mutex debug_report_mutex;
void DebugReportSetUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
+ std::unique_lock<std::mutex> lock(debug_report_mutex);
if (pNameInfo->pObjectName) {
debugUtilsObjectNameMap.insert(
std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->objectHandle, pNameInfo->pObjectName));
@@ -102,6 +107,7 @@
}
void DebugReportSetMarkerObjectName(const VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
+ std::unique_lock<std::mutex> lock(debug_report_mutex);
if (pNameInfo->pObjectName) {
debugObjectNameMap.insert(
std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->object, pNameInfo->pObjectName));
@@ -551,8 +557,10 @@
static inline void layer_debug_utils_destroy_instance(debug_report_data *debug_data) {
if (debug_data) {
+ std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
RemoveAllMessageCallbacks(debug_data, &debug_data->default_debug_callback_list);
RemoveAllMessageCallbacks(debug_data, &debug_data->debug_callback_list);
+ lock.unlock();
delete (debug_data);
}
}
@@ -569,6 +577,7 @@
static inline void layer_destroy_messenger_callback(debug_report_data *debug_data, VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks *allocator) {
+ std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
RemoveDebugUtilsMessenger(debug_data, &debug_data->debug_callback_list, messenger);
RemoveDebugUtilsMessenger(debug_data, &debug_data->default_debug_callback_list, messenger);
}
@@ -577,6 +586,7 @@
const VkDebugUtilsMessengerCreateInfoEXT *create_info,
const VkAllocationCallbacks *allocator,
VkDebugUtilsMessengerEXT *messenger) {
+ std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
if (!pNewDbgFuncNode) return VK_ERROR_OUT_OF_HOST_MEMORY;
memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
@@ -618,6 +628,7 @@
static inline void layer_destroy_report_callback(debug_report_data *debug_data, VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *allocator) {
+ std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
RemoveDebugUtilsMessageCallback(debug_data, &debug_data->debug_callback_list, callback);
RemoveDebugUtilsMessageCallback(debug_data, &debug_data->default_debug_callback_list, callback);
}
@@ -625,6 +636,7 @@
static inline VkResult layer_create_report_callback(debug_report_data *debug_data, bool default_callback,
const VkDebugReportCallbackCreateInfoEXT *create_info,
const VkAllocationCallbacks *allocator, VkDebugReportCallbackEXT *callback) {
+ std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
if (!pNewDbgFuncNode) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -910,6 +922,7 @@
static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
uint64_t src_object, std::string vuid_text, const char *format, ...) {
if (!debug_data) return false;
+ std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
VkFlags local_severity = 0;
VkFlags local_type = 0;
DebugReportFlagsToAnnotFlags(msg_flags, true, &local_severity, &local_type);
@@ -1088,6 +1101,7 @@
static inline void BeginQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
const VkDebugUtilsLabelEXT *label_info) {
+ std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
if (nullptr != label_info && nullptr != label_info->pLabelName) {
auto label_iter = report_data->debugUtilsQueueLabels.find(queue);
if (label_iter == report_data->debugUtilsQueueLabels.end()) {
@@ -1109,6 +1123,7 @@
}
static inline void EndQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue) {
+ std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
auto label_iter = report_data->debugUtilsQueueLabels.find(queue);
if (label_iter != report_data->debugUtilsQueueLabels.end()) {
// If the last thing was a label insert, we need to pop it off of the label vector before any
@@ -1126,6 +1141,7 @@
static inline void InsertQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
const VkDebugUtilsLabelEXT *label_info) {
+ std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
if (nullptr != label_info && nullptr != label_info->pLabelName) {
auto label_iter = report_data->debugUtilsQueueLabels.find(queue);
if (label_iter == report_data->debugUtilsQueueLabels.end()) {
@@ -1150,6 +1166,7 @@
static inline void BeginCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
const VkDebugUtilsLabelEXT *label_info) {
+ std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
if (nullptr != label_info && nullptr != label_info->pLabelName) {
auto label_iter = report_data->debugUtilsCmdBufLabels.find(command_buffer);
if (label_iter == report_data->debugUtilsCmdBufLabels.end()) {
@@ -1171,6 +1188,7 @@
}
static inline void EndCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer) {
+ std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
auto label_iter = report_data->debugUtilsCmdBufLabels.find(command_buffer);
if (label_iter != report_data->debugUtilsCmdBufLabels.end()) {
// If the last thing was a label insert, we need to pop it off of the label vector before any
@@ -1191,6 +1209,7 @@
static inline void InsertCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
const VkDebugUtilsLabelEXT *label_info) {
+ std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
if (nullptr != label_info && nullptr != label_info->pLabelName) {
auto label_iter = report_data->debugUtilsCmdBufLabels.find(command_buffer);
if (label_iter == report_data->debugUtilsCmdBufLabels.end()) {