~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/synth/util_mem.c

Version: ~ [ linux-5.15-rc7 ] ~ [ linux-5.14.14 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.75 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.155 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.213 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.252 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.287 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.289 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  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 <linux/init.h>
 23 #include <linux/slab.h>
 24 #include <linux/module.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         if (!hdr)
 60                 return;
 61         /* release all blocks */
 62         while ((p = hdr->block.next) != &hdr->block) {
 63                 list_del(p);
 64                 kfree(get_memblk(p));
 65         }
 66         kfree(hdr);
 67 }
 68 
 69 /*
 70  * allocate a memory block (without mutex)
 71  */
 72 struct snd_util_memblk *
 73 __snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
 74 {
 75         struct snd_util_memblk *blk;
 76         unsigned int units, prev_offset;
 77         struct list_head *p;
 78 
 79         if (snd_BUG_ON(!hdr || size <= 0))
 80                 return NULL;
 81 
 82         /* word alignment */
 83         units = size;
 84         if (units & 1)
 85                 units++;
 86         if (units > hdr->size)
 87                 return NULL;
 88 
 89         /* look for empty block */
 90         prev_offset = 0;
 91         list_for_each(p, &hdr->block) {
 92                 blk = get_memblk(p);
 93                 if (blk->offset - prev_offset >= units)
 94                         goto __found;
 95                 prev_offset = blk->offset + blk->size;
 96         }
 97         if (hdr->size - prev_offset < units)
 98                 return NULL;
 99 
100 __found:
101         return __snd_util_memblk_new(hdr, units, p->prev);
102 }
103 
104 
105 /*
106  * create a new memory block with the given size
107  * the block is linked next to prev
108  */
109 struct snd_util_memblk *
110 __snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units,
111                       struct list_head *prev)
112 {
113         struct snd_util_memblk *blk;
114 
115         blk = kmalloc(sizeof(struct snd_util_memblk) + hdr->block_extra_size,
116                       GFP_KERNEL);
117         if (blk == NULL)
118                 return NULL;
119 
120         if (prev == &hdr->block)
121                 blk->offset = 0;
122         else {
123                 struct snd_util_memblk *p = get_memblk(prev);
124                 blk->offset = p->offset + p->size;
125         }
126         blk->size = units;
127         list_add(&blk->list, prev);
128         hdr->nblocks++;
129         hdr->used += units;
130         return blk;
131 }
132 
133 
134 /*
135  * allocate a memory block (with mutex)
136  */
137 struct snd_util_memblk *
138 snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
139 {
140         struct snd_util_memblk *blk;
141         mutex_lock(&hdr->block_mutex);
142         blk = __snd_util_mem_alloc(hdr, size);
143         mutex_unlock(&hdr->block_mutex);
144         return blk;
145 }
146 
147 
148 /*
149  * remove the block from linked-list and free resource
150  * (without mutex)
151  */
152 void
153 __snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
154 {
155         list_del(&blk->list);
156         hdr->nblocks--;
157         hdr->used -= blk->size;
158         kfree(blk);
159 }
160 
161 /*
162  * free a memory block (with mutex)
163  */
164 int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
165 {
166         if (snd_BUG_ON(!hdr || !blk))
167                 return -EINVAL;
168 
169         mutex_lock(&hdr->block_mutex);
170         __snd_util_mem_free(hdr, blk);
171         mutex_unlock(&hdr->block_mutex);
172         return 0;
173 }
174 
175 /*
176  * return available memory size
177  */
178 int snd_util_mem_avail(struct snd_util_memhdr *hdr)
179 {
180         unsigned int size;
181         mutex_lock(&hdr->block_mutex);
182         size = hdr->size - hdr->used;
183         mutex_unlock(&hdr->block_mutex);
184         return size;
185 }
186 
187 
188 EXPORT_SYMBOL(snd_util_memhdr_new);
189 EXPORT_SYMBOL(snd_util_memhdr_free);
190 EXPORT_SYMBOL(snd_util_mem_alloc);
191 EXPORT_SYMBOL(snd_util_mem_free);
192 EXPORT_SYMBOL(snd_util_mem_avail);
193 EXPORT_SYMBOL(__snd_util_mem_alloc);
194 EXPORT_SYMBOL(__snd_util_mem_free);
195 EXPORT_SYMBOL(__snd_util_memblk_new);
196 
197 /*
198  *  INIT part
199  */
200 
201 static int __init alsa_util_mem_init(void)
202 {
203         return 0;
204 }
205 
206 static void __exit alsa_util_mem_exit(void)
207 {
208 }
209 
210 module_init(alsa_util_mem_init)
211 module_exit(alsa_util_mem_exit)
212 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp