1 // Copyright 2024 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #include "pw_allocator/benchmarks/benchmark.h" 16 17 #include "pw_allocator/fragmentation.h" 18 #include "pw_assert/check.h" 19 20 namespace pw::allocator::internal { 21 22 // GenericBlockAllocatorBenchmark methods 23 BeforeAllocate(const Layout & layout)24void GenericBlockAllocatorBenchmark::BeforeAllocate(const Layout& layout) { 25 size_ = layout.size(); 26 DoBefore(); 27 } 28 AfterAllocate(const void * ptr)29void GenericBlockAllocatorBenchmark::AfterAllocate(const void* ptr) { 30 DoAfter(); 31 if (ptr == nullptr) { 32 data_.failed = true; 33 } else { 34 ++num_allocations_; 35 } 36 Update(); 37 } 38 BeforeDeallocate(const void * ptr)39void GenericBlockAllocatorBenchmark::BeforeDeallocate(const void* ptr) { 40 size_ = GetBlockInnerSize(ptr); 41 DoBefore(); 42 } 43 AfterDeallocate()44void GenericBlockAllocatorBenchmark::AfterDeallocate() { 45 DoAfter(); 46 data_.failed = false; 47 PW_CHECK(num_allocations_ != 0); 48 --num_allocations_; 49 Update(); 50 } 51 BeforeReallocate(const Layout & layout)52void GenericBlockAllocatorBenchmark::BeforeReallocate(const Layout& layout) { 53 size_ = layout.size(); 54 DoBefore(); 55 } 56 AfterReallocate(const void * new_ptr)57void GenericBlockAllocatorBenchmark::AfterReallocate(const void* new_ptr) { 58 DoAfter(); 59 data_.failed = new_ptr == nullptr; 60 Update(); 61 } 62 DoBefore()63void GenericBlockAllocatorBenchmark::DoBefore() { 64 start_ = chrono::SystemClock::now(); 65 } 66 DoAfter()67void GenericBlockAllocatorBenchmark::DoAfter() { 68 auto finish = chrono::SystemClock::now(); 69 PW_ASSERT(start_.has_value()); 70 auto elapsed = finish - start_.value(); 71 data_.nanoseconds = 72 std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count(); 73 74 IterateOverBlocks(data_); 75 Fragmentation fragmentation = GetBlockFragmentation(); 76 data_.fragmentation = CalculateFragmentation(fragmentation); 77 } 78 Update()79void GenericBlockAllocatorBenchmark::Update() { 80 measurements_.GetByCount(num_allocations_).Update(data_); 81 measurements_.GetByFragmentation(data_.fragmentation).Update(data_); 82 measurements_.GetBySize(size_).Update(data_); 83 } 84 85 } // namespace pw::allocator::internal 86