Просмотр исходного кода

Now passes trivial tests. free_memblock() needs neatening up.

tags/v0.9.3
Michael Brown 18 лет назад
Родитель
Сommit
4e92f29c9e
1 измененных файлов: 34 добавлений и 15 удалений
  1. 34
    15
      src/core/malloc.c

+ 34
- 15
src/core/malloc.c Просмотреть файл

74
 	/* Round up alignment and size to multiples of MIN_MEMBLOCK_SIZE */
74
 	/* Round up alignment and size to multiples of MIN_MEMBLOCK_SIZE */
75
 	align = ( align + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
75
 	align = ( align + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
76
 	size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
76
 	size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
77
+	DBG ( "Allocating %zx (aligned %zx)\n", size, align );
77
 
78
 
78
 	/* Search through blocks for the first one with enough space */
79
 	/* Search through blocks for the first one with enough space */
79
 	list_for_each_entry ( block, &free_blocks, list ) {
80
 	list_for_each_entry ( block, &free_blocks, list ) {
88
 			pre   = block;
89
 			pre   = block;
89
 			block = ( ( ( void * ) pre   ) + pre_size );
90
 			block = ( ( ( void * ) pre   ) + pre_size );
90
 			post  = ( ( ( void * ) block ) + size     );
91
 			post  = ( ( ( void * ) block ) + size     );
92
+			DBG ( "[%p,%p) ->  [%p,%p) + [%p,%p)\n", pre,
93
+			      ( ( ( void * ) pre ) + pre->size ), pre, block,
94
+			      post, ( ( ( void * ) pre ) + pre->size ) );
91
 			/* If there is a "post" block, add it in to
95
 			/* If there is a "post" block, add it in to
92
 			 * the free list.  Leak it if it is too small
96
 			 * the free list.  Leak it if it is too small
93
 			 * (which can happen only at the very end of
97
 			 * (which can happen only at the very end of
111
 				list_del ( &pre->list );
115
 				list_del ( &pre->list );
112
 			/* Zero allocated memory, for calloc() */
116
 			/* Zero allocated memory, for calloc() */
113
 			memset ( block, 0, size );
117
 			memset ( block, 0, size );
118
+			DBG ( "Allocated [%p,%p)\n", block,
119
+			      ( ( ( void * ) block ) + size ) );
114
 			return block;
120
 			return block;
115
 		}
121
 		}
116
 	}
122
 	}
129
 	struct memory_block *freeing;
135
 	struct memory_block *freeing;
130
 	struct memory_block *block;
136
 	struct memory_block *block;
131
 	ssize_t gap_before;
137
 	ssize_t gap_before;
132
-	ssize_t gap_after;
138
+	ssize_t gap_after = -1;
133
 
139
 
134
 	/* Allow for ptr==NULL */
140
 	/* Allow for ptr==NULL */
135
 	if ( ! ptr )
141
 	if ( ! ptr )
141
 	size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
147
 	size = ( size + MIN_MEMBLOCK_SIZE - 1 ) & ~( MIN_MEMBLOCK_SIZE - 1 );
142
 	freeing = ptr;
148
 	freeing = ptr;
143
 	freeing->size = size;
149
 	freeing->size = size;
150
+	DBG ( "Freeing [%p,%p)\n", freeing, ( ( ( void * ) freeing ) + size ));
144
 
151
 
145
 	/* Insert/merge into free list */
152
 	/* Insert/merge into free list */
146
 	list_for_each_entry ( block, &free_blocks, list ) {
153
 	list_for_each_entry ( block, &free_blocks, list ) {
151
 			      ( ( ( void * ) freeing ) + freeing->size ) );
158
 			      ( ( ( void * ) freeing ) + freeing->size ) );
152
 		/* Merge with immediately preceding block, if possible */
159
 		/* Merge with immediately preceding block, if possible */
153
 		if ( gap_before == 0 ) {
160
 		if ( gap_before == 0 ) {
161
+			DBG ( "[%p,%p) + [%p,%p) -> [%p,%p)\n", block,
162
+			      ( ( ( void * ) block ) + block->size ), freeing,
163
+			      ( ( ( void * ) freeing ) + freeing->size ),block,
164
+			      ( ( ( void * ) freeing ) + freeing->size ) );
154
 			block->size += size;
165
 			block->size += size;
155
 			list_del ( &block->list );
166
 			list_del ( &block->list );
156
 			freeing = block;
167
 			freeing = block;
157
 		}
168
 		}
158
-		/* Insert before the immediately following block.  If
159
-		 * possible, merge the following block into the
160
-		 * "freeing" block.
161
-		 */
162
-		if ( gap_after >= 0 ) {
163
-			list_add_tail ( &freeing->list, &block->list );
164
-			if ( gap_after == 0 ) {
165
-				freeing->size += block->size;
166
-				list_del ( &block->list );
167
-			}
169
+		/* Stop processing as soon as we reach a following block */
170
+		if ( gap_after >= 0 )
168
 			break;
171
 			break;
169
-		}
172
+	}
173
+
174
+	/* Insert before the immediately following block.  If
175
+	 * possible, merge the following block into the "freeing"
176
+	 * block.
177
+	 */
178
+	DBG ( "[%p,%p)\n", freeing, ( ( ( void * ) freeing ) + freeing->size));
179
+	list_add_tail ( &freeing->list, &block->list );
180
+	if ( gap_after == 0 ) {
181
+		DBG ( "[%p,%p) + [%p,%p) -> [%p,%p)\n", freeing,
182
+		      ( ( ( void * ) freeing ) + freeing->size ), block,
183
+		      ( ( ( void * ) block ) + block->size ), freeing,
184
+		      ( ( ( void * ) block ) + block->size ) );
185
+		freeing->size += block->size;
186
+		list_del ( &block->list );
170
 	}
187
 	}
171
 }
188
 }
172
 
189
 
192
 	block = alloc_memblock ( total_size, 1 );
209
 	block = alloc_memblock ( total_size, 1 );
193
 	if ( ! block )
210
 	if ( ! block )
194
 		return NULL;
211
 		return NULL;
195
-	block->size = size;
212
+	block->size = total_size;
196
 	return &block->data;
213
 	return &block->data;
197
 }
214
 }
198
 
215
 
227
  * @c start must be aligned to at least a multiple of sizeof(void*).
244
  * @c start must be aligned to at least a multiple of sizeof(void*).
228
  */
245
  */
229
 void mpopulate ( void *start, size_t len ) {
246
 void mpopulate ( void *start, size_t len ) {
247
+	/* Prevent free_memblock() from rounding up len beyond the end
248
+	 * of what we were actually given...
249
+	 */
230
 	free_memblock ( start, ( len & ~( MIN_MEMBLOCK_SIZE - 1 ) ) );
250
 	free_memblock ( start, ( len & ~( MIN_MEMBLOCK_SIZE - 1 ) ) );
231
 }
251
 }
232
 
252
 
233
-#if 1
253
+#if 0
234
 #include <vsprintf.h>
254
 #include <vsprintf.h>
235
 /**
255
 /**
236
  * Dump free block list
256
  * Dump free block list
246
 	}
266
 	}
247
 }
267
 }
248
 #endif
268
 #endif
249
-

Загрузка…
Отмена
Сохранить