Skip to content

Commit c3be8ba

Browse files
committed
initial import from hack-malloc
Source: https://github.com/wware/stuff/tree/master/hack-malloc
0 parents  commit c3be8ba

File tree

6 files changed

+543
-0
lines changed

6 files changed

+543
-0
lines changed

FreeRTOS.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Fake values for convenient testing of defrag code.
3+
*/
4+
5+
#include <stdio.h>
6+
7+
#define ALIGNMENT_BITS 2
8+
#define portBYTE_ALIGNMENT (1 << ALIGNMENT_BITS)
9+
#define portBYTE_ALIGNMENT_MASK (portBYTE_ALIGNMENT - 1)
10+
#define configUSE_MALLOC_FAILED_HOOK 0
11+
#define configTOTAL_HEAP_SIZE 4096
12+
#define pdFALSE 0
13+
#define pdTRUE 1
14+
15+
typedef int portBASE_TYPE;
16+
17+
#define vTaskSuspendAll()
18+
#define xTaskResumeAll()
19+
20+
#ifdef ENABLE_DEBUG
21+
#define DBGPRINTF(x) printf("%s %d: ", __FILE__, __LINE__); printf(x)
22+
#define DBGPRINTF1(x,a) printf("%s %d: ", __FILE__, __LINE__); printf(x, a)
23+
#define DBGPRINTF2(x,a,b) printf("%s %d: ", __FILE__, __LINE__); printf(x, a, b)
24+
#define DBGPRINTF3(x,a,b,c) printf("%s %d: ", __FILE__, __LINE__); printf(x, a, b, c)
25+
#else
26+
#define DBGPRINTF(x)
27+
#define DBGPRINTF1(x,a)
28+
#define DBGPRINTF2(x,a,b)
29+
#define DBGPRINTF3(x,a,b,c)
30+
#endif
31+

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CC = gcc
2+
CFLAGS = -g -Wall
3+
4+
tryit: tryit.o heap_ww.o
5+
gcc -o tryit tryit.o heap_ww.o
6+
7+
clean:
8+
rm -f *~ *.o tryit

README.rst

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
Fooling around with memory allocation
2+
=====================================
3+
4+
Memory allocation is one of those classically hard problems of computer
5+
science, or so I had been led to believe. So imagine my surprise when I came
6+
across a really simple elegant memory allocator as part of the FreeRTOS
7+
operating system.
8+
9+
http://code.google.com/p/lumweb/source/browse/trunk/src/external/freeRTOS/Source/portable/MemMang/heap_2.c
10+
11+
The free list is maintained as a linked list of blocks in order of increasing
12+
size. The malloc() function steps through them, looking for the first one
13+
large enough to accommodate a request. If the block is larger than the request
14+
by a sufficient margin, it is split into two blocks, the first one returned,
15+
and the second kept in the free list. When a block is freed, it is returned to
16+
the free list, retaining the ordering by block size. This is done by the
17+
prvInsertBlockIntoFreeList function. Each block begins with a struct
18+
containing the next-pointer for the size-ordered linked list, and a byte
19+
count. The allocation (the pointer returned by malloc) comes right after
20+
the struct. There are likely to be word alignment issues to think about, for
21+
example I am planning to use this on a 32-bit architecture so the smallest
22+
possible allocation would be four bytes.
23+
24+
It's quite ingenious but it's prone to fragmentation. If you have lots of very
25+
small allocations they can chop the heap into small pieces, so that a later
26+
large allocation request is unnecessarily denied even though there is really
27+
enough free memory to serve it.
28+
29+
I've got an idea for defragmentation which I will be tinkering with here. The
30+
idea is that when you free a block, you look at the immediately preceding and
31+
following blocks, not in order of increasing block size but in order of
32+
physical memory address, and you look to see, what is the largest contiguous
33+
block I can reassemble right now? If two or more blocks are contiguous (they
34+
have zero bytes between them) then they can be merged into one big block.
35+
36+
A couple of minor details. The struct at the beginning of each block will need
37+
one more next-pointer for the ordering by physical address. The time spent in
38+
free() will be a little more, and during that time, any thread that might want
39+
to call malloc() or free() will need to be suspended (as is done in FreeRTOS
40+
already).
41+
42+
I plan to try implementing this and writing some tests to see if it works as
43+
well as I hope. In particular it should be possible to do the worst-case thing
44+
above of many small allocations followed by one very large allocation. If it
45+
passes tests, I'll suggest it to the FreeRTOS folks as an alternative to
46+
heap_2.c.
47+
48+
source: https://github.com/wware/stuff/tree/master/hack-malloc

0 commit comments

Comments
 (0)