diff options
Diffstat (limited to 'runtime/monitor_pool_test.cc')
-rw-r--r-- | runtime/monitor_pool_test.cc | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/runtime/monitor_pool_test.cc b/runtime/monitor_pool_test.cc new file mode 100644 index 0000000..cddc245 --- /dev/null +++ b/runtime/monitor_pool_test.cc @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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 "monitor_pool.h" + +#include "common_runtime_test.h" + +namespace art { + +class MonitorPoolTest : public CommonRuntimeTest {}; + +class RandGen { + public: + explicit RandGen(uint32_t seed) : val_(seed) {} + + uint32_t next() { + val_ = val_ * 48271 % 2147483647 + 13; + return val_; + } + + uint32_t val_; +}; + +static void VerifyMonitor(Monitor* mon, Thread* self) { + // Check whether the monitor id is correct. + EXPECT_EQ(MonitorPool::MonitorIdFromMonitor(mon), mon->GetMonitorId()); + // Check whether the monitor id agrees with the compuation. + EXPECT_EQ(MonitorPool::ComputeMonitorId(mon, self), mon->GetMonitorId()); + // Check whether we can use the monitor ID to get the monitor. + EXPECT_EQ(mon, MonitorPool::MonitorFromMonitorId(mon->GetMonitorId())); +} + +TEST_F(MonitorPoolTest, MonitorPoolTest) { + std::vector<Monitor*> monitors; + RandGen r(0x1234); + + // 1) Create and release monitors without increasing the storage. + + // Number of max alive monitors before resize. + // Note: for correct testing, make sure this is corresponding to monitor-pool's initial size. + const size_t kMaxUsage = 28; + + Thread* self = Thread::Current(); + ScopedObjectAccess soa(self); + + // Allocate and release monitors. + for (size_t i = 0; i < 1000 ; i++) { + bool alloc; + if (monitors.size() == 0) { + alloc = true; + } else if (monitors.size() == kMaxUsage) { + alloc = false; + } else { + // Random decision. + alloc = r.next() % 2 == 0; + } + + if (alloc) { + Monitor* mon = MonitorPool::CreateMonitor(self, self, nullptr, static_cast<int32_t>(i)); + monitors.push_back(mon); + + VerifyMonitor(mon, self); + } else { + // Release a random monitor. + size_t index = r.next() % monitors.size(); + Monitor* mon = monitors[index]; + monitors.erase(monitors.begin() + index); + + // Recheck the monitor. + VerifyMonitor(mon, self); + + MonitorPool::ReleaseMonitor(self, mon); + } + } + + // Loop some time. + + for (size_t i = 0; i < 10; ++i) { + // 2.1) Create enough monitors to require new chunks. + size_t target_size = monitors.size() + 2*kMaxUsage; + while (monitors.size() < target_size) { + Monitor* mon = MonitorPool::CreateMonitor(self, self, nullptr, + static_cast<int32_t>(-monitors.size())); + monitors.push_back(mon); + + VerifyMonitor(mon, self); + } + + // 2.2) Verify all monitors. + for (Monitor* mon : monitors) { + VerifyMonitor(mon, self); + } + + // 2.3) Release a number of monitors randomly. + for (size_t j = 0; j < kMaxUsage; j++) { + // Release a random monitor. + size_t index = r.next() % monitors.size(); + Monitor* mon = monitors[index]; + monitors.erase(monitors.begin() + index); + + MonitorPool::ReleaseMonitor(self, mon); + } + } + + // Check and release all remaining monitors. + for (Monitor* mon : monitors) { + VerifyMonitor(mon, self); + MonitorPool::ReleaseMonitor(self, mon); + } +} + +} // namespace art |