blob: 61d614aa4a2d6c2509686b39dea79cf7321e0c0a [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301/*
2 * Copyright (c) 2019, Infosys Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef INCLUDE_CMN_MEMPOOLMANAGER_H_
18#define INCLUDE_CMN_MEMPOOLMANAGER_H_
19
20#include <cstdint>
21#include <memory>
22#include <cstring>
23
24namespace cmn {
25 namespace memPool {
26 template <typename T>
27 class MemBlock
28 {
29 public:
30 union Data {
31 MemBlock<T>* next_mp;
32 alignas(alignof(T)) uint8_t dataBlock_m[sizeof(T)];
33 };
34
35 MemBlock() { memset(data_m.dataBlock_m, 0, sizeof(T)); }
36
37 void reset() { memset(data_m.dataBlock_m, 0, sizeof(T)); }
38
39 MemBlock<T>* getNextMemBlock() { return data_m.next_mp; }
40 void setNextMemBlock(MemBlock<T>* nxtBlk_p) { data_m.next_mp = nxtBlk_p; }
41
42 T* getDataBlock() { return (reinterpret_cast<T*> (data_m.dataBlock_m)); }
43
44 private:
45 Data data_m;
46 };
47
48 template <typename T>
49 class MemChunk
50 {
51 public:
52
53 MemChunk(uint32_t numOfBlocks)
54 {
55 std::unique_ptr<MemBlock<T>[]> blkArray_p(new MemBlock<T>[numOfBlocks]);
56 blockArray_mpa.reset(blkArray_p.release());
57
58 uint32_t i = 1;
59 for (; i < numOfBlocks; i++)
60 {
61 blockArray_mpa[i-1].setNextMemBlock(&blockArray_mpa[i]);
62 }
63 blockArray_mpa[i].setNextMemBlock(NULL);
64 }
65
66 MemBlock<T>* getMemBlockArray() { return blockArray_mpa.get(); }
67
68 void setNextMemChunk(std::unique_ptr<MemChunk> &&nxtChunk_p) { nextMemChunk_mp.reset(nxtChunk_p.release()); }
69
70 private:
71 std::unique_ptr<MemChunk<T>> nextMemChunk_mp;
72 std::unique_ptr<MemBlock<T>[]> blockArray_mpa;
73 };
74
75 template <typename T>
76 class MemPoolManager
77 {
78 public:
79 MemPoolManager(size_t chunkSize):chunkSize_m(chunkSize),
80 currentChunk_mp(new MemChunk<T>(chunkSize)),
81 freeList_mp(currentChunk_mp->getMemBlockArray())
82 {
83
84 }
85
86 template <typename... Args> T* allocate(Args &&... args)
87 {
88 if (freeList_mp == NULL)
89 {
90 std::unique_ptr<MemChunk<T>> newChunk_p (new MemChunk<T>(chunkSize_m));
91 newChunk_p->setNextMemChunk(std::move(currentChunk_mp));
92 currentChunk_mp.reset(newChunk_p.release());
93
94 freeList_mp = currentChunk_mp->getMemBlockArray();
95 }
96 MemBlock<T>* currentBlock_p = freeList_mp;
97 freeList_mp = freeList_mp->getNextMemBlock();
98
99 T* dataBlock_p = currentBlock_p->getDataBlock();
100
101 new (dataBlock_p) T(std::forward<Args>(args)...);
102 return dataBlock_p;
103 }
104
105 void free(T* data_p)
106 {
107 data_p->T::~T();
108 MemBlock<T>* currentBlock_p = reinterpret_cast<MemBlock<T>*>(data_p);
109
110 currentBlock_p->reset();
111
112 currentBlock_p->setNextMemBlock(freeList_mp);
113 freeList_mp = currentBlock_p;
114 }
115 private:
116 size_t chunkSize_m;
117 std::unique_ptr<MemChunk<T>> currentChunk_mp;
118 MemBlock<T>* freeList_mp;
119 };
120 }
121}
122
123
124#endif /* INCLUDE_CMN_MEMPOOLMANAGER_H_ */