summaryrefslogtreecommitdiff
path: root/pjmedia/src/pjmedia/portaudio/pa_allocation.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjmedia/src/pjmedia/portaudio/pa_allocation.c')
-rw-r--r--pjmedia/src/pjmedia/portaudio/pa_allocation.c489
1 files changed, 255 insertions, 234 deletions
diff --git a/pjmedia/src/pjmedia/portaudio/pa_allocation.c b/pjmedia/src/pjmedia/portaudio/pa_allocation.c
index 035b4d0b..d9f068c4 100644
--- a/pjmedia/src/pjmedia/portaudio/pa_allocation.c
+++ b/pjmedia/src/pjmedia/portaudio/pa_allocation.c
@@ -1,234 +1,255 @@
-/*
- * $Id: pa_allocation.c,v 1.1.2.6 2004/12/20 12:07:51 rossbencina Exp $
- * Portable Audio I/O Library allocation group implementation
- * memory allocation group for tracking allocation groups
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/** @file
- @brief Allocation Group implementation.
-*/
-
-
-#include "pa_allocation.h"
-#include "pa_util.h"
-
-
-/*
- Maintain 3 singly linked lists...
- linkBlocks: the buffers used to allocate the links
- spareLinks: links available for use in the allocations list
- allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory()
-
- Link block size is doubled every time new links are allocated.
-*/
-
-
-#define PA_INITIAL_LINK_COUNT_ 16
-
-struct PaUtilAllocationGroupLink
-{
- struct PaUtilAllocationGroupLink *next;
- void *buffer;
-};
-
-/*
- Allocate a block of links. The first link will have it's buffer member
- pointing to the block, and it's next member set to <nextBlock>. The remaining
- links will have NULL buffer members, and each link will point to
- the next link except the last, which will point to <nextSpare>
-*/
-static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
- struct PaUtilAllocationGroupLink *nextBlock,
- struct PaUtilAllocationGroupLink *nextSpare )
-{
- struct PaUtilAllocationGroupLink *result;
- int i;
-
- result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
- sizeof(struct PaUtilAllocationGroupLink) * count );
- if( result )
- {
- /* the block link */
- result[0].buffer = result;
- result[0].next = nextBlock;
-
- /* the spare links */
- for( i=1; i<count; ++i )
- {
- result[i].buffer = 0;
- result[i].next = &result[i+1];
- }
- result[count-1].next = nextSpare;
- }
-
- return result;
-}
-
-
-PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void )
-{
- PaUtilAllocationGroup* result = 0;
- struct PaUtilAllocationGroupLink *links;
-
-
- links = AllocateLinks( PA_INITIAL_LINK_COUNT_, 0, 0 );
- if( links != 0 )
- {
- result = (PaUtilAllocationGroup*)PaUtil_AllocateMemory( sizeof(PaUtilAllocationGroup) );
- if( result )
- {
- result->linkCount = PA_INITIAL_LINK_COUNT_;
- result->linkBlocks = &links[0];
- result->spareLinks = &links[1];
- result->allocations = 0;
- }
- else
- {
- PaUtil_FreeMemory( links );
- }
- }
-
- return result;
-}
-
-
-void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group )
-{
- struct PaUtilAllocationGroupLink *current = group->linkBlocks;
- struct PaUtilAllocationGroupLink *next;
-
- while( current )
- {
- next = current->next;
- PaUtil_FreeMemory( current->buffer );
- current = next;
- }
-
- PaUtil_FreeMemory( group );
-}
-
-
-void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
-{
- struct PaUtilAllocationGroupLink *links, *link;
- void *result = 0;
-
- /* allocate more links if necessary */
- if( !group->spareLinks )
- {
- /* double the link count on each block allocation */
- links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks );
- if( links )
- {
- group->linkCount += group->linkCount;
- group->linkBlocks = &links[0];
- group->spareLinks = &links[1];
- }
- }
-
- if( group->spareLinks )
- {
- result = PaUtil_AllocateMemory( size );
- if( result )
- {
- link = group->spareLinks;
- group->spareLinks = link->next;
-
- link->buffer = result;
- link->next = group->allocations;
-
- group->allocations = link;
- }
- }
-
- return result;
-}
-
-
-void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer )
-{
- struct PaUtilAllocationGroupLink *current = group->allocations;
- struct PaUtilAllocationGroupLink *previous = 0;
-
- if( buffer == 0 )
- return;
-
- /* find the right link and remove it */
- while( current )
- {
- if( current->buffer == buffer )
- {
- if( previous )
- {
- previous->next = current->next;
- }
- else
- {
- group->allocations = current->next;
- }
-
- current->buffer = 0;
- current->next = group->spareLinks;
- group->spareLinks = current;
-
- break;
- }
-
- previous = current;
- current = current->next;
- }
-
- PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */
-}
-
-
-void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group )
-{
- struct PaUtilAllocationGroupLink *current = group->allocations;
- struct PaUtilAllocationGroupLink *previous = 0;
-
- /* free all buffers in the allocations list */
- while( current )
- {
- PaUtil_FreeMemory( current->buffer );
- current->buffer = 0;
-
- previous = current;
- current = current->next;
- }
-
- /* link the former allocations list onto the front of the spareLinks list */
- if( previous )
- {
- previous->next = group->spareLinks;
- group->spareLinks = group->allocations;
- group->allocations = 0;
- }
-}
-
+/*
+ * $Id: pa_allocation.c,v 1.1.2.6 2004/12/20 12:07:51 rossbencina Exp $
+ * Portable Audio I/O Library allocation group implementation
+ * memory allocation group for tracking allocation groups
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * PJMEDIA - Multimedia over IP Stack
+ * (C)2003-2005 Benny Prijono <bennylp@bulukucing.org>
+ *
+ * Author:
+ * Benny Prijono <bennylp@bulukucing.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** @file
+ @brief Allocation Group implementation.
+*/
+
+
+#include "pa_allocation.h"
+#include "pa_util.h"
+
+
+/*
+ Maintain 3 singly linked lists...
+ linkBlocks: the buffers used to allocate the links
+ spareLinks: links available for use in the allocations list
+ allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory()
+
+ Link block size is doubled every time new links are allocated.
+*/
+
+
+#define PA_INITIAL_LINK_COUNT_ 16
+
+struct PaUtilAllocationGroupLink
+{
+ struct PaUtilAllocationGroupLink *next;
+ void *buffer;
+};
+
+/*
+ Allocate a block of links. The first link will have it's buffer member
+ pointing to the block, and it's next member set to <nextBlock>. The remaining
+ links will have NULL buffer members, and each link will point to
+ the next link except the last, which will point to <nextSpare>
+*/
+static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
+ struct PaUtilAllocationGroupLink *nextBlock,
+ struct PaUtilAllocationGroupLink *nextSpare )
+{
+ struct PaUtilAllocationGroupLink *result;
+ int i;
+
+ result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
+ sizeof(struct PaUtilAllocationGroupLink) * count );
+ if( result )
+ {
+ /* the block link */
+ result[0].buffer = result;
+ result[0].next = nextBlock;
+
+ /* the spare links */
+ for( i=1; i<count; ++i )
+ {
+ result[i].buffer = 0;
+ result[i].next = &result[i+1];
+ }
+ result[count-1].next = nextSpare;
+ }
+
+ return result;
+}
+
+
+PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void )
+{
+ PaUtilAllocationGroup* result = 0;
+ struct PaUtilAllocationGroupLink *links;
+
+
+ links = AllocateLinks( PA_INITIAL_LINK_COUNT_, 0, 0 );
+ if( links != 0 )
+ {
+ result = (PaUtilAllocationGroup*)PaUtil_AllocateMemory( sizeof(PaUtilAllocationGroup) );
+ if( result )
+ {
+ result->linkCount = PA_INITIAL_LINK_COUNT_;
+ result->linkBlocks = &links[0];
+ result->spareLinks = &links[1];
+ result->allocations = 0;
+ }
+ else
+ {
+ PaUtil_FreeMemory( links );
+ }
+ }
+
+ return result;
+}
+
+
+void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group )
+{
+ struct PaUtilAllocationGroupLink *current = group->linkBlocks;
+ struct PaUtilAllocationGroupLink *next;
+
+ while( current )
+ {
+ next = current->next;
+ PaUtil_FreeMemory( current->buffer );
+ current = next;
+ }
+
+ PaUtil_FreeMemory( group );
+}
+
+
+void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
+{
+ struct PaUtilAllocationGroupLink *links, *link;
+ void *result = 0;
+
+ /* allocate more links if necessary */
+ if( !group->spareLinks )
+ {
+ /* double the link count on each block allocation */
+ links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks );
+ if( links )
+ {
+ group->linkCount += group->linkCount;
+ group->linkBlocks = &links[0];
+ group->spareLinks = &links[1];
+ }
+ }
+
+ if( group->spareLinks )
+ {
+ result = PaUtil_AllocateMemory( size );
+ if( result )
+ {
+ link = group->spareLinks;
+ group->spareLinks = link->next;
+
+ link->buffer = result;
+ link->next = group->allocations;
+
+ group->allocations = link;
+ }
+ }
+
+ return result;
+}
+
+
+void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer )
+{
+ struct PaUtilAllocationGroupLink *current = group->allocations;
+ struct PaUtilAllocationGroupLink *previous = 0;
+
+ if( buffer == 0 )
+ return;
+
+ /* find the right link and remove it */
+ while( current )
+ {
+ if( current->buffer == buffer )
+ {
+ if( previous )
+ {
+ previous->next = current->next;
+ }
+ else
+ {
+ group->allocations = current->next;
+ }
+
+ current->buffer = 0;
+ current->next = group->spareLinks;
+ group->spareLinks = current;
+
+ break;
+ }
+
+ previous = current;
+ current = current->next;
+ }
+
+ PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */
+}
+
+
+void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group )
+{
+ struct PaUtilAllocationGroupLink *current = group->allocations;
+ struct PaUtilAllocationGroupLink *previous = 0;
+
+ /* free all buffers in the allocations list */
+ while( current )
+ {
+ PaUtil_FreeMemory( current->buffer );
+ current->buffer = 0;
+
+ previous = current;
+ current = current->next;
+ }
+
+ /* link the former allocations list onto the front of the spareLinks list */
+ if( previous )
+ {
+ previous->next = group->spareLinks;
+ group->spareLinks = group->allocations;
+ group->allocations = 0;
+ }
+}
+