ART: Add thread safety test for LargeObjectSpace
Add a test that just calls Alloc and Free repeatedly with multiple
threads, checking whether things are really race-free.
Change-Id: I39ea9e7449e3354b49c3aa11c27fcfeb07acff9f
diff --git a/runtime/gc/space/large_object_space_test.cc b/runtime/gc/space/large_object_space_test.cc
index 23c67ff..f733584 100644
--- a/runtime/gc/space/large_object_space_test.cc
+++ b/runtime/gc/space/large_object_space_test.cc
@@ -24,6 +24,10 @@
class LargeObjectSpaceTest : public SpaceTest {
public:
void LargeObjectTest();
+
+ static constexpr size_t kNumThreads = 10;
+ static constexpr size_t kNumIterations = 1000;
+ void RaceTest();
};
@@ -89,11 +93,64 @@
}
}
+class AllocRaceTask : public Task {
+ public:
+ AllocRaceTask(size_t id, size_t iterations, size_t size, LargeObjectSpace* los) :
+ id_(id), iterations_(iterations), size_(size), los_(los) {}
+
+ void Run(Thread* self) {
+ for (size_t i = 0; i < iterations_ ; ++i) {
+ size_t alloc_size;
+ mirror::Object* ptr = los_->Alloc(self, size_, &alloc_size, nullptr);
+
+ NanoSleep((id_ + 3) * 1000); // (3+id) mu s
+
+ los_->Free(self, ptr);
+ }
+ }
+
+ virtual void Finalize() {
+ delete this;
+ }
+
+ private:
+ size_t id_;
+ size_t iterations_;
+ size_t size_;
+ LargeObjectSpace* los_;
+};
+
+void LargeObjectSpaceTest::RaceTest() {
+ for (size_t los_type = 0; los_type < 2; ++los_type) {
+ LargeObjectSpace* los = nullptr;
+ if (los_type == 0) {
+ los = space::LargeObjectMapSpace::Create("large object space");
+ } else {
+ los = space::FreeListSpace::Create("large object space", nullptr, 128 * MB);
+ }
+
+ Thread* self = Thread::Current();
+ ThreadPool thread_pool("Large object space test thread pool", kNumThreads);
+ for (size_t i = 0; i < kNumThreads; ++i) {
+ thread_pool.AddTask(self, new AllocRaceTask(i, kNumIterations, 16 * KB, los));
+ }
+
+ thread_pool.StartWorkers(self);
+
+ thread_pool.Wait(self, true, false);
+
+ delete los;
+ }
+}
TEST_F(LargeObjectSpaceTest, LargeObjectTest) {
LargeObjectTest();
}
+TEST_F(LargeObjectSpaceTest, RaceTest) {
+ RaceTest();
+}
+
} // namespace space
} // namespace gc
} // namespace art