view src/lib/mempool.h @ 4633:9de853d23279 HEAD

Added p_free_and_null() and did some cleanups.
author Timo Sirainen <tss@iki.fi>
date Sun, 08 Oct 2006 16:28:56 +0300
parents bf0a03691989
children b0daeec3d416
line wrap: on
line source

#ifndef __MEMPOOL_H
#define __MEMPOOL_H

#include "macros.h"

/* Memory allocated and reallocated (the new data in it) in pools is always
   zeroed, it will cost only a few CPU cycles and may well save some debug
   time. */

typedef struct pool *pool_t;

struct pool {
	const char *(*get_name)(pool_t pool);

	void (*ref)(pool_t pool);
	void (*unref)(pool_t *pool);

	void *(*malloc)(pool_t pool, size_t size);
	void (*free)(pool_t pool, void *mem);

	/* memory in old_size..new_size will be zeroed */
	void *(*realloc)(pool_t pool, void *mem,
			 size_t old_size, size_t new_size);

	/* Frees all the memory in pool. NOTE: system_pool doesn't support
	   this and crashes if it's used */
	void (*clear)(pool_t pool);

	/* Returns the maximum amount of bytes that can be allocated with
	   minimal trouble. If there's no such concept, always returns 0. */
	size_t (*get_max_easy_alloc_size)(pool_t pool);

	unsigned int alloconly_pool:1;
	unsigned int datastack_pool:1;
};

/* system_pool uses calloc() + realloc() + free() */
extern pool_t system_pool;

/* memory allocated from data_stack is valid only until next t_pop() call.
   No checks are performed. */
extern pool_t unsafe_data_stack_pool;

/* Create a new alloc-only pool. Note that `size' specifies the initial
   malloc()ed block size, part of it is used internally. */
pool_t pool_alloconly_create(const char *name, size_t size);

/* When allocating memory from returned pool, the data stack frame must be
   the same as it was when calling this function. pool_unref() also checks
   that the stack frame is the same. This should make it quite safe to use. */
pool_t pool_datastack_create(void);

/* Similar to nearest_power(), but try not to exceed buffer's easy
   allocation size. If you don't have any explicit minimum size, use
   old_size + 1. */
size_t pool_get_exp_grown_size(pool_t pool, size_t old_size, size_t min_size);

/* Pools should be used through these macros: */
#define pool_get_name(pool) (pool)->get_name(pool)
#define pool_ref(pool) (pool)->ref(pool)
#define pool_unref(pool) (pool)->unref(&(pool))

#define p_new(pool, type, count) \
	((type *) p_malloc(pool, sizeof(type) * (count)))

#define p_malloc(pool, size) (pool)->malloc(pool, size)
#define p_realloc(pool, mem, old_size, new_size) \
	(pool)->realloc(pool, mem, old_size, new_size)

/* Free the memory. Currently it also sets memory to NULL, but that shouldn't
   be relied on as it's only an extra safety check. It might as well be later
   changed to some invalid pointer causing a segfault, or removed completely
   in some "optimization".. */
#define p_free(pool, mem) \
	STMT_START { \
          (pool)->free(pool, mem); \
          (mem) = NULL; \
	} STMT_END

/* A macro that's guaranteed to set mem = NULL. */
#define p_free_and_null(pool, mem) p_free(pool, mem)

#define p_clear(pool) (pool)->clear(pool)

#define p_get_max_easy_alloc_size(pool) (pool)->get_max_easy_alloc_size(pool)

#endif