OSDN Git Service

Merge "Use memory chunks for monitors on LP64"
[android-x86/art.git] / runtime / monitor_pool_test.cc
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "monitor_pool.h"
18
19 #include "common_runtime_test.h"
20
21 namespace art {
22
23 class MonitorPoolTest : public CommonRuntimeTest {};
24
25 class RandGen {
26  public:
27   explicit RandGen(uint32_t seed) : val_(seed) {}
28
29   uint32_t next() {
30     val_ = val_ * 48271 % 2147483647 + 13;
31     return val_;
32   }
33
34   uint32_t val_;
35 };
36
37 static void VerifyMonitor(Monitor* mon, Thread* self) {
38   // Check whether the monitor id is correct.
39   EXPECT_EQ(MonitorPool::MonitorIdFromMonitor(mon), mon->GetMonitorId());
40   // Check whether the monitor id agrees with the compuation.
41   EXPECT_EQ(MonitorPool::ComputeMonitorId(mon, self), mon->GetMonitorId());
42   // Check whether we can use the monitor ID to get the monitor.
43   EXPECT_EQ(mon, MonitorPool::MonitorFromMonitorId(mon->GetMonitorId()));
44 }
45
46 TEST_F(MonitorPoolTest, MonitorPoolTest) {
47   std::vector<Monitor*> monitors;
48   RandGen r(0x1234);
49
50   // 1) Create and release monitors without increasing the storage.
51
52   // Number of max alive monitors before resize.
53   // Note: for correct testing, make sure this is corresponding to monitor-pool's initial size.
54   const size_t kMaxUsage = 28;
55
56   Thread* self = Thread::Current();
57   ScopedObjectAccess soa(self);
58
59   // Allocate and release monitors.
60   for (size_t i = 0; i < 1000 ; i++) {
61     bool alloc;
62     if (monitors.size() == 0) {
63       alloc = true;
64     } else if (monitors.size() == kMaxUsage) {
65       alloc = false;
66     } else {
67       // Random decision.
68       alloc = r.next() % 2 == 0;
69     }
70
71     if (alloc) {
72       Monitor* mon = MonitorPool::CreateMonitor(self, self, nullptr, static_cast<int32_t>(i));
73       monitors.push_back(mon);
74
75       VerifyMonitor(mon, self);
76     } else {
77       // Release a random monitor.
78       size_t index = r.next() % monitors.size();
79       Monitor* mon = monitors[index];
80       monitors.erase(monitors.begin() + index);
81
82       // Recheck the monitor.
83       VerifyMonitor(mon, self);
84
85       MonitorPool::ReleaseMonitor(self, mon);
86     }
87   }
88
89   // Loop some time.
90
91   for (size_t i = 0; i < 10; ++i) {
92     // 2.1) Create enough monitors to require new chunks.
93     size_t target_size = monitors.size() + 2*kMaxUsage;
94     while (monitors.size() < target_size) {
95       Monitor* mon = MonitorPool::CreateMonitor(self, self, nullptr,
96                                                 static_cast<int32_t>(-monitors.size()));
97       monitors.push_back(mon);
98
99       VerifyMonitor(mon, self);
100     }
101
102     // 2.2) Verify all monitors.
103     for (Monitor* mon : monitors) {
104       VerifyMonitor(mon, self);
105     }
106
107     // 2.3) Release a number of monitors randomly.
108     for (size_t j = 0; j < kMaxUsage; j++) {
109       // Release a random monitor.
110       size_t index = r.next() % monitors.size();
111       Monitor* mon = monitors[index];
112       monitors.erase(monitors.begin() + index);
113
114       MonitorPool::ReleaseMonitor(self, mon);
115     }
116   }
117
118   // Check and release all remaining monitors.
119   for (Monitor* mon : monitors) {
120     VerifyMonitor(mon, self);
121     MonitorPool::ReleaseMonitor(self, mon);
122   }
123 }
124
125 }  // namespace art