// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. #include #include #include "runtime/free_list.hpp" #include "runtime/mem_pool.h" #include "runtime/mem_tracker.h" namespace doris { TEST(FreeListTest, Basic) { MemTracker tracker; MemPool pool(&tracker); FreeList list; int allocated_size; uint8_t* free_list_mem = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_EQ(nullptr, free_list_mem); EXPECT_EQ(allocated_size, 0); uint8_t* mem = pool.allocate(FreeList::min_size()); EXPECT_TRUE(mem != NULL); list.add(mem, FreeList::min_size()); free_list_mem = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_EQ(mem, free_list_mem); EXPECT_EQ(allocated_size, FreeList::min_size()); free_list_mem = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_EQ(nullptr, free_list_mem); EXPECT_EQ(allocated_size, 0); // Make 3 allocations and add them to the free list. // Get them all back from the free list, scribbling to the // returned memory in between. // Attempt a 4th allocation from the free list and make sure // we get NULL. // Repeat with the same memory blocks. uint8_t* free_list_mem1 = nullptr; uint8_t* free_list_mem2 = nullptr; uint8_t* free_list_mem3 = nullptr; mem = pool.allocate(FreeList::min_size()); list.add(mem, FreeList::min_size()); mem = pool.allocate(FreeList::min_size()); list.add(mem, FreeList::min_size()); mem = pool.allocate(FreeList::min_size()); list.add(mem, FreeList::min_size()); free_list_mem1 = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_TRUE(free_list_mem1 != NULL); EXPECT_EQ(allocated_size, FreeList::min_size()); bzero(free_list_mem1, FreeList::min_size()); free_list_mem2 = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_TRUE(free_list_mem2 != NULL); EXPECT_EQ(allocated_size, FreeList::min_size()); bzero(free_list_mem2, FreeList::min_size()); free_list_mem3 = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_TRUE(free_list_mem3 != NULL); EXPECT_EQ(allocated_size, FreeList::min_size()); bzero(free_list_mem3, FreeList::min_size()); free_list_mem = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_EQ(NULL, free_list_mem); EXPECT_EQ(allocated_size, 0); list.add(free_list_mem1, FreeList::min_size()); list.add(free_list_mem2, FreeList::min_size()); list.add(free_list_mem3, FreeList::min_size()); free_list_mem1 = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_TRUE(free_list_mem1 != NULL); EXPECT_EQ(allocated_size, FreeList::min_size()); bzero(free_list_mem1, FreeList::min_size()); free_list_mem2 = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_TRUE(free_list_mem2 != NULL); EXPECT_EQ(allocated_size, FreeList::min_size()); bzero(free_list_mem2, FreeList::min_size()); free_list_mem3 = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_TRUE(free_list_mem3 != NULL); EXPECT_EQ(allocated_size, FreeList::min_size()); bzero(free_list_mem3, FreeList::min_size()); free_list_mem = list.allocate(FreeList::min_size(), &allocated_size); EXPECT_EQ(NULL, free_list_mem); EXPECT_EQ(allocated_size, 0); // Try some allocations with different sizes int size1 = FreeList::min_size(); int size2 = FreeList::min_size() * 2; int size4 = FreeList::min_size() * 4; uint8_t* mem1 = pool.allocate(size1); uint8_t* mem2 = pool.allocate(size2); uint8_t* mem4 = pool.allocate(size4); list.add(mem2, size2); free_list_mem = list.allocate(size4, &allocated_size); EXPECT_EQ(NULL, free_list_mem); EXPECT_EQ(allocated_size, 0); free_list_mem = list.allocate(size1, &allocated_size); EXPECT_TRUE(free_list_mem != NULL); EXPECT_EQ(allocated_size, size2); bzero(free_list_mem, size1); free_list_mem = list.allocate(size1, &allocated_size); EXPECT_EQ(NULL, free_list_mem); EXPECT_EQ(allocated_size, 0); list.add(mem2, size2); list.add(mem4, size4); list.add(mem1, size1); free_list_mem = list.allocate(size4, &allocated_size); EXPECT_EQ(mem4, free_list_mem); EXPECT_EQ(allocated_size, size4); bzero(free_list_mem, size4); free_list_mem = list.allocate(size2, &allocated_size); EXPECT_EQ(mem2, free_list_mem); EXPECT_EQ(allocated_size, size2); bzero(free_list_mem, size2); free_list_mem = list.allocate(size1, &allocated_size); EXPECT_EQ(mem1, free_list_mem); EXPECT_EQ(allocated_size, size1); bzero(free_list_mem, size1); } } int main(int argc, char** argv) { #if 0 std::string conffile = std::string(getenv("DORIS_HOME")) + "/conf/be.conf"; if (!doris::config::init(conffile.c_str(), false)) { fprintf(stderr, "error read config file. \n"); return -1; } init_glog("be-test"); #endif ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }