Remove global lock in order maintenance
Change-Id: I6c2d29d13e42adb6419411bf166dded74c7b5725
diff --git a/stream-servers/vulkan/VkDecoderGlobalState.cpp b/stream-servers/vulkan/VkDecoderGlobalState.cpp
index 2b89fb6..44ef6ba 100644
--- a/stream-servers/vulkan/VkDecoderGlobalState.cpp
+++ b/stream-servers/vulkan/VkDecoderGlobalState.cpp
@@ -3553,27 +3553,26 @@
auto commandBuffer = unbox_VkCommandBuffer(boxed_commandBuffer);
- AutoLock lock(mLock);
- auto& info = mCmdBufferInfo[commandBuffer];
+ OrderMaintenanceInfo* order = ordmaint_VkCommandBuffer(boxed_commandBuffer);
+ if (!order) return;
- bool doWait = false;
+ AutoLock lock(order->lock);
if (needHostSync) {
- while ((sequenceNumber - info.sequenceNumber) != 1) {
+ while ((sequenceNumber - __atomic_load_n(&order->sequenceNumber, __ATOMIC_ACQUIRE) != 1)) {
auto waitUntilUs = nextDeadline();
- mCvWaitSequenceNumber.timedWait(
- &mLock, waitUntilUs);
- doWait = true;
+ order->cv.timedWait(
+ &order->lock, waitUntilUs);
if (timeoutDeadline < android::base::getUnixTimeUs()) {
- fprintf(stderr, "%s: warning: command buffer sync timed out! curr %u info %u\n", __func__, sequenceNumber, info.sequenceNumber);
break;
}
}
}
- info.sequenceNumber = sequenceNumber;
- mCvWaitSequenceNumber.signal();
+ __atomic_store_n(&order->sequenceNumber, sequenceNumber, __ATOMIC_RELEASE);
+ order->cv.signal();
+ releaseOrderMaintInfo(order);
}
void hostSyncQueue(
@@ -3588,29 +3587,28 @@
auto timeoutDeadline = android::base::getUnixTimeUs() + 5000000; // 5 s
- auto queue = unbox_VkQueue(boxed_queue);
+ auto commandBuffer = unbox_VkQueue(boxed_queue);
- AutoLock lock(mLock);
- auto& info = mQueueInfo[queue];
+ OrderMaintenanceInfo* order = ordmaint_VkQueue(boxed_queue);
+ if (!order) return;
- bool doWait = false;
+ AutoLock lock(order->lock);
if (needHostSync) {
- while ((sequenceNumber - info.sequenceNumber) != 1) {
+ while ((sequenceNumber - __atomic_load_n(&order->sequenceNumber, __ATOMIC_ACQUIRE) != 1)) {
auto waitUntilUs = nextDeadline();
- mCvWaitSequenceNumber.timedWait(
- &mLock, waitUntilUs);
- doWait = true;
+ order->cv.timedWait(
+ &order->lock, waitUntilUs);
if (timeoutDeadline < android::base::getUnixTimeUs()) {
- fprintf(stderr, "%s: warning: command buffer sync timed out! curr %u info %u\n", __func__, sequenceNumber, info.sequenceNumber);
break;
}
}
}
- info.sequenceNumber = sequenceNumber;
- mCvWaitSequenceNumber.signal();
+ __atomic_store_n(&order->sequenceNumber, sequenceNumber, __ATOMIC_RELEASE);
+ order->cv.signal();
+ releaseOrderMaintInfo(order);
}
VkResult on_vkCreateImageWithRequirementsGOOGLE(
@@ -3954,12 +3952,39 @@
DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(VkExternalImageFormatProperties)
DEFINE_EXTERNAL_MEMORY_PROPERTIES_TRANSFORM(VkExternalBufferProperties)
+ struct OrderMaintenanceInfo {
+ uint32_t sequenceNumber = 0;
+ Lock lock;
+ ConditionVariable cv;
+
+ uint32_t refcount = 1;
+
+ void incRef() {
+ __atomic_add_fetch(&refcount, 1, __ATOMIC_SEQ_CST);
+ }
+
+ bool decRef() {
+ return 0 == __atomic_sub_fetch(&refcount, 1, __ATOMIC_SEQ_CST);
+ }
+ };
+
+ static void acquireOrderMaintInfo(OrderMaintenanceInfo* ord) {
+ if (!ord) return;
+ ord->incRef();
+ }
+
+ static void releaseOrderMaintInfo(OrderMaintenanceInfo* ord) {
+ if (!ord) return;
+ if (ord->decRef()) delete ord;
+ }
+
template <class T>
class DispatchableHandleInfo {
public:
T underlying;
VulkanDispatch* dispatch = nullptr;
bool ownDispatch = false;
+ OrderMaintenanceInfo* ordMaintInfo = nullptr;
};
#define DEFINE_BOXED_HANDLE_TYPE_TAG(type) \
@@ -3990,10 +4015,15 @@
item.underlying = (uint64_t)underlying; \
item.dispatch = dispatch ? dispatch : new VulkanDispatch; \
item.ownDispatch = ownDispatch; \
+ item.ordMaintInfo = new OrderMaintenanceInfo; \
auto res = (type)newGlobalHandle(item, Tag_##type); \
return res; \
} \
void delete_boxed_##type(type boxed) { \
+ auto elt = mGlobalHandleStore.getLocked( \
+ (uint64_t)(uintptr_t)boxed); \
+ if (!elt) return; \
+ releaseOrderMaintInfo(elt->ordMaintInfo); \
mGlobalHandleStore.remove((uint64_t)boxed); \
} \
type unbox_##type(type boxed) { \
@@ -4002,6 +4032,14 @@
if (!elt) return VK_NULL_HANDLE; \
return (type)elt->underlying; \
} \
+ OrderMaintenanceInfo* ordmaint_##type(type boxed) { \
+ auto elt = mGlobalHandleStore.getLocked( \
+ (uint64_t)(uintptr_t)boxed); \
+ if (!elt) return 0; \
+ auto info = elt->ordMaintInfo; \
+ if (!info) return 0; \
+ acquireOrderMaintInfo(info); return info; \
+ } \
type unboxed_to_boxed_##type(type unboxed) { \
return (type)mGlobalHandleStore.getBoxedFromUnboxedLocked( \
(uint64_t)(uintptr_t)unboxed); \
@@ -5390,7 +5428,6 @@
PFN_vkUseIOSurfaceMVK m_useIOSurfaceFunc = nullptr;
Lock mLock;
- ConditionVariable mCvWaitSequenceNumber;
// We always map the whole size on host.
// This makes it much easier to implement