* Copyright (c) 2021-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "libarkbase/macros.h"
#include "libarkbase/utils/logger.h"
#include "runtime/include/locks.h"
#include "runtime/include/mutator.h"
#include <memory>
#if defined(USE_ADDRESS_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
namespace ark {
static bool g_isInitialized = false;
os::memory::Mutex *Locks::customTlsLock_ = nullptr;
os::memory::Mutex *Locks::userSuspensionLock_ = nullptr;
void Locks::Initialize()
{
if (!g_isInitialized) {
Locks::customTlsLock_ = new os::memory::Mutex();
Locks::userSuspensionLock_ = new os::memory::Mutex();
g_isInitialized = true;
}
}
MutatorLock *Locks::NewMutatorLock()
{
auto *lock = new MutatorLock();
#if defined(USE_ADDRESS_SANITIZER)
__lsan_ignore_object(lock);
#endif
return lock;
}
#ifndef NDEBUG
void MutatorLock::ReadLock()
{
ASSERT(!HasLock());
LockT::ReadLock();
LOG(DEBUG, RUNTIME) << "MutatorLock::ReadLock";
Mutator::GetCurrent()->SetLockState(RDLOCK);
}
void MutatorLock::WriteLock()
{
ASSERT(!HasLock());
LockT::WriteLock();
LOG(DEBUG, RUNTIME) << "MutatorLock::WriteLock";
Mutator::GetCurrent()->SetLockState(WRLOCK);
}
bool MutatorLock::TryReadLock()
{
bool ret = LockT::TryReadLock();
LOG(DEBUG, RUNTIME) << "MutatorLock::TryReadLock";
if (ret) {
Mutator::GetCurrent()->SetLockState(RDLOCK);
}
return ret;
}
bool MutatorLock::TryWriteLock()
{
bool ret = LockT::TryWriteLock();
LOG(DEBUG, RUNTIME) << "MutatorLock::TryWriteLock";
if (ret) {
if (LIKELY(Mutator::GetCurrent() != nullptr)) {
Mutator::GetCurrent()->SetLockState(WRLOCK);
}
}
return ret;
}
void MutatorLock::Unlock()
{
if (LIKELY(Mutator::GetCurrent() != nullptr)) {
ASSERT(HasLock());
}
LockT::Unlock();
LOG(DEBUG, RUNTIME) << "MutatorLock::Unlock";
if (LIKELY(Mutator::GetCurrent() != nullptr)) {
Mutator::GetCurrent()->SetLockState(UNLOCKED);
}
}
MutatorLock::MutatorLockState MutatorLock::GetState() const
{
return Mutator::GetCurrent()->GetLockState();
}
bool MutatorLock::HasLock() const
{
auto state = Mutator::GetCurrent()->GetLockState();
return state == RDLOCK || state == WRLOCK;
}
#endif
}