1 /* Copyright (c) 2021 Samsung Electronics Co., Ltd. All Rights Reserved
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "luci_interpreter/MemoryManager.h"
18 #ifndef LUCI_INTERPRETER_BUDDY_MEMORY_MANAGER_H
19 #define LUCI_INTERPRETER_BUDDY_MEMORY_MANAGER_H
21 namespace luci_interpreter
24 class BuddyMemoryManager : public IMemoryManager
27 BuddyMemoryManager(uint8_t *memory_start, int32_t memSize);
29 void allocate_memory(luci_interpreter::Tensor &tensor) final;
30 void release_memory(luci_interpreter::Tensor &tensor) final;
45 Block *_free_blocks[32]{};
47 static int32_t lowerLog2(uint32_t val)
56 void addToBlocks(Block *block, int32_t l)
61 block->next_free = _free_blocks[l];
62 _free_blocks[l] = block;
65 void removeFromBlocks(const Block *block, int32_t l)
70 Block *tmp = _free_blocks[l];
74 _free_blocks[l] = block->next_free;
80 if (tmp->next_free == block)
82 tmp->next_free = block->next_free;
90 void divideBlock(Block *block, int32_t l)
92 int32_t size = ((block->size + sizeof(Block)) / 2) - sizeof(Block);
94 removeFromBlocks(block, l);
96 // there is no need to add to the free_blocks list here
97 block->is_free = true;
102 buddy = (Block *)((uint8_t *)block + sizeof(Block) + size);
103 buddy->is_free = true;
107 addToBlocks(buddy, l - 1);
110 Block *mergeBlock(Block *block)
114 const int32_t l = lowerLog2(block->size + sizeof(Block));
116 const int64_t address = ((uint8_t *)block - (uint8_t *)_start_block);
117 buddy = (Block *)((address ^ (1 << l)) + (uint8_t *)_start_block);
119 if (!buddy->is_free || buddy->size != block->size)
129 removeFromBlocks(block, l);
130 removeFromBlocks(buddy, l);
132 block->size = block->size * 2 + sizeof(Block);
133 block->is_free = true;
136 addToBlocks(block, l + 1);
142 } // namespace luci_interpreter
144 #endif // LUCI_INTERPRETER_BUDDY_MEMORY_MANAGER_H