summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibaut Mattern <tmattern@users.sourceforge.net>2006-01-27 07:53:28 +0000
committerThibaut Mattern <tmattern@users.sourceforge.net>2006-01-27 07:53:28 +0000
commitb96a355c274078dcb699a75996c7461ce2be70b4 (patch)
treeec75e26faa40d4ce79a1b5173bb97b7aecb0d364
parent0a391246fd4e8a3c64f3d817cd8ec11c9aaaffd9 (diff)
downloadxine-lib-b96a355c274078dcb699a75996c7461ce2be70b4.tar.gz
xine-lib-b96a355c274078dcb699a75996c7461ce2be70b4.tar.bz2
Added dynamic object pool.
CVS patchset: 7849 CVS date: 2006/01/27 07:53:28
-rw-r--r--src/xine-utils/pool.c179
-rw-r--r--src/xine-utils/pool.h50
2 files changed, 229 insertions, 0 deletions
diff --git a/src/xine-utils/pool.c b/src/xine-utils/pool.c
new file mode 100644
index 000000000..3532def56
--- /dev/null
+++ b/src/xine-utils/pool.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2000-2006 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine 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.
+ *
+ * xine 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: pool.c,v 1.1 2006/01/27 07:53:28 tmattern Exp $
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include "pool.h"
+#include "array.h"
+
+#define MIN_CHUNK_SIZE 32
+#define MAX_CHUNK_SIZE 65536
+
+/* chunk of objects */
+typedef struct xine_pool_chunk_s xine_pool_chunk_t;
+struct xine_pool_chunk_s {
+ void *mem_base; /* the allocated elements */
+ int count; /* object count in the chunk */
+ int current_id; /* next free object in the chunk */
+};
+
+struct xine_pool_s {
+ size_t object_size;
+
+ /* callbacks */
+ void (*create_object)(void *object);
+ void (*prepare_object)(void *object);
+ void (*return_object)(void *object);
+ void (*delete_object)(void *object);
+
+ /* chunks */
+ xine_array_t *chunk_list;
+ xine_array_t *free_list;
+
+};
+
+/* Allocates a new chunk of n elements
+ * One malloc call is used to allocate the struct and the elements.
+ */
+static xine_pool_chunk_t *xine_pool_alloc_chunk(size_t object_size, size_t object_count) {
+ xine_pool_chunk_t *new_chunk;
+ size_t chunk_mem_size;;
+
+ assert(object_size > 0);
+ assert(object_count > 0);
+ chunk_mem_size = sizeof(xine_pool_chunk_t);
+ chunk_mem_size += object_size * object_count;
+
+ new_chunk = (xine_pool_chunk_t *)malloc(chunk_mem_size);
+ new_chunk->mem_base = (xine_pool_chunk_t*)(new_chunk + 1);
+ new_chunk->current_id = 0;
+ new_chunk->count = object_count;
+
+ return new_chunk;
+}
+
+/* Delete a chunk */
+static void xine_pool_delete_chunk(xine_pool_chunk_t *chunk) {
+ assert(chunk);
+ free(chunk);
+}
+
+xine_pool_t *xine_pool_new(size_t object_size,
+ void (*create_object)(void *object),
+ void (*prepare_object)(void *object),
+ void (*return_object)(void *object),
+ void (*delete_object)(void *object)) {
+ xine_pool_t *new_pool;
+ assert(object_size > 0);
+
+ new_pool = malloc(sizeof(xine_pool_t));
+ new_pool->object_size = object_size;
+ new_pool->create_object = create_object;
+ new_pool->prepare_object = prepare_object;
+ new_pool->return_object = return_object;
+ new_pool->delete_object = delete_object;
+ new_pool->chunk_list = xine_array_new(0);
+ new_pool->free_list = xine_array_new(MIN_CHUNK_SIZE);
+
+ xine_array_add(new_pool->chunk_list,
+ xine_pool_alloc_chunk (object_size, MIN_CHUNK_SIZE));
+ return new_pool;
+}
+
+void xine_pool_delete(xine_pool_t *pool) {
+ int list_id, list_size;
+
+ assert(pool);
+ list_size = xine_array_size(pool->chunk_list);
+
+ for (list_id = 0; list_id < list_size; list_id++) {
+ xine_pool_chunk_t *chunk = xine_array_get(pool->chunk_list, list_id);
+
+ /* delete each created object */
+ if (pool->delete_object) {
+ int i;
+
+ for (i = 0; i < chunk->current_id; i++) {
+ void *object = ((uint8_t*)(chunk->mem_base)) + i * pool->object_size;
+ pool->delete_object(object);
+ }
+ }
+ xine_pool_delete_chunk(chunk);
+ }
+ free (pool);
+}
+
+void *xine_pool_get(xine_pool_t *pool) {
+ void *object = NULL;
+ int free_count;
+
+ assert(pool);
+
+ /* check the free list */
+ free_count = xine_array_size(pool->free_list);
+ if (free_count > 0) {
+ object = xine_array_get(pool->free_list, free_count - 1);
+ xine_array_remove(pool->free_list, free_count - 1);
+ } else {
+ /* check the current chunk */
+ int chunk_count = xine_array_size(pool->chunk_list);
+ xine_pool_chunk_t *current_chunk = xine_array_get(pool->chunk_list, chunk_count - 1);
+
+ if (current_chunk->current_id < current_chunk->count) {
+ /* take the next entry of the chunk */
+ object = ((uint8_t*)(current_chunk->mem_base)) +
+ current_chunk->current_id * pool->object_size;
+ current_chunk->current_id++;
+ } else {
+ /* create a new chunk */
+ xine_pool_chunk_t *new_chunk;
+ int new_chunk_count = current_chunk->count * 2;
+ if (new_chunk_count > MAX_CHUNK_SIZE) {
+ new_chunk_count = MAX_CHUNK_SIZE;
+ }
+ new_chunk = xine_pool_alloc_chunk (pool->object_size, new_chunk_count);
+ xine_array_add(pool->chunk_list, new_chunk);
+ object = new_chunk->mem_base;
+ new_chunk->current_id = 1;
+ }
+ if (pool->create_object) {
+ pool->create_object(object);
+ }
+ }
+
+ if (pool->prepare_object) {
+ pool->prepare_object(object);
+ }
+ return object;
+}
+
+void xine_pool_put(xine_pool_t *pool, void *object) {
+ assert(pool);
+ assert(object);
+ if (pool->return_object) {
+ pool->return_object(object);
+ }
+ xine_array_add(pool->free_list, object);
+}
diff --git a/src/xine-utils/pool.h b/src/xine-utils/pool.h
new file mode 100644
index 000000000..d2fa39497
--- /dev/null
+++ b/src/xine-utils/pool.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2000-2006 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine 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.
+ *
+ * xine 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: pool.h,v 1.1 2006/01/27 07:53:28 tmattern Exp $
+ *
+ * Object Pool
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+typedef struct xine_pool_s xine_pool_t;
+
+/* Creates a new pool
+ * object_size: sizeof(your struct)
+ * create_object: function called to create an object (can be NULL)
+ * prepare_object: function called to prepare an object to returned to the client (can be NULL)
+ * return_object: function called to prepare an object to returned to the pool (can be NULL)
+ * delete_object: function called to delete an object (can be NULL)
+ */
+xine_pool_t *xine_pool_new(size_t object_size,
+ void (create_object)(void *object),
+ void (prepare_object)(void *object),
+ void (return_object)(void *object),
+ void (delete_object)(void *object));
+
+/* Deletes a pool */
+void xine_pool_delete(xine_pool_t *pool);
+
+/* Get an object from the pool */
+void *xine_pool_get(xine_pool_t *pool);
+
+/* Returns an object to the pool */
+void xine_pool_put(xine_pool_t *pool, void *object);