OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [sound/] [synth/] [util_mem.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
3
 *
4
 *  Generic memory management routines for soundcard memory allocation
5
 *
6
 *   This program is free software; you can redistribute it and/or modify
7
 *   it under the terms of the GNU General Public License as published by
8
 *   the Free Software Foundation; either version 2 of the License, or
9
 *   (at your option) any later version.
10
 *
11
 *   This program is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU General Public License for more details.
15
 *
16
 *   You should have received a copy of the GNU General Public License
17
 *   along with this program; if not, write to the Free Software
18
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19
 */
20
 
21
#include <linux/mutex.h>
22
#include <sound/driver.h>
23
#include <linux/init.h>
24
#include <linux/slab.h>
25
#include <sound/core.h>
26
#include <sound/util_mem.h>
27
 
28
MODULE_AUTHOR("Takashi Iwai");
29
MODULE_DESCRIPTION("Generic memory management routines for soundcard memory allocation");
30
MODULE_LICENSE("GPL");
31
 
32
#define get_memblk(p)   list_entry(p, struct snd_util_memblk, list)
33
 
34
/*
35
 * create a new memory manager
36
 */
37
struct snd_util_memhdr *
38
snd_util_memhdr_new(int memsize)
39
{
40
        struct snd_util_memhdr *hdr;
41
 
42
        hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
43
        if (hdr == NULL)
44
                return NULL;
45
        hdr->size = memsize;
46
        mutex_init(&hdr->block_mutex);
47
        INIT_LIST_HEAD(&hdr->block);
48
 
49
        return hdr;
50
}
51
 
52
/*
53
 * free a memory manager
54
 */
55
void snd_util_memhdr_free(struct snd_util_memhdr *hdr)
56
{
57
        struct list_head *p;
58
 
59
        snd_assert(hdr != NULL, return);
60
        /* release all blocks */
61
        while ((p = hdr->block.next) != &hdr->block) {
62
                list_del(p);
63
                kfree(get_memblk(p));
64
        }
65
        kfree(hdr);
66
}
67
 
68
/*
69
 * allocate a memory block (without mutex)
70
 */
71
struct snd_util_memblk *
72
__snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
73
{
74
        struct snd_util_memblk *blk;
75
        unsigned int units, prev_offset;
76
        struct list_head *p;
77
 
78
        snd_assert(hdr != NULL, return NULL);
79
        snd_assert(size > 0, return NULL);
80
 
81
        /* word alignment */
82
        units = size;
83
        if (units & 1)
84
                units++;
85
        if (units > hdr->size)
86
                return NULL;
87
 
88
        /* look for empty block */
89
        prev_offset = 0;
90
        list_for_each(p, &hdr->block) {
91
                blk = get_memblk(p);
92
                if (blk->offset - prev_offset >= units)
93
                        goto __found;
94
                prev_offset = blk->offset + blk->size;
95
        }
96
        if (hdr->size - prev_offset < units)
97
                return NULL;
98
 
99
__found:
100
        return __snd_util_memblk_new(hdr, units, p->prev);
101
}
102
 
103
 
104
/*
105
 * create a new memory block with the given size
106
 * the block is linked next to prev
107
 */
108
struct snd_util_memblk *
109
__snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units,
110
                      struct list_head *prev)
111
{
112
        struct snd_util_memblk *blk;
113
 
114
        blk = kmalloc(sizeof(struct snd_util_memblk) + hdr->block_extra_size,
115
                      GFP_KERNEL);
116
        if (blk == NULL)
117
                return NULL;
118
 
119
        if (prev == &hdr->block)
120
                blk->offset = 0;
121
        else {
122
                struct snd_util_memblk *p = get_memblk(prev);
123
                blk->offset = p->offset + p->size;
124
        }
125
        blk->size = units;
126
        list_add(&blk->list, prev);
127
        hdr->nblocks++;
128
        hdr->used += units;
129
        return blk;
130
}
131
 
132
 
133
/*
134
 * allocate a memory block (with mutex)
135
 */
136
struct snd_util_memblk *
137
snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
138
{
139
        struct snd_util_memblk *blk;
140
        mutex_lock(&hdr->block_mutex);
141
        blk = __snd_util_mem_alloc(hdr, size);
142
        mutex_unlock(&hdr->block_mutex);
143
        return blk;
144
}
145
 
146
 
147
/*
148
 * remove the block from linked-list and free resource
149
 * (without mutex)
150
 */
151
void
152
__snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
153
{
154
        list_del(&blk->list);
155
        hdr->nblocks--;
156
        hdr->used -= blk->size;
157
        kfree(blk);
158
}
159
 
160
/*
161
 * free a memory block (with mutex)
162
 */
163
int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
164
{
165
        snd_assert(hdr && blk, return -EINVAL);
166
 
167
        mutex_lock(&hdr->block_mutex);
168
        __snd_util_mem_free(hdr, blk);
169
        mutex_unlock(&hdr->block_mutex);
170
        return 0;
171
}
172
 
173
/*
174
 * return available memory size
175
 */
176
int snd_util_mem_avail(struct snd_util_memhdr *hdr)
177
{
178
        unsigned int size;
179
        mutex_lock(&hdr->block_mutex);
180
        size = hdr->size - hdr->used;
181
        mutex_unlock(&hdr->block_mutex);
182
        return size;
183
}
184
 
185
 
186
EXPORT_SYMBOL(snd_util_memhdr_new);
187
EXPORT_SYMBOL(snd_util_memhdr_free);
188
EXPORT_SYMBOL(snd_util_mem_alloc);
189
EXPORT_SYMBOL(snd_util_mem_free);
190
EXPORT_SYMBOL(snd_util_mem_avail);
191
EXPORT_SYMBOL(__snd_util_mem_alloc);
192
EXPORT_SYMBOL(__snd_util_mem_free);
193
EXPORT_SYMBOL(__snd_util_memblk_new);
194
 
195
/*
196
 *  INIT part
197
 */
198
 
199
static int __init alsa_util_mem_init(void)
200
{
201
        return 0;
202
}
203
 
204
static void __exit alsa_util_mem_exit(void)
205
{
206
}
207
 
208
module_init(alsa_util_mem_init)
209
module_exit(alsa_util_mem_exit)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.