1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://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,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <ditto/memory_allocation.h>
16
17 #include <ditto/logger.h>
18
19 #include <sys/mman.h>
20
21 namespace dittosuite {
22
allocate_memory(std::stack<void * > * addresses,size_t size)23 void allocate_memory(std::stack<void*>* addresses, size_t size) {
24 const int protection = PROT_READ | PROT_WRITE;
25 const int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_LOCKED;
26 void* addr = nullptr;
27
28 addr = mmap(NULL, size, protection, flags, -1, 0);
29 if (addr == MAP_FAILED) {
30 PLOGF("mmap failed");
31 }
32
33 addresses->push(addr);
34 LOGD("mmap successful, stack size: " + std::to_string(addresses->size()));
35 }
36
deallocate_memory(std::stack<void * > * addresses,size_t size)37 void deallocate_memory(std::stack<void*>* addresses, size_t size) {
38 while (!addresses->empty()) {
39 void* addr = addresses->top();
40 addresses->pop();
41 if (munmap(addr, size) == -1) {
42 PLOGF("munmap failed");
43 }
44 LOGD("munmap successful, stack size: " + std::to_string(addresses->size()));
45 }
46 }
47
MemoryAllocation(const Params & params,const uint64_t size,const FreePolicy free_policy)48 MemoryAllocation::MemoryAllocation(const Params& params, const uint64_t size,
49 const FreePolicy free_policy)
50 : Instruction(kName, params), size_(size), free_policy_(free_policy) {}
51
~MemoryAllocation()52 MemoryAllocation::~MemoryAllocation() {
53 deallocate_memory(&allocated_addresses_, size_);
54 }
55
RunSingle()56 void MemoryAllocation::RunSingle() {
57 allocate_memory(&allocated_addresses_, size_);
58 }
59
TearDownSingle(bool is_last)60 void MemoryAllocation::TearDownSingle(bool is_last) {
61 switch (free_policy_) {
62 case dittosuite::FreePolicy::kKeep:
63 break;
64 case dittosuite::FreePolicy::kFreeEveryPeriod:
65 deallocate_memory(&allocated_addresses_, size_);
66 break;
67 case dittosuite::FreePolicy::kFreeLastPeriod:
68 if (is_last) {
69 deallocate_memory(&allocated_addresses_, size_);
70 }
71 break;
72 }
73 }
74
75 } // namespace dittosuite
76