Commit ade18c04 authored by Daniel Salzman's avatar Daniel Salzman

Merge branch 'mm_functions' into 'master'

Added mm_calloc and mm_strdup

See merge request knot/knot-dns!854
parents 763150ad 53956f1d
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -218,37 +218,35 @@ static void hhash_free_buckets(hhash_t *tbl)
for (unsigned i = 0; i < tbl->size; ++i) {
mm_free(tbl->mm, tbl->item[i].d);
}
hhash_invalidate_index(tbl);
}
hhash_t *hhash_create(uint32_t size)
{
knot_mm_t mm;
mm_ctx_init(&mm);
return hhash_create_mm(size, &mm);
}
hhash_t *hhash_create_mm(uint32_t size, const knot_mm_t *mm)
hhash_t *hhash_create_mm(uint32_t size, knot_mm_t *mm)
{
if (size == 0) {
return NULL;
}
const size_t total_len = sizeof(hhash_t) + size * sizeof(hhelem_t);
hhash_t *tbl = mm_alloc((knot_mm_t *)mm, total_len);
hhash_t *tbl = mm_calloc(mm, total_len, sizeof(uint8_t));
if (tbl == NULL) {
return NULL;
}
memset(tbl, 0, total_len);
knot_mm_t *mm_copy = mm_alloc((knot_mm_t *)mm, sizeof(knot_mm_t));
knot_mm_t *mm_copy = mm_alloc(mm, sizeof(*mm_copy));
if (mm_copy == NULL) {
mm_free((knot_mm_t *)mm, tbl);
mm_free(mm, tbl);
return NULL;
}
memcpy(mm_copy, mm, sizeof(knot_mm_t));
memcpy(mm_copy, mm, sizeof(*mm_copy));
tbl->size = size;
tbl->mm = mm_copy;
......
/* Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -17,9 +17,6 @@
* \file
*
* \brief Hopscotch hashing scheme based hash table.
*
* \addtogroup contrib
* @{
*/
#pragma once
......@@ -77,7 +74,7 @@ typedef struct hhash {
hhash_t *hhash_create(uint32_t size);
/*! \brief Create hopscotch hash table (custom memory manager). */
hhash_t *hhash_create_mm(uint32_t size, const struct knot_mm *mm);
hhash_t *hhash_create_mm(uint32_t size, struct knot_mm *mm);
/*!
* \brief Clear hash table.
......@@ -201,5 +198,3 @@ const char *hhash_iter_key (hhash_iter_t*, uint16_t* len);
/*! \brief Return current value. */
value_t *hhash_iter_val(hhash_iter_t*);
/*! @} */
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,6 +19,12 @@
#include "contrib/mempattern.h"
#include "contrib/ucw/mempool.h"
/*
* Inspired by OPENSSL_cleanse. Such a memset shouldn't be optimized out.
*/
typedef void *(*memset_t)(void *, int, size_t);
static volatile memset_t volatile_memset = memset;
static void mm_nofree(void *p)
{
/* nop */
......@@ -39,6 +45,26 @@ void *mm_alloc(knot_mm_t *mm, size_t size)
}
}
void *mm_calloc(knot_mm_t *mm, size_t nmemb, size_t size)
{
if (nmemb == 0 || size == 0) {
return NULL;
}
if (mm) {
size_t total_size = nmemb * size;
if (total_size / nmemb != size) { // Overflow check
return NULL;
}
void *mem = mm_alloc(mm, total_size);
if (mem == NULL) {
return NULL;
}
return volatile_memset(mem, 0, total_size);
} else {
return calloc(nmemb, size);
}
}
void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t prev_size)
{
if (mm) {
......@@ -58,6 +84,23 @@ void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t prev_size)
}
}
char *mm_strdup(knot_mm_t *mm, const char *s)
{
if (s == NULL) {
return NULL;
}
if (mm) {
size_t len = strlen(s) + 1;
void *mem = mm_alloc(mm, len);
if (mem == NULL) {
return NULL;
}
return memcpy(mem, s, len);
} else {
return strdup(s);
}
}
void mm_free(knot_mm_t *mm, void *what)
{
if (mm) {
......
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -17,22 +17,27 @@
* \file
*
* \brief Memory allocation related functions.
*
* \addtogroup contrib
* @{
*/
#pragma once
#include "libknot/mm_ctx.h"
/* Default memory block size. */
/*! \brief Default memory block size. */
#define MM_DEFAULT_BLKSIZE 4096
/*! \brief Allocs using 'mm' if any, uses system malloc() otherwise. */
void *mm_alloc(knot_mm_t *mm, size_t size);
/*! \brief Callocs using 'mm' if any, uses system calloc() otherwise. */
void *mm_calloc(knot_mm_t *mm, size_t nmemb, size_t size);
/*! \brief Reallocs using 'mm' if any, uses system realloc() otherwise. */
void *mm_realloc(knot_mm_t *mm, void *what, size_t size, size_t prev_size);
/*! \brief Strdups using 'mm' if any, uses system strdup() otherwise. */
char *mm_strdup(knot_mm_t *mm, const char *s);
/*! \brief Free using 'mm' if any, uses system free() otherwise. */
void mm_free(knot_mm_t *mm, void *what);
......@@ -41,5 +46,3 @@ void mm_ctx_init(knot_mm_t *mm);
/*! \brief Memory pool context. */
void mm_ctx_mempool(knot_mm_t *mm, size_t chunk_size);
/*! @} */
......@@ -481,11 +481,10 @@ typedef struct {
static send_ctx_t *create_send_ctx(const knot_dname_t *zone_name, ctl_args_t *args)
{
send_ctx_t *ctx = mm_alloc(&args->mm, sizeof(*ctx));
send_ctx_t *ctx = mm_calloc(&args->mm, 1, sizeof(*ctx));
if (ctx == NULL) {
return NULL;
}
memset(ctx, 0, sizeof(*ctx));
ctx->args = args;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment