Test that we can reclaim buffers and pages from the same arena or a different arena. Allocates then frees memory on 'src_core' then allocates on 'dst_core' to force reclamation of memory from src_core's free buffer lists and clean page lists. If 'src_core' or 'dst_core' is -1, randomly switch between cores instead of sticking to a fixed core.
| 1375 | // If 'src_core' or 'dst_core' is -1, randomly switch between cores instead of sticking |
| 1376 | // to a fixed core. |
| 1377 | void BufferPoolTest::TestMemoryReclamation(BufferPool* pool, int src_core, int dst_core) { |
| 1378 | LOG(INFO) << "TestMemoryReclamation " << src_core << " -> " << dst_core; |
| 1379 | const bool rand_src_core = src_core == -1; |
| 1380 | const bool rand_dst_core = dst_core == -1; |
| 1381 | |
| 1382 | BufferPool::ClientHandle clients[MEM_RECLAMATION_NUM_CLIENTS]; |
| 1383 | for (int i = 0; i < MEM_RECLAMATION_NUM_CLIENTS; ++i) { |
| 1384 | ASSERT_OK(pool->RegisterClient(Substitute("test client $0", i), NewFileGroup(), |
| 1385 | &global_reservations_, NULL, MEM_RECLAMATION_CLIENT_RESERVATION, NewProfile(), |
| 1386 | &clients[i])); |
| 1387 | ASSERT_TRUE(clients[i].IncreaseReservation(MEM_RECLAMATION_CLIENT_RESERVATION)); |
| 1388 | } |
| 1389 | |
| 1390 | // Allocate and free the whole pool's buffers on src_core to populate its free lists. |
| 1391 | if (!rand_src_core) CpuTestUtil::PinToCore(src_core); |
| 1392 | vector<BufferPool::BufferHandle> client_buffers[MEM_RECLAMATION_NUM_CLIENTS]; |
| 1393 | AllocateBuffers(pool, &clients[0], 32 * TEST_BUFFER_LEN, |
| 1394 | MEM_RECLAMATION_CLIENT_RESERVATION, &client_buffers[0], rand_src_core); |
| 1395 | AllocateBuffers(pool, &clients[1], 32 * TEST_BUFFER_LEN, |
| 1396 | MEM_RECLAMATION_CLIENT_RESERVATION, &client_buffers[1], rand_src_core); |
| 1397 | FreeBuffers(pool, &clients[0], &client_buffers[0], rand_src_core); |
| 1398 | FreeBuffers(pool, &clients[1], &client_buffers[1], rand_src_core); |
| 1399 | |
| 1400 | // Allocate buffers again on dst_core. Make sure the size is bigger, smaller, and the |
| 1401 | // same size as buffers we allocated earlier to we exercise different code paths. |
| 1402 | if (!rand_dst_core) CpuTestUtil::PinToCore(dst_core); |
| 1403 | AllocateBuffers(pool, &clients[0], 4 * TEST_BUFFER_LEN, |
| 1404 | MEM_RECLAMATION_CLIENT_RESERVATION, &client_buffers[0], rand_dst_core); |
| 1405 | FreeBuffers(pool, &clients[0], &client_buffers[0], rand_dst_core); |
| 1406 | |
| 1407 | // Allocate and unpin the whole pool's buffers as clean pages on src_core to populate |
| 1408 | // its clean page lists. |
| 1409 | if (!rand_src_core) CpuTestUtil::PinToCore(src_core); |
| 1410 | vector<BufferPool::PageHandle> client_pages[MEM_RECLAMATION_NUM_CLIENTS]; |
| 1411 | CreatePages(pool, &clients[0], 32 * TEST_BUFFER_LEN, MEM_RECLAMATION_CLIENT_RESERVATION, |
| 1412 | &client_pages[0], rand_src_core); |
| 1413 | CreatePages(pool, &clients[1], 32 * TEST_BUFFER_LEN, MEM_RECLAMATION_CLIENT_RESERVATION, |
| 1414 | &client_pages[1], rand_src_core); |
| 1415 | for (auto& page : client_pages[0]) pool->Unpin(&clients[0], &page); |
| 1416 | for (auto& page : client_pages[1]) pool->Unpin(&clients[1], &page); |
| 1417 | |
| 1418 | // Allocate the buffers again to force reclamation of the buffers from the clean pages. |
| 1419 | if (!rand_dst_core) CpuTestUtil::PinToCore(dst_core); |
| 1420 | AllocateBuffers(pool, &clients[0], 4 * TEST_BUFFER_LEN, |
| 1421 | MEM_RECLAMATION_CLIENT_RESERVATION, &client_buffers[0], rand_dst_core); |
| 1422 | FreeBuffers(pool, &clients[0], &client_buffers[0]); |
| 1423 | |
| 1424 | // Just for good measure, pin the pages again then destroy them. |
| 1425 | for (auto& page : client_pages[0]) { |
| 1426 | ASSERT_OK(pool->Pin(&clients[0], &page)); |
| 1427 | pool->DestroyPage(&clients[0], &page); |
| 1428 | } |
| 1429 | for (auto& page : client_pages[1]) { |
| 1430 | ASSERT_OK(pool->Pin(&clients[1], &page)); |
| 1431 | pool->DestroyPage(&clients[1], &page); |
| 1432 | } |
| 1433 | for (BufferPool::ClientHandle& client : clients) pool->DeregisterClient(&client); |
| 1434 | } |
nothing calls this directly
no test coverage detected