/* * 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 _SOL_UMEM_H #define _SOL_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 #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