]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libspl/include/umem.h
OpenZFS restructuring - move linux tracing code to platform directories
[FreeBSD/FreeBSD.git] / lib / libspl / include / umem.h
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27 #ifndef _LIBSPL_UMEM_H
28 #define _LIBSPL_UMEM_H
29
30 /*
31  * XXX: We should use the real portable umem library if it is detected
32  * at configure time.  However, if the library is not available, we can
33  * use a trivial malloc based implementation.  This obviously impacts
34  * performance, but unless you are using a full userspace build of zpool for
35  * something other than ztest, you are likely not going to notice or care.
36  *
37  * https://labs.omniti.com/trac/portableumem
38  */
39
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43
44 #ifdef  __cplusplus
45 extern "C" {
46 #endif
47
48 typedef void vmem_t;
49
50 /*
51  * Flags for umem_alloc/umem_free
52  */
53 #define UMEM_DEFAULT            0x0000  /* normal -- may fail */
54 #define UMEM_NOFAIL             0x0100  /* Never fails */
55
56 /*
57  * Flags for umem_cache_create()
58  */
59 #define UMC_NOTOUCH             0x00010000
60 #define UMC_NODEBUG             0x00020000
61 #define UMC_NOMAGAZINE          0x00040000
62 #define UMC_NOHASH              0x00080000
63
64 #define UMEM_CACHE_NAMELEN      31
65
66 typedef int umem_nofail_callback_t(void);
67 typedef int umem_constructor_t(void *, void *, int);
68 typedef void umem_destructor_t(void *, void *);
69 typedef void umem_reclaim_t(void *);
70
71 typedef struct umem_cache {
72         char                    cache_name[UMEM_CACHE_NAMELEN + 1];
73         size_t                  cache_bufsize;
74         size_t                  cache_align;
75         umem_constructor_t      *cache_constructor;
76         umem_destructor_t       *cache_destructor;
77         umem_reclaim_t          *cache_reclaim;
78         void                    *cache_private;
79         void                    *cache_arena;
80         int                     cache_cflags;
81 } umem_cache_t;
82
83 static inline void *
84 umem_alloc(size_t size, int flags)
85 {
86         void *ptr = NULL;
87
88         do {
89                 ptr = malloc(size);
90         } while (ptr == NULL && (flags & UMEM_NOFAIL));
91
92         return (ptr);
93 }
94
95 static inline void *
96 umem_alloc_aligned(size_t size, size_t align, int flags)
97 {
98         void *ptr = NULL;
99         int rc = EINVAL;
100
101         do {
102                 rc = posix_memalign(&ptr, align, size);
103         } while (rc == ENOMEM && (flags & UMEM_NOFAIL));
104
105         if (rc == EINVAL) {
106                 fprintf(stderr, "%s: invalid memory alignment (%zd)\n",
107                     __func__, align);
108                 if (flags & UMEM_NOFAIL)
109                         abort();
110                 return (NULL);
111         }
112
113         return (ptr);
114 }
115
116 static inline void *
117 umem_zalloc(size_t size, int flags)
118 {
119         void *ptr = NULL;
120
121         ptr = umem_alloc(size, flags);
122         if (ptr)
123                 memset(ptr, 0, size);
124
125         return (ptr);
126 }
127
128 static inline void
129 umem_free(void *ptr, size_t size)
130 {
131         free(ptr);
132 }
133
134 static inline void
135 umem_nofail_callback(umem_nofail_callback_t *cb)
136 {}
137
138 static inline umem_cache_t *
139 umem_cache_create(
140     char *name, size_t bufsize, size_t align,
141     umem_constructor_t *constructor,
142     umem_destructor_t *destructor,
143     umem_reclaim_t *reclaim,
144     void *priv, void *vmp, int cflags)
145 {
146         umem_cache_t *cp;
147
148         cp = umem_alloc(sizeof (umem_cache_t), UMEM_DEFAULT);
149         if (cp) {
150                 strlcpy(cp->cache_name, name, UMEM_CACHE_NAMELEN);
151                 cp->cache_bufsize = bufsize;
152                 cp->cache_align = align;
153                 cp->cache_constructor = constructor;
154                 cp->cache_destructor = destructor;
155                 cp->cache_reclaim = reclaim;
156                 cp->cache_private = priv;
157                 cp->cache_arena = vmp;
158                 cp->cache_cflags = cflags;
159         }
160
161         return (cp);
162 }
163
164 static inline void
165 umem_cache_destroy(umem_cache_t *cp)
166 {
167         umem_free(cp, sizeof (umem_cache_t));
168 }
169
170 static inline void *
171 umem_cache_alloc(umem_cache_t *cp, int flags)
172 {
173         void *ptr = NULL;
174
175         if (cp->cache_align != 0)
176                 ptr = umem_alloc_aligned(
177                     cp->cache_bufsize, cp->cache_align, flags);
178         else
179                 ptr = umem_alloc(cp->cache_bufsize, flags);
180
181         if (ptr && cp->cache_constructor)
182                 cp->cache_constructor(ptr, cp->cache_private, UMEM_DEFAULT);
183
184         return (ptr);
185 }
186
187 static inline void
188 umem_cache_free(umem_cache_t *cp, void *ptr)
189 {
190         if (cp->cache_destructor)
191                 cp->cache_destructor(ptr, cp->cache_private);
192
193         umem_free(ptr, cp->cache_bufsize);
194 }
195
196 static inline void
197 umem_cache_reap_now(umem_cache_t *cp)
198 {
199 }
200
201 #ifdef  __cplusplus
202 }
203 #endif
204
205 #endif