src/libANGLE/GlobalMutex.cpp


Log

Author Commit Date CI Message
Yuxin Hu e5619a5c 2024-10-15T18:27:00 Use EGL sync global lock for all EGL*sync entrypoint calls To free EGL sync operations from waiting for other EGL calls to finish, we use a separate global lock for EGL*sync entrypoints. Below angle::SimpleMutex are added to protect resources that may have race condition due to being accessed by EGL*sync calls and non EGL*sync calls at the same time: 1. Display::mContextMapMutex that protects Display::mState.contextMap 2. static angle::base::NoDestructor<angle::SimpleMutex> anglePlatformDisplayMapMutex that protects static angle::base::NoDestructor<ANGLEPlatformDisplayMap> displays 3. static angle::base::NoDestructor<angle::SimpleMutex> devicePlatformDisplayMapMutex that protects static angle::base::NoDestructor<DevicePlatformDisplayMap> displays EGL_Terminate() entry point takes both global lock and global egl sync lock. This is to protect Display::mSyncMap, Display::mSyncPools, and Display::mSyncHandleAllocator being get cleared by thread 1 calling eglTerminate, while they are still accessed by thread 2 through a call such as eglCreateSync. So that we won't have thread 2 finish validating the sync object with syncID exists in Display::mSyncMap, but then find the mSyncMap.find(syncID) returns a nullptr due to the mSyncMap is cleared by thread 1. Same applies to EGL_LabelObjectKHR(), EGL_ReleaseThread(), ThreadCleanupCallback(). EGL_Initialize() writes to Display::mInitialized. This is read by EGL Sync API validation functions. EGL_Initialize() also takes both global lock and global sync lock to prevent race conditions between EGL_Initialize() and EGL Sync APIs. When ANGLE_CAPTURE_ENABLED is enabled, fall back to global lock, as the CaptureEGLCallToFrameCapture() touches many resources (e.g. mMaxAccessedResourceIDs, mFrameCalls) that could lead to race conditions without a global lock. Bug: b/362604439 Change-Id: Ic0d54a4cd66743bcd0f48f41f247dd223cff2f5e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5933570 Reviewed-by: Roman Lavrov <romanl@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Igor Nazarov <i.nazarov@samsung.com> Commit-Queue: Yuxin Hu <yuxinhu@google.com>
Igor Nazarov 25ce3dfe 2023-06-29T15:51:55 Use compare_exchange_weak() in AllocateGlobalMutexImpl() Speculative fix of the crash. New logic will ensure that `currentMutex` is not `nullptr` when returned from `AllocateGlobalMutexImpl()` Also removed explicit memory order for safety (no actual difference in generated code on ARM64/x86-64, but ARM generates less instructions). Bug: chromium:1457915 Change-Id: I8d932ee499f9d8ee4e38ab2173f4f1cefd0aa294 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4650794 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Igor Nazarov 8b97c8d3 2023-03-31T15:54:40 Implement build option for load-time GlobalMutex allocation. Performance difference on S906B for 1000'000 `eglGetError()` calls. Before: 26.5 ms After: 23.8 ms (Assuming `angle::FastMutex2` is used). Potentially can be enabled for other platforms. Bug: angleproject:8101 Change-Id: Ic2037edaae6da82dbded71288bae250d7981e7d3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4386408 Reviewed-by: Charlie Lao <cclao@google.com> Commit-Queue: Igor Nazarov <i.nazarov@samsung.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Igor Nazarov b22124bd 2023-01-17T17:44:06 Implement new "Global Mutex" functionality. This CL improves performance compared to the existing code as well as allows using non-std mutex implementations. Also acts as a base for future changes. CL adds new build option: angle_enable_global_mutex_recursion = is_android && angle_enable_vulkan "mutex_recursion" work same way as `std::recursive_mutex` before. It will help in situations when Vulkan API may return back to the ANGLE. For example: RenderDoc layer EGL deadlock. Automatic loading of "libVkLayer_GLES_RenderDoc.so" layer causes deadlock in EGL. Recursion stack: #01 pc 000000000029ea80 /vendor/lib64/egl/libGLESv2_angle.so (egl::GlobalMutexHelper::lock(int)+596) #02 pc 000000000029c59c /vendor/lib64/egl/libGLESv2_angle.so (EGL_GetError+32) #04 pc 0000000000062368 /system/lib64/libEGL.so (eglQueryString+20) #05 pc 0000000000508fec /data/local/debug/vulkan/libVkLayer_GLES_RenderDoc.so #20 pc 0000000000016690 /system/lib64/libvulkan.so (vulkan::api::EnumerateInstanceLayerProperties(unsigned int*, VkLayerProperties*)+40) #21 pc 00000000005aa030 /vendor/lib64/egl/libGLESv2_angle.so (rx::RendererVk::initialize(rx::DisplayVk*, egl::Display*, char const*, char const*)+292) #26 pc 000000000029c7e8 /vendor/lib64/egl/libGLESv2_angle.so (EGL_Initialize+192) Additionally, recursive mutex will partially solve Android SurfaceTexture deadlock (angleproject:4354). Some performance numbers for 1000'000 `eglGetError()` calls. Mutex Time (ms.) Android S906B egl::GetGlobalMutex()(std::recursive_mutex) 41.4 (Default) GlobalMutex (std::recursive_mutex) 39.1 (Recursive) GlobalMutex (std::mutex) 34.9 (Debug) GlobalMutex (std::mutex) 34.7 (Default) GlobalMutex (std::mutex) 34.4 Windows egl::GetGlobalMutex()(std::recursive_mutex) 20.5 (Default) GlobalMutex (std::recursive_mutex) 20.0 (Recursive) GlobalMutex (std::mutex) 21.9 (Debug) GlobalMutex (std::mutex) 20.5 (Default) GlobalMutex (std::mutex) 19.9 Note: Recursive GlobalMutex enabled only for Android Vulkan by default. Original fix: https://chromium-review.googlesource.com/c/angle/angle/+/2029218 Bug: angleproject:8101 Bug: angleproject:4354 Test: angle_unittests --gtest_filter=GlobalMutexTest.* Change-Id: I9e9d9b5c598ad1177ffa147ea690bd955946a712 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4401940 Commit-Queue: Igor Nazarov <i.nazarov@samsung.com> Reviewed-by: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>