FreeRTOS C-Addons  1.1.0
C-Addon functionality to FreeRTOS
mem_pool.c
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2017, Michael Becker (michael.f.becker@gmail.com)
4  *
5  * This file is part of the FreeRTOS Add-ons project.
6  *
7  * Source Code:
8  * https://github.com/michaelbecker/freertos-addons
9  *
10  * Project Page:
11  * http://michaelbecker.github.io/freertos-addons/
12  *
13  * On-line Documentation:
14  * http://michaelbecker.github.io/freertos-addons/docs/html/index.html
15  *
16  * Permission is hereby granted, free of charge, to any person obtaining a
17  * copy of this software and associated documentation files
18  * (the "Software"), to deal in the Software without restriction, including
19  * without limitation the rights to use, copy, modify, merge, publish,
20  * distribute, sublicense, and/or sell copies of the Software, and to
21  * permit persons to whom the Software is furnished to do so,subject to the
22  * following conditions:
23  *
24  * + The above copyright notice and this permission notice shall be included
25  * in all copies or substantial portions of the Software.
26  * + Credit is appreciated, but not required, if you find this project
27  * useful enough to include in your application, product, device, etc.
28  *
29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
32  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
33  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
34  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
35  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36  *
37  ***************************************************************************/
38 
39 
40 #include <stdlib.h>
41 #include "FreeRTOS.h"
42 #include "semphr.h"
43 #include "mem_pool.h"
44 #include "stack_simple.h"
45 
46 
52 typedef struct MemPool_t_ {
53 
57  SemaphoreHandle_t Lock;
58 
63 
67  int ItemSize;
68 
72  int Alignment;
73 
77  unsigned char Buffer[1];
78 
79 } MemPool_t;
80 
81 
83 {
84  /*********************************/
85  int i;
86  int alignmentBit = 0x1;
87  /*********************************/
88 
92  if (Alignment < (int)sizeof(unsigned char *)) {
93  Alignment = (int)sizeof(unsigned char *);
94  }
95 
96  for (i = 0; i < 31; i++) {
97  if (Alignment == alignmentBit) {
98  break;
99  }
100  alignmentBit <<= 1;
101  }
102 
103  if (i >= 31) {
104  return 0;
105  }
106  else {
107  return Alignment;
108  }
109 }
110 
111 
112 static int CalculateItemSize( int ItemSize,
113  int Alignment)
114 {
115  /*********************************/
116  int alignmentCount;
117  /*********************************/
118 
119  if (ItemSize <= Alignment) {
123  ItemSize = 2 * Alignment;
124  }
125  else {
126  alignmentCount = ItemSize / Alignment;
127  if (ItemSize % Alignment != 0) {
128  alignmentCount++;
129  }
133  ItemSize = ((alignmentCount + 1) * Alignment);
134  }
135 
136  return ItemSize;
137 }
138 
139 
141  int ItemCount,
142  int Alignment)
143 {
144  /*********************************/
145  MemPool_t *MemPool;
146  int MemPoolSize;
147  unsigned char *ptr;
148  SlNode_t *Node;
149  int i;
150  /*********************************/
151 
152  Alignment = CalculateAndVerifyAlignment(Alignment);
153 
154  if (Alignment == 0) {
155  return NULL;
156  }
157 
158  ItemSize = CalculateItemSize(ItemSize, Alignment);
159 
160  MemPoolSize = sizeof(MemPool_t) - sizeof(unsigned char)
161  + (ItemCount * ItemSize);
162 
163  MemPool = (MemPool_t *)malloc(MemPoolSize);
164  if (!MemPool) {
165  return NULL;
166  }
167 
168  MemPool->Lock = xSemaphoreCreateMutex();
169  if (MemPool->Lock == NULL) {
170  free(MemPool);
171  return NULL;
172  }
173 
174  InitStack(&MemPool->Stack);
175  MemPool->ItemSize = ItemSize;
176  MemPool->Alignment = Alignment;
177 
178  ptr = MemPool->Buffer;
179 
180  for (i = 0; i < ItemCount; i++) {
181 
182  Node = (SlNode_t *)ptr;
183 
184  PushOnStack(&MemPool->Stack, Node);
185 
186  ptr += MemPool->ItemSize;
187  }
188 
189  return (MemoryPool_t)MemPool;
190 }
191 
192 
194  int ItemCount)
195 {
196  /*********************************/
197  MemPool_t *MemPool;
198  SlNode_t *Node;
199  unsigned char *ptr;
200  int i;
201  int AdditionalPoolSize;
202  /*********************************/
203 
204  MemPool = (MemPool_t *)pool;
205 
206  AdditionalPoolSize = ItemCount * MemPool->ItemSize;
207 
208  ptr = (unsigned char *)malloc(AdditionalPoolSize);
209  if (ptr == NULL) {
210  return pdFAIL;
211  }
212 
213  for (i = 0; i < ItemCount; i++) {
214 
215  Node = (SlNode_t *)ptr;
216 
217  xSemaphoreTake(MemPool->Lock, portMAX_DELAY);
218 
219  PushOnStack(&MemPool->Stack, Node);
220 
221  xSemaphoreGive(MemPool->Lock);
222 
223  ptr += MemPool->ItemSize;
224  }
225 
226  return pdPASS;
227 }
228 
229 
231  void *PreallocatedMemory,
232  int PreallocatedMemorySize,
233  int Alignment)
234 {
235  /*********************************/
236  MemPool_t *MemPool;
237  int MemPoolSize;
238  unsigned char *ptr;
239  SlNode_t *Node;
240  /*********************************/
241 
242  Alignment = CalculateAndVerifyAlignment(Alignment);
243 
244  if (Alignment == 0) {
245  return NULL;
246  }
247 
248  ItemSize = CalculateItemSize(ItemSize, Alignment);
249 
250  MemPoolSize = sizeof(MemPool_t) - sizeof(unsigned char);
251 
252  MemPool = (MemPool_t *)malloc(MemPoolSize);
253  if (!MemPool) {
254  return NULL;
255  }
256 
257  MemPool->Lock = xSemaphoreCreateMutex();
258  if (MemPool->Lock == NULL) {
259  free(MemPool);
260  return NULL;
261  }
262 
263  InitStack(&MemPool->Stack);
264  MemPool->ItemSize = ItemSize;
265  MemPool->Alignment = Alignment;
266 
267  ptr = (unsigned char *)PreallocatedMemory;
268 
269  while (PreallocatedMemorySize >= ItemSize) {
270 
271  Node = (SlNode_t *)ptr;
272  PushOnStack(&MemPool->Stack, Node);
273  ptr += MemPool->ItemSize;
274  PreallocatedMemorySize -= MemPool->ItemSize;
275  }
276 
277  return (MemoryPool_t)MemPool;
278 }
279 
280 
282  void *PreallocatedMemory,
283  int PreallocatedMemorySize)
284 {
285  /*********************************/
286  MemPool_t *MemPool;
287  SlNode_t *Node;
288  unsigned char *ptr;
289  /*********************************/
290 
291  MemPool = (MemPool_t *)pool;
292  ptr = (unsigned char *)PreallocatedMemory;
293 
294  while (PreallocatedMemorySize >= MemPool->ItemSize) {
295 
296  Node = (SlNode_t *)ptr;
297 
298  xSemaphoreTake(MemPool->Lock, portMAX_DELAY);
299 
300  PushOnStack(&MemPool->Stack, Node);
301 
302  xSemaphoreGive(MemPool->Lock);
303 
304  ptr += MemPool->ItemSize;
305  }
306 
307  return pdPASS;
308 }
309 
310 
312 {
313  /*********************************/
314  MemPool_t *MemPool;
315  SlNode_t *Node;
316  unsigned char *ptr;
317  /*********************************/
318 
319  MemPool = (MemPool_t *)pool;
320 
321  xSemaphoreTake(MemPool->Lock, portMAX_DELAY);
322 
323  if (MemPool->Stack.Count == 0) {
324  xSemaphoreGive(MemPool->Lock);
325  return NULL;
326  }
327 
328  Node = PopOffStack(&MemPool->Stack);
329 
330  xSemaphoreGive(MemPool->Lock);
331 
332  ptr = ((unsigned char *)Node) + MemPool->Alignment;
333 
334  return (void *)ptr;
335 }
336 
337 
338 void MemoryPoolFree(MemoryPool_t pool, void *memory)
339 {
340  /*********************************/
341  MemPool_t *MemPool;
342  SlNode_t *Node;
343  unsigned char *ptr;
344  /*********************************/
345 
346  MemPool = (MemPool_t *)pool;
347 
348  ptr = ((unsigned char *)memory) - MemPool->Alignment;
349 
350  Node = (SlNode_t *)ptr;
351 
352  xSemaphoreTake(MemPool->Lock, portMAX_DELAY);
353 
354  PushOnStack(&MemPool->Stack, Node);
355 
356  xSemaphoreGive(MemPool->Lock);
357 }
358 
359 
360 
MemoryPool_t CreateMemoryPoolStatic(int ItemSize, void *PreallocatedMemory, int PreallocatedMemorySize, int Alignment)
Definition: mem_pool.c:230
void MemoryPoolFree(MemoryPool_t pool, void *memory)
Definition: mem_pool.c:338
int AddExtraMemoryToPool(MemoryPool_t pool, int ItemCount)
Definition: mem_pool.c:193
SlNode_t * PopOffStack(Stack_t *Stack)
Definition: stack_simple.c:65
int AddExtraMemoryToPoolStatic(MemoryPool_t pool, void *PreallocatedMemory, int PreallocatedMemorySize)
Definition: mem_pool.c:281
struct MemPool_t_ MemPool_t
unsigned char Buffer[1]
Definition: mem_pool.c:77
void PushOnStack(Stack_t *Stack, SlNode_t *Node)
Definition: stack_simple.c:51
SemaphoreHandle_t Lock
Definition: mem_pool.c:57
void * MemoryPool_t
Definition: mem_pool.h:49
static int CalculateAndVerifyAlignment(int Alignment)
Definition: mem_pool.c:82
MemoryPool_t CreateMemoryPool(int ItemSize, int ItemCount, int Alignment)
Definition: mem_pool.c:140
int ItemSize
Definition: mem_pool.c:67
int Alignment
Definition: mem_pool.c:72
Stack_t Stack
Definition: mem_pool.c:62
static int CalculateItemSize(int ItemSize, int Alignment)
Definition: mem_pool.c:112
void * MemoryPoolAllocate(MemoryPool_t pool)
Definition: mem_pool.c:311
void InitStack(Stack_t *Stack)
Definition: stack_simple.c:44