SphinxBase 0.6

src/libsphinxbase/util/ckd_alloc.c

00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
00002 /* ====================================================================
00003  * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights
00004  * reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer. 
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in
00015  *    the documentation and/or other materials provided with the
00016  *    distribution.
00017  *
00018  * This work was supported in part by funding from the Defense Advanced 
00019  * Research Projects Agency and the National Science Foundation of the 
00020  * United States of America, and the CMU Sphinx Speech Consortium.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
00023  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00024  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00025  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
00026  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
00029  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
00030  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * ====================================================================
00035  *
00036  */
00037 /*
00038  * ckd_alloc.c -- Memory allocation package.
00039  *
00040  * **********************************************
00041  * CMU ARPA Speech Project
00042  *
00043  * Copyright (c) 1999 Carnegie Mellon University.
00044  * ALL RIGHTS RESERVED.
00045  * **********************************************
00046  * 
00047  * HISTORY
00048  * $Log: ckd_alloc.c,v $
00049  * Revision 1.6  2005/06/22 02:59:25  arthchan2003
00050  * Added  keyword
00051  *
00052  * Revision 1.3  2005/03/30 01:22:48  archan
00053  * Fixed mistakes in last updates. Add
00054  *
00055  * 
00056  * 19-Jun-97    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
00057  *              Removed file,line arguments from free functions.
00058  *              Removed debugging stuff.
00059  * 
00060  * 01-Jan-96    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
00061  *              Created.
00062  */
00063 
00064 
00065 /*********************************************************************
00066  *
00067  * $Header: /cvsroot/cmusphinx/sphinx3/src/libutil/ckd_alloc.c,v 1.6 2005/06/22 02:59:25 arthchan2003 Exp $
00068  *
00069  * Carnegie Mellon ARPA Speech Group
00070  *
00071  * Copyright (c) 1994 Carnegie Mellon University.
00072  * All rights reserved.
00073  *
00074  *********************************************************************
00075  *
00076  * file: ckd_alloc.c
00077  * 
00078  * traceability: 
00079  * 
00080  * description: 
00081  * 
00082  * author: 
00083  * 
00084  *********************************************************************/
00085 
00086 
00087 #include <stdio.h>
00088 #include <stdlib.h>
00089 #include <string.h>
00090 #include <assert.h>
00091 #include <stdarg.h>
00092 
00093 #ifdef _MSC_VER
00094 #pragma warning (disable: 4996)
00095 #endif
00096 
00097 #include "sphinxbase/ckd_alloc.h"
00098 #include "sphinxbase/err.h"
00099 
00105 static jmp_buf *ckd_target;
00106 static int jmp_abort;
00107 
00108 jmp_buf *
00109 ckd_set_jump(jmp_buf *env, int abort)
00110 {
00111     jmp_buf *old;
00112 
00113     if (abort)
00114         jmp_abort = 1;
00115 
00116     old = ckd_target;
00117     ckd_target = env;
00118     return old;
00119 }
00120 
00121 void
00122 ckd_fail(char *format, ...)
00123 {
00124     va_list args;
00125 
00126     va_start(args, format);
00127     vfprintf(stderr, format, args);
00128     va_end(args);
00129 
00130     if (jmp_abort)
00131         /* Silvio Moioli: abort() doesn't exist in Windows CE */
00132         #if defined(_WIN32_WCE)
00133         exit(-1);
00134         #else
00135         abort();
00136         #endif
00137     else if (ckd_target)
00138         longjmp(*ckd_target, 1);
00139     else
00140         exit(-1);
00141 }
00142 
00143 void *
00144 __ckd_calloc__(size_t n_elem, size_t elem_size,
00145                const char *caller_file, int caller_line)
00146 {
00147     void *mem;
00148 
00149 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
00150     if ((mem = heap_calloc(heap_lookup(1),n_elem, elem_size)) == NULL)
00151         if ((mem = heap_calloc(heap_lookup(0),n_elem, elem_size)) == NULL) 
00152         {
00153                 ckd_fail("calloc(%d,%d) failed from %s(%d), free space: %d\n", n_elem,
00154                 elem_size, caller_file, caller_line,space_unused());
00155         }
00156 #else
00157     if ((mem = calloc(n_elem, elem_size)) == NULL) {
00158         ckd_fail("calloc(%d,%d) failed from %s(%d)\n", n_elem,
00159                 elem_size, caller_file, caller_line);
00160         }
00161 #endif
00162         
00163 
00164     return mem;
00165 }
00166 
00167 
00168 void *
00169 __ckd_malloc__(size_t size, const char *caller_file, int caller_line)
00170 {
00171     void *mem;
00172 
00173 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
00174     if ((mem = heap_malloc(heap_lookup(0),size)) == NULL)
00175         if ((mem = heap_malloc(heap_lookup(1),size)) == NULL) 
00176 #else
00177     if ((mem = malloc(size)) == NULL)
00178 #endif
00179                 ckd_fail("malloc(%d) failed from %s(%d)\n", size,
00180                 caller_file, caller_line);
00181                 
00182     return mem;
00183 }
00184 
00185 
00186 void *
00187 __ckd_realloc__(void *ptr, size_t new_size,
00188                 const char *caller_file, int caller_line)
00189 {
00190     void *mem;
00191 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
00192     if ((mem = heap_realloc(heap_lookup(0),ptr, new_size)) == NULL) {
00193 #else
00194     if ((mem = realloc(ptr, new_size)) == NULL) {
00195 #endif
00196         ckd_fail("malloc(%d) failed from %s(%d)\n", new_size,
00197                 caller_file, caller_line);
00198     }
00199 
00200     return mem;
00201 }
00202 
00203 
00204 char *
00205 __ckd_salloc__(const char *orig, const char *caller_file,
00206                int caller_line)
00207 {
00208     size_t len;
00209     char *buf;
00210 
00211     len = strlen(orig) + 1;
00212     buf = (char *) __ckd_malloc__(len, caller_file, caller_line);
00213 
00214     strcpy(buf, orig);
00215     return (buf);
00216 }
00217 
00218 
00219 void *
00220 __ckd_calloc_2d__(size_t d1, size_t d2, size_t elemsize,
00221                   const char *caller_file, int caller_line)
00222 {
00223     char **ref, *mem;
00224     size_t i, offset;
00225 
00226     mem =
00227         (char *) __ckd_calloc__(d1 * d2, elemsize, caller_file,
00228                                 caller_line);
00229     ref =
00230         (char **) __ckd_malloc__(d1 * sizeof(void *), caller_file,
00231                                  caller_line);
00232 
00233     for (i = 0, offset = 0; i < d1; i++, offset += d2 * elemsize)
00234         ref[i] = mem + offset;
00235 
00236     return ref;
00237 }
00238 
00239 
00240 void
00241 ckd_free(void *ptr)
00242 {
00243     if (ptr)
00244 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
00245         heap_free(0,ptr);
00246 #else
00247                 free(ptr);
00248 #endif
00249 }
00250 
00251 void
00252 ckd_free_2d(void *tmpptr)
00253 {
00254     void **ptr = (void **)tmpptr;
00255     if (ptr)
00256         ckd_free(ptr[0]);
00257     ckd_free(ptr);
00258 }
00259 
00260 
00261 void *
00262 __ckd_calloc_3d__(size_t d1, size_t d2, size_t d3, size_t elemsize,
00263                   const char *caller_file, int caller_line)
00264 {
00265     char ***ref1, **ref2, *mem;
00266     size_t i, j, offset;
00267 
00268     mem =
00269         (char *) __ckd_calloc__(d1 * d2 * d3, elemsize, caller_file,
00270                                 caller_line);
00271     ref1 =
00272         (char ***) __ckd_malloc__(d1 * sizeof(void **), caller_file,
00273                                   caller_line);
00274     ref2 =
00275         (char **) __ckd_malloc__(d1 * d2 * sizeof(void *), caller_file,
00276                                  caller_line);
00277 
00278     for (i = 0, offset = 0; i < d1; i++, offset += d2)
00279         ref1[i] = ref2 + offset;
00280 
00281     offset = 0;
00282     for (i = 0; i < d1; i++) {
00283         for (j = 0; j < d2; j++) {
00284             ref1[i][j] = mem + offset;
00285             offset += d3 * elemsize;
00286         }
00287     }
00288 
00289     return ref1;
00290 }
00291 
00292 
00293 void
00294 ckd_free_3d(void *inptr)
00295 {
00296     void ***ptr = (void ***)inptr;
00297 
00298     if (ptr && ptr[0])
00299         ckd_free(ptr[0][0]);
00300     if (ptr)
00301         ckd_free(ptr[0]);
00302     ckd_free(ptr);
00303 }
00304 
00305 
00306 void ****
00307 __ckd_calloc_4d__(size_t d1,
00308                   size_t d2,
00309                   size_t d3,
00310                   size_t d4,
00311                   size_t elem_size,
00312                   char *file,
00313                   int line)
00314 {
00315     void *store;
00316     void **tmp1;
00317     void ***tmp2;
00318     void ****out;
00319     size_t i, j;
00320 
00321     store = calloc(d1 * d2 * d3 * d4, elem_size);
00322     if (store == NULL) {
00323         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
00324                 file, line, __FILE__, __LINE__);
00325     }
00326     
00327     tmp1 = calloc(d1 * d2 * d3, sizeof(void *));
00328     if (tmp1 == NULL) {
00329         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
00330                 file, line, __FILE__, __LINE__);
00331     }
00332 
00333     tmp2 = ckd_calloc(d1 * d2, sizeof(void **));
00334     if (tmp2 == NULL) {
00335         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
00336                 file, line, __FILE__, __LINE__);
00337     }
00338 
00339     out = ckd_calloc(d1, sizeof(void ***));
00340     if (out == NULL) {
00341         E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
00342                 file, line, __FILE__, __LINE__);
00343     }
00344     
00345     for (i = 0, j = 0; i < d1*d2*d3; i++, j += d4) {
00346         tmp1[i] = &((char *)store)[j*elem_size];
00347     }
00348 
00349     for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
00350         tmp2[i] = &tmp1[j];
00351     }
00352 
00353     for (i = 0, j = 0; i < d1; i++, j += d2) {
00354         out[i] = &tmp2[j];
00355     }
00356 
00357     return out;
00358 }
00359 
00360 void
00361 ckd_free_4d(void *inptr)
00362 {
00363     void ****ptr = (void ****)inptr;
00364     if (ptr == NULL)
00365         return;
00366     /* free the underlying store */
00367     ckd_free(ptr[0][0][0]);
00368 
00369     /* free the access overhead */
00370     ckd_free(ptr[0][0]);
00371     ckd_free(ptr[0]);
00372     ckd_free(ptr);
00373 }
00374 
00375 /* Layers a 3d array access structure over a preallocated storage area */
00376 void *
00377 __ckd_alloc_3d_ptr(size_t d1,
00378                    size_t d2,
00379                    size_t d3,
00380                    void *store,
00381                    size_t elem_size,
00382                    char *file,
00383                    int line)
00384 {
00385     void **tmp1;
00386     void ***out;
00387     size_t i, j;
00388     
00389     tmp1 = __ckd_calloc__(d1 * d2, sizeof(void *), file, line);
00390 
00391     out  = __ckd_calloc__(d1, sizeof(void **), file, line);
00392     
00393     for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
00394         tmp1[i] = &((char *)store)[j*elem_size];
00395     }
00396     
00397     for (i = 0, j = 0; i < d1; i++, j += d2) {
00398         out[i] = &tmp1[j];
00399     }
00400     
00401     return out;
00402 }
00403 
00404 void *
00405 __ckd_alloc_2d_ptr(size_t d1,
00406                    size_t d2,
00407                    void *store,
00408                    size_t elem_size,
00409                    char *file,
00410                    int line)
00411 {
00412     void **out;
00413     size_t i, j;
00414     
00415     out = __ckd_calloc__(d1, sizeof(void *), file, line);
00416     
00417     for (i = 0, j = 0; i < d1; i++, j += d2) {
00418         out[i] = &((char *)store)[j*elem_size];
00419     }
00420 
00421     return out;
00422 }