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 19 namespace panda::ecmascript { 20 #ifndef NDEBUG ReadLock()21void MutatorLock::ReadLock() 22 { 23 ASSERT(!HasLock()); 24 RWLock::ReadLock(); 25 SetState(MutatorLockState::RDLOCK); 26 } 27 WriteLock()28void MutatorLock::WriteLock() 29 { 30 ASSERT(!HasLock()); 31 RWLock::WriteLock(); 32 SetState(MutatorLockState::WRLOCK); 33 } 34 TryReadLock()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 TryWriteLock()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 Unlock()55void MutatorLock::Unlock() 56 { 57 ASSERT(HasLock()); 58 RWLock::Unlock(); 59 SetState(MutatorLockState::UNLOCKED); 60 } 61 HasLock() const62bool MutatorLock::HasLock() const 63 { 64 return GetState() != MutatorLockState::UNLOCKED; 65 } 66 GetState() const67MutatorLock::MutatorLockState MutatorLock::GetState() const 68 { 69 return JSThread::GetCurrent()->GetMutatorLockState(); 70 } 71 SetState(MutatorLock::MutatorLockState newState)72void MutatorLock::SetState(MutatorLock::MutatorLockState newState) 73 { 74 JSThread::GetCurrent()->SetMutatorLockState(newState); 75 } 76 #endif 77 Wait()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 PassCount(int32_t delta)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