diff options
author | Thibaut Mattern <tmattern@users.sourceforge.net> | 2006-01-27 07:53:28 +0000 |
---|---|---|
committer | Thibaut Mattern <tmattern@users.sourceforge.net> | 2006-01-27 07:53:28 +0000 |
commit | b96a355c274078dcb699a75996c7461ce2be70b4 (patch) | |
tree | ec75e26faa40d4ce79a1b5173bb97b7aecb0d364 | |
parent | 0a391246fd4e8a3c64f3d817cd8ec11c9aaaffd9 (diff) | |
download | xine-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.c | 179 | ||||
-rw-r--r-- | src/xine-utils/pool.h | 50 |
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); |