• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)25 Monitor *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)44 Monitor *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)54 void 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()65 void 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)79 void 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)91 PandaSet<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