示例#1
0
static void memory_init(void)
{
  memtypes_size = 1024;
  memtypes = malloc(memtypes_size * sizeof(*memtypes));
  if (!memtypes) {
    memory_panic("failed to allocate memtypes array");
  }

  memory_scope = ph_counter_scope_define(NULL, "memory", 16);
  if (!memory_scope) {
    memory_panic("failed to define memory scope");
  }
}
示例#2
0
ph_memtype_t ph_memtype_register(const ph_memtype_def_t *def)
{
  ph_memtype_t mt;
  ph_counter_scope_t *scope, *fac_scope;
  struct mem_type *mem_type;
  const char **names;
  int num_slots;

  fac_scope = resolve_facility(def->facility);
  if (!fac_scope) {
    return PH_MEMTYPE_INVALID;
  }
  scope = ph_counter_scope_define(fac_scope, def->name,
      MEM_COUNTER_SLOTS);
  ph_counter_scope_delref(fac_scope);

  if (!scope) {
    return PH_MEMTYPE_INVALID;
  }

  mt = ck_pr_faa_int(&next_memtype, 1);
  if ((uint32_t)mt >= memtypes_size) {
    memory_panic("You need to recompile libphenom with memtypes_size = %d",
        2 * memtypes_size);
  }
  mem_type = &memtypes[mt];
  memset(mem_type, 0, sizeof(*mem_type));

  mem_type->def = *def;
  mem_type->def.facility = strdup(def->facility);
  mem_type->def.name = strdup(def->name);
  mem_type->scope = scope;

  if (mem_type->def.item_size == 0) {
    names = vsize_counter_names;
    num_slots = MEM_COUNTER_SLOTS;
  } else {
    names = sized_counter_names;
    num_slots = MEM_COUNTER_SLOTS - 1;
  }
  if (!ph_counter_scope_register_counter_block(
      scope, num_slots, 0, names)) {
    memory_panic("failed to register counter block for memory scope %s",
      def->name);
  }

  return mt;
}
示例#3
0
static struct mem_type *resolve_mt(ph_memtype_t mt)
{
  if (ph_unlikely(mt < PH_MEMTYPE_FIRST || mt >= next_memtype)) {
    memory_panic(
      "resolve_mt: mt(%d) < PH_MEMTYPE_FIRST || mt(%d) >= next_memtype(%d)",
      mt, mt, next_memtype);
  }
  return &memtypes[mt];
}
示例#4
0
char *jsonnet_realloc(JsonnetVm *vm, char *str, size_t sz)
{
    (void)vm;
    if (str == nullptr) {
        if (sz == 0)
            return nullptr;
        auto *r = static_cast<char *>(::malloc(sz));
        if (r == nullptr)
            memory_panic();
        return r;
    } else {
        if (sz == 0) {
            ::free(str);
            return nullptr;
        } else {
            auto *r = static_cast<char *>(::realloc(str, sz));
            if (r == nullptr)
                memory_panic();
            return r;
        }
    }
}
示例#5
0
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;
}
示例#6
0
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;
}
示例#7
0
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);
}
示例#8
0
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;
}
示例#9
0
ph_memtype_t ph_memtype_register_block(
    uint8_t num_types,
    const ph_memtype_def_t *defs,
    ph_memtype_t *types)
{
  int i;
  ph_counter_scope_t *fac_scope, *scope = NULL;
  ph_memtype_t mt;
  struct mem_type *mem_type;
  const char **names;
  uint32_t num_slots;

  /* must all be same facility */
  for (i = 0; i < num_types; i++) {
    if (strcmp(defs[0].facility, defs[i].facility)) {
      return PH_MEMTYPE_INVALID;
    }
  }

  fac_scope = resolve_facility(defs[0].facility);
  if (!fac_scope) {
    return PH_MEMTYPE_INVALID;
  }

  mt = ck_pr_faa_int(&next_memtype, num_types);
  if ((uint32_t)mt >= memtypes_size) {
    memory_panic("You need to recompile libphenom with memtypes_size = %d",
        2 * memtypes_size);
  }

  for (i = 0; i < num_types; i++) {
    mem_type = &memtypes[mt + i];
    memset(mem_type, 0, sizeof(*mem_type));

    mem_type->def = defs[i];
    if (i == 0) {
      mem_type->def.facility = strdup(defs[0].facility);
    } else {
      mem_type->def.facility = memtypes[mt].def.facility;
    }
    mem_type->def.name = strdup(defs[i].name);

    scope = ph_counter_scope_define(fac_scope, mem_type->def.name,
        MEM_COUNTER_SLOTS);
    if (!scope) {
      // FIXME: cleaner error handling
      return PH_MEMTYPE_INVALID;
    }
    mem_type->scope = scope;

    if (mem_type->def.item_size == 0) {
      names = vsize_counter_names;
      num_slots = MEM_COUNTER_SLOTS;
    } else {
      names = sized_counter_names;
      num_slots = MEM_COUNTER_SLOTS - 1;
    }
    mem_type->first_slot = ph_counter_scope_get_num_slots(scope);
    if (!ph_counter_scope_register_counter_block(
          scope, num_slots, 0, names)) {
      memory_panic("failed to register counter block for memory scope %s",
        mem_type->def.name);
    }
  }

  if (types) {
    for (i = 0; i < num_types; i++) {
      types[i] = mt + i;
    }
  }

  ph_counter_scope_delref(fac_scope);

  return mt;
}