#include <AvailabilityMacros.h>
#include <malloc/malloc.h>
#include <mach/mach.h>
#include <stdlib.h>
static kern_return_t enumerator(task_t, void *, unsigned, vm_address_t,
memory_reader_t, vm_range_recorder_t)
{
return KERN_FAILURE;
}
static size_t good_size(malloc_zone_t *, size_t size)
{
return size;
}
static boolean_t zone_check(malloc_zone_t *)
{
return true;
}
static void zone_print(malloc_zone_t *, boolean_t) { }
static void zone_log(malloc_zone_t *, void *) {}
static void zone_force_lock(malloc_zone_t *) {}
static void zone_force_unlock(malloc_zone_t *) {}
static void zone_statistics(malloc_zone_t *, malloc_statistics_t *s)
{
s->blocks_in_use = 0;
s->size_in_use = s->max_size_in_use = s->size_allocated = 0;
}
static boolean_t zone_locked(malloc_zone_t *)
{
return false;
}
static boolean_t impl_zone_enable_discharge_checking(malloc_zone_t *)
{
return false;
}
static void impl_zone_disable_discharge_checking(malloc_zone_t *) {}
static void impl_zone_discharge(malloc_zone_t *, void *) {}
static void impl_zone_destroy(struct _malloc_zone_t *) {}
static size_t impl_malloc_usable_size(struct _malloc_zone_t *, const void *ptr)
{
return __TBB_malloc_safer_msize(const_cast<void*>(ptr), NULL);
}
static void *impl_malloc(struct _malloc_zone_t *, size_t size);
static void *impl_calloc(struct _malloc_zone_t *, size_t num_items, size_t size);
static void *impl_valloc(struct _malloc_zone_t *, size_t size);
static void impl_free(struct _malloc_zone_t *, void *ptr);
static void *impl_realloc(struct _malloc_zone_t *, void *ptr, size_t size);
static void *impl_memalign(struct _malloc_zone_t *, size_t alignment, size_t size);
static void impl_free_definite_size(struct _malloc_zone_t*, void *ptr, size_t size)
{
__TBB_malloc_free_definite_size(ptr, size);
}
static size_t impl_pressure_relief(struct _malloc_zone_t *, size_t )
{
return 0;
}
static malloc_zone_t *system_zone = NULL;
struct DoMallocReplacement {
DoMallocReplacement() {
static malloc_introspection_t introspect;
memset(&introspect, 0, sizeof(malloc_introspection_t));
static malloc_zone_t zone;
memset(&zone, 0, sizeof(malloc_zone_t));
introspect.enumerator = &enumerator;
introspect.good_size = &good_size;
introspect.check = &zone_check;
introspect.print = &zone_print;
introspect.log = zone_log;
introspect.force_lock = &zone_force_lock;
introspect.force_unlock = &zone_force_unlock;
introspect.statistics = zone_statistics;
introspect.zone_locked = &zone_locked;
introspect.enable_discharge_checking = &impl_zone_enable_discharge_checking;
introspect.disable_discharge_checking = &impl_zone_disable_discharge_checking;
introspect.discharge = &impl_zone_discharge;
zone.size = &impl_malloc_usable_size;
zone.malloc = &impl_malloc;
zone.calloc = &impl_calloc;
zone.valloc = &impl_valloc;
zone.free = &impl_free;
zone.realloc = &impl_realloc;
zone.destroy = &impl_zone_destroy;
zone.zone_name = "tbbmalloc";
zone.introspect = &introspect;
zone.version = 8;
zone.memalign = impl_memalign;
zone.free_definite_size = &impl_free_definite_size;
zone.pressure_relief = &impl_pressure_relief;
malloc_default_purgeable_zone();
void* ptr = malloc(1);
unsigned zcount = 0;
malloc_zone_t** zone_array = NULL;
kern_return_t errorcode = malloc_get_all_zones(mach_task_self(),NULL,(vm_address_t**)&zone_array,&zcount);
if (!errorcode && zone_array && zcount>0) {
for (unsigned i=0; i<zcount; ++i) {
malloc_zone_t* z = zone_array[i];
if (z && z->size(z,ptr)>0) { system_zone = z;
break;
}
}
}
free(ptr);
malloc_zone_register(&zone);
if (system_zone) {
malloc_zone_unregister(system_zone);
malloc_zone_register(system_zone);
}
}
};
static DoMallocReplacement doMallocReplacement;