Initial import to Tizen
[profile/ivi/sphinxbase.git] / src / libsphinxbase / util / ckd_alloc.c
1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced 
19  * Research Projects Agency and the National Science Foundation of the 
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ====================================================================
35  *
36  */
37 /*
38  * ckd_alloc.c -- Memory allocation package.
39  *
40  * **********************************************
41  * CMU ARPA Speech Project
42  *
43  * Copyright (c) 1999 Carnegie Mellon University.
44  * ALL RIGHTS RESERVED.
45  * **********************************************
46  * 
47  * HISTORY
48  * $Log: ckd_alloc.c,v $
49  * Revision 1.6  2005/06/22 02:59:25  arthchan2003
50  * Added  keyword
51  *
52  * Revision 1.3  2005/03/30 01:22:48  archan
53  * Fixed mistakes in last updates. Add
54  *
55  * 
56  * 19-Jun-97    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
57  *              Removed file,line arguments from free functions.
58  *              Removed debugging stuff.
59  * 
60  * 01-Jan-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
61  *              Created.
62  */
63
64
65 /*********************************************************************
66  *
67  * $Header: /cvsroot/cmusphinx/sphinx3/src/libutil/ckd_alloc.c,v 1.6 2005/06/22 02:59:25 arthchan2003 Exp $
68  *
69  * Carnegie Mellon ARPA Speech Group
70  *
71  * Copyright (c) 1994 Carnegie Mellon University.
72  * All rights reserved.
73  *
74  *********************************************************************
75  *
76  * file: ckd_alloc.c
77  * 
78  * traceability: 
79  * 
80  * description: 
81  * 
82  * author: 
83  * 
84  *********************************************************************/
85
86
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <assert.h>
91 #include <stdarg.h>
92
93 #ifdef _MSC_VER
94 #pragma warning (disable: 4996)
95 #endif
96
97 #include "sphinxbase/ckd_alloc.h"
98 #include "sphinxbase/err.h"
99
100 /**
101  * Target for longjmp() on failure.
102  * 
103  * FIXME: This should be in thread-local storage.
104  */
105 static jmp_buf *ckd_target;
106 static int jmp_abort;
107
108 jmp_buf *
109 ckd_set_jump(jmp_buf *env, int abort)
110 {
111     jmp_buf *old;
112
113     if (abort)
114         jmp_abort = 1;
115
116     old = ckd_target;
117     ckd_target = env;
118     return old;
119 }
120
121 void
122 ckd_fail(char *format, ...)
123 {
124     va_list args;
125
126     va_start(args, format);
127     vfprintf(stderr, format, args);
128     va_end(args);
129
130     if (jmp_abort)
131         /* Silvio Moioli: abort() doesn't exist in Windows CE */
132         #if defined(_WIN32_WCE)
133         exit(-1);
134         #else
135         abort();
136         #endif
137     else if (ckd_target)
138         longjmp(*ckd_target, 1);
139     else
140         exit(-1);
141 }
142
143 void *
144 __ckd_calloc__(size_t n_elem, size_t elem_size,
145                const char *caller_file, int caller_line)
146 {
147     void *mem;
148
149 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
150     if ((mem = heap_calloc(heap_lookup(1),n_elem, elem_size)) == NULL)
151         if ((mem = heap_calloc(heap_lookup(0),n_elem, elem_size)) == NULL) 
152         {
153                 ckd_fail("calloc(%d,%d) failed from %s(%d), free space: %d\n", n_elem,
154                 elem_size, caller_file, caller_line,space_unused());
155         }
156 #else
157     if ((mem = calloc(n_elem, elem_size)) == NULL) {
158         ckd_fail("calloc(%d,%d) failed from %s(%d)\n", n_elem,
159                 elem_size, caller_file, caller_line);
160         }
161 #endif
162         
163
164     return mem;
165 }
166
167
168 void *
169 __ckd_malloc__(size_t size, const char *caller_file, int caller_line)
170 {
171     void *mem;
172
173 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
174     if ((mem = heap_malloc(heap_lookup(0),size)) == NULL)
175         if ((mem = heap_malloc(heap_lookup(1),size)) == NULL) 
176 #else
177     if ((mem = malloc(size)) == NULL)
178 #endif
179                 ckd_fail("malloc(%d) failed from %s(%d)\n", size,
180                 caller_file, caller_line);
181                 
182     return mem;
183 }
184
185
186 void *
187 __ckd_realloc__(void *ptr, size_t new_size,
188                 const char *caller_file, int caller_line)
189 {
190     void *mem;
191 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
192     if ((mem = heap_realloc(heap_lookup(0),ptr, new_size)) == NULL) {
193 #else
194     if ((mem = realloc(ptr, new_size)) == NULL) {
195 #endif
196         ckd_fail("malloc(%d) failed from %s(%d)\n", new_size,
197                 caller_file, caller_line);
198     }
199
200     return mem;
201 }
202
203
204 char *
205 __ckd_salloc__(const char *orig, const char *caller_file,
206                int caller_line)
207 {
208     size_t len;
209     char *buf;
210
211     len = strlen(orig) + 1;
212     buf = (char *) __ckd_malloc__(len, caller_file, caller_line);
213
214     strcpy(buf, orig);
215     return (buf);
216 }
217
218
219 void *
220 __ckd_calloc_2d__(size_t d1, size_t d2, size_t elemsize,
221                   const char *caller_file, int caller_line)
222 {
223     char **ref, *mem;
224     size_t i, offset;
225
226     mem =
227         (char *) __ckd_calloc__(d1 * d2, elemsize, caller_file,
228                                 caller_line);
229     ref =
230         (char **) __ckd_malloc__(d1 * sizeof(void *), caller_file,
231                                  caller_line);
232
233     for (i = 0, offset = 0; i < d1; i++, offset += d2 * elemsize)
234         ref[i] = mem + offset;
235
236     return ref;
237 }
238
239
240 void
241 ckd_free(void *ptr)
242 {
243     if (ptr)
244 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
245         heap_free(0,ptr);
246 #else
247                 free(ptr);
248 #endif
249 }
250
251 void
252 ckd_free_2d(void *tmpptr)
253 {
254     void **ptr = (void **)tmpptr;
255     if (ptr)
256         ckd_free(ptr[0]);
257     ckd_free(ptr);
258 }
259
260
261 void *
262 __ckd_calloc_3d__(size_t d1, size_t d2, size_t d3, size_t elemsize,
263                   const char *caller_file, int caller_line)
264 {
265     char ***ref1, **ref2, *mem;
266     size_t i, j, offset;
267
268     mem =
269         (char *) __ckd_calloc__(d1 * d2 * d3, elemsize, caller_file,
270                                 caller_line);
271     ref1 =
272         (char ***) __ckd_malloc__(d1 * sizeof(void **), caller_file,
273                                   caller_line);
274     ref2 =
275         (char **) __ckd_malloc__(d1 * d2 * sizeof(void *), caller_file,
276                                  caller_line);
277
278     for (i = 0, offset = 0; i < d1; i++, offset += d2)
279         ref1[i] = ref2 + offset;
280
281     offset = 0;
282     for (i = 0; i < d1; i++) {
283         for (j = 0; j < d2; j++) {
284             ref1[i][j] = mem + offset;
285             offset += d3 * elemsize;
286         }
287     }
288
289     return ref1;
290 }
291
292
293 void
294 ckd_free_3d(void *inptr)
295 {
296     void ***ptr = (void ***)inptr;
297
298     if (ptr && ptr[0])
299         ckd_free(ptr[0][0]);
300     if (ptr)
301         ckd_free(ptr[0]);
302     ckd_free(ptr);
303 }
304
305
306 void ****
307 __ckd_calloc_4d__(size_t d1,
308                   size_t d2,
309                   size_t d3,
310                   size_t d4,
311                   size_t elem_size,
312                   char *file,
313                   int line)
314 {
315     void *store;
316     void **tmp1;
317     void ***tmp2;
318     void ****out;
319     size_t i, j;
320
321     store = calloc(d1 * d2 * d3 * d4, elem_size);
322     if (store == NULL) {
323         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
324                 file, line, __FILE__, __LINE__);
325     }
326     
327     tmp1 = calloc(d1 * d2 * d3, sizeof(void *));
328     if (tmp1 == NULL) {
329         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
330                 file, line, __FILE__, __LINE__);
331     }
332
333     tmp2 = ckd_calloc(d1 * d2, sizeof(void **));
334     if (tmp2 == NULL) {
335         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
336                 file, line, __FILE__, __LINE__);
337     }
338
339     out = ckd_calloc(d1, sizeof(void ***));
340     if (out == NULL) {
341         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
342                 file, line, __FILE__, __LINE__);
343     }
344     
345     for (i = 0, j = 0; i < d1*d2*d3; i++, j += d4) {
346         tmp1[i] = &((char *)store)[j*elem_size];
347     }
348
349     for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
350         tmp2[i] = &tmp1[j];
351     }
352
353     for (i = 0, j = 0; i < d1; i++, j += d2) {
354         out[i] = &tmp2[j];
355     }
356
357     return out;
358 }
359
360 void
361 ckd_free_4d(void *inptr)
362 {
363     void ****ptr = (void ****)inptr;
364     if (ptr == NULL)
365         return;
366     /* free the underlying store */
367     ckd_free(ptr[0][0][0]);
368
369     /* free the access overhead */
370     ckd_free(ptr[0][0]);
371     ckd_free(ptr[0]);
372     ckd_free(ptr);
373 }
374
375 /* Layers a 3d array access structure over a preallocated storage area */
376 void *
377 __ckd_alloc_3d_ptr(size_t d1,
378                    size_t d2,
379                    size_t d3,
380                    void *store,
381                    size_t elem_size,
382                    char *file,
383                    int line)
384 {
385     void **tmp1;
386     void ***out;
387     size_t i, j;
388     
389     tmp1 = __ckd_calloc__(d1 * d2, sizeof(void *), file, line);
390
391     out  = __ckd_calloc__(d1, sizeof(void **), file, line);
392     
393     for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
394         tmp1[i] = &((char *)store)[j*elem_size];
395     }
396     
397     for (i = 0, j = 0; i < d1; i++, j += d2) {
398         out[i] = &tmp1[j];
399     }
400     
401     return out;
402 }
403
404 void *
405 __ckd_alloc_2d_ptr(size_t d1,
406                    size_t d2,
407                    void *store,
408                    size_t elem_size,
409                    char *file,
410                    int line)
411 {
412     void **out;
413     size_t i, j;
414     
415     out = __ckd_calloc__(d1, sizeof(void *), file, line);
416     
417     for (i = 0, j = 0; i < d1; i++, j += d2) {
418         out[i] = &((char *)store)[j*elem_size];
419     }
420
421     return out;
422 }