/*
 * 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 are using a full userspace build of zpool for
 * something other than ztest, you are likely not going to notice or care.
 *
 * https://labs.omniti.com/trac/portableumem
 */
#include <sys/debug.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef  __cplusplus
extern "C" {
#endif

typedef void vmem_t;

/*
 * Flags for umem_alloc/umem_free
 */
#define	UMEM_DEFAULT		0x0000  /* normal -- may fail */
#define	UMEM_NOFAIL		0x0100  /* Never fails */

/*
 * Flags for umem_cache_create()
 */
#define	UMC_NODEBUG		0x00020000

#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;

/* Prototypes for functions to provide defaults for umem envvars */
const char *_umem_debug_init(void);
const char *_umem_options_init(void);
const char *_umem_logging_init(void);

static inline void *
umem_alloc(size_t size, int flags)
{
	void *ptr = NULL;

	do {
		ptr = malloc(size);
	} while (ptr == NULL && (flags & UMEM_NOFAIL));

	return (ptr);
}

static inline void *
umem_alloc_aligned(size_t size, size_t align, int flags)
{
	void *ptr = NULL;
	int rc = EINVAL;

	do {
		rc = posix_memalign(&ptr, align, size);
	} while (rc == ENOMEM && (flags & UMEM_NOFAIL));

	if (rc == EINVAL) {
		fprintf(stderr, "%s: invalid memory alignment (%zd)\n",
		    __func__, align);
		if (flags & UMEM_NOFAIL)
			abort();
		return (NULL);
	}

	return (ptr);
}

static inline void *
umem_zalloc(size_t size, int flags)
{
	void *ptr = NULL;

	ptr = umem_alloc(size, flags);
	if (ptr)
		memset(ptr, 0, size);

	return (ptr);
}

static inline void
umem_free(void *ptr, size_t size __maybe_unused)
{
	free(ptr);
}

static inline void
umem_nofail_callback(umem_nofail_callback_t *cb __maybe_unused)
{}

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_cache_t *)umem_alloc(sizeof (umem_cache_t), UMEM_DEFAULT);
	if (cp) {
		strlcpy(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 = NULL;

	if (cp->cache_align != 0)
		ptr = umem_alloc_aligned(
		    cp->cache_bufsize, cp->cache_align, flags);
	else
		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);
}

static inline void
umem_cache_reap_now(umem_cache_t *cp __maybe_unused)
{
}

#ifdef  __cplusplus
}
#endif

#endif
