26 #if !defined(POLARSSL_CONFIG_FILE)
29 #include POLARSSL_CONFIG_FILE
32 #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
38 #if defined(POLARSSL_MEMORY_DEBUG)
40 #if defined(POLARSSL_MEMORY_BACKTRACE)
45 #if defined(POLARSSL_THREADING_C)
49 #if defined(POLARSSL_PLATFORM_C)
52 #define polarssl_fprintf fprintf
55 #define MAGIC1 0xFF00AA55
56 #define MAGIC2 0xEE119966
59 typedef struct _memory_header memory_header;
67 memory_header *prev_free;
68 memory_header *next_free;
69 #if defined(POLARSSL_MEMORY_BACKTRACE)
81 memory_header *first_free;
82 size_t current_alloc_size;
84 #if defined(POLARSSL_MEMORY_DEBUG)
90 size_t maximum_header_count;
92 #if defined(POLARSSL_THREADING_C)
93 threading_mutex_t mutex;
98 static buffer_alloc_ctx heap;
100 #if defined(POLARSSL_MEMORY_DEBUG)
101 static void debug_header( memory_header *hdr )
103 #if defined(POLARSSL_MEMORY_BACKTRACE)
108 "ALLOC(%u), SIZE(%10u)\n",
109 (
size_t) hdr, (
size_t) hdr->prev, (
size_t) hdr->next,
110 hdr->alloc, hdr->size );
112 (
size_t) hdr->prev_free, (
size_t) hdr->next_free );
114 #if defined(POLARSSL_MEMORY_BACKTRACE)
116 for( i = 0; i < hdr->trace_count; i++ )
122 static void debug_chain()
124 memory_header *cur = heap.first;
134 cur = heap.first_free;
139 cur = cur->next_free;
144 static int verify_header( memory_header *hdr )
146 if( hdr->magic1 != MAGIC1 )
148 #if defined(POLARSSL_MEMORY_DEBUG)
154 if( hdr->magic2 != MAGIC2 )
156 #if defined(POLARSSL_MEMORY_DEBUG)
164 #if defined(POLARSSL_MEMORY_DEBUG)
170 if( hdr->prev != NULL && hdr->prev == hdr->next )
172 #if defined(POLARSSL_MEMORY_DEBUG)
178 if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
180 #if defined(POLARSSL_MEMORY_DEBUG)
189 static int verify_chain()
191 memory_header *prv = heap.first, *cur = heap.first->next;
193 if( verify_header( heap.first ) != 0 )
195 #if defined(POLARSSL_MEMORY_DEBUG)
202 if( heap.first->prev != NULL )
204 #if defined(POLARSSL_MEMORY_DEBUG)
206 "first->prev != NULL\n" );
213 if( verify_header( cur ) != 0 )
215 #if defined(POLARSSL_MEMORY_DEBUG)
222 if( cur->prev != prv )
224 #if defined(POLARSSL_MEMORY_DEBUG)
226 "cur->prev != prv\n" );
238 static void *buffer_alloc_malloc(
size_t len )
240 memory_header *
new, *cur = heap.first_free;
242 #if defined(POLARSSL_MEMORY_BACKTRACE)
243 void *trace_buffer[MAX_BT];
247 if( heap.buf == NULL || heap.first == NULL )
260 if( cur->size >= len )
263 cur = cur->next_free;
269 if( cur->alloc != 0 )
271 #if defined(POLARSSL_MEMORY_DEBUG)
278 #if defined(POLARSSL_MEMORY_DEBUG)
284 if( cur->size - len <
sizeof(memory_header) +
285 POLARSSL_MEMORY_ALIGN_MULTIPLE )
291 if( cur->prev_free != NULL )
292 cur->prev_free->next_free = cur->next_free;
294 heap.first_free = cur->next_free;
296 if( cur->next_free != NULL )
297 cur->next_free->prev_free = cur->prev_free;
299 cur->prev_free = NULL;
300 cur->next_free = NULL;
302 #if defined(POLARSSL_MEMORY_DEBUG)
303 heap.total_used += cur->size;
304 if( heap.total_used > heap.maximum_used)
305 heap.maximum_used = heap.total_used;
307 #if defined(POLARSSL_MEMORY_BACKTRACE)
308 trace_cnt = backtrace( trace_buffer, MAX_BT );
309 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
310 cur->trace_count = trace_cnt;
316 return ( (
unsigned char *) cur ) +
sizeof(memory_header);
319 p = ( (
unsigned char *) cur ) +
sizeof(memory_header) + len;
320 new = (memory_header *) p;
322 new->size = cur->size - len -
sizeof(memory_header);
325 new->next = cur->next;
326 #if defined(POLARSSL_MEMORY_BACKTRACE)
328 new->trace_count = 0;
330 new->magic1 = MAGIC1;
331 new->magic2 = MAGIC2;
333 if( new->next != NULL )
334 new->next->prev =
new;
338 new->prev_free = cur->prev_free;
339 new->next_free = cur->next_free;
340 if( new->prev_free != NULL )
341 new->prev_free->next_free =
new;
343 heap.first_free =
new;
345 if( new->next_free != NULL )
346 new->next_free->prev_free =
new;
351 cur->prev_free = NULL;
352 cur->next_free = NULL;
354 #if defined(POLARSSL_MEMORY_DEBUG)
356 if( heap.header_count > heap.maximum_header_count )
357 heap.maximum_header_count = heap.header_count;
358 heap.total_used += cur->size;
359 if( heap.total_used > heap.maximum_used)
360 heap.maximum_used = heap.total_used;
362 #if defined(POLARSSL_MEMORY_BACKTRACE)
363 trace_cnt = backtrace( trace_buffer, MAX_BT );
364 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
365 cur->trace_count = trace_cnt;
371 return ( (
unsigned char *) cur ) +
sizeof(memory_header);
374 static void buffer_alloc_free(
void *ptr )
376 memory_header *hdr, *old = NULL;
377 unsigned char *p = (
unsigned char *) ptr;
379 if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
382 if( p < heap.buf || p > heap.buf + heap.len )
384 #if defined(POLARSSL_MEMORY_DEBUG)
391 p -=
sizeof(memory_header);
392 hdr = (memory_header *) p;
394 if( verify_header( hdr ) != 0 )
397 if( hdr->alloc != 1 )
399 #if defined(POLARSSL_MEMORY_DEBUG)
408 #if defined(POLARSSL_MEMORY_DEBUG)
410 heap.total_used -= hdr->size;
415 if( hdr->prev != NULL && hdr->prev->alloc == 0 )
417 #if defined(POLARSSL_MEMORY_DEBUG)
420 hdr->prev->size +=
sizeof(memory_header) + hdr->size;
421 hdr->prev->next = hdr->next;
425 if( hdr->next != NULL )
426 hdr->next->prev = hdr;
428 #if defined(POLARSSL_MEMORY_BACKTRACE)
431 memset( old, 0,
sizeof(memory_header) );
436 if( hdr->next != NULL && hdr->next->alloc == 0 )
438 #if defined(POLARSSL_MEMORY_DEBUG)
441 hdr->size +=
sizeof(memory_header) + hdr->next->size;
443 hdr->next = hdr->next->next;
445 if( hdr->prev_free != NULL || hdr->next_free != NULL )
447 if( hdr->prev_free != NULL )
448 hdr->prev_free->next_free = hdr->next_free;
450 heap.first_free = hdr->next_free;
452 if( hdr->next_free != NULL )
453 hdr->next_free->prev_free = hdr->prev_free;
456 hdr->prev_free = old->prev_free;
457 hdr->next_free = old->next_free;
459 if( hdr->prev_free != NULL )
460 hdr->prev_free->next_free = hdr;
462 heap.first_free = hdr;
464 if( hdr->next_free != NULL )
465 hdr->next_free->prev_free = hdr;
467 if( hdr->next != NULL )
468 hdr->next->prev = hdr;
470 #if defined(POLARSSL_MEMORY_BACKTRACE)
473 memset( old, 0,
sizeof(memory_header) );
481 hdr->next_free = heap.first_free;
482 heap.first_free->prev_free = hdr;
483 heap.first_free = hdr;
486 #if defined(POLARSSL_MEMORY_BACKTRACE)
488 hdr->trace_count = 0;
497 heap.verify = verify;
502 return verify_chain();
505 #if defined(POLARSSL_MEMORY_DEBUG)
506 void memory_buffer_alloc_status()
509 "Current use: %u blocks / %u bytes, max: %u blocks / "
510 "%u bytes (total %u bytes), malloc / free: %u / %u\n",
511 heap.header_count, heap.total_used,
512 heap.maximum_header_count, heap.maximum_used,
513 heap.maximum_header_count *
sizeof( memory_header )
515 heap.malloc_count, heap.free_count );
517 if( heap.first->next == NULL )
527 #if defined(POLARSSL_THREADING_C)
528 static void *buffer_alloc_malloc_mutexed(
size_t len )
532 buf = buffer_alloc_malloc( len );
537 static void buffer_alloc_free_mutexed(
void *ptr )
540 buffer_alloc_free( ptr );
547 memset( &heap, 0,
sizeof(buffer_alloc_ctx) );
548 memset( buf, 0, len );
550 #if defined(POLARSSL_THREADING_C)
552 platform_set_malloc_free( buffer_alloc_malloc_mutexed,
553 buffer_alloc_free_mutexed );
555 platform_set_malloc_free( buffer_alloc_malloc, buffer_alloc_free );
561 heap.first = (memory_header *) buf;
562 heap.first->size = len -
sizeof(memory_header);
563 heap.first->magic1 = MAGIC1;
564 heap.first->magic2 = MAGIC2;
565 heap.first_free = heap.first;
571 #if defined(POLARSSL_THREADING_C)
574 memset( &heap, 0,
sizeof(buffer_alloc_ctx) );
#define POLARSSL_MEMORY_ALIGN_MULTIPLE
Align on multiples of this value.
int(* polarssl_mutex_lock)(threading_mutex_t *mutex)
void memory_buffer_alloc_free(void)
Free the mutex for thread-safety and clear remaining memory.
Configuration options (set of defines)
void memory_buffer_set_verify(int verify)
Determine when the allocator should automatically verify the state of the entire chain of headers / m...
int memory_buffer_alloc_init(unsigned char *buf, size_t len)
Initialize use of stack-based memory allocator.
#define MEMORY_VERIFY_FREE
Threading abstraction layer.
#define MEMORY_VERIFY_ALLOC
int memory_buffer_alloc_verify(void)
Verifies that all headers in the memory buffer are correct and contain sane values.
Buffer-based memory allocator.
int(* polarssl_mutex_free)(threading_mutex_t *mutex)
int(* polarssl_mutex_unlock)(threading_mutex_t *mutex)
int(* polarssl_mutex_init)(threading_mutex_t *mutex)