2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include <string.h> /* memset */
24 #include "gstmemchunk.h"
25 #include "gsttrashstack.h"
27 #define GST_MEM_CHUNK_AREA(chunk) (((GstMemChunkElement*)(chunk))->area)
28 #define GST_MEM_CHUNK_DATA(chunk) ((gpointer)(((GstMemChunkElement*)(chunk)) + 1))
29 #define GST_MEM_CHUNK_LINK(mem) ((GstMemChunkElement*)((guint8*)(mem) - sizeof (GstMemChunkElement)))
31 typedef struct _GstMemChunkElement GstMemChunkElement;
33 struct _GstMemChunkElement
35 GstTrashStackElement elem; /* make sure we can safely push it on the trashstack */
36 gpointer area; /* pointer to data areas */
50 /*******************************************************
52 * +-------------------------------------------------------+
56 * !next!area|data... !next!area!data.... !next!area!data...
58 * +------------------+ +-----------------+ +--------> NULL
62 populate (GstMemChunk *mem_chunk)
67 if (mem_chunk->cleanup)
70 area = (guint8 *) g_malloc0 (mem_chunk->area_size);
72 for (i=0; i < mem_chunk->area_size; i += mem_chunk->chunk_size) {
73 GST_MEM_CHUNK_AREA (area + i) = area;
74 gst_trash_stack_push (&mem_chunk->stack, area + i);
82 * @name: the name of the chunk
83 * @atom_size: the size of the allocated atoms
84 * @area_size: the initial size of the memory area
85 * @type: the allocation strategy to use
87 * Creates a new memchunk that will allocate atom_sized memchunks.
88 * The initial area is set to area_size and will grow automatically
89 * when it is too small (with a small overhead when that happens)
91 * Returns: a new #GstMemChunk
94 gst_mem_chunk_new (gchar* name, gint atom_size, gulong area_size, gint type)
96 GstMemChunk *mem_chunk;
98 g_return_val_if_fail (atom_size > 0, NULL);
99 g_return_val_if_fail (area_size >= atom_size, NULL);
101 mem_chunk = g_malloc (sizeof (GstMemChunk));
103 mem_chunk->chunk_size = atom_size + sizeof (GstMemChunkElement);
104 area_size = (area_size/atom_size) * mem_chunk->chunk_size;
106 mem_chunk->name = g_strdup (name);
107 mem_chunk->atom_size = atom_size;
108 mem_chunk->area_size = area_size;
109 mem_chunk->cleanup = FALSE;
110 gst_trash_stack_init (&mem_chunk->stack);
112 populate (mem_chunk);
118 free_area (gpointer key, gpointer value, gpointer user_data)
126 * gst_mem_chunk_destroy:
127 * @mem_chunk: the GstMemChunk to destroy
129 * Free the memory allocated by the memchunk
132 gst_mem_chunk_destroy (GstMemChunk *mem_chunk)
134 GHashTable *elements = g_hash_table_new (NULL, NULL);
137 mem_chunk->cleanup = TRUE;
139 data = gst_mem_chunk_alloc (mem_chunk);
141 GstMemChunkElement *elem = GST_MEM_CHUNK_LINK (data);
143 g_hash_table_insert (elements, GST_MEM_CHUNK_AREA (elem), NULL);
145 data = gst_mem_chunk_alloc (mem_chunk);
147 g_hash_table_foreach_remove (elements, free_area, NULL);
149 g_hash_table_destroy (elements);
150 g_free (mem_chunk->name);
155 * gst_mem_chunk_alloc:
156 * @mem_chunk: the mem chunk to use
158 * Allocate a new memory region from the chunk. The size
159 * of the allocated memory was specified when the memchunk
162 * Returns: a pointer to the allocated memory region.
165 gst_mem_chunk_alloc (GstMemChunk *mem_chunk)
167 GstMemChunkElement *chunk;
169 g_return_val_if_fail (mem_chunk != NULL, NULL);
172 chunk = gst_trash_stack_pop (&mem_chunk->stack);
173 /* chunk is empty, try to refill */
175 if (populate (mem_chunk))
181 return GST_MEM_CHUNK_DATA (chunk);
185 * gst_mem_chunk_alloc0:
186 * @mem_chunk: the mem chunk to use
188 * Allocate a new memory region from the chunk. The size
189 * of the allocated memory was specified when the memchunk
190 * was created. The memory will be set to all zeroes.
192 * Returns: a pointer to the allocated memory region.
195 gst_mem_chunk_alloc0 (GstMemChunk *mem_chunk)
197 gpointer mem = gst_mem_chunk_alloc (mem_chunk);
200 memset (mem, 0, mem_chunk->atom_size);
206 * gst_mem_chunk_free:
207 * @mem_chunk: the mem chunk to use
208 * @mem: the memory region to hand back to the chunk
210 * Free the memeory region allocated from the chunk.
213 gst_mem_chunk_free (GstMemChunk *mem_chunk, gpointer mem)
215 GstMemChunkElement *chunk;
217 g_return_if_fail (mem_chunk != NULL);
218 g_return_if_fail (mem != NULL);
220 chunk = GST_MEM_CHUNK_LINK (mem);
222 gst_trash_stack_push (&mem_chunk->stack, chunk);