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