1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/mutator_lock.h" 17#include "ecmascript/js_thread.h" 18 19namespace panda::ecmascript { 20#ifndef NDEBUG 21void MutatorLock::ReadLock() 22{ 23 ASSERT(!HasLock()); 24 RWLock::ReadLock(); 25 SetState(MutatorLockState::RDLOCK); 26} 27 28void MutatorLock::WriteLock() 29{ 30 ASSERT(!HasLock()); 31 RWLock::WriteLock(); 32 SetState(MutatorLockState::WRLOCK); 33} 34 35bool MutatorLock::TryReadLock() 36{ 37 ASSERT(!HasLock()); 38 bool res = RWLock::TryReadLock(); 39 if (res) { 40 SetState(MutatorLockState::RDLOCK); 41 } 42 return res; 43} 44 45bool MutatorLock::TryWriteLock() 46{ 47 ASSERT(!HasLock()); 48 bool res = RWLock::TryWriteLock(); 49 if (res) { 50 SetState(MutatorLockState::WRLOCK); 51 } 52 return res; 53} 54 55void MutatorLock::Unlock() 56{ 57 ASSERT(HasLock()); 58 RWLock::Unlock(); 59 SetState(MutatorLockState::UNLOCKED); 60} 61 62bool MutatorLock::HasLock() const 63{ 64 return GetState() != MutatorLockState::UNLOCKED; 65} 66 67MutatorLock::MutatorLockState MutatorLock::GetState() const 68{ 69 return JSThread::GetCurrent()->GetMutatorLockState(); 70} 71 72void MutatorLock::SetState(MutatorLock::MutatorLockState newState) 73{ 74 JSThread::GetCurrent()->SetMutatorLockState(newState); 75} 76#endif 77 78void SuspendBarrier::Wait() 79{ 80 while (true) { 81 int32_t curCount = passBarrierCount_.load(std::memory_order_relaxed); 82 if (LIKELY(curCount > 0)) { 83#if defined(PANDA_TARGET_OHOS) 84 sched_yield(); 85#endif 86 } else { 87 // Use seq_cst to synchronize memory. 88 curCount = passBarrierCount_.load(std::memory_order_seq_cst); 89 ASSERT(curCount == 0); 90 break; 91 } 92 } 93} 94 95void SuspendBarrier::PassCount(int32_t delta) 96{ 97 bool done = false; 98 do { 99 int32_t curCount = passBarrierCount_.load(std::memory_order_relaxed); 100 // Reduce value by 1. 101 done = passBarrierCount_.compare_exchange_strong(curCount, curCount + delta); 102 } while (!done); 103} 104} // namespace panda::ecmascript