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
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or https://opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _LIBSPL_UMEM_H
28 #define _LIBSPL_UMEM_H
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.
37 * https://labs.omniti.com/trac/portableumem
39 #include <sys/debug.h>
52 * Flags for umem_alloc/umem_free
54 #define UMEM_DEFAULT 0x0000 /* normal -- may fail */
55 #define UMEM_NOFAIL 0x0100 /* Never fails */
58 * Flags for umem_cache_create()
60 #define UMC_NODEBUG 0x00020000
62 #define UMEM_CACHE_NAMELEN 31
64 typedef int umem_nofail_callback_t(void);
65 typedef int umem_constructor_t(void *, void *, int);
66 typedef void umem_destructor_t(void *, void *);
67 typedef void umem_reclaim_t(void *);
69 typedef struct umem_cache
{
70 char cache_name
[UMEM_CACHE_NAMELEN
+ 1];
73 umem_constructor_t
*cache_constructor
;
74 umem_destructor_t
*cache_destructor
;
75 umem_reclaim_t
*cache_reclaim
;
81 /* Prototypes for functions to provide defaults for umem envvars */
82 const char *_umem_debug_init(void);
83 const char *_umem_options_init(void);
84 const char *_umem_logging_init(void);
86 __attribute__((malloc
, alloc_size(1)))
88 umem_alloc(size_t size
, int flags
)
94 } while (ptr
== NULL
&& (flags
& UMEM_NOFAIL
));
99 __attribute__((malloc
, alloc_size(1)))
101 umem_alloc_aligned(size_t size
, size_t align
, int flags
)
107 rc
= posix_memalign(&ptr
, align
, size
);
108 } while (rc
== ENOMEM
&& (flags
& UMEM_NOFAIL
));
111 fprintf(stderr
, "%s: invalid memory alignment (%zd)\n",
113 if (flags
& UMEM_NOFAIL
)
121 __attribute__((malloc
, alloc_size(1)))
123 umem_zalloc(size_t size
, int flags
)
127 ptr
= umem_alloc(size
, flags
);
129 memset(ptr
, 0, size
);
135 umem_free(const void *ptr
, size_t size __maybe_unused
)
141 * umem_free_aligned was added for supporting portability
142 * with non-POSIX platforms that require a different free
143 * to be used with aligned allocations.
146 umem_free_aligned(void *ptr
, size_t size __maybe_unused
)
156 umem_nofail_callback(umem_nofail_callback_t
*cb __maybe_unused
)
159 static inline umem_cache_t
*
161 const char *name
, size_t bufsize
, size_t align
,
162 umem_constructor_t
*constructor
,
163 umem_destructor_t
*destructor
,
164 umem_reclaim_t
*reclaim
,
165 void *priv
, void *vmp
, int cflags
)
169 cp
= (umem_cache_t
*)umem_alloc(sizeof (umem_cache_t
), UMEM_DEFAULT
);
171 strlcpy(cp
->cache_name
, name
, UMEM_CACHE_NAMELEN
);
172 cp
->cache_bufsize
= bufsize
;
173 cp
->cache_align
= align
;
174 cp
->cache_constructor
= constructor
;
175 cp
->cache_destructor
= destructor
;
176 cp
->cache_reclaim
= reclaim
;
177 cp
->cache_private
= priv
;
178 cp
->cache_arena
= vmp
;
179 cp
->cache_cflags
= cflags
;
186 umem_cache_destroy(umem_cache_t
*cp
)
188 umem_free(cp
, sizeof (umem_cache_t
));
191 __attribute__((malloc
))
193 umem_cache_alloc(umem_cache_t
*cp
, int flags
)
197 if (cp
->cache_align
!= 0)
198 ptr
= umem_alloc_aligned(
199 cp
->cache_bufsize
, cp
->cache_align
, flags
);
201 ptr
= umem_alloc(cp
->cache_bufsize
, flags
);
203 if (ptr
&& cp
->cache_constructor
)
204 cp
->cache_constructor(ptr
, cp
->cache_private
, UMEM_DEFAULT
);
210 umem_cache_free(umem_cache_t
*cp
, void *ptr
)
212 if (cp
->cache_destructor
)
213 cp
->cache_destructor(ptr
, cp
->cache_private
);
215 if (cp
->cache_align
!= 0)
216 umem_free_aligned(ptr
, cp
->cache_bufsize
);
218 umem_free(ptr
, cp
->cache_bufsize
);
222 umem_cache_reap_now(umem_cache_t
*cp __maybe_unused
)