1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
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
16 #include "mem_pool.h"
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 /*******************************************************************************
23 Function : MpDestroyMemPool
24
25 Description : This function will be invoked to destroy the memory pool
26 created using MpCreateMemPool.
27
28 Input : pool - memory pool handle
29
30 Output : None
31
32 Return : None
33 *******************************************************************************/
MpDestroyMemPool(struct MemPool * pool)34 void MpDestroyMemPool(struct MemPool *pool)
35 {
36 if (pool == FILLP_NULL_PTR) {
37 return;
38 }
39
40 switch (pool->allocType) {
41 case SPUNGE_ALLOC_TYPE_MALLOC:
42 case SPUNGE_ALLOC_TYPE_CALLOC:
43 SpungeFree(pool, pool->allocType);
44 break;
45 default:
46 break;
47 }
48 return;
49 }
50
51 /*******************************************************************************
52 Function : MpCalMemSize
53
54 Description : This function will be invoked to calculate the memory size
55 required for memory pool, based on size and num.
56
57 Input : itemSize - Size of item
58 itemNum - item number
59
60 Output : None
61
62 Return : Memory size of memory pool.
63 *******************************************************************************/
MpCalMemSize(size_t itemSize,size_t itemNum)64 size_t MpCalMemSize(size_t itemSize, size_t itemNum)
65 {
66 size_t sizePrepare;
67 size_t memSize;
68
69 sizePrepare = itemSize + sizeof(struct MemPoolItem);
70 if ((itemSize == 0) || (sizePrepare < sizeof(struct MemPoolItem))) {
71 return 0;
72 }
73
74 memSize = (sizePrepare * itemNum);
75 if ((memSize == 0) || (memSize / sizePrepare != itemNum)) {
76 return 0;
77 }
78
79 memSize = memSize + sizeof(struct MemPool);
80 if (memSize < sizeof(struct MemPool)) {
81 return 0;
82 }
83
84 sizePrepare = FillpQueueCalMemSize(itemNum);
85 memSize = memSize + sizePrepare;
86 if ((sizePrepare == 0) || (memSize < sizePrepare)) {
87 return 0;
88 }
89
90 return memSize;
91 }
92
93 /*******************************************************************************
94 Function : MpCreateMemPool
95
96 Description : This function will be invoked to create memory pool, based on
97 size and num.
98
99 Input : name - memory pool name
100 itemSize - Size of item
101 itemNum - item number
102 allocType - type of alloc
103
104 Output : None
105
106 Return : Memory pool handle.
107 *******************************************************************************/
MpCreateMemPool(FILLP_CHAR * name,FILLP_SIZE_T itemSize,FILLP_SIZE_T itemNum,FILLP_INT allocType)108 struct MemPool *MpCreateMemPool(
109 FILLP_CHAR *name,
110 FILLP_SIZE_T itemSize,
111 FILLP_SIZE_T itemNum,
112 FILLP_INT allocType)
113 {
114 FILLP_SIZE_T i;
115 FILLP_SIZE_T offset;
116 struct MemPool *pool = FILLP_NULL_PTR;
117 FILLP_SIZE_T itemTotalSize = itemSize + sizeof(struct MemPoolItem);
118 if (itemNum == 0) {
119 return FILLP_NULL_PTR;
120 }
121
122 pool = (struct MemPool *)SpungeAlloc(1, MpCalMemSize(itemSize, itemNum), allocType);
123 if (pool == FILLP_NULL_PTR) {
124 FILLP_LOGERR("Failed to allocate the MemPool data \n");
125 return FILLP_NULL_PTR;
126 }
127
128 pool->allocType = allocType;
129
130 FillpQueueInit(&pool->q, name, itemNum, allocType);
131
132 pool->memStart = (void *)((char *)&pool->q + FillpQueueCalMemSize(itemNum));
133 pool->size = 0;
134
135 offset = 0;
136 for (i = 0; i < itemNum; i++) {
137 struct MemPoolItem *item = (struct MemPoolItem *)(void *)((char *)pool->memStart + offset);
138 offset += itemTotalSize;
139
140 item->p = (void *)((char *)item + sizeof(struct MemPoolItem));
141 item->pool = pool;
142
143 if (FillpQueuePush(&pool->q, (void *)&item, FILLP_TRUE, 1)) {
144 FILLP_LOGERR("Failed to enqueue item \r\n");
145 MpDestroyMemPool(pool);
146 return FILLP_NULL_PTR;
147 }
148
149 pool->size++;
150 }
151
152 return pool;
153 }
154
MpSetConsSafe(struct MemPool * mp,FILLP_BOOL consSafe)155 void MpSetConsSafe(struct MemPool *mp, FILLP_BOOL consSafe)
156 {
157 FillpQueueSetConsSafe(&mp->q, consSafe);
158 }
159
MpSetProdSafe(struct MemPool * mp,FILLP_BOOL prodSafe)160 void MpSetProdSafe(struct MemPool *mp, FILLP_BOOL prodSafe)
161 {
162 FillpQueueSetProdSafe(&mp->q, prodSafe);
163 }
164
165
166 /*******************************************************************************
167 Function : MpMallocWait
168
169 Description : This function will be invoked to create memory pool, based on
170 size and num.
171
172 Input : mp - memory pool handle
173 pp - memory to be allocated
174 wait - flag to wait
175
176 Output : pp - allocated memory
177
178 Return : ERR_OK on success. Error codes on failure.
179 *******************************************************************************/
MpMallocWait(struct MemPool * mp,void ** pp)180 FillpErrorType MpMallocWait(struct MemPool *mp, void **pp)
181 {
182 struct MemPoolItem *tmp = FILLP_NULL_PTR;
183 if (mp == FILLP_NULL_PTR) {
184 FILLP_LOGERR("MemPool pointer is invalid \n");
185 return ERR_NULLPTR;
186 }
187
188 if (FillpQueuePop(&mp->q, (void *)&tmp, 1) <= 0) {
189 return ERR_NOBUFS;
190 }
191 *pp = (char *)tmp + sizeof(struct MemPoolItem); /* For Shaed Memory, access tmp->p may core dump */
192 return ERR_OK;
193 }
194
195 /* Shared Memory . Can't access item->pool, so has to delivery the pool
196 pool should be ok to access, and data is the address of FillP */
MpFreeWithPool(void * data,struct MemPool * pool)197 void MpFreeWithPool(void *data, struct MemPool *pool)
198 {
199 struct MemPoolItem *item = FILLP_NULL_PTR;
200 if ((data == FILLP_NULL_PTR) || (pool == FILLP_NULL_PTR)) {
201 return;
202 }
203
204 item = MpItemEntry(data);
205 if (FillpQueuePush(&pool->q, (void *)&item, FILLP_FALSE, 1)) {
206 return;
207 }
208 }
209
210 #ifdef __cplusplus
211 }
212 #endif
213