Blame view
sound/synth/util_mem.c
4.55 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> * * Generic memory management routines for soundcard memory allocation * * This program 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. * * This program 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 */ |
ef9f0a42d [ALSA] semaphore ... |
20 |
#include <linux/mutex.h> |
1da177e4c Linux-2.6.12-rc2 |
21 22 |
#include <linux/init.h> #include <linux/slab.h> |
da155d5b4 sound: Add module... |
23 |
#include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
24 25 26 27 28 29 |
#include <sound/core.h> #include <sound/util_mem.h> MODULE_AUTHOR("Takashi Iwai"); MODULE_DESCRIPTION("Generic memory management routines for soundcard memory allocation"); MODULE_LICENSE("GPL"); |
03da312ac [ALSA] Remove xxx... |
30 |
#define get_memblk(p) list_entry(p, struct snd_util_memblk, list) |
1da177e4c Linux-2.6.12-rc2 |
31 32 33 34 |
/* * create a new memory manager */ |
03da312ac [ALSA] Remove xxx... |
35 |
struct snd_util_memhdr * |
1da177e4c Linux-2.6.12-rc2 |
36 37 |
snd_util_memhdr_new(int memsize) { |
03da312ac [ALSA] Remove xxx... |
38 |
struct snd_util_memhdr *hdr; |
1da177e4c Linux-2.6.12-rc2 |
39 |
|
561b220a4 [ALSA] Replace wi... |
40 |
hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 |
if (hdr == NULL) return NULL; hdr->size = memsize; |
ef9f0a42d [ALSA] semaphore ... |
44 |
mutex_init(&hdr->block_mutex); |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 48 49 50 51 52 |
INIT_LIST_HEAD(&hdr->block); return hdr; } /* * free a memory manager */ |
03da312ac [ALSA] Remove xxx... |
53 |
void snd_util_memhdr_free(struct snd_util_memhdr *hdr) |
1da177e4c Linux-2.6.12-rc2 |
54 55 |
{ struct list_head *p; |
5e246b850 ALSA: Kill snd_as... |
56 57 |
if (!hdr) return; |
1da177e4c Linux-2.6.12-rc2 |
58 59 60 61 62 63 64 65 66 67 68 |
/* release all blocks */ while ((p = hdr->block.next) != &hdr->block) { list_del(p); kfree(get_memblk(p)); } kfree(hdr); } /* * allocate a memory block (without mutex) */ |
03da312ac [ALSA] Remove xxx... |
69 70 |
struct snd_util_memblk * __snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size) |
1da177e4c Linux-2.6.12-rc2 |
71 |
{ |
03da312ac [ALSA] Remove xxx... |
72 73 |
struct snd_util_memblk *blk; unsigned int units, prev_offset; |
1da177e4c Linux-2.6.12-rc2 |
74 |
struct list_head *p; |
5e246b850 ALSA: Kill snd_as... |
75 76 |
if (snd_BUG_ON(!hdr || size <= 0)) return NULL; |
1da177e4c Linux-2.6.12-rc2 |
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
/* word alignment */ units = size; if (units & 1) units++; if (units > hdr->size) return NULL; /* look for empty block */ prev_offset = 0; list_for_each(p, &hdr->block) { blk = get_memblk(p); if (blk->offset - prev_offset >= units) goto __found; prev_offset = blk->offset + blk->size; } if (hdr->size - prev_offset < units) return NULL; __found: return __snd_util_memblk_new(hdr, units, p->prev); } /* * create a new memory block with the given size * the block is linked next to prev */ |
03da312ac [ALSA] Remove xxx... |
105 106 |
struct snd_util_memblk * __snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units, |
1da177e4c Linux-2.6.12-rc2 |
107 108 |
struct list_head *prev) { |
03da312ac [ALSA] Remove xxx... |
109 |
struct snd_util_memblk *blk; |
1da177e4c Linux-2.6.12-rc2 |
110 |
|
03da312ac [ALSA] Remove xxx... |
111 112 |
blk = kmalloc(sizeof(struct snd_util_memblk) + hdr->block_extra_size, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
113 114 |
if (blk == NULL) return NULL; |
8e6c962cd [ALSA] sound/synt... |
115 |
if (prev == &hdr->block) |
1da177e4c Linux-2.6.12-rc2 |
116 117 |
blk->offset = 0; else { |
03da312ac [ALSA] Remove xxx... |
118 |
struct snd_util_memblk *p = get_memblk(prev); |
1da177e4c Linux-2.6.12-rc2 |
119 120 121 122 123 124 125 126 127 128 129 130 131 |
blk->offset = p->offset + p->size; } blk->size = units; list_add(&blk->list, prev); hdr->nblocks++; hdr->used += units; return blk; } /* * allocate a memory block (with mutex) */ |
03da312ac [ALSA] Remove xxx... |
132 133 |
struct snd_util_memblk * snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size) |
1da177e4c Linux-2.6.12-rc2 |
134 |
{ |
03da312ac [ALSA] Remove xxx... |
135 |
struct snd_util_memblk *blk; |
ef9f0a42d [ALSA] semaphore ... |
136 |
mutex_lock(&hdr->block_mutex); |
1da177e4c Linux-2.6.12-rc2 |
137 |
blk = __snd_util_mem_alloc(hdr, size); |
ef9f0a42d [ALSA] semaphore ... |
138 |
mutex_unlock(&hdr->block_mutex); |
1da177e4c Linux-2.6.12-rc2 |
139 140 141 142 143 144 145 146 147 |
return blk; } /* * remove the block from linked-list and free resource * (without mutex) */ void |
03da312ac [ALSA] Remove xxx... |
148 |
__snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk) |
1da177e4c Linux-2.6.12-rc2 |
149 150 151 152 153 154 155 156 157 158 |
{ list_del(&blk->list); hdr->nblocks--; hdr->used -= blk->size; kfree(blk); } /* * free a memory block (with mutex) */ |
03da312ac [ALSA] Remove xxx... |
159 |
int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk) |
1da177e4c Linux-2.6.12-rc2 |
160 |
{ |
5e246b850 ALSA: Kill snd_as... |
161 162 |
if (snd_BUG_ON(!hdr || !blk)) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
163 |
|
ef9f0a42d [ALSA] semaphore ... |
164 |
mutex_lock(&hdr->block_mutex); |
1da177e4c Linux-2.6.12-rc2 |
165 |
__snd_util_mem_free(hdr, blk); |
ef9f0a42d [ALSA] semaphore ... |
166 |
mutex_unlock(&hdr->block_mutex); |
1da177e4c Linux-2.6.12-rc2 |
167 168 169 170 171 172 |
return 0; } /* * return available memory size */ |
03da312ac [ALSA] Remove xxx... |
173 |
int snd_util_mem_avail(struct snd_util_memhdr *hdr) |
1da177e4c Linux-2.6.12-rc2 |
174 175 |
{ unsigned int size; |
ef9f0a42d [ALSA] semaphore ... |
176 |
mutex_lock(&hdr->block_mutex); |
1da177e4c Linux-2.6.12-rc2 |
177 |
size = hdr->size - hdr->used; |
ef9f0a42d [ALSA] semaphore ... |
178 |
mutex_unlock(&hdr->block_mutex); |
1da177e4c Linux-2.6.12-rc2 |
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
return size; } EXPORT_SYMBOL(snd_util_memhdr_new); EXPORT_SYMBOL(snd_util_memhdr_free); EXPORT_SYMBOL(snd_util_mem_alloc); EXPORT_SYMBOL(snd_util_mem_free); EXPORT_SYMBOL(snd_util_mem_avail); EXPORT_SYMBOL(__snd_util_mem_alloc); EXPORT_SYMBOL(__snd_util_mem_free); EXPORT_SYMBOL(__snd_util_memblk_new); /* * INIT part */ static int __init alsa_util_mem_init(void) { return 0; } static void __exit alsa_util_mem_exit(void) { } module_init(alsa_util_mem_init) module_exit(alsa_util_mem_exit) |