1 /** 2 * Copyright (c) 2021-2022 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 "runtime/monitor_pool.h" 17 18 #include "runtime/include/object_header.h" 19 #include "runtime/include/runtime.h" 20 #include "runtime/mark_word.h" 21 #include "runtime/monitor.h" 22 23 namespace panda { 24 CreateMonitor(ObjectHeader * obj)25Monitor *MonitorPool::CreateMonitor(ObjectHeader *obj) 26 { 27 os::memory::LockHolder lock(pool_lock_); 28 for (Monitor::MonitorId i = 0; i < MAX_MONITOR_ID; i++) { 29 last_id_ = (last_id_ + 1) % MAX_MONITOR_ID; 30 if (monitors_.count(last_id_) == 0) { 31 auto monitor = allocator_->New<Monitor>(last_id_); 32 if (monitor == nullptr) { 33 return nullptr; 34 } 35 monitors_[last_id_] = monitor; 36 monitor->SetObject(obj); 37 return monitor; 38 } 39 } 40 LOG(FATAL, RUNTIME) << "Out of MonitorPool indexes"; 41 UNREACHABLE(); 42 } 43 LookupMonitor(Monitor::MonitorId id)44Monitor *MonitorPool::LookupMonitor(Monitor::MonitorId id) 45 { 46 os::memory::LockHolder lock(pool_lock_); 47 auto it = monitors_.find(id); 48 if (it != monitors_.end()) { 49 return it->second; 50 } 51 return nullptr; 52 } 53 FreeMonitor(Monitor::MonitorId id)54void MonitorPool::FreeMonitor(Monitor::MonitorId id) 55 { 56 os::memory::LockHolder lock(pool_lock_); 57 auto it = monitors_.find(id); 58 if (it != monitors_.end()) { 59 auto *monitor = it->second; 60 monitors_.erase(it); 61 allocator_->Delete(monitor); 62 } 63 } 64 DeflateMonitors()65void MonitorPool::DeflateMonitors() 66 { 67 os::memory::LockHolder lock(pool_lock_); 68 for (auto monitor_iter = monitors_.begin(); monitor_iter != monitors_.end();) { 69 auto monitor = monitor_iter->second; 70 if (monitor->DeflateInternal()) { 71 monitor_iter = monitors_.erase(monitor_iter); 72 allocator_->Delete(monitor); 73 } else { 74 monitor_iter++; 75 } 76 } 77 } 78 ReleaseMonitors(MTManagedThread * thread)79void MonitorPool::ReleaseMonitors(MTManagedThread *thread) 80 { 81 os::memory::LockHolder lock(pool_lock_); 82 for (auto &it : monitors_) { 83 auto *monitor = it.second; 84 // Recursive lock is possible 85 while (monitor->GetOwner() == thread) { 86 monitor->Release(thread); 87 } 88 } 89 } 90 GetEnteredMonitorsIds(MTManagedThread * thread)91PandaSet<Monitor::MonitorId> MonitorPool::GetEnteredMonitorsIds(MTManagedThread *thread) 92 { 93 PandaSet<Monitor::MonitorId> entered_monitors_ids; 94 os::memory::LockHolder lock(pool_lock_); 95 for (auto &it : monitors_) { 96 auto *monitor = it.second; 97 if (monitor->GetOwner() == thread) { 98 entered_monitors_ids.insert(monitor->GetId()); 99 } 100 } 101 return entered_monitors_ids; 102 } 103 104 } // namespace panda 105