Ver código fonte

Merged the unaligned and aligned heap APIs and simplified the code.

tags/v0.9.3
Michael Brown 19 anos atrás
pai
commit
eff4fa5a04
2 arquivos alterados com 116 adições e 81 exclusões
  1. 54
    81
      src/core/heap.c
  2. 62
    0
      src/include/heap.h

+ 54
- 81
src/core/heap.c Ver arquivo

@@ -1,6 +1,14 @@
1 1
 #include "etherboot.h"
2 2
 #include "init.h"
3 3
 #include "memsizes.h"
4
+#include "heap.h"
5
+
6
+#define ASSERT(...)
7
+
8
+struct heap_block {
9
+	size_t size;
10
+	char data[0];
11
+};
4 12
 
5 13
 size_t heap_ptr, heap_top, heap_bot;
6 14
 
@@ -86,94 +94,59 @@ static void init_heap(void)
86 94
 	heap_ptr = heap_bot;
87 95
 }
88 96
 
89
-static void reset_heap(void)
90
-{
91
-	heap_ptr = heap_bot;
92
-}
93
-
94
-void *allot(size_t size)
95
-{
96
-	void *ptr;
97
-	size_t *mark, addr;
98
-	/* Get an 16 byte aligned chunk of memory off of the heap 
99
-	 * An extra sizeof(size_t) bytes is allocated to track
100
-	 * the size of the object allocated on the heap.
101
-	 */
102
-	addr = (heap_ptr - (size + sizeof(size_t))) &  ~15;
103
-	if (addr < heap_top) {
104
-		ptr = 0;
105
-	} else {
106
-		mark = phys_to_virt(addr);
107
-		*mark = size;
108
-		heap_ptr = addr;
109
-		ptr = phys_to_virt(addr + sizeof(size_t));
97
+/*
98
+ * Allocate a block from the heap.
99
+ *
100
+ */
101
+void * emalloc ( size_t size, unsigned int align ) {
102
+	physaddr_t addr;
103
+	struct heap_block *block;
104
+	
105
+	ASSERT ( ! ( align & ( align - 1 ) ) );
106
+	
107
+	addr = ( ( ( heap_ptr - size ) & ~( align - 1 ) )
108
+		 - sizeof ( struct heap_block ) );
109
+	if ( addr < heap_top ) {
110
+		return NULL;
110 111
 	}
111
-	return ptr;
112
+
113
+	block = phys_to_virt ( addr );
114
+	block->size = ( heap_ptr - addr );
115
+	heap_ptr = addr;
116
+	return block->data;
112 117
 }
113 118
 
114
-//if mask = 0xf, it will be 16 byte aligned
115
-//if mask = 0xff, it will be 256 byte aligned
116
-//For DMA memory allocation, because it has more reqiurement on alignment
117
-void *allot2(size_t size, uint32_t mask)
118
-{
119
-        void *ptr;
120
-        size_t *mark, addr;
121
-	uint32_t *mark1;
122
-        
123
-	addr = ((heap_ptr - size ) &  ~mask) - sizeof(size_t) - sizeof(uint32_t);
124
-        if (addr < heap_top) {
125
-                ptr = 0;        
126
-        } else {        
127
-                mark = phys_to_virt(addr);
128
-                *mark = size;  
129
-		mark1 = phys_to_virt(addr+sizeof(size_t));
130
-		*mark1 = mask; 
131
-                heap_ptr = addr;
132
-                ptr = phys_to_virt(addr + sizeof(size_t) + sizeof(uint32_t));
133
-        }                       
134
-        return ptr;             
135
-}  
119
+/*
120
+ * Allocate all remaining space on the heap
121
+ *
122
+ */
123
+void * emalloc_all ( size_t *size ) {
124
+	*size = heap_ptr - heap_top - sizeof ( struct heap_block );
125
+	return emalloc ( *size, sizeof ( void * ) );
126
+}
136 127
 
137
-void forget(void *ptr)
138
-{
139
-	size_t *mark, addr;
140
-	size_t size;
128
+/*
129
+ * Free a heap block
130
+ *
131
+ */
132
+void efree ( void *ptr ) {
133
+	struct heap_block *block;
141 134
 
142
-	if (!ptr) {
143
-		return;
144
-	}
145
-	addr = virt_to_phys(ptr);
146
-	mark = phys_to_virt(addr - sizeof(size_t));
147
-	size = *mark;
148
-	addr += (size + 15) & ~15;
135
+	ASSERT ( ptr == ( heap_ptr + sizeof ( size_t ) ) );
149 136
 	
150
-	if (addr > heap_bot) {
151
-		addr = heap_bot;
152
-	}
153
-	heap_ptr = addr;
154
-}
155
-
156
-void forget2(void *ptr)
157
-{
158
-        size_t *mark, addr;
159
-        size_t size;
160
-	uint32_t mask;
161
-	uint32_t *mark1;
137
+	block = ( struct heap_block * )
138
+		( ptr - offsetof ( struct heap_block, data ) );
139
+	heap_ptr += block->size;
162 140
 
163
-        if (!ptr) {
164
-                return;
165
-        }
166
-        addr = virt_to_phys(ptr);
167
-        mark = phys_to_virt(addr - sizeof(size_t) - sizeof(uint32_t));
168
-        size = *mark;
169
-	mark1 = phys_to_virt(addr - sizeof(uint32_t));
170
-	mask = *mark1;
171
-        addr += (size + mask) & ~mask;
141
+	ASSERT ( heap_ptr <= heap_bot );
142
+}
172 143
 
173
-        if (addr > heap_bot) {
174
-                addr = heap_bot;
175
-        }
176
-        heap_ptr = addr;
144
+/*
145
+ * Free all allocated heap blocks
146
+ *
147
+ */
148
+void efree_all ( void ) {
149
+	heap_ptr = heap_bot;
177 150
 }
178 151
 
179
-INIT_FN ( INIT_HEAP, init_heap, reset_heap, NULL );
152
+INIT_FN ( INIT_HEAP, init_heap, efree_all, NULL );

+ 62
- 0
src/include/heap.h Ver arquivo

@@ -0,0 +1,62 @@
1
+#ifndef HEAP_H
2
+#define HEAP_H
3
+
4
+/*
5
+ * Allocate a block with specified (physical) alignment
6
+ *
7
+ * "align" must be a power of 2.
8
+ *
9
+ * Note that "align" affects the alignment of the physical address,
10
+ * not the virtual address.  This is almost certainly what you want.
11
+ *
12
+ */
13
+extern void * emalloc ( size_t size, unsigned int align );
14
+
15
+/*
16
+ * Allocate a block, with no particular alignment requirements.
17
+ *
18
+ */
19
+static inline void * malloc ( size_t size ) {
20
+	return emalloc ( size, sizeof ( void * ) );
21
+}
22
+
23
+/*
24
+ * Allocate all remaining space on the heap
25
+ *
26
+ */
27
+extern void * emalloc_all ( size_t *size );
28
+
29
+/*
30
+ * Free a block.
31
+ *
32
+ * The caller must ensure that the block being freed is the last (most
33
+ * recent) block allocated on the heap, otherwise heap corruption will
34
+ * occur.
35
+ *
36
+ */
37
+extern void efree ( void *ptr );
38
+
39
+static inline void free ( void *ptr ) {
40
+	efree ( ptr );
41
+}
42
+
43
+/*
44
+ * Free all allocated blocks on the heap
45
+ *
46
+ */
47
+extern void efree_all ( void );
48
+
49
+/*
50
+ * Resize a block.
51
+ *
52
+ * The caller must ensure that the block being resized is the last
53
+ * (most recent) block allocated on the heap, otherwise heap
54
+ * corruption will occur.
55
+ *
56
+ */
57
+static inline void * erealloc ( void *ptr, size_t size, unsigned int align ) {
58
+	efree ( ptr );
59
+	return emalloc ( size, align );
60
+}
61
+
62
+#endif /* HEAP_H */

Carregando…
Cancelar
Salvar