1168404Spjd/*
2168404Spjd * CDDL HEADER START
3168404Spjd *
4168404Spjd * The contents of this file are subject to the terms of the
5168404Spjd * Common Development and Distribution License (the "License").
6168404Spjd * You may not use this file except in compliance with the License.
7168404Spjd *
8168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9168404Spjd * or http://www.opensolaris.org/os/licensing.
10168404Spjd * See the License for the specific language governing permissions
11168404Spjd * and limitations under the License.
12168404Spjd *
13168404Spjd * When distributing Covered Code, include this CDDL HEADER in each
14168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15168404Spjd * If applicable, add the following below this CDDL HEADER, with the
16168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying
17168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
18168404Spjd *
19168404Spjd * CDDL HEADER END
20178414Sjb *
21178414Sjb * $FreeBSD$
22168404Spjd */
23168404Spjd/*
24168404Spjd * Copyright 2006 Ricardo Correia.  All rights reserved.
25168404Spjd * Use is subject to license terms.
26168404Spjd */
27168404Spjd
28168404Spjd#include <umem.h>
29168404Spjd#include <stdlib.h>
30168404Spjd#include <assert.h>
31168404Spjd
32168404Spjdstatic umem_nofail_callback_t *nofail_cb = NULL;
33168404Spjd
34168404Spjdstruct umem_cache {
35168404Spjd	umem_constructor_t *constructor;
36168404Spjd	umem_destructor_t *destructor;
37168404Spjd	void *callback_data;
38168404Spjd	size_t bufsize;
39168404Spjd};
40168404Spjd
41168404Spjd/*
42168404Spjd * Simple stub for umem_alloc(). The callback isn't expected to return.
43168404Spjd */
44168404Spjdvoid *umem_alloc(size_t size, int flags)
45168404Spjd{
46168404Spjd	assert(flags == UMEM_DEFAULT || flags == UMEM_NOFAIL);
47168404Spjd
48168404Spjd	if(size == 0)
49168404Spjd		return NULL;
50168404Spjd
51168404Spjd	void *ret = malloc(size);
52168404Spjd	if(ret == NULL) {
53168404Spjd		if(!(flags & UMEM_NOFAIL))
54168404Spjd			return NULL;
55168404Spjd
56168404Spjd		if(nofail_cb != NULL)
57168404Spjd			nofail_cb();
58168404Spjd		abort();
59168404Spjd	}
60168404Spjd
61168404Spjd	return ret;
62168404Spjd}
63168404Spjd
64168404Spjd/*
65168404Spjd * Simple stub for umem_zalloc().
66168404Spjd */
67168404Spjdvoid *umem_zalloc(size_t size, int flags)
68168404Spjd{
69168404Spjd	assert(flags == UMEM_DEFAULT || flags == UMEM_NOFAIL);
70168404Spjd
71168404Spjd	if(size == 0)
72168404Spjd		return NULL;
73168404Spjd
74168404Spjd	void *ret = calloc(1, size);
75168404Spjd	if(ret == NULL) {
76168404Spjd		if(!(flags & UMEM_NOFAIL))
77168404Spjd			return NULL;
78168404Spjd
79168404Spjd		if(nofail_cb != NULL)
80168404Spjd			nofail_cb();
81168404Spjd		abort();
82168404Spjd	}
83168404Spjd
84168404Spjd	return ret;
85168404Spjd}
86168404Spjd
87168404Spjd/*
88168404Spjd * Simple stub for umem_free().
89168404Spjd */
90168404Spjdvoid umem_free(void *buf, size_t size)
91168404Spjd{
92168404Spjd	free(buf);
93168404Spjd}
94168404Spjd
95168404Spjd/*
96168404Spjd * Simple stub for umem_nofail_callback().
97168404Spjd */
98168404Spjdvoid umem_nofail_callback(umem_nofail_callback_t *callback)
99168404Spjd{
100168404Spjd	nofail_cb = callback;
101168404Spjd}
102168404Spjd
103168404Spjd/*
104168404Spjd * Simple stub for umem_cache_create().
105168404Spjd */
106168404Spjdumem_cache_t *umem_cache_create(char *debug_name, size_t bufsize, size_t align, umem_constructor_t *constructor, umem_destructor_t *destructor, umem_reclaim_t *reclaim, void *callback_data, void *source, int cflags)
107168404Spjd{
108168404Spjd	assert(source == NULL);
109168404Spjd
110168404Spjd	umem_cache_t *cache = malloc(sizeof(umem_cache_t));
111168404Spjd	if(cache == NULL)
112168404Spjd		return NULL;
113168404Spjd
114168404Spjd	cache->constructor = constructor;
115168404Spjd	cache->destructor = destructor;
116168404Spjd	cache->callback_data = callback_data;
117168404Spjd	cache->bufsize = bufsize;
118168404Spjd
119168404Spjd	return cache;
120168404Spjd}
121168404Spjd
122168404Spjd/*
123168404Spjd * Simple stub for umem_cache_alloc(). The nofail callback isn't expected to return.
124168404Spjd */
125168404Spjdvoid *umem_cache_alloc(umem_cache_t *cache, int flags)
126168404Spjd{
127168404Spjd	void *buf = malloc(cache->bufsize);
128168404Spjd	if(buf == NULL) {
129168404Spjd		if(!(flags & UMEM_NOFAIL))
130168404Spjd			return NULL;
131168404Spjd
132168404Spjd		if(nofail_cb != NULL)
133168404Spjd			nofail_cb();
134168404Spjd		abort();
135168404Spjd	}
136168404Spjd
137168404Spjd	if(cache->constructor != NULL) {
138168404Spjd		if(cache->constructor(buf, cache->callback_data, flags) != 0) {
139168404Spjd			free(buf);
140168404Spjd			if(!(flags & UMEM_NOFAIL))
141168404Spjd				return NULL;
142168404Spjd
143168404Spjd			if(nofail_cb != NULL)
144168404Spjd				nofail_cb();
145168404Spjd			abort();
146168404Spjd		}
147168404Spjd	}
148168404Spjd
149168404Spjd	return buf;
150168404Spjd}
151168404Spjd
152168404Spjd/*
153168404Spjd * Simple stub for umem_cache_free().
154168404Spjd */
155168404Spjdvoid umem_cache_free(umem_cache_t *cache, void *buffer)
156168404Spjd{
157168404Spjd	if(cache->destructor != NULL)
158168404Spjd		cache->destructor(buffer, cache->callback_data);
159168404Spjd
160168404Spjd	free(buffer);
161168404Spjd}
162168404Spjd
163168404Spjd/*
164168404Spjd * Simple stub for umem_cache_destroy().
165168404Spjd */
166168404Spjdvoid umem_cache_destroy(umem_cache_t *cache)
167168404Spjd{
168168404Spjd	free(cache);
169168404Spjd}
170