1 /*
2 ** Two Level Segregated Fit memory allocator, version 3.1.
3 ** Written by Matthew Conte
4 **	http://tlsf.baisoku.org
5 **
6 ** Based on the original documentation by Miguel Masmano:
7 **	http://www.gii.upv.es/tlsf/main/docs
8 **
9 ** This implementation was written to the specification
10 ** of the document, therefore no GPL restrictions apply.
11 **
12 ** Copyright (c) 2006-2016, Matthew Conte
13 ** All rights reserved.
14 **
15 ** Redistribution and use in source and binary forms, with or without
16 ** modification, are permitted provided that the following conditions are met:
17 **     * Redistributions of source code must retain the above copyright
18 **       notice, this list of conditions and the following disclaimer.
19 **     * Redistributions in binary form must reproduce the above copyright
20 **       notice, this list of conditions and the following disclaimer in the
21 **       documentation and/or other materials provided with the distribution.
22 **     * Neither the name of the copyright holder nor the
23 **       names of its contributors may be used to endorse or promote products
24 **       derived from this software without specific prior written permission.
25 **
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 ** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
30 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37 
38 #pragma once
39 #include <assert.h>
40 #include <limits.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <stddef.h>
46 #include "heap_tlsf_config.h"
47 
48 #if defined(__cplusplus)
49 extern "C" {
50 #endif
51 
52 /*
53 ** Cast and min/max macros.
54 */
55 #define tlsf_cast(t, exp)	((t) (exp))
56 #define tlsf_min(a, b)		((a) < (b) ? (a) : (b))
57 #define tlsf_max(a, b)		((a) > (b) ? (a) : (b))
58 
59 /* A type used for casting when doing pointer arithmetic. */
60 typedef ptrdiff_t tlsfptr_t;
61 
62 typedef struct block_header_t
63 {
64 	/* Points to the previous physical block. */
65 	struct block_header_t* prev_phys_block;
66 
67 	/* The size of this block, excluding the block header. */
68 	size_t size;
69 
70 	/* Next and previous free blocks. */
71 	struct block_header_t* next_free;
72 	struct block_header_t* prev_free;
73 } block_header_t;
74 
75 /* The TLSF control structure. */
76 typedef struct control_t
77 {
78 	/* Empty lists point at this block to indicate they are free. */
79 	block_header_t block_null;
80 
81 	/* Bitmaps for free lists. */
82 	unsigned int fl_bitmap;
83 	unsigned int sl_bitmap[FL_INDEX_COUNT];
84 
85 	/* Head of free lists. */
86 	block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT];
87 } control_t;
88 
89 #include "heap_tlsf_block_functions.h"
90 
91 /* tlsf_t: a TLSF structure. Can contain 1 to N pools. */
92 /* pool_t: a block of memory that TLSF can manage. */
93 typedef void* tlsf_t;
94 typedef void* pool_t;
95 
96 /* Create/destroy a memory pool. */
97 tlsf_t tlsf_create(void* mem);
98 tlsf_t tlsf_create_with_pool(void* mem, size_t bytes);
99 pool_t tlsf_get_pool(tlsf_t tlsf);
100 
101 /* Add/remove memory pools. */
102 pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes);
103 void tlsf_remove_pool(tlsf_t tlsf, pool_t pool);
104 
105 /* malloc/memalign/realloc/free replacements. */
106 void* tlsf_malloc(tlsf_t tlsf, size_t size);
107 void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size);
108 void* tlsf_memalign_offs(tlsf_t tlsf, size_t align, size_t size, size_t offset);
109 void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size);
110 void tlsf_free(tlsf_t tlsf, void* ptr);
111 
112 /* Returns internal block size, not original request size */
113 size_t tlsf_block_size(void* ptr);
114 
115 /* Overheads/limits of internal structures. */
116 size_t tlsf_size(void);
117 size_t tlsf_align_size(void);
118 size_t tlsf_block_size_min(void);
119 size_t tlsf_block_size_max(void);
120 size_t tlsf_pool_overhead(void);
121 size_t tlsf_alloc_overhead(void);
122 
123 /* Debugging. */
124 typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user);
125 void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
126 /* Returns nonzero if any internal consistency check fails. */
127 int tlsf_check(tlsf_t tlsf);
128 int tlsf_check_pool(pool_t pool);
129 
130 #if defined(__cplusplus)
131 };
132 #endif
133