diff options
-rw-r--r-- | libpurple/memorypool.c | 362 | ||||
-rw-r--r-- | libpurple/memorypool.h | 196 | ||||
-rw-r--r-- | libpurple/meson.build | 2 | ||||
-rw-r--r-- | po/POTFILES.in | 1 |
4 files changed, 0 insertions, 561 deletions
diff --git a/libpurple/memorypool.c b/libpurple/memorypool.c deleted file mode 100644 index bf02d2bd46..0000000000 --- a/libpurple/memorypool.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Purple - * - * Purple is the legal property of its developers, whose names are too - * numerous to list here. Please refer to the COPYRIGHT file distributed - * with this source distribution - * - * 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 - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "memorypool.h" - -#include <string.h> - -#define PURPLE_MEMORY_POOL_BLOCK_PADDING (sizeof(guint64)) -#define PURPLE_MEMORY_POINTER_SHIFT(pointer, value) \ - (gpointer)((guintptr)(pointer) + (value)) -#define PURPLE_MEMORY_PADDED(pointer, padding) \ - (gpointer)((((guintptr)(pointer) - 1) / (padding) + 1) * padding) - -#define PURPLE_MEMORY_POOL_DEFAULT_BLOCK_SIZE 1024 -#define PURPLE_MEMORY_POOL_DISABLED FALSE - -typedef struct _PurpleMemoryPoolBlock PurpleMemoryPoolBlock; - -typedef struct -{ - gboolean disabled; - gulong block_size; - - PurpleMemoryPoolBlock *first_block; - PurpleMemoryPoolBlock *last_block; -} PurpleMemoryPoolPrivate; - -struct _PurpleMemoryPoolBlock -{ - gpointer available_ptr; - gpointer end_ptr; - PurpleMemoryPoolBlock *next; -}; - -enum -{ - PROP_ZERO, - PROP_BLOCK_SIZE, - PROP_LAST -}; - -static GParamSpec *properties[PROP_LAST]; - -G_DEFINE_TYPE_WITH_PRIVATE(PurpleMemoryPool, purple_memory_pool, - G_TYPE_OBJECT); - -/******************************************************************************* - * Memory allocation/deallocation - ******************************************************************************/ - -static PurpleMemoryPoolBlock * -purple_memory_pool_block_new(gulong block_size) -{ - gpointer block_raw; - PurpleMemoryPoolBlock *block; - gsize total_size; - - /* ceil block struct size to the multiply of align */ - total_size = ((sizeof(PurpleMemoryPoolBlock) - 1) / - PURPLE_MEMORY_POOL_BLOCK_PADDING + 1) * - sizeof(PurpleMemoryPoolBlock); - g_return_val_if_fail(block_size < G_MAXSIZE - total_size, NULL); - total_size += block_size; - - block_raw = g_try_malloc(total_size); - g_return_val_if_fail(block_raw != NULL, NULL); - block = block_raw; - - /* in fact, we don't set available_ptr padded to - * PURPLE_MEMORY_POOL_BLOCK_PADDING, but we guarantee, there is at least - * block_size long block if padded to that value. */ - block->available_ptr = PURPLE_MEMORY_POINTER_SHIFT(block_raw, - sizeof(PurpleMemoryPoolBlock)); - block->end_ptr = PURPLE_MEMORY_POINTER_SHIFT(block_raw, total_size); - block->next = NULL; - - return block; -} - -static gpointer -purple_memory_pool_alloc_impl(PurpleMemoryPool *pool, gsize size, guint alignment) -{ - PurpleMemoryPoolPrivate *priv = NULL; - PurpleMemoryPoolBlock *blk; - gpointer mem = NULL; - - g_return_val_if_fail(PURPLE_IS_MEMORY_POOL(pool), NULL); - - priv = purple_memory_pool_get_instance_private(pool); - - if (priv->disabled) { - /* XXX: this may cause some leaks */ - return g_try_malloc(size); - } - - g_return_val_if_fail(alignment <= PURPLE_MEMORY_POOL_BLOCK_PADDING, NULL); - g_warn_if_fail(alignment >= 1); - if (alignment < 1) - alignment = 1; - - blk = priv->last_block; - - if (blk) { - mem = PURPLE_MEMORY_PADDED(blk->available_ptr, alignment); - if (mem >= blk->end_ptr) - mem = NULL; - else if (mem < blk->available_ptr) /* gpointer overflow */ - mem = NULL; - else if (PURPLE_MEMORY_POINTER_SHIFT(mem, size) >= blk->end_ptr) - mem = NULL; - } - - if (mem == NULL) { - gsize real_size = priv->block_size; - if (real_size < size) - real_size = size; - blk = purple_memory_pool_block_new(real_size); - g_return_val_if_fail(blk != NULL, NULL); - - g_assert((priv->first_block == NULL) == - (priv->last_block == NULL)); - - if (priv->first_block == NULL) { - priv->first_block = blk; - priv->last_block = blk; - } else { - priv->last_block->next = blk; - priv->last_block = blk; - } - - mem = PURPLE_MEMORY_PADDED(blk->available_ptr, alignment); - g_assert((guintptr)mem + size < (guintptr)blk->end_ptr); - g_assert(mem >= blk->available_ptr); /* gpointer overflow */ - } - - g_assert(blk != NULL); - g_assert(mem != NULL); - - blk->available_ptr = PURPLE_MEMORY_POINTER_SHIFT(mem, size); - g_assert(blk->available_ptr <= blk->end_ptr); - - return mem; -} - -static void -purple_memory_pool_cleanup_impl(PurpleMemoryPool *pool) -{ - PurpleMemoryPoolPrivate *priv = - purple_memory_pool_get_instance_private(pool); - PurpleMemoryPoolBlock *blk; - - blk = priv->first_block; - priv->first_block = NULL; - priv->last_block = NULL; - while (blk) { - PurpleMemoryPoolBlock *next = blk->next; - g_free(blk); - blk = next; - } -} - - -/******************************************************************************* - * API implementation - ******************************************************************************/ - -void -purple_memory_pool_set_block_size(PurpleMemoryPool *pool, gulong block_size) -{ - PurpleMemoryPoolPrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_MEMORY_POOL(pool)); - - priv = purple_memory_pool_get_instance_private(pool); - priv->block_size = block_size; - g_object_notify_by_pspec(G_OBJECT(pool), properties[PROP_BLOCK_SIZE]); -} - -gpointer -purple_memory_pool_alloc(PurpleMemoryPool *pool, gsize size, guint alignment) -{ - PurpleMemoryPoolClass *klass; - - if (size == 0) - return NULL; - - g_return_val_if_fail(PURPLE_IS_MEMORY_POOL(pool), NULL); - - klass = PURPLE_MEMORY_POOL_GET_CLASS(pool); - g_return_val_if_fail(klass != NULL, NULL); - g_return_val_if_fail(klass->palloc != NULL, NULL); - - return klass->palloc(pool, size, alignment); -} - -gpointer -purple_memory_pool_alloc0(PurpleMemoryPool *pool, gsize size, guint alignment) -{ - gpointer mem; - - if (size == 0) - return NULL; - - mem = purple_memory_pool_alloc(pool, size, alignment); - g_return_val_if_fail(mem != NULL, NULL); - - memset(mem, 0, size); - - return mem; -} - -void -purple_memory_pool_free(PurpleMemoryPool *pool, gpointer mem) -{ - PurpleMemoryPoolClass *klass; - - if (mem == NULL) - return; - - g_return_if_fail(PURPLE_IS_MEMORY_POOL(pool)); - - klass = PURPLE_MEMORY_POOL_GET_CLASS(pool); - g_return_if_fail(klass != NULL); - - if (klass->pfree) - klass->pfree(pool, mem); -} - -void -purple_memory_pool_cleanup(PurpleMemoryPool *pool) -{ - PurpleMemoryPoolClass *klass; - - g_return_if_fail(PURPLE_IS_MEMORY_POOL(pool)); - - klass = PURPLE_MEMORY_POOL_GET_CLASS(pool); - g_return_if_fail(klass != NULL); - - klass->cleanup(pool); -} - - -/******************************************************************************* - * Object stuff - ******************************************************************************/ - -PurpleMemoryPool * -purple_memory_pool_new(void) -{ - return g_object_new(PURPLE_TYPE_MEMORY_POOL, NULL); -} - -static void -purple_memory_pool_init(PurpleMemoryPool *pool) -{ - PurpleMemoryPoolPrivate *priv = - purple_memory_pool_get_instance_private(pool); - - priv->disabled = PURPLE_MEMORY_POOL_DISABLED; -} - -static void -purple_memory_pool_finalize(GObject *obj) -{ - purple_memory_pool_cleanup(PURPLE_MEMORY_POOL(obj)); - - G_OBJECT_CLASS(purple_memory_pool_parent_class)->finalize(obj); -} - -static void -purple_memory_pool_get_property(GObject *obj, guint param_id, GValue *value, - GParamSpec *pspec) -{ - PurpleMemoryPool *pool = PURPLE_MEMORY_POOL(obj); - PurpleMemoryPoolPrivate *priv = - purple_memory_pool_get_instance_private(pool); - - switch (param_id) { - case PROP_BLOCK_SIZE: - g_value_set_ulong(value, priv->block_size); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - } -} - -static void -purple_memory_pool_set_property(GObject *obj, guint param_id, - const GValue *value, GParamSpec *pspec) -{ - PurpleMemoryPool *pool = PURPLE_MEMORY_POOL(obj); - PurpleMemoryPoolPrivate *priv = - purple_memory_pool_get_instance_private(pool); - - switch (param_id) { - case PROP_BLOCK_SIZE: - priv->block_size = g_value_get_ulong(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - } -} - -static void -purple_memory_pool_class_init(PurpleMemoryPoolClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - obj_class->finalize = purple_memory_pool_finalize; - obj_class->get_property = purple_memory_pool_get_property; - obj_class->set_property = purple_memory_pool_set_property; - - klass->palloc = purple_memory_pool_alloc_impl; - klass->cleanup = purple_memory_pool_cleanup_impl; - - properties[PROP_BLOCK_SIZE] = g_param_spec_ulong("block-size", - "Block size", "The default size of each block of pool memory.", - 0, G_MAXULONG, PURPLE_MEMORY_POOL_DEFAULT_BLOCK_SIZE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(obj_class, PROP_LAST, properties); -} - -gchar * -purple_memory_pool_strdup(PurpleMemoryPool *pool, const gchar *str) -{ - gsize str_len; - gchar *str_dup; - - if (str == NULL) - return NULL; - - g_return_val_if_fail(PURPLE_IS_MEMORY_POOL(pool), NULL); - - str_len = strlen(str); - str_dup = purple_memory_pool_alloc(pool, str_len + 1, sizeof(gchar)); - g_return_val_if_fail(str_dup != NULL, NULL); - - memcpy(str_dup, str, str_len); - str_dup[str_len] = '\0'; - - return str_dup; -} diff --git a/libpurple/memorypool.h b/libpurple/memorypool.h deleted file mode 100644 index 35444a0ef8..0000000000 --- a/libpurple/memorypool.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Purple - * - * Purple is the legal property of its developers, whose names are too - * numerous to list here. Please refer to the COPYRIGHT file distributed - * with this source distribution - * - * 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 - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) -# error "only <purple.h> may be included directly" -#endif - -#ifndef PURPLE_MEMORY_POOL_H -#define PURPLE_MEMORY_POOL_H - -#include <glib-object.h> - -#define PURPLE_TYPE_MEMORY_POOL (purple_memory_pool_get_type()) -#define PURPLE_MEMORY_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_MEMORY_POOL, PurpleMemoryPool)) -#define PURPLE_MEMORY_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_MEMORY_POOL, PurpleMemoryPoolClass)) -#define PURPLE_IS_MEMORY_POOL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_MEMORY_POOL)) -#define PURPLE_IS_MEMORY_POOL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_MEMORY_POOL)) -#define PURPLE_MEMORY_POOL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_MEMORY_POOL, PurpleMemoryPoolClass)) - -typedef struct _PurpleMemoryPool PurpleMemoryPool; -typedef struct _PurpleMemoryPoolClass PurpleMemoryPoolClass; - -/** - * PurpleMemoryPool: - * - * A #PurpleMemoryPool allows allocating many small objects within a single - * memory range and releasing them all at once using a single call. This - * prevents memory fragmentation and improves performance when used properly. - * Its purpose is to act as an internal storage for other object private - * structures, like tree nodes, string chunks, list elements. - * - * Current implementation is not optimized for releasing individual objects, - * so it may be extremely inefficient, when misused. On every memory allocation, - * it checks if there is enough space in current block. If there is not enough - * room here, it creates another block of memory. On pool destruction or calling - * #purple_memory_pool_cleanup, the whole block chain will be freed, using only - * one #g_free call for every block. - */ -struct _PurpleMemoryPool -{ - /*< private >*/ - GObject parent_instance; -}; - -/** - * PurpleMemoryPoolClass: - * @palloc: alloates memory for a specific memory pool subclass, - * see #purple_memory_pool_alloc. - * @pfree: frees memory allocated within a pool, see #purple_memory_pool_free. - * May be %NULL. - * @cleanup: frees (or marks as unused) all memory allocated within a pool. - * See #purple_memory_pool_cleanup. - * - * Base class for #PurpleMemoryPool objects. - */ -struct _PurpleMemoryPoolClass -{ - /*< private >*/ - GObjectClass parent_class; - - /*< public >*/ - gpointer (*palloc)(PurpleMemoryPool *pool, gsize size, guint alignment); - gpointer (*pfree)(PurpleMemoryPool *pool, gpointer mem); - void (*cleanup)(PurpleMemoryPool *pool); - - /*< private >*/ - void (*purple_reserved1)(void); - void (*purple_reserved2)(void); - void (*purple_reserved3)(void); - void (*purple_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * purple_memory_pool_get_type: - * - * Returns: the #GType for a #PurpleMemoryPool. - */ -GType -purple_memory_pool_get_type(void); - -/** - * purple_memory_pool_new: - * - * Creates a new memory pool. - * - * Returns: the new #PurpleMemoryPool. - */ -PurpleMemoryPool * -purple_memory_pool_new(void); - -/** - * purple_memory_pool_set_block_size: - * @pool: the memory pool. - * @block_size: the new default block size. - * - * Sets new default block size for a memory pool. You might want to call this - * before any allocation, to have it applied to the every created block. - */ -void -purple_memory_pool_set_block_size(PurpleMemoryPool *pool, gulong block_size); - -/** - * purple_memory_pool_alloc: - * @pool: the memory pool. - * @size: the size of memory to be allocated. - * @alignment: the alignment of memory block (should be a power of two). - * - * Allocates an aligned memory block within a pool. - * - * Returns: the pointer to a memory block. This should be freed with - * a call to #purple_memory_pool_free. - */ -gpointer -purple_memory_pool_alloc(PurpleMemoryPool *pool, gsize size, guint alignment); - -/** - * purple_memory_pool_alloc0: - * @pool: the memory pool. - * @size: the size of memory to be allocated. - * @alignment: the alignment of memory block (should be a power of two). - * - * Allocates an aligned memory block within a pool and sets its contents to - * zeros. - * - * Returns: the pointer to a memory block. This should be freed with - * a call to #purple_memory_pool_free. - */ -gpointer -purple_memory_pool_alloc0(PurpleMemoryPool *pool, gsize size, guint alignment); - -/** - * purple_memory_pool_free: - * @pool: the memory pool. - * @mem: the pointer to a memory block. - * - * Frees a memory allocated within a memory pool. This can be a no-op in certain - * implementations. Thus, it don't need to be called in every case. Thus, the - * freed memory is wasted until you call #purple_memory_pool_cleanup - * or destroy the @pool. - */ -void -purple_memory_pool_free(PurpleMemoryPool *pool, gpointer mem); - -/** - * purple_memory_pool_cleanup: - * @pool: the memory pool. - * - * Marks all memory allocated within a memory pool as not used. It may free - * resources, but don't have to. - */ -void -purple_memory_pool_cleanup(PurpleMemoryPool *pool); - -/** - * purple_memory_pool_strdup: - * @pool: the memory pool. - * @str: the string to duplicate. - * - * Duplicates a string using a memory allocated within a memory pool. If @str is - * %NULL, it returns %NULL. The returned string should be freed with g_free() - * when no longer needed. - * - * Returns: a newly-allocated copy of @str. - */ -gchar * -purple_memory_pool_strdup(PurpleMemoryPool *pool, const gchar *str); - -G_END_DECLS - -#endif /* PURPLE_MEMORY_POOL_H */ diff --git a/libpurple/meson.build b/libpurple/meson.build index 3f2bbde684..a8f6887266 100644 --- a/libpurple/meson.build +++ b/libpurple/meson.build @@ -26,7 +26,6 @@ purple_coresources = [ 'media/enum-types.c', 'media.c', 'mediamanager.c', - 'memorypool.c', 'nat-pmp.c', 'network.c', 'notify.c', @@ -128,7 +127,6 @@ purple_coreheaders = [ 'media.h', 'media-gst.h', 'mediamanager.h', - 'memorypool.h', 'nat-pmp.h', 'network.h', 'notify.h', diff --git a/po/POTFILES.in b/po/POTFILES.in index 1a82e862a2..4821100ff8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -48,7 +48,6 @@ libpurple/media/candidate.c libpurple/media/codec.c libpurple/media/enum-types.c libpurple/mediamanager.c -libpurple/memorypool.c libpurple/nat-pmp.c libpurple/network.c libpurple/notify.c |