xref: /btstack/src/btstack_memory_pool.c (revision 29d0c4f70f8121f49d9f743f4ec2e211360de81a)
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 
38d2e6c4b7SMatthias Ringwald /*
39d2e6c4b7SMatthias Ringwald  *  btstack_memory_pool.c
40d2e6c4b7SMatthias Ringwald  *
41d2e6c4b7SMatthias Ringwald  *  Fixed-size block allocation
42d2e6c4b7SMatthias Ringwald  *
43d2e6c4b7SMatthias Ringwald  *  Free blocks are kept in singly linked list
44d2e6c4b7SMatthias Ringwald  *
45d2e6c4b7SMatthias Ringwald  */
46d2e6c4b7SMatthias Ringwald 
47d2e6c4b7SMatthias Ringwald #include "btstack_memory_pool.h"
48d2e6c4b7SMatthias Ringwald 
49d2e6c4b7SMatthias Ringwald #include <stddef.h>
50d2e6c4b7SMatthias Ringwald #include "btstack_debug.h"
51d2e6c4b7SMatthias Ringwald 
52d2e6c4b7SMatthias Ringwald typedef struct node {
53d2e6c4b7SMatthias Ringwald     struct node * next;
54d2e6c4b7SMatthias Ringwald } node_t;
55d2e6c4b7SMatthias Ringwald 
56*29d0c4f7SMatthias Ringwald void btstack_memory_pool_create(btstack_memory_pool_t *pool, void * storage, int count, int block_size){
57d2e6c4b7SMatthias Ringwald     node_t *free_blocks = (node_t*) pool;
58d2e6c4b7SMatthias Ringwald     char   *mem_ptr = (char *) storage;
59d2e6c4b7SMatthias Ringwald     int i;
60d2e6c4b7SMatthias Ringwald 
61d2e6c4b7SMatthias Ringwald     // create singly linked list of all available blocks
62d2e6c4b7SMatthias Ringwald     free_blocks->next = NULL;
63d2e6c4b7SMatthias Ringwald     for (i = 0 ; i < count ; i++){
64*29d0c4f7SMatthias Ringwald         btstack_memory_pool_free(pool, mem_ptr);
65d2e6c4b7SMatthias Ringwald         mem_ptr += block_size;
66d2e6c4b7SMatthias Ringwald     }
67d2e6c4b7SMatthias Ringwald }
68d2e6c4b7SMatthias Ringwald 
69*29d0c4f7SMatthias Ringwald void * btstack_memory_pool_get(btstack_memory_pool_t *pool){
70d2e6c4b7SMatthias Ringwald     node_t *free_blocks = (node_t*) pool;
71d2e6c4b7SMatthias Ringwald 
72d2e6c4b7SMatthias Ringwald     if (!free_blocks->next) return NULL;
73d2e6c4b7SMatthias Ringwald 
74d2e6c4b7SMatthias Ringwald     // remove first
75d2e6c4b7SMatthias Ringwald     node_t *node      = free_blocks->next;
76d2e6c4b7SMatthias Ringwald     free_blocks->next = node->next;
77d2e6c4b7SMatthias Ringwald 
78d2e6c4b7SMatthias Ringwald     return (void*) node;
79d2e6c4b7SMatthias Ringwald }
80d2e6c4b7SMatthias Ringwald 
81*29d0c4f7SMatthias Ringwald void btstack_memory_pool_free(btstack_memory_pool_t *pool, void * block){
82d2e6c4b7SMatthias Ringwald     node_t *free_blocks = (node_t*) pool;
83d2e6c4b7SMatthias Ringwald     node_t *node        = (node_t*) block;
84d2e6c4b7SMatthias Ringwald 
85d2e6c4b7SMatthias Ringwald     // raise error and abort if node already in list
86d2e6c4b7SMatthias Ringwald     node_t * it;
87d2e6c4b7SMatthias Ringwald     for (it = free_blocks->next; it ; it = it->next){
88d2e6c4b7SMatthias Ringwald         if (it == node) {
89*29d0c4f7SMatthias Ringwald             log_error("btstack_memory_pool_free: block %p freed twice for pool %p", block, pool);
90d2e6c4b7SMatthias Ringwald             return;
91d2e6c4b7SMatthias Ringwald         }
92d2e6c4b7SMatthias Ringwald     }
93d2e6c4b7SMatthias Ringwald 
94d2e6c4b7SMatthias Ringwald     // add block as node to list
95d2e6c4b7SMatthias Ringwald     node->next          = free_blocks->next;
96d2e6c4b7SMatthias Ringwald     free_blocks->next   = node;
97d2e6c4b7SMatthias Ringwald }
98