SphinxBase  5prealpha
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 
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  /* 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  if (!orig)
212  return NULL;
213 
214  len = strlen(orig) + 1;
215  buf = (char *) __ckd_malloc__(len, caller_file, caller_line);
216 
217  strcpy(buf, orig);
218  return (buf);
219 }
220 
221 
222 void *
223 __ckd_calloc_2d__(size_t d1, size_t d2, size_t elemsize,
224  const char *caller_file, int caller_line)
225 {
226  char **ref, *mem;
227  size_t i, offset;
228 
229  mem =
230  (char *) __ckd_calloc__(d1 * d2, elemsize, caller_file,
231  caller_line);
232  ref =
233  (char **) __ckd_malloc__(d1 * sizeof(void *), caller_file,
234  caller_line);
235 
236  for (i = 0, offset = 0; i < d1; i++, offset += d2 * elemsize)
237  ref[i] = mem + offset;
238 
239  return ref;
240 }
241 
242 
243 void
244 ckd_free(void *ptr)
245 {
246 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
247  if (ptr)
248  heap_free(0,ptr);
249 #else
250  free(ptr);
251 #endif
252 }
253 
254 void
255 ckd_free_2d(void *tmpptr)
256 {
257  void **ptr = (void **)tmpptr;
258  if (ptr)
259  ckd_free(ptr[0]);
260  ckd_free(ptr);
261 }
262 
263 
264 void *
265 __ckd_calloc_3d__(size_t d1, size_t d2, size_t d3, size_t elemsize,
266  const char *caller_file, int caller_line)
267 {
268  char ***ref1, **ref2, *mem;
269  size_t i, j, offset;
270 
271  mem =
272  (char *) __ckd_calloc__(d1 * d2 * d3, elemsize, caller_file,
273  caller_line);
274  ref1 =
275  (char ***) __ckd_malloc__(d1 * sizeof(void **), caller_file,
276  caller_line);
277  ref2 =
278  (char **) __ckd_malloc__(d1 * d2 * sizeof(void *), caller_file,
279  caller_line);
280 
281  for (i = 0, offset = 0; i < d1; i++, offset += d2)
282  ref1[i] = ref2 + offset;
283 
284  offset = 0;
285  for (i = 0; i < d1; i++) {
286  for (j = 0; j < d2; j++) {
287  ref1[i][j] = mem + offset;
288  offset += d3 * elemsize;
289  }
290  }
291 
292  return ref1;
293 }
294 
295 
296 void
297 ckd_free_3d(void *inptr)
298 {
299  void ***ptr = (void ***)inptr;
300 
301  if (ptr && ptr[0])
302  ckd_free(ptr[0][0]);
303  if (ptr)
304  ckd_free(ptr[0]);
305  ckd_free(ptr);
306 }
307 
308 
309 void ****
311  size_t d2,
312  size_t d3,
313  size_t d4,
314  size_t elem_size,
315  char *file,
316  int line)
317 {
318  void *store;
319  void **tmp1;
320  void ***tmp2;
321  void ****out;
322  size_t i, j;
323 
324  store = calloc(d1 * d2 * d3 * d4, elem_size);
325  if (store == NULL) {
326  E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
327  file, line, __FILE__, __LINE__);
328  }
329 
330  tmp1 = calloc(d1 * d2 * d3, sizeof(void *));
331  if (tmp1 == NULL) {
332  E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
333  file, line, __FILE__, __LINE__);
334  }
335 
336  tmp2 = ckd_calloc(d1 * d2, sizeof(void **));
337  if (tmp2 == NULL) {
338  E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
339  file, line, __FILE__, __LINE__);
340  }
341 
342  out = ckd_calloc(d1, sizeof(void ***));
343  if (out == NULL) {
344  E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
345  file, line, __FILE__, __LINE__);
346  }
347 
348  for (i = 0, j = 0; i < d1*d2*d3; i++, j += d4) {
349  tmp1[i] = &((char *)store)[j*elem_size];
350  }
351 
352  for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
353  tmp2[i] = &tmp1[j];
354  }
355 
356  for (i = 0, j = 0; i < d1; i++, j += d2) {
357  out[i] = &tmp2[j];
358  }
359 
360  return out;
361 }
362 
363 void
364 ckd_free_4d(void *inptr)
365 {
366  void ****ptr = (void ****)inptr;
367  if (ptr == NULL)
368  return;
369  /* free the underlying store */
370  ckd_free(ptr[0][0][0]);
371 
372  /* free the access overhead */
373  ckd_free(ptr[0][0]);
374  ckd_free(ptr[0]);
375  ckd_free(ptr);
376 }
377 
378 /* Layers a 3d array access structure over a preallocated storage area */
379 void *
381  size_t d2,
382  size_t d3,
383  void *store,
384  size_t elem_size,
385  char *file,
386  int line)
387 {
388  void **tmp1;
389  void ***out;
390  size_t i, j;
391 
392  tmp1 = __ckd_calloc__(d1 * d2, sizeof(void *), file, line);
393 
394  out = __ckd_calloc__(d1, sizeof(void **), file, line);
395 
396  for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
397  tmp1[i] = &((char *)store)[j*elem_size];
398  }
399 
400  for (i = 0, j = 0; i < d1; i++, j += d2) {
401  out[i] = &tmp1[j];
402  }
403 
404  return out;
405 }
406 
407 void *
409  size_t d2,
410  void *store,
411  size_t elem_size,
412  char *file,
413  int line)
414 {
415  void **out;
416  size_t i, j;
417 
418  out = __ckd_calloc__(d1, sizeof(void *), file, line);
419 
420  for (i = 0, j = 0; i < d1; i++, j += d2) {
421  out[i] = &((char *)store)[j*elem_size];
422  }
423 
424  return out;
425 }
426 
427 /* vim: set ts=4 sw=4: */
SPHINXBASE_EXPORT void **** __ckd_calloc_4d__(size_t d1, size_t d2, size_t d3, size_t d4, size_t elem_size, char *caller_file, int caller_line)
Allocate a 34D array and return ptr to it.
Definition: ckd_alloc.c:310
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Definition: ckd_alloc.h:248
SPHINXBASE_EXPORT void ckd_free_4d(void *ptr)
Free a 4-D array (ptr) previously allocated by ckd_calloc_4d.
Definition: ckd_alloc.c:364
Sphinx&#39;s memory allocation/deallocation routines.
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition: ckd_alloc.c:244
jmp_buf * ckd_set_jump(jmp_buf *env, int abort)
Control behaviour of the program when allocation fails.
Definition: ckd_alloc.c:109
Implementation of logging routines.
SPHINXBASE_EXPORT void ckd_free_3d(void *ptr)
Free a 3-D array (ptr) previously allocated by ckd_calloc_3d.
Definition: ckd_alloc.c:297
SPHINXBASE_EXPORT void * __ckd_alloc_3d_ptr(size_t d1, size_t d2, size_t d3, void *store, size_t elem_size, char *caller_file, int caller_line)
Overlay a 3-D array over a previously allocated storage area.
Definition: ckd_alloc.c:380
SPHINXBASE_EXPORT void ckd_free_2d(void *ptr)
Free a 2-D array (ptr) previously allocated by ckd_calloc_2d.
Definition: ckd_alloc.c:255
SPHINXBASE_EXPORT void * __ckd_alloc_2d_ptr(size_t d1, size_t d2, void *store, size_t elem_size, char *caller_file, int caller_line)
Overlay a s-D array over a previously allocated storage area.
Definition: ckd_alloc.c:408
void ckd_fail(char *format,...)
Fail (with a message) according to behaviour specified by ckd_set_jump().
Definition: ckd_alloc.c:122
SPHINXBASE_EXPORT void * __ckd_calloc_3d__(size_t d1, size_t d2, size_t d3, size_t elemsize, const char *caller_file, int caller_line)
Allocate a 3-D array and return ptr to it.
Definition: ckd_alloc.c:265
#define E_FATAL(...)
Exit with non-zero status after error message.
Definition: err.h:81
SPHINXBASE_EXPORT void * __ckd_calloc_2d__(size_t d1, size_t d2, size_t elemsize, const char *caller_file, int caller_line)
Allocate a 2-D array and return ptr to it (ie, ptr to vector of ptrs).
Definition: ckd_alloc.c:223
SPHINXBASE_EXPORT char * __ckd_salloc__(const char *origstr, const char *caller_file, int caller_line)
Like strdup, except that if an error occurs it prints a diagnostic message and exits.
Definition: ckd_alloc.c:205