Hash :
d9d583bf
Author :
Date :
2024-04-15T00:24:47
Implement a lock/unlock-only mutex based on futex Pthread mutexes are expensive due to their numerous features. When a mutex only needs to support lock and unlock, its implementation can be much simpler. The implementation in this change is "inspired" by a similar mutex in mesa. Expected uses of this mutex are: - Allowing some OpenGL calls to avoid the share group lock and instead lock the specific shared object they operate on. - Replacing SpinLock in the OpenCL implementation (spin-lock in user space is a bad idea [1]) - Generally anywhere we use std::mutex just to do lock/unlock Tests based on patch authored by Igor Nazarov <i.nazarov@samsung.com> [1]:https://www.realworldtech.com/forum/?threadid=189711&curpostid=189723 Bug: angleproject:8667 Change-Id: I52278c9d19616338c499bbcef6684746caead6ca Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5446558 Reviewed-by: Roman Lavrov <romanl@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
//
// Copyright 2024 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// SimpleMutex.cpp:
// Implementation of SimpleMutex.h.
#include "common/SimpleMutex.h"
#if ANGLE_USE_FUTEX
# include <limits.h>
# include <stdint.h>
# if defined(ANGLE_PLATFORM_LINUX) || defined(ANGLE_PLATFORM_ANDROID)
# include <linux/futex.h>
# include <sys/syscall.h>
# include <unistd.h>
# endif // defined(ANGLE_PLATFORM_LINUX) || defined(ANGLE_PLATFORM_ANDROID)
# if defined(ANGLE_PLATFORM_WINDOWS)
# include <errno.h>
# include <windows.h>
# endif // defined(ANGLE_PLATFORM_WINDOWS)
namespace angle
{
namespace priv
{
# if defined(ANGLE_PLATFORM_LINUX) || defined(ANGLE_PLATFORM_ANDROID)
namespace
{
ANGLE_INLINE void SysFutex(void *addr, int op, int val, int val3)
{
syscall(SYS_futex, addr, op, val, nullptr, nullptr, val3);
}
} // anonymous namespace
void MutexOnFutex::futexWait()
{
SysFutex(&mState, FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG, kBlocked, FUTEX_BITSET_MATCH_ANY);
}
void MutexOnFutex::futexWake()
{
SysFutex(&mState, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, kLocked, 0);
}
# endif // defined(ANGLE_PLATFORM_LINUX) || defined(ANGLE_PLATFORM_ANDROID)
# if defined(ANGLE_PLATFORM_WINDOWS)
void MutexOnFutex::futexWait()
{
int value = kBlocked;
WaitOnAddress(&mState, &value, sizeof(value), INFINITE);
}
void MutexOnFutex::futexWake()
{
WakeByAddressSingle(&mState);
}
# endif // defined(ANGLE_PLATFORM_WINDOWS)
} // namespace priv
} // namespace angle
#endif // ANGLE_USE_FUTEX