ckd_alloc.c
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2004 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* This work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
*/
/*
* ckd_alloc.c -- Memory allocation package.
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1999 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
*
* HISTORY
* $Log: ckd_alloc.c,v $
* Revision 1.6 2005/06/22 02:59:25 arthchan2003
* Added keyword
*
* Revision 1.3 2005/03/30 01:22:48 archan
* Fixed mistakes in last updates. Add
*
*
* 19-Jun-97 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
* Removed file,line arguments from free functions.
* Removed debugging stuff.
*
* 01-Jan-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
* Created.
*/
/*********************************************************************
*
* $Header: /cvsroot/cmusphinx/sphinx3/src/libutil/ckd_alloc.c,v 1.6 2005/06/22 02:59:25 arthchan2003 Exp $
*
* Carnegie Mellon ARPA Speech Group
*
* Copyright (c) 1994 Carnegie Mellon University.
* All rights reserved.
*
*********************************************************************
*
* file: ckd_alloc.c
*
* traceability:
*
* description:
*
* author:
*
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#ifdef _MSC_VER
#pragma warning (disable: 4996)
#endif
#include "sphinxbase/ckd_alloc.h"
#include "sphinxbase/err.h"
static jmp_buf *ckd_target;
static int jmp_abort;
jmp_buf *
ckd_set_jump(jmp_buf *env, int abort)
{
jmp_buf *old;
if (abort)
jmp_abort = 1;
old = ckd_target;
ckd_target = env;
return old;
}
void
ckd_fail(char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
if (jmp_abort)
/* Silvio Moioli: abort() doesn't exist in Windows CE */
#if defined(_WIN32_WCE)
exit(-1);
#else
abort();
#endif
else if (ckd_target)
longjmp(*ckd_target, 1);
else
exit(-1);
}
void *
__ckd_calloc__(size_t n_elem, size_t elem_size,
const char *caller_file, int caller_line)
{
void *mem;
#if defined(__ADSPBLACKFIN__) && !defined(__linux__)
if ((mem = heap_calloc(heap_lookup(1),n_elem, elem_size)) == NULL)
if ((mem = heap_calloc(heap_lookup(0),n_elem, elem_size)) == NULL)
{
ckd_fail("calloc(%d,%d) failed from %s(%d), free space: %d\n", n_elem,
elem_size, caller_file, caller_line,space_unused());
}
#else
if ((mem = calloc(n_elem, elem_size)) == NULL) {
ckd_fail("calloc(%d,%d) failed from %s(%d)\n", n_elem,
elem_size, caller_file, caller_line);
}
#endif
return mem;
}
void *
__ckd_malloc__(size_t size, const char *caller_file, int caller_line)
{
void *mem;
#if defined(__ADSPBLACKFIN__) && !defined(__linux__)
if ((mem = heap_malloc(heap_lookup(0),size)) == NULL)
if ((mem = heap_malloc(heap_lookup(1),size)) == NULL)
#else
if ((mem = malloc(size)) == NULL)
#endif
ckd_fail("malloc(%d) failed from %s(%d)\n", size,
caller_file, caller_line);
return mem;
}
void *
__ckd_realloc__(void *ptr, size_t new_size,
const char *caller_file, int caller_line)
{
void *mem;
#if defined(__ADSPBLACKFIN__) && !defined(__linux__)
if ((mem = heap_realloc(heap_lookup(0),ptr, new_size)) == NULL) {
#else
if ((mem = realloc(ptr, new_size)) == NULL) {
#endif
ckd_fail("malloc(%d) failed from %s(%d)\n", new_size,
caller_file, caller_line);
}
return mem;
}
char *
__ckd_salloc__(const char *orig, const char *caller_file,
int caller_line)
{
size_t len;
char *buf;
len = strlen(orig) + 1;
buf = (char *) __ckd_malloc__(len, caller_file, caller_line);
strcpy(buf, orig);
return (buf);
}
void *
__ckd_calloc_2d__(size_t d1, size_t d2, size_t elemsize,
const char *caller_file, int caller_line)
{
char **ref, *mem;
size_t i, offset;
mem =
(char *) __ckd_calloc__(d1 * d2, elemsize, caller_file,
caller_line);
ref =
(char **) __ckd_malloc__(d1 * sizeof(void *), caller_file,
caller_line);
for (i = 0, offset = 0; i < d1; i++, offset += d2 * elemsize)
ref[i] = mem + offset;
return ref;
}
void
ckd_free(void *ptr)
{
if (ptr)
#if defined(__ADSPBLACKFIN__) && !defined(__linux__)
heap_free(0,ptr);
#else
free(ptr);
#endif
}
void
ckd_free_2d(void *tmpptr)
{
void **ptr = (void **)tmpptr;
if (ptr)
ckd_free(ptr[0]);
ckd_free(ptr);
}
void *
__ckd_calloc_3d__(size_t d1, size_t d2, size_t d3, size_t elemsize,
const char *caller_file, int caller_line)
{
char ***ref1, **ref2, *mem;
size_t i, j, offset;
mem =
(char *) __ckd_calloc__(d1 * d2 * d3, elemsize, caller_file,
caller_line);
ref1 =
(char ***) __ckd_malloc__(d1 * sizeof(void **), caller_file,
caller_line);
ref2 =
(char **) __ckd_malloc__(d1 * d2 * sizeof(void *), caller_file,
caller_line);
for (i = 0, offset = 0; i < d1; i++, offset += d2)
ref1[i] = ref2 + offset;
offset = 0;
for (i = 0; i < d1; i++) {
for (j = 0; j < d2; j++) {
ref1[i][j] = mem + offset;
offset += d3 * elemsize;
}
}
return ref1;
}
void
ckd_free_3d(void *inptr)
{
void ***ptr = (void ***)inptr;
if (ptr && ptr[0])
ckd_free(ptr[0][0]);
if (ptr)
ckd_free(ptr[0]);
ckd_free(ptr);
}
void ****
__ckd_calloc_4d__(size_t d1,
size_t d2,
size_t d3,
size_t d4,
size_t elem_size,
char *file,
int line)
{
void *store;
void **tmp1;
void ***tmp2;
void ****out;
size_t i, j;
store = calloc(d1 * d2 * d3 * d4, elem_size);
if (store == NULL) {
E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
file, line, __FILE__, __LINE__);
}
tmp1 = calloc(d1 * d2 * d3, sizeof(void *));
if (tmp1 == NULL) {
E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
file, line, __FILE__, __LINE__);
}
tmp2 = ckd_calloc(d1 * d2, sizeof(void **));
if (tmp2 == NULL) {
E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
file, line, __FILE__, __LINE__);
}
out = ckd_calloc(d1, sizeof(void ***));
if (out == NULL) {
E_FATAL("ckd_calloc_4d failed for caller at %s(%d) at %s(%d)\n",
file, line, __FILE__, __LINE__);
}
for (i = 0, j = 0; i < d1*d2*d3; i++, j += d4) {
tmp1[i] = &((char *)store)[j*elem_size];
}
for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
tmp2[i] = &tmp1[j];
}
for (i = 0, j = 0; i < d1; i++, j += d2) {
out[i] = &tmp2[j];
}
return out;
}
void
ckd_free_4d(void *inptr)
{
void ****ptr = (void ****)inptr;
if (ptr == NULL)
return;
/* free the underlying store */
ckd_free(ptr[0][0][0]);
/* free the access overhead */
ckd_free(ptr[0][0]);
ckd_free(ptr[0]);
ckd_free(ptr);
}
/* Layers a 3d array access structure over a preallocated storage area */
void *
__ckd_alloc_3d_ptr(size_t d1,
size_t d2,
size_t d3,
void *store,
size_t elem_size,
char *file,
int line)
{
void **tmp1;
void ***out;
size_t i, j;
tmp1 = __ckd_calloc__(d1 * d2, sizeof(void *), file, line);
out = __ckd_calloc__(d1, sizeof(void **), file, line);
for (i = 0, j = 0; i < d1*d2; i++, j += d3) {
tmp1[i] = &((char *)store)[j*elem_size];
}
for (i = 0, j = 0; i < d1; i++, j += d2) {
out[i] = &tmp1[j];
}
return out;
}
void *
__ckd_alloc_2d_ptr(size_t d1,
size_t d2,
void *store,
size_t elem_size,
char *file,
int line)
{
void **out;
size_t i, j;
out = __ckd_calloc__(d1, sizeof(void *), file, line);
for (i = 0, j = 0; i < d1; i++, j += d2) {
out[i] = &((char *)store)[j*elem_size];
}
return out;
}
__ckd_calloc_4d__
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:307
ckd_calloc
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Definition: ckd_alloc.h:248
ckd_free_4d
SPHINXBASE_EXPORT void ckd_free_4d(void *ptr)
Free a 4-D array (ptr) previously allocated by ckd_calloc_4d.
Definition: ckd_alloc.c:361
ckd_alloc.h
Sphinx's memory allocation/deallocation routines.
ckd_free
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition: ckd_alloc.c:241
ckd_set_jump
jmp_buf * ckd_set_jump(jmp_buf *env, int abort)
Control behaviour of the program when allocation fails.
Definition: ckd_alloc.c:109
err.h
Implementation of logging routines.
ckd_free_3d
SPHINXBASE_EXPORT void ckd_free_3d(void *ptr)
Free a 3-D array (ptr) previously allocated by ckd_calloc_3d.
Definition: ckd_alloc.c:294
__ckd_alloc_3d_ptr
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:377
E_FATAL
#define E_FATAL
Exit with non-zero status after error message.
Definition: err.h:127
ckd_free_2d
SPHINXBASE_EXPORT void ckd_free_2d(void *ptr)
Free a 2-D array (ptr) previously allocated by ckd_calloc_2d.
Definition: ckd_alloc.c:252
__ckd_alloc_2d_ptr
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:405
ckd_fail
void ckd_fail(char *format,...)
Fail (with a message) according to behaviour specified by ckd_set_jump().
Definition: ckd_alloc.c:122
__ckd_calloc_3d__
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:262
__ckd_calloc_2d__
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:220
__ckd_salloc__
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