Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 27 additions & 38 deletions stl/inc/mutex
Original file line number Diff line number Diff line change
Expand Up @@ -343,30 +343,25 @@ int _Try_lock_range(const int _First, const int _Last, _LockN&... _LkN) {
return -1;
}

template <class _Lock0, class _Lock1, class _Lock2, class... _LockN>
int _Try_lock1(_Lock0& _Lk0, _Lock1& _Lk1, _Lock2& _Lk2, _LockN&... _LkN) { // try to lock 3 or more locks
return _Try_lock_range(0, sizeof...(_LockN) + 3, _Lk0, _Lk1, _Lk2, _LkN...);
}
_EXPORT_STD template <class _Lock0, class _Lock1, class... _LockN>
_NODISCARD_TRY_CHANGE_STATE int try_lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN) { // try to lock multiple locks
if constexpr (sizeof...(_LockN) == 0) {
// try to lock 2 locks, special case for better codegen and reduced metaprogramming for common case
if (!_Lk0.try_lock()) {
return 0;
}

template <class _Lock0, class _Lock1>
int _Try_lock1(_Lock0& _Lk0, _Lock1& _Lk1) {
// try to lock 2 locks, special case for better codegen and reduced metaprogramming for common case
if (!_Lk0.try_lock()) {
return 0;
}
_Unlock_one_guard<_Lock0> _Guard{_Lk0};
if (!_Lk1.try_lock()) {
return 1;
}

_Unlock_one_guard<_Lock0> _Guard{_Lk0};
if (!_Lk1.try_lock()) {
return 1;
_Guard._Lk_ptr = nullptr;
return -1;
} else {
// try to lock 3 or more locks
return _Try_lock_range(0, sizeof...(_LockN) + 2, _Lk0, _Lk1, _LkN...);
}

_Guard._Lk_ptr = nullptr;
return -1;
}

_EXPORT_STD template <class _Lock0, class _Lock1, class... _LockN>
_NODISCARD_TRY_CHANGE_STATE int try_lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN) { // try to lock multiple locks
return _Try_lock1(_Lk0, _Lk1, _LkN...);
}

template <class... _LockN>
Expand Down Expand Up @@ -399,15 +394,6 @@ int _Lock_attempt(const int _Hard_lock, _LockN&... _LkN) {
return _Failed;
}

template <class _Lock0, class _Lock1, class _Lock2, class... _LockN>
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1, _Lock2& _Lk2, _LockN&... _LkN) {
// lock 3 or more locks, without deadlock
int _Hard_lock = 0;
while (_Hard_lock != -1) {
_Hard_lock = _Lock_attempt(_Hard_lock, _Lk0, _Lk1, _Lk2, _LkN...);
}
}

template <class _Lock0, class _Lock1>
bool _Lock_attempt_small(_Lock0& _Lk0, _Lock1& _Lk1) {
// attempt to lock 2 locks, by first locking _Lk0, and then trying to lock _Lk1 returns whether to try again
Expand All @@ -424,16 +410,19 @@ bool _Lock_attempt_small(_Lock0& _Lk0, _Lock1& _Lk1) {
return true;
}

template <class _Lock0, class _Lock1>
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1) {
// lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
while (_Lock_attempt_small(_Lk0, _Lk1) && _Lock_attempt_small(_Lk1, _Lk0)) { // keep trying
}
}

_EXPORT_STD template <class _Lock0, class _Lock1, class... _LockN>
void lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN) { // lock multiple locks, without deadlock
_Lock_nonmember1(_Lk0, _Lk1, _LkN...);
if constexpr (sizeof...(_LockN) == 0) {
// lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
while (_Lock_attempt_small(_Lk0, _Lk1) && _Lock_attempt_small(_Lk1, _Lk0)) { // keep trying
}
} else {
// lock 3 or more locks, without deadlock
int _Hard_lock = 0;
while (_Hard_lock != -1) {
_Hard_lock = _Lock_attempt(_Hard_lock, _Lk0, _Lk1, _LkN...);
}
}
}

_EXPORT_STD template <class _Mutex>
Expand Down