174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe/*
274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * Copyright (C) 2014 The Android Open Source Project
374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe *
474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * you may not use this file except in compliance with the License.
674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * You may obtain a copy of the License at
774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe *
874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe *
1074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * Unless required by applicable law or agreed to in writing, software
1174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
1274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * See the License for the specific language governing permissions and
1474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe * limitations under the License.
1574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe */
1674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
1774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe#include "monitor_pool.h"
1874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
1974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe#include "common_runtime_test.h"
20e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "scoped_thread_state_change.h"
21e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "thread-inl.h"
2274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
2374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampenamespace art {
2474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
2574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampeclass MonitorPoolTest : public CommonRuntimeTest {};
2674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
2774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampeclass RandGen {
2874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe public:
2974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  explicit RandGen(uint32_t seed) : val_(seed) {}
3074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
3174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  uint32_t next() {
3274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    val_ = val_ * 48271 % 2147483647 + 13;
3374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    return val_;
3474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  }
3574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
3674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  uint32_t val_;
3774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe};
3874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
3974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampestatic void VerifyMonitor(Monitor* mon, Thread* self) {
4074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Check whether the monitor id is correct.
4174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  EXPECT_EQ(MonitorPool::MonitorIdFromMonitor(mon), mon->GetMonitorId());
4274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Check whether the monitor id agrees with the compuation.
4374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  EXPECT_EQ(MonitorPool::ComputeMonitorId(mon, self), mon->GetMonitorId());
4474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Check whether we can use the monitor ID to get the monitor.
4574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  EXPECT_EQ(mon, MonitorPool::MonitorFromMonitorId(mon->GetMonitorId()));
4674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe}
4774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
4874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas GampeTEST_F(MonitorPoolTest, MonitorPoolTest) {
4974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  std::vector<Monitor*> monitors;
5074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  RandGen r(0x1234);
5174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
5274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // 1) Create and release monitors without increasing the storage.
5374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
5474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Number of max alive monitors before resize.
5574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Note: for correct testing, make sure this is corresponding to monitor-pool's initial size.
5674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  const size_t kMaxUsage = 28;
5774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
5874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  Thread* self = Thread::Current();
5974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  ScopedObjectAccess soa(self);
6074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
6174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Allocate and release monitors.
6274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  for (size_t i = 0; i < 1000 ; i++) {
6374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    bool alloc;
6474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    if (monitors.size() == 0) {
6574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      alloc = true;
6674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    } else if (monitors.size() == kMaxUsage) {
6774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      alloc = false;
6874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    } else {
6974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      // Random decision.
7074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      alloc = r.next() % 2 == 0;
7174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    }
7274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
7374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    if (alloc) {
7474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      Monitor* mon = MonitorPool::CreateMonitor(self, self, nullptr, static_cast<int32_t>(i));
7574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      monitors.push_back(mon);
7674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
7774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      VerifyMonitor(mon, self);
7874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    } else {
7974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      // Release a random monitor.
8074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      size_t index = r.next() % monitors.size();
8174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      Monitor* mon = monitors[index];
8274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      monitors.erase(monitors.begin() + index);
8374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
8474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      // Recheck the monitor.
8574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      VerifyMonitor(mon, self);
8674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
8774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      MonitorPool::ReleaseMonitor(self, mon);
8874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    }
8974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  }
9074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
9174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Loop some time.
9274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
9374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  for (size_t i = 0; i < 10; ++i) {
9474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    // 2.1) Create enough monitors to require new chunks.
9574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    size_t target_size = monitors.size() + 2*kMaxUsage;
9674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    while (monitors.size() < target_size) {
9774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      Monitor* mon = MonitorPool::CreateMonitor(self, self, nullptr,
9874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe                                                static_cast<int32_t>(-monitors.size()));
9974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      monitors.push_back(mon);
10074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
10174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      VerifyMonitor(mon, self);
10274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    }
10374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
10474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    // 2.2) Verify all monitors.
10574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    for (Monitor* mon : monitors) {
10674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      VerifyMonitor(mon, self);
10774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    }
10874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
10974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    // 2.3) Release a number of monitors randomly.
11074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    for (size_t j = 0; j < kMaxUsage; j++) {
11174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      // Release a random monitor.
11274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      size_t index = r.next() % monitors.size();
11374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      Monitor* mon = monitors[index];
11474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      monitors.erase(monitors.begin() + index);
11574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
11674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe      MonitorPool::ReleaseMonitor(self, mon);
11774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    }
11874240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  }
11974240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
12074240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  // Check and release all remaining monitors.
12174240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  for (Monitor* mon : monitors) {
12274240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    VerifyMonitor(mon, self);
12374240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe    MonitorPool::ReleaseMonitor(self, mon);
12474240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe  }
12574240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe}
12674240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe
12774240819ae09e29b2753ef38f4eb4be1c2762e2eAndreas Gampe}  // namespace art
128