Do not call Scheduler destructor in libVulkan.
This is causing a deadlock on Windows 7. The process teardown is
calling a destructor function that ends up calling a bunch of
synchronization logic that should not be called on process exit.
Bug: b/141380274
Bug: angleproject:3909
Change-Id: I4787d495d965e8b43d15be9c952c4b1de9bdf197
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/36548
Presubmit-Ready: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 1112b56..69d1107 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -16,6 +16,9 @@
#include "VkConfig.h"
#include "Pipeline/SpirvShader.hpp" // sw::SIMD::Width
+#include "System/CPUID.hpp"
+
+#include "marl/thread.h"
#include <limits>
#include <cstring>
@@ -23,8 +26,13 @@
namespace vk
{
-PhysicalDevice::PhysicalDevice(const void*, void* mem)
+PhysicalDevice::PhysicalDevice(const void*, void* mem) : scheduler(new marl::Scheduler())
{
+ scheduler->setThreadInitializer([] {
+ sw::CPUID::setFlushToZero(true);
+ sw::CPUID::setDenormalsAreZero(true);
+ });
+ scheduler->setWorkerThreadCount(std::min<size_t>(marl::Thread::numLogicalCPUs(), 16));
}
const VkPhysicalDeviceFeatures& PhysicalDevice::getFeatures() const
@@ -795,4 +803,9 @@
return properties;
}
+marl::Scheduler* PhysicalDevice::getScheduler() const
+{
+ return scheduler.get();
+}
+
} // namespace vk
diff --git a/src/Vulkan/VkPhysicalDevice.hpp b/src/Vulkan/VkPhysicalDevice.hpp
index c126675..f824851 100644
--- a/src/Vulkan/VkPhysicalDevice.hpp
+++ b/src/Vulkan/VkPhysicalDevice.hpp
@@ -18,6 +18,8 @@
#include "VkObject.hpp"
#include "VkFormat.h"
+#include "marl/scheduler.h"
+
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include <vulkan/vk_android_native_buffer.h>
#endif
@@ -70,9 +72,13 @@
VkQueueFamilyProperties* pQueueFamilyProperties) const;
const VkPhysicalDeviceMemoryProperties& getMemoryProperties() const;
+ marl::Scheduler *getScheduler() const;
+
private:
const VkPhysicalDeviceLimits& getLimits() const;
VkSampleCountFlags getSampleCounts() const;
+
+ std::unique_ptr<marl::Scheduler> scheduler;
};
using DispatchablePhysicalDevice = DispatchableObject<PhysicalDevice, VkPhysicalDevice>;
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index c300382..996cfd3 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -68,9 +68,6 @@
#include "Reactor/Nucleus.hpp"
-#include "marl/scheduler.h"
-#include "marl/thread.h"
-
#include "System/CPUID.hpp"
#include <algorithm>
@@ -120,17 +117,6 @@
sw::CPUID::setEnableSSE(true);
}
-marl::Scheduler* getOrCreateScheduler()
-{
- static auto scheduler = std::unique_ptr<marl::Scheduler>(new marl::Scheduler());
- scheduler->setThreadInitializer([] {
- sw::CPUID::setFlushToZero(true);
- sw::CPUID::setDenormalsAreZero(true);
- });
- scheduler->setWorkerThreadCount(std::min<size_t>(marl::Thread::numLogicalCPUs(), 16));
- return scheduler.get();
-}
-
// initializeLibrary() is called by vkCreateInstance() to perform one-off global
// initialization of the swiftshader driver.
void initializeLibrary()
@@ -602,7 +588,7 @@
(void)queueFamilyPropertyCount; // Silence unused variable warning
}
- auto scheduler = getOrCreateScheduler();
+ auto scheduler = vk::Cast(physicalDevice)->getScheduler();
return vk::DispatchableDevice::Create(pAllocator, pCreateInfo, pDevice, vk::Cast(physicalDevice), enabledFeatures, scheduler);
}