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