static void test_memory_pool(skiatest::Reporter* reporter) { // prealloc and min alloc sizes for the pool static const size_t gSizes[][2] = { {0, 0}, {10 * sizeof(A), 20 * sizeof(A)}, {100 * sizeof(A), 100 * sizeof(A)}, {500 * sizeof(A), 500 * sizeof(A)}, {10000 * sizeof(A), 0}, {1, 100 * sizeof(A)}, }; // different percentages of creation vs deletion static const float gCreateFraction[] = {1.f, .95f, 0.75f, .5f}; // number of create/destroys per test static const int kNumIters = 20000; // check that all the values stored in A objects are correct after this // number of iterations static const int kCheckPeriod = 500; SkRandom r; for (size_t s = 0; s < SK_ARRAY_COUNT(gSizes); ++s) { A::SetAllocator(gSizes[s][0], gSizes[s][1]); for (size_t c = 0; c < SK_ARRAY_COUNT(gCreateFraction); ++c) { SkTDArray<Rec> instanceRecs; for (int i = 0; i < kNumIters; ++i) { float createOrDestroy = r.nextUScalar1(); if (createOrDestroy < gCreateFraction[c] || 0 == instanceRecs.count()) { Rec* rec = instanceRecs.append(); rec->fInstance = A::Create(&r); rec->fValue = static_cast<int>(r.nextU()); rec->fInstance->setValues(rec->fValue); } else { int d = r.nextRangeU(0, instanceRecs.count() - 1); Rec& rec = instanceRecs[d]; REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue)); delete rec.fInstance; instanceRecs.removeShuffle(d); } if (0 == i % kCheckPeriod) { for (int r = 0; r < instanceRecs.count(); ++r) { Rec& rec = instanceRecs[r]; REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue)); } } } for (int i = 0; i < instanceRecs.count(); ++i) { Rec& rec = instanceRecs[i]; REPORTER_ASSERT(reporter, rec.fInstance->checkValues(rec.fValue)); delete rec.fInstance; } #ifdef SK_ENABLE_INST_COUNT REPORTER_ASSERT(reporter, !A::GetInstanceCount()); #endif } } }