157 lines
3.7 KiB
C
157 lines
3.7 KiB
C
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License, Version 1.0 only
|
|
* (the "License"). You may not use this file except in compliance
|
|
* with the License.
|
|
*
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
* or http://www.opensolaris.org/os/licensing.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
/*
|
|
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
|
* Use is subject to license terms.
|
|
*/
|
|
|
|
#ifndef _LIBSPL_UMEM_H
|
|
#define _LIBSPL_UMEM_H
|
|
|
|
/* XXX: We should use the real portable umem library if it is detected
|
|
* at configure time. However, if the library is not available we can
|
|
* use a trivial malloc based implementation. This obviously impacts
|
|
* performance but unless you using a full userspace build of zpool for
|
|
* something other than ztest your likely not going to notice or care.
|
|
*
|
|
* https://labs.omniti.com/trac/portableumem
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define UMEM_DEFAULT 0x0000 /* normal -- may fail */
|
|
#define UMEM_NOFAIL 0x0100 /* Never fails */
|
|
|
|
#define UMEM_CACHE_NAMELEN 31
|
|
|
|
typedef int umem_nofail_callback_t(void);
|
|
typedef int umem_constructor_t(void *, void *, int);
|
|
typedef void umem_destructor_t(void *, void *);
|
|
typedef void umem_reclaim_t(void *);
|
|
|
|
typedef struct umem_cache {
|
|
char cache_name[UMEM_CACHE_NAMELEN + 1];
|
|
size_t cache_bufsize;
|
|
size_t cache_align;
|
|
umem_constructor_t *cache_constructor;
|
|
umem_destructor_t *cache_destructor;
|
|
umem_reclaim_t *cache_reclaim;
|
|
void *cache_private;
|
|
void *cache_arena;
|
|
int cache_cflags;
|
|
} umem_cache_t;
|
|
|
|
static inline void *
|
|
umem_alloc(size_t size, int flags)
|
|
{
|
|
void *ptr;
|
|
|
|
ptr = malloc(size);
|
|
while (ptr == NULL && (flags & UMEM_NOFAIL))
|
|
ptr = malloc(size);
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static inline void *
|
|
umem_zalloc(size_t size, int flags)
|
|
{
|
|
void *ptr;
|
|
|
|
ptr = umem_alloc(size, flags);
|
|
if (ptr)
|
|
memset(ptr, 0, size);
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static inline void
|
|
umem_free(void *ptr, size_t size)
|
|
{
|
|
free(ptr);
|
|
}
|
|
|
|
static inline void
|
|
umem_nofail_callback(umem_nofail_callback_t *cb) {}
|
|
|
|
static inline umem_cache_t *
|
|
umem_cache_create(char *name, size_t bufsize, size_t align,
|
|
umem_constructor_t *constructor,
|
|
umem_destructor_t *destructor,
|
|
umem_reclaim_t *reclaim,
|
|
void *priv, void *vmp, int cflags)
|
|
{
|
|
umem_cache_t *cp;
|
|
|
|
cp = umem_alloc(sizeof(umem_cache_t), UMEM_DEFAULT);
|
|
if (cp) {
|
|
strncpy(cp->cache_name, name, UMEM_CACHE_NAMELEN);
|
|
cp->cache_bufsize = bufsize;
|
|
cp->cache_align = align;
|
|
cp->cache_constructor = constructor;
|
|
cp->cache_destructor = destructor;
|
|
cp->cache_reclaim = reclaim;
|
|
cp->cache_private = priv;
|
|
cp->cache_arena = vmp;
|
|
cp->cache_cflags = cflags;
|
|
}
|
|
|
|
return cp;
|
|
}
|
|
|
|
static inline void
|
|
umem_cache_destroy(umem_cache_t *cp)
|
|
{
|
|
umem_free(cp, sizeof(umem_cache_t));
|
|
}
|
|
|
|
static inline void *
|
|
umem_cache_alloc(umem_cache_t *cp, int flags)
|
|
{
|
|
void *ptr;
|
|
|
|
ptr = umem_alloc(cp->cache_bufsize, flags);
|
|
if (ptr && cp->cache_constructor)
|
|
cp->cache_constructor(ptr, cp->cache_private, UMEM_DEFAULT);
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static inline void
|
|
umem_cache_free(umem_cache_t *cp, void *ptr)
|
|
{
|
|
if (cp->cache_destructor)
|
|
cp->cache_destructor(ptr, cp->cache_private);
|
|
|
|
umem_free(ptr, cp->cache_bufsize);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|