xref: /btstack/src/btstack_memory_pool.c (revision d2e6c4b762dcc377f289e211dfa917e640f4d468)
1*d2e6c4b7SMatthias Ringwald /*
2*d2e6c4b7SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*d2e6c4b7SMatthias Ringwald  *
4*d2e6c4b7SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*d2e6c4b7SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*d2e6c4b7SMatthias Ringwald  * are met:
7*d2e6c4b7SMatthias Ringwald  *
8*d2e6c4b7SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*d2e6c4b7SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*d2e6c4b7SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*d2e6c4b7SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*d2e6c4b7SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*d2e6c4b7SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*d2e6c4b7SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*d2e6c4b7SMatthias Ringwald  *    from this software without specific prior written permission.
16*d2e6c4b7SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*d2e6c4b7SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*d2e6c4b7SMatthias Ringwald  *    monetary gain.
19*d2e6c4b7SMatthias Ringwald  *
20*d2e6c4b7SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*d2e6c4b7SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*d2e6c4b7SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*d2e6c4b7SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*d2e6c4b7SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*d2e6c4b7SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*d2e6c4b7SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*d2e6c4b7SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*d2e6c4b7SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*d2e6c4b7SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*d2e6c4b7SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*d2e6c4b7SMatthias Ringwald  * SUCH DAMAGE.
32*d2e6c4b7SMatthias Ringwald  *
33*d2e6c4b7SMatthias Ringwald  * Please inquire about commercial licensing options at
34*d2e6c4b7SMatthias Ringwald  * [email protected]
35*d2e6c4b7SMatthias Ringwald  *
36*d2e6c4b7SMatthias Ringwald  */
37*d2e6c4b7SMatthias Ringwald 
38*d2e6c4b7SMatthias Ringwald /*
39*d2e6c4b7SMatthias Ringwald  *  btstack_memory_pool.c
40*d2e6c4b7SMatthias Ringwald  *
41*d2e6c4b7SMatthias Ringwald  *  Fixed-size block allocation
42*d2e6c4b7SMatthias Ringwald  *
43*d2e6c4b7SMatthias Ringwald  *  Free blocks are kept in singly linked list
44*d2e6c4b7SMatthias Ringwald  *
45*d2e6c4b7SMatthias Ringwald  */
46*d2e6c4b7SMatthias Ringwald 
47*d2e6c4b7SMatthias Ringwald #include "btstack_memory_pool.h"
48*d2e6c4b7SMatthias Ringwald 
49*d2e6c4b7SMatthias Ringwald #include <stddef.h>
50*d2e6c4b7SMatthias Ringwald #include "btstack_debug.h"
51*d2e6c4b7SMatthias Ringwald 
52*d2e6c4b7SMatthias Ringwald typedef struct node {
53*d2e6c4b7SMatthias Ringwald     struct node * next;
54*d2e6c4b7SMatthias Ringwald } node_t;
55*d2e6c4b7SMatthias Ringwald 
56*d2e6c4b7SMatthias Ringwald void memory_pool_create(memory_pool_t *pool, void * storage, int count, int block_size){
57*d2e6c4b7SMatthias Ringwald     node_t *free_blocks = (node_t*) pool;
58*d2e6c4b7SMatthias Ringwald     char   *mem_ptr = (char *) storage;
59*d2e6c4b7SMatthias Ringwald     int i;
60*d2e6c4b7SMatthias Ringwald 
61*d2e6c4b7SMatthias Ringwald     // create singly linked list of all available blocks
62*d2e6c4b7SMatthias Ringwald     free_blocks->next = NULL;
63*d2e6c4b7SMatthias Ringwald     for (i = 0 ; i < count ; i++){
64*d2e6c4b7SMatthias Ringwald         memory_pool_free(pool, mem_ptr);
65*d2e6c4b7SMatthias Ringwald         mem_ptr += block_size;
66*d2e6c4b7SMatthias Ringwald     }
67*d2e6c4b7SMatthias Ringwald }
68*d2e6c4b7SMatthias Ringwald 
69*d2e6c4b7SMatthias Ringwald void * memory_pool_get(memory_pool_t *pool){
70*d2e6c4b7SMatthias Ringwald     node_t *free_blocks = (node_t*) pool;
71*d2e6c4b7SMatthias Ringwald 
72*d2e6c4b7SMatthias Ringwald     if (!free_blocks->next) return NULL;
73*d2e6c4b7SMatthias Ringwald 
74*d2e6c4b7SMatthias Ringwald     // remove first
75*d2e6c4b7SMatthias Ringwald     node_t *node      = free_blocks->next;
76*d2e6c4b7SMatthias Ringwald     free_blocks->next = node->next;
77*d2e6c4b7SMatthias Ringwald 
78*d2e6c4b7SMatthias Ringwald     return (void*) node;
79*d2e6c4b7SMatthias Ringwald }
80*d2e6c4b7SMatthias Ringwald 
81*d2e6c4b7SMatthias Ringwald void memory_pool_free(memory_pool_t *pool, void * block){
82*d2e6c4b7SMatthias Ringwald     node_t *free_blocks = (node_t*) pool;
83*d2e6c4b7SMatthias Ringwald     node_t *node        = (node_t*) block;
84*d2e6c4b7SMatthias Ringwald 
85*d2e6c4b7SMatthias Ringwald     // raise error and abort if node already in list
86*d2e6c4b7SMatthias Ringwald     node_t * it;
87*d2e6c4b7SMatthias Ringwald     for (it = free_blocks->next; it ; it = it->next){
88*d2e6c4b7SMatthias Ringwald         if (it == node) {
89*d2e6c4b7SMatthias Ringwald             log_error("memory_pool_free: block %p freed twice for pool %p", block, pool);
90*d2e6c4b7SMatthias Ringwald             return;
91*d2e6c4b7SMatthias Ringwald         }
92*d2e6c4b7SMatthias Ringwald     }
93*d2e6c4b7SMatthias Ringwald 
94*d2e6c4b7SMatthias Ringwald     // add block as node to list
95*d2e6c4b7SMatthias Ringwald     node->next          = free_blocks->next;
96*d2e6c4b7SMatthias Ringwald     free_blocks->next   = node;
97*d2e6c4b7SMatthias Ringwald }
98