Julian Elischer posted an interesting proof-of-concept to freebsd-current
[dragonfly.git] / sys / dev / usbmisc / ugen / ugenbuf.c
1 /*
2  * $DragonFly: src/sys/dev/usbmisc/ugen/ugenbuf.c,v 1.1 2004/07/08 03:53:54 dillon Exp $
3  */
4
5 #include <sys/param.h>
6 #include <sys/systm.h>
7 #include <sys/kernel.h>
8 #include <sys/malloc.h>
9 #include <sys/sysctl.h>
10 #include "ugenbuf.h"
11
12 static MALLOC_DEFINE(M_UGENBUF, "ugenbufs", "Temporary buffer space");
13 static void *ugencache_buf;
14 static int ugencache_size;
15
16 /*
17  * getugenbuf()
18  *
19  *      Allocate a temporary buffer for UGEN.  This routine is called from
20  *      mainline code only and the BGL is held.
21  */
22 void *
23 getugenbuf(int reqsize, int *bsize)
24 {
25     void *buf;
26
27     if (reqsize < 256)
28         reqsize = 256;
29     if (reqsize > 262144)
30         reqsize = 262144;
31     *bsize = reqsize;
32
33     buf = ugencache_buf;
34     if (buf == NULL) {
35         buf = malloc(reqsize, M_UGENBUF, M_WAITOK);
36     } else if (ugencache_size != reqsize) {
37         ugencache_buf = NULL;
38         free(buf, M_UGENBUF);
39         buf = malloc(reqsize, M_UGENBUF, M_WAITOK);
40     } else {
41         buf = ugencache_buf;
42         ugencache_buf = NULL;
43     }
44     return(buf);
45 }
46
47 /*
48  * relugenbuf()
49  *
50  *      Release a temporary buffer for UGEN.  This routine is called from
51  *      mainline code only and the BGL is held.
52  */
53 void
54 relugenbuf(void *buf, int bsize)
55 {
56     if (ugencache_buf == NULL) {
57         ugencache_buf = buf;
58         ugencache_size = bsize;
59     } else {
60         free(buf, M_UGENBUF);
61     }
62 }
63