123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * partition_realloc.c
- */
- #include <string.h>
- #include "private.h"
- /*--------------------------------------------------------- */
- void
- lub_partition_stop_here(lub_heap_status_t status,
- char *old_ptr, size_t new_size)
- {
- /* This is provided as a debug aid */
- status = status;
- old_ptr = old_ptr;
- new_size = new_size;
- }
- /*--------------------------------------------------------- */
- void lub_partition_time_to_die(lub_partition_t * this)
- {
- bool_t time_to_die = BOOL_TRUE;
- lub_heap_stats_t stats;
- lub_heap_t *local_heap = lub_partition__get_local_heap(this);
- if (local_heap) {
- lub_heap__get_stats(local_heap, &stats);
- if (stats.alloc_blocks) {
- time_to_die = BOOL_FALSE;
- }
- }
- if (BOOL_FALSE == time_to_die) {
- lub_partition_lock(this);
- lub_heap__get_stats(this->m_global_heap, &stats);
- lub_partition_unlock(this);
- if (stats.alloc_blocks) {
- time_to_die = BOOL_FALSE;
- }
- }
- if (BOOL_TRUE == time_to_die) {
- /* and so the time has come... */
- lub_partition_destroy(this);
- }
- }
- /*--------------------------------------------------------- */
- lub_heap_status_t
- lub_partition_global_realloc(lub_partition_t * this,
- char **ptr,
- size_t size, lub_heap_align_t alignment)
- {
- lub_heap_status_t status = LUB_HEAP_FAILED;
- lub_partition_lock(this);
- if (!this->m_global_heap) {
- /*
- * Create the global heap
- */
- size_t required = size;
- void *segment = lub_partition_segment_alloc(this, &required);
- this->m_global_heap = lub_heap_create(segment, required);
- }
- if (this->m_global_heap) {
- status =
- lub_heap_realloc(this->m_global_heap, ptr, size, alignment);
- if (LUB_HEAP_FAILED == status) {
- /* expand memory and try again */
- if (lub_partition_extend_memory(this, size)) {
- status = lub_heap_realloc(this->m_global_heap,
- ptr, size, alignment);
- }
- }
- }
- lub_partition_unlock(this);
- return status;
- }
- /*--------------------------------------------------------- */
- lub_heap_status_t
- lub_partition_realloc(lub_partition_t * this,
- char **ptr, size_t size, lub_heap_align_t alignment)
- {
- lub_heap_status_t status = LUB_HEAP_FAILED;
- size_t requested_size = size;
- lub_heap_t *local_heap;
- if ((0 == size) && (0 == *ptr)) {
- /* simple optimisation */
- return LUB_HEAP_OK;
- }
- if (this->m_dying) {
- local_heap = lub_partition__get_local_heap(this);
- if (size) {
- /* don't allocate any new memory when dying */
- size = 0;
- }
- } else {
- local_heap = lub_partition_findcreate_local_heap(this);
- }
- if (local_heap) {
- /* try the fast local heap first */
- status = lub_heap_realloc(local_heap, ptr, size, alignment);
- }
- if ((LUB_HEAP_FAILED == status) || (LUB_HEAP_INVALID_POINTER == status)) {
- char *old_ptr = 0;
- if (local_heap && (LUB_HEAP_FAILED == status) && size) {
- /* we need to reallocate from the global and copy from the local */
- old_ptr = *ptr;
- *ptr = 0;
- }
- /* time to use the slower global heap */
- status =
- lub_partition_global_realloc(this, ptr, size, alignment);
- if (old_ptr && (LUB_HEAP_OK == status)) {
- /* copy from the local to the global */
- memcpy(*ptr, old_ptr, size);
- /* and release the local block */
- status =
- lub_heap_realloc(local_heap, &old_ptr, 0,
- alignment);
- }
- }
- if (LUB_HEAP_OK != status) {
- lub_partition_stop_here(status, *ptr, size);
- }
- /* allow the partion to destroy itself if necessary */
- if (this->m_dying) {
- lub_partition_time_to_die(this);
- if (requested_size) {
- /* we don't allocate memory whilst dying */
- status = LUB_HEAP_FAILED;
- }
- }
- return status;
- }
- /*-------------------------------------------------------- */
|