@@ -10,18 +10,18 @@ might get expensive.
10
10
11
11
## Acknowledgements
12
12
13
- Joerg Wunsch and the avr-libc provided the first malloc() implementation
13
+ Joerg Wunsch and the avr-libc provided the first ` malloc() ` implementation
14
14
that I examined in detail.
15
15
16
- http://www.nongnu.org/avr-libc
16
+ ` http://www.nongnu.org/avr-libc `
17
17
18
18
Doug Lea's paper on malloc() was another excellent reference and provides
19
19
a lot of detail on advanced memory management techniques such as binning.
20
20
21
- http://g.oswego.edu/dl/html/malloc.html
21
+ ` http://g.oswego.edu/dl/html/malloc.html `
22
22
23
23
Bill Dittman provided excellent suggestions, including macros to support
24
- using these functions in critical sections, and for optimizing realloc()
24
+ using these functions in critical sections, and for optimizing ` realloc() `
25
25
further by checking to see if the previous block was free and could be
26
26
used for the new block size. This can help to reduce heap fragmentation
27
27
significantly.
@@ -30,11 +30,73 @@ Yaniv Ankin suggested that a way to dump the current heap condition
30
30
might be useful. I combined this with an idea from plarroy to also
31
31
allow checking a free pointer to make sure it's valid.
32
32
33
+ Dimitry Frank contributed many helpful additions to make things more
34
+ robust including a user specified config file and a method of testing
35
+ the integrity of the data structures.
36
+
37
+ ## Usage
38
+
39
+ Copy the ` umm_malloc_cfg_example.h ` file to ` umm_malloc_cfg.h ` and
40
+ make the changes required to support your application.
41
+
42
+ The following ` #define ` s must be set to something useful for the
43
+ library to work at all
44
+
45
+ - ` UMM_MALLOC_CFG_HEAP_ADDR ` must be set to the symbol representing
46
+ the starting address of the heap. The heap must be
47
+ aligned on the natural boundary size of the processor.
48
+ - ` UMM_MALLOC_CFG_HEAP_SIZE ` must be set to the size of the heap.
49
+ The heap size must be a multiple of the natural boundary size of
50
+ the processor.
51
+
52
+ The fit algorithm is defined as either:
53
+
54
+ - ` UMM_BEST_FIT ` which scans the entire free list and looks
55
+ for either an exact fit or the smallest block that will
56
+ satisfy the request. This is the default fit method.
57
+ - ` UMM_FIRST_FIT ` which scans the entire free list and looks
58
+ for the first block that satisfies the request.
59
+
60
+ The following ` #define ` s are disabled by default and should
61
+ remain disabled for production use. They are helpful when
62
+ testing allocation errors (which are normally due to bugs in
63
+ the application code) or for running the test suite when
64
+ making changes to the code.
65
+
66
+ You can define them in your compiler command line or uncomment
67
+ the corresponding entries is ` umm_malloc_cfg.h ` :
68
+
69
+ - ` UMM_INFO ` is used to include code that allows dumping
70
+ the entire heap structure (helpful when there's a problem).
71
+
72
+ - ` UMM_INTEGRITY_CHECK ` is used to include code that
73
+ performs an integrity check on the heap structure. It's
74
+ up to you to call the ` umm_integrity_check() ` function.
75
+
76
+ - ` UMM_POISON_CHECK ` is used to include code that
77
+ adds some bytes around the memory being allocated that
78
+ are filled with known data. If the data is not intact
79
+ when the block is checked, then somone has written outside
80
+ of the memory block they have been allocated. It is up
81
+ to you to call the ` umm_poison_check() ` function.
82
+
83
+ ## API
84
+
85
+ The following functions are available for your application:
86
+
87
+ - ` void *umm_malloc( size_t size ); `
88
+ - ` void *umm_calloc( size_t num, size_t size ); `
89
+ - ` void *umm_realloc( void *ptr, size_t size ); `
90
+ - ` void umm_free( void *ptr ); `
91
+
92
+ They have exactly the same semantics as the corresponding standard library
93
+ functions.
94
+
33
95
## Background
34
96
35
97
The memory manager assumes the following things:
36
98
37
- 1 . The standard POSIX compliant malloc/realloc/free semantics are used
99
+ 1 . The standard POSIX compliant malloc/calloc/ realloc/free semantics are used
38
100
1 . All memory used by the manager is allocated at link time, it is aligned
39
101
on a 32 bit boundary, it is contiguous, and its extent (start and end
40
102
address) is filled in by the linker.
@@ -45,17 +107,17 @@ The fastest linked list implementations use doubly linked lists so that
45
107
its possible to insert and delete blocks in constant time. This memory
46
108
manager keeps track of both free and used blocks in a doubly linked list.
47
109
48
- Most memory managers use some kind of list structure made up of pointers
110
+ Most memory managers use a list structure made up of pointers
49
111
to keep track of used - and sometimes free - blocks of memory. In an
50
112
embedded system, this can get pretty expensive as each pointer can use
51
113
up to 32 bits.
52
114
53
- In most embedded systems there is no need for managing large blocks
54
- of memory dynamically, so a full 32 bit pointer based data structure
115
+ In most embedded systems there is no need for managing a large quantity
116
+ of memory block dynamically, so a full 32 bit pointer based data structure
55
117
for the free and used block lists is wasteful. A block of memory on
56
118
the free list would use 16 bytes just for the pointers!
57
119
58
- This memory management library sees the malloc heap as an array of blocks,
120
+ This memory management library sees the heap as an array of blocks,
59
121
and uses block numbers to keep track of locations. The block numbers are
60
122
15 bits - which allows for up to 32767 blocks of memory. The high order
61
123
bit marks a block as being either free or in use, which will be explained
@@ -75,7 +137,7 @@ can always add more data bytes to the body of the memory block
75
137
at the expense of free block size overhead.
76
138
77
139
There are a lot of little features and optimizations in this memory
78
- management system that makes it especially suited to small embedded, but
140
+ management system that makes it especially suited to small systems, and
79
141
the best way to appreciate them is to review the data structures and
80
142
algorithms used, so let's get started.
81
143
@@ -124,10 +186,9 @@ Where:
124
186
- n is the index of the next block in the heap
125
187
- p is the index of the previous block in the heap
126
188
127
- Note that the free list information is gone, because it's now being used to
128
- store actual data for the application. It would have been nice to store
129
- the next and previous free list indexes as well, but that would be a waste
130
- of space. If we had even 500 items in use, that would be 2,000 bytes for
189
+ Note that the free list information is gone because it's now
190
+ being used to store actual data for the application. If we had
191
+ even 500 items in use, that would be 2,000 bytes for
131
192
free list information. We simply can't afford to waste that much.
132
193
133
194
The address of the ` ... ` area is what is returned to the application
@@ -143,7 +204,7 @@ described.
143
204
` ... ` between memory blocks indicates zero or more additional blocks are
144
205
allocated for use by the upper block.
145
206
146
- And while we're talking about "upper" and "lower" blocks, we should make
207
+ While we're talking about "upper" and "lower" blocks, we should make
147
208
a comment about adresses. In the diagrams, a block higher up in the
148
209
picture is at a lower address. And the blocks grow downwards their
149
210
block index increases as does their physical address.
@@ -166,24 +227,27 @@ we're at the end of the list!
166
227
167
228
At this point, the malloc has a special test that checks if the current
168
229
block index is 0, which it is. This special case initializes the free
169
- list to point at block index 1.
230
+ list to point at block index 1 and then points block 1 to the
231
+ last block (lf) on the heap.
170
232
171
233
```
172
234
BEFORE AFTER
173
235
174
236
+----+----+----+----+ +----+----+----+----+
175
- 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
237
+ 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
176
238
+----+----+----+----+ +----+----+----+----+
177
239
+----+----+----+----+
178
- 1 | 0 | 0 | 0 | 0 |
240
+ 1 |*lf | 0 | 0 | 0 |
241
+ +----+----+----+----+
242
+ ...
243
+ +----+----+----+----+
244
+ lf | 0 | 1 | 0 | 0 |
179
245
+----+----+----+----+
180
246
```
181
247
182
248
The heap is now ready to complete the first malloc operation.
183
249
184
-
185
- ### Operation of malloc when we have reached the end of the free list and
186
- there is no block large enough to accommodate the request.
250
+ ### Operation of malloc when we have reached the end of the free list and there is no block large enough to accommodate the request.
187
251
188
252
This happens at the very first malloc operation, or any time the free
189
253
list is traversed and no free block large enough for the request is
306
370
```
307
371
308
372
Step 1 of the free operation checks if the next block is free, and if it
309
- is then insert this block into the free list and assimilate the next block
310
- with this one.
373
+ is assimilate the next block with this one.
311
374
312
375
Note that c is the block we are freeing up, cf is the free block that
313
376
follows it.
0 commit comments