To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / portaudio_20161030_catalina_patch / src / common / pa_allocation.c @ 164:9fa11135915a

History | View | Annotate | Download (6.71 KB)

1
/*
2
 * $Id$
3
 * Portable Audio I/O Library allocation group implementation
4
 * memory allocation group for tracking allocation groups
5
 *
6
 * Based on the Open Source API proposed by Ross Bencina
7
 * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining
10
 * a copy of this software and associated documentation files
11
 * (the "Software"), to deal in the Software without restriction,
12
 * including without limitation the rights to use, copy, modify, merge,
13
 * publish, distribute, sublicense, and/or sell copies of the Software,
14
 * and to permit persons to whom the Software is furnished to do so,
15
 * subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be
18
 * included in all copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
24
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
 */
28

    
29
/*
30
 * The text above constitutes the entire PortAudio license; however, 
31
 * the PortAudio community also makes the following non-binding requests:
32
 *
33
 * Any person wishing to distribute modifications to the Software is
34
 * requested to send the modifications to the original developer so that
35
 * they can be incorporated into the canonical version. It is also 
36
 * requested that these non-binding requests be included along with the 
37
 * license above.
38
 */
39

    
40
/** @file
41
 @ingroup common_src
42

43
 @brief Allocation Group implementation.
44
*/
45

    
46

    
47
#include "pa_allocation.h"
48
#include "pa_util.h"
49

    
50

    
51
/*
52
    Maintain 3 singly linked lists...
53
    linkBlocks: the buffers used to allocate the links
54
    spareLinks: links available for use in the allocations list
55
    allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory()
56

57
    Link block size is doubled every time new links are allocated.
58
*/
59

    
60

    
61
#define PA_INITIAL_LINK_COUNT_    16
62

    
63
struct PaUtilAllocationGroupLink
64
{
65
    struct PaUtilAllocationGroupLink *next;
66
    void *buffer;
67
};
68

    
69
/*
70
    Allocate a block of links. The first link will have it's buffer member
71
    pointing to the block, and it's next member set to <nextBlock>. The remaining
72
    links will have NULL buffer members, and each link will point to
73
    the next link except the last, which will point to <nextSpare>
74
*/
75
static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
76
        struct PaUtilAllocationGroupLink *nextBlock,
77
        struct PaUtilAllocationGroupLink *nextSpare )
78
{
79
    struct PaUtilAllocationGroupLink *result;
80
    int i;
81
    
82
    result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
83
            sizeof(struct PaUtilAllocationGroupLink) * count );
84
    if( result )
85
    {
86
        /* the block link */
87
        result[0].buffer = result;
88
        result[0].next = nextBlock;
89

    
90
        /* the spare links */
91
        for( i=1; i<count; ++i )
92
        {
93
            result[i].buffer = 0;
94
            result[i].next = &result[i+1];
95
        }
96
        result[count-1].next = nextSpare;
97
    }
98
    
99
    return result;
100
}
101

    
102

    
103
PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void )
104
{
105
    PaUtilAllocationGroup* result = 0;
106
    struct PaUtilAllocationGroupLink *links;
107

    
108

    
109
    links = AllocateLinks( PA_INITIAL_LINK_COUNT_, 0, 0 );
110
    if( links != 0 )
111
    {
112
        result = (PaUtilAllocationGroup*)PaUtil_AllocateMemory( sizeof(PaUtilAllocationGroup) );
113
        if( result )
114
        {
115
            result->linkCount = PA_INITIAL_LINK_COUNT_;
116
            result->linkBlocks = &links[0];
117
            result->spareLinks = &links[1];
118
            result->allocations = 0;
119
        }
120
        else
121
        {
122
            PaUtil_FreeMemory( links );
123
        }
124
    }
125

    
126
    return result;
127
}
128

    
129

    
130
void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group )
131
{
132
    struct PaUtilAllocationGroupLink *current = group->linkBlocks;
133
    struct PaUtilAllocationGroupLink *next;
134

    
135
    while( current )
136
    {
137
        next = current->next;
138
        PaUtil_FreeMemory( current->buffer );
139
        current = next;
140
    }
141

    
142
    PaUtil_FreeMemory( group );
143
}
144

    
145

    
146
void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
147
{
148
    struct PaUtilAllocationGroupLink *links, *link;
149
    void *result = 0;
150
    
151
    /* allocate more links if necessary */
152
    if( !group->spareLinks )
153
    {
154
        /* double the link count on each block allocation */
155
        links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks );
156
        if( links )
157
        {
158
            group->linkCount += group->linkCount;
159
            group->linkBlocks = &links[0];
160
            group->spareLinks = &links[1];
161
        }
162
    }
163

    
164
    if( group->spareLinks )
165
    {
166
        result = PaUtil_AllocateMemory( size );
167
        if( result )
168
        {
169
            link = group->spareLinks;
170
            group->spareLinks = link->next;
171

    
172
            link->buffer = result;
173
            link->next = group->allocations;
174

    
175
            group->allocations = link;
176
        }
177
    }
178

    
179
    return result;    
180
}
181

    
182

    
183
void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer )
184
{
185
    struct PaUtilAllocationGroupLink *current = group->allocations;
186
    struct PaUtilAllocationGroupLink *previous = 0;
187

    
188
    if( buffer == 0 )
189
        return;
190

    
191
    /* find the right link and remove it */
192
    while( current )
193
    {
194
        if( current->buffer == buffer )
195
        {
196
            if( previous )
197
            {
198
                previous->next = current->next;
199
            }
200
            else
201
            {
202
                group->allocations = current->next;
203
            }
204

    
205
            current->buffer = 0;
206
            current->next = group->spareLinks;
207
            group->spareLinks = current;
208

    
209
            break;
210
        }
211
        
212
        previous = current;
213
        current = current->next;
214
    }
215

    
216
    PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */
217
}
218

    
219

    
220
void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group )
221
{
222
    struct PaUtilAllocationGroupLink *current = group->allocations;
223
    struct PaUtilAllocationGroupLink *previous = 0;
224

    
225
    /* free all buffers in the allocations list */
226
    while( current )
227
    {
228
        PaUtil_FreeMemory( current->buffer );
229
        current->buffer = 0;
230

    
231
        previous = current;
232
        current = current->next;
233
    }
234

    
235
    /* link the former allocations list onto the front of the spareLinks list */
236
    if( previous )
237
    {
238
        previous->next = group->spareLinks;
239
        group->spareLinks = group->allocations;
240
        group->allocations = 0;
241
    }
242
}
243