1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * $FreeBSD$
22 */
23/*
24 * Copyright 2006 Ricardo Correia.  All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#include <umem.h>
29#include <stdlib.h>
30#include <assert.h>
31
32static umem_nofail_callback_t *nofail_cb = NULL;
33
34struct umem_cache {
35	umem_constructor_t *constructor;
36	umem_destructor_t *destructor;
37	void *callback_data;
38	size_t bufsize;
39};
40
41/*
42 * Simple stub for umem_alloc(). The callback isn't expected to return.
43 */
44void *umem_alloc(size_t size, int flags)
45{
46	assert(flags == UMEM_DEFAULT || flags == UMEM_NOFAIL);
47
48	if(size == 0)
49		return NULL;
50
51	void *ret = malloc(size);
52	if(ret == NULL) {
53		if(!(flags & UMEM_NOFAIL))
54			return NULL;
55
56		if(nofail_cb != NULL)
57			nofail_cb();
58		abort();
59	}
60
61	return ret;
62}
63
64/*
65 * Simple stub for umem_zalloc().
66 */
67void *umem_zalloc(size_t size, int flags)
68{
69	assert(flags == UMEM_DEFAULT || flags == UMEM_NOFAIL);
70
71	if(size == 0)
72		return NULL;
73
74	void *ret = calloc(1, size);
75	if(ret == NULL) {
76		if(!(flags & UMEM_NOFAIL))
77			return NULL;
78
79		if(nofail_cb != NULL)
80			nofail_cb();
81		abort();
82	}
83
84	return ret;
85}
86
87/*
88 * Simple stub for umem_free().
89 */
90void umem_free(void *buf, size_t size)
91{
92	free(buf);
93}
94
95/*
96 * Simple stub for umem_nofail_callback().
97 */
98void umem_nofail_callback(umem_nofail_callback_t *callback)
99{
100	nofail_cb = callback;
101}
102
103/*
104 * Simple stub for umem_cache_create().
105 */
106umem_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)
107{
108	assert(source == NULL);
109
110	umem_cache_t *cache = malloc(sizeof(umem_cache_t));
111	if(cache == NULL)
112		return NULL;
113
114	cache->constructor = constructor;
115	cache->destructor = destructor;
116	cache->callback_data = callback_data;
117	cache->bufsize = bufsize;
118
119	return cache;
120}
121
122/*
123 * Simple stub for umem_cache_alloc(). The nofail callback isn't expected to return.
124 */
125void *umem_cache_alloc(umem_cache_t *cache, int flags)
126{
127	void *buf = malloc(cache->bufsize);
128	if(buf == NULL) {
129		if(!(flags & UMEM_NOFAIL))
130			return NULL;
131
132		if(nofail_cb != NULL)
133			nofail_cb();
134		abort();
135	}
136
137	if(cache->constructor != NULL) {
138		if(cache->constructor(buf, cache->callback_data, flags) != 0) {
139			free(buf);
140			if(!(flags & UMEM_NOFAIL))
141				return NULL;
142
143			if(nofail_cb != NULL)
144				nofail_cb();
145			abort();
146		}
147	}
148
149	return buf;
150}
151
152/*
153 * Simple stub for umem_cache_free().
154 */
155void umem_cache_free(umem_cache_t *cache, void *buffer)
156{
157	if(cache->destructor != NULL)
158		cache->destructor(buffer, cache->callback_data);
159
160	free(buffer);
161}
162
163/*
164 * Simple stub for umem_cache_destroy().
165 */
166void umem_cache_destroy(umem_cache_t *cache)
167{
168	free(cache);
169}
170