void *ph_mem_alloc_size(ph_memtype_t mt, uint64_t size) { struct mem_type *mem_type = resolve_mt(mt); struct sized_header *ptr; ph_counter_block_t *block; static const uint8_t slots[2] = { SLOT_BYTES, SLOT_ALLOCS }; int64_t values[2]; if (mem_type->def.item_size) { memory_panic( "mem_type %s is not vsize, cannot be used with ph_mem_alloc_size", mem_type->def.name); return NULL; } if (size > INT64_MAX) { // we can't account for numbers this big return NULL; } ptr = malloc(size + HEADER_RESERVATION); if (!ptr) { ph_counter_scope_add(mem_type->scope, mem_type->first_slot + SLOT_OOM, 1); if (mem_type->def.flags & PH_MEM_FLAGS_PANIC) { ph_panic("OOM while allocating %" PRIu64 " bytes of %s/%s memory", size + HEADER_RESERVATION, mem_type->def.facility, mem_type->def.name); } return NULL; } ptr->size = size; ptr->mt = mt; ptr++; block = ph_counter_block_open(mem_type->scope); values[0] = size; values[1] = 1; ph_counter_block_bulk_add(block, 2, slots, values); ph_counter_block_delref(block); if (mem_type->def.flags & PH_MEM_FLAGS_ZERO) { memset(ptr, 0, size); } return ptr; }
static void *spin_and_count(void *ptr) { struct counter_data *data = (struct counter_data*)ptr; ph_counter_block_t *block; uint32_t i; while (ck_pr_load_uint(&data->barrier) == 0); block = ph_counter_block_open(data->scope); for (i = 0; i < data->iters; i++) { ph_counter_block_add(block, data->slot, 1); } ph_counter_block_delref(block); return NULL; }
void *ph_mem_alloc(ph_memtype_t mt) { struct mem_type *mem_type = resolve_mt(mt); void *ptr; ph_counter_block_t *block; int64_t values[3]; static const uint8_t slots[2] = { SLOT_BYTES, SLOT_ALLOCS }; if (mem_type->def.item_size == 0) { memory_panic("mem_type %s is vsize, cannot be used with ph_mem_alloc", mem_type->def.name); return NULL; } ptr = malloc(mem_type->def.item_size); if (!ptr) { ph_counter_scope_add(mem_type->scope, mem_type->first_slot + SLOT_OOM, 1); if (mem_type->def.flags & PH_MEM_FLAGS_PANIC) { ph_panic("OOM while allocating %" PRIu64 " bytes of %s/%s memory", mem_type->def.item_size, mem_type->def.facility, mem_type->def.name); } return NULL; } block = ph_counter_block_open(mem_type->scope); values[0] = mem_type->def.item_size; values[1] = 1; ph_counter_block_bulk_add(block, 2, slots, values); ph_counter_block_delref(block); if (mem_type->def.flags & PH_MEM_FLAGS_ZERO) { memset(ptr, 0, mem_type->def.item_size); } return ptr; }
void ph_mem_free(ph_memtype_t mt, void *ptr) { struct mem_type *mem_type; ph_counter_block_t *block; static const uint8_t slots[2] = { SLOT_BYTES, SLOT_FREES }; int64_t values[2]; uint64_t size; if (!ptr) { return; } mem_type = resolve_mt(mt); if (mem_type->def.item_size) { size = mem_type->def.item_size; } else { struct sized_header *hdr = ptr; hdr--; ptr = hdr; size = hdr->size; if (hdr->mt != mt) { memory_panic("ph_mem_free: hdr->mt %d != caller provided mt %d %s", hdr->mt, mt, mem_type->def.name); } } free(ptr); block = ph_counter_block_open(mem_type->scope); values[0] = -size; values[1] = 1; ph_counter_block_bulk_add(block, 2, slots, values); ph_counter_block_delref(block); }
void *ph_mem_realloc(ph_memtype_t mt, void *ptr, uint64_t size) { struct mem_type *mem_type; ph_counter_block_t *block; static const uint8_t slots[2] = { SLOT_BYTES, SLOT_REALLOC }; int64_t values[3]; struct sized_header *hdr; uint64_t orig_size; void *new_ptr; if (size == 0) { ph_mem_free(mt, ptr); return NULL; } if (ptr == NULL) { return ph_mem_alloc_size(mt, size); } mem_type = resolve_mt(mt); if (mem_type->def.item_size) { memory_panic( "mem_type %s is not vsize and cannot be used with ph_mem_realloc", mem_type->def.name); return NULL; } hdr = ptr; hdr--; ptr = hdr; if (hdr->mt != mt) { memory_panic("ph_mem_realloc: hdr->mt %d != caller provided mt %d %s", hdr->mt, mt, mem_type->def.name); } orig_size = hdr->size; if (orig_size == size) { return ptr; } hdr = realloc(ptr, size + HEADER_RESERVATION); if (!hdr) { ph_counter_scope_add(mem_type->scope, mem_type->first_slot + SLOT_OOM, 1); if (mem_type->def.flags & PH_MEM_FLAGS_PANIC) { ph_panic("OOM while allocating %" PRIu64 " bytes of %s/%s memory", size + HEADER_RESERVATION, mem_type->def.facility, mem_type->def.name); } return NULL; } new_ptr = hdr + 1; hdr->size = size; block = ph_counter_block_open(mem_type->scope); values[0] = size - orig_size; values[1] = 1; ph_counter_block_bulk_add(block, 2, slots, values); ph_counter_block_delref(block); if (size > orig_size && mem_type->def.flags & PH_MEM_FLAGS_ZERO) { memset((char*)new_ptr + orig_size, 0, size - orig_size); } return new_ptr; }