1 /*        $NetBSD: umem.c,v 1.3 2019/05/26 10:21:00 hannken Exp $     */
2 
3 /*
4  * CDDL HEADER START
5  *
6  * The contents of this file are subject to the terms of the
7  * Common Development and Distribution License (the "License").
8  * You may not use this file except in compliance with the License.
9  *
10  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11  * or http://www.opensolaris.org/os/licensing.
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
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 
32 static umem_nofail_callback_t *nofail_cb = NULL;
33 
34 struct 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  */
umem_alloc(size_t size,int flags)44 void *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  */
umem_zalloc(size_t size,int flags)67 void *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  */
umem_free(void * buf,size_t size)90 void umem_free(void *buf, size_t size)
91 {
92           free(buf);
93 }
94 
95 /*
96  * Simple stub for umem_nofail_callback().
97  */
umem_nofail_callback(umem_nofail_callback_t * callback)98 void umem_nofail_callback(umem_nofail_callback_t *callback)
99 {
100           nofail_cb = callback;
101 }
102 
103 /*
104  * Simple stub for umem_cache_create().
105  */
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)106 umem_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  */
umem_cache_alloc(umem_cache_t * cache,int flags)125 void *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  */
umem_cache_free(umem_cache_t * cache,void * buffer)155 void 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  */
umem_cache_destroy(umem_cache_t * cache)166 void umem_cache_destroy(umem_cache_t *cache)
167 {
168           free(cache);
169 }
170