intl/icu/source/common/cmemory.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/common/cmemory.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,183 @@
     1.4 +/*
     1.5 +******************************************************************************
     1.6 +*
     1.7 +*   Copyright (C) 2002-2012, International Business Machines
     1.8 +*   Corporation and others.  All Rights Reserved.
     1.9 +*
    1.10 +******************************************************************************
    1.11 +*
    1.12 +* File cmemory.c      ICU Heap allocation.
    1.13 +*                     All ICU heap allocation, both for C and C++ new of ICU
    1.14 +*                     class types, comes through these functions.
    1.15 +*
    1.16 +*                     If you have a need to replace ICU allocation, this is the
    1.17 +*                     place to do it.
    1.18 +*
    1.19 +*                     Note that uprv_malloc(0) returns a non-NULL pointer, and
    1.20 +*                     that a subsequent free of that pointer value is a NOP.
    1.21 +*
    1.22 +******************************************************************************
    1.23 +*/
    1.24 +#include "unicode/uclean.h"
    1.25 +#include "cmemory.h"
    1.26 +#include "putilimp.h"
    1.27 +#include "uassert.h"
    1.28 +#include <stdlib.h>
    1.29 +
    1.30 +/* uprv_malloc(0) returns a pointer to this read-only data. */
    1.31 +static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0};
    1.32 +
    1.33 +/* Function Pointers for user-supplied heap functions  */
    1.34 +static const void     *pContext;
    1.35 +static UMemAllocFn    *pAlloc;
    1.36 +static UMemReallocFn  *pRealloc;
    1.37 +static UMemFreeFn     *pFree;
    1.38 +
    1.39 +/* Flag indicating whether any heap allocations have happened.
    1.40 + *   Used to prevent changing out the heap functions after allocations have been made */
    1.41 +static UBool   gHeapInUse;
    1.42 +
    1.43 +#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
    1.44 +#include <stdio.h>
    1.45 +static int n=0;
    1.46 +static long b=0; 
    1.47 +#endif
    1.48 +
    1.49 +#if U_DEBUG
    1.50 +
    1.51 +static char gValidMemorySink = 0;
    1.52 +
    1.53 +U_CAPI void uprv_checkValidMemory(const void *p, size_t n) {
    1.54 +    /*
    1.55 +     * Access the memory to ensure that it's all valid.
    1.56 +     * Load and save a computed value to try to ensure that the compiler
    1.57 +     * does not throw away the whole loop.
    1.58 +     * A thread analyzer might complain about un-mutexed access to gValidMemorySink
    1.59 +     * which is true but harmless because no one ever uses the value in gValidMemorySink.
    1.60 +     */
    1.61 +    const char *s = (const char *)p;
    1.62 +    char c = gValidMemorySink;
    1.63 +    size_t i;
    1.64 +    U_ASSERT(p != NULL);
    1.65 +    for(i = 0; i < n; ++i) {
    1.66 +        c ^= s[i];
    1.67 +    }
    1.68 +    gValidMemorySink = c;
    1.69 +}
    1.70 +
    1.71 +#endif  /* U_DEBUG */
    1.72 +
    1.73 +U_CAPI void * U_EXPORT2
    1.74 +uprv_malloc(size_t s) {
    1.75 +#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
    1.76 +#if 1
    1.77 +  putchar('>');
    1.78 +  fflush(stdout);
    1.79 +#else
    1.80 +  fprintf(stderr,"MALLOC\t#%d\t%ul bytes\t%ul total\n", ++n,s,(b+=s)); fflush(stderr);
    1.81 +#endif
    1.82 +#endif
    1.83 +    if (s > 0) {
    1.84 +        gHeapInUse = TRUE;
    1.85 +        if (pAlloc) {
    1.86 +            return (*pAlloc)(pContext, s);
    1.87 +        } else {
    1.88 +            return uprv_default_malloc(s);
    1.89 +        }
    1.90 +    } else {
    1.91 +        return (void *)zeroMem;
    1.92 +    }
    1.93 +}
    1.94 +
    1.95 +U_CAPI void * U_EXPORT2
    1.96 +uprv_realloc(void * buffer, size_t size) {
    1.97 +#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
    1.98 +  putchar('~');
    1.99 +  fflush(stdout);
   1.100 +#endif
   1.101 +    if (buffer == zeroMem) {
   1.102 +        return uprv_malloc(size);
   1.103 +    } else if (size == 0) {
   1.104 +        if (pFree) {
   1.105 +            (*pFree)(pContext, buffer);
   1.106 +        } else {
   1.107 +            uprv_default_free(buffer);
   1.108 +        }
   1.109 +        return (void *)zeroMem;
   1.110 +    } else {
   1.111 +        gHeapInUse = TRUE;
   1.112 +        if (pRealloc) {
   1.113 +            return (*pRealloc)(pContext, buffer, size);
   1.114 +        } else {
   1.115 +            return uprv_default_realloc(buffer, size);
   1.116 +        }
   1.117 +    }
   1.118 +}
   1.119 +
   1.120 +U_CAPI void U_EXPORT2
   1.121 +uprv_free(void *buffer) {
   1.122 +#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
   1.123 +  putchar('<');
   1.124 +  fflush(stdout);
   1.125 +#endif
   1.126 +    if (buffer != zeroMem) {
   1.127 +        if (pFree) {
   1.128 +            (*pFree)(pContext, buffer);
   1.129 +        } else {
   1.130 +            uprv_default_free(buffer);
   1.131 +        }
   1.132 +    }
   1.133 +}
   1.134 +
   1.135 +U_CAPI void * U_EXPORT2
   1.136 +uprv_calloc(size_t num, size_t size) {
   1.137 +    void *mem = NULL;
   1.138 +    size *= num;
   1.139 +    mem = uprv_malloc(size);
   1.140 +    if (mem) {
   1.141 +        uprv_memset(mem, 0, size);
   1.142 +    }
   1.143 +    return mem;
   1.144 +}
   1.145 +
   1.146 +U_CAPI void U_EXPORT2
   1.147 +u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f,  UErrorCode *status)
   1.148 +{
   1.149 +    if (U_FAILURE(*status)) {
   1.150 +        return;
   1.151 +    }
   1.152 +    if (a==NULL || r==NULL || f==NULL) {
   1.153 +        *status = U_ILLEGAL_ARGUMENT_ERROR;
   1.154 +        return;
   1.155 +    }
   1.156 +    if (gHeapInUse) {
   1.157 +        *status = U_INVALID_STATE_ERROR;
   1.158 +        return;
   1.159 +    }
   1.160 +    pContext  = context;
   1.161 +    pAlloc    = a;
   1.162 +    pRealloc  = r;
   1.163 +    pFree     = f;
   1.164 +}
   1.165 +
   1.166 +
   1.167 +U_CFUNC UBool cmemory_cleanup(void) {
   1.168 +    pContext   = NULL;
   1.169 +    pAlloc     = NULL;
   1.170 +    pRealloc   = NULL;
   1.171 +    pFree      = NULL;
   1.172 +    gHeapInUse = FALSE;
   1.173 +    return TRUE;
   1.174 +}
   1.175 +
   1.176 +
   1.177 +/*
   1.178 + *   gHeapInUse
   1.179 + *       Return True if ICU has allocated any memory.
   1.180 + *       Used by u_SetMutexFunctions() and similar to verify that ICU has not
   1.181 + *               been used, that it is in a pristine initial state.
   1.182 + */
   1.183 +U_CFUNC UBool cmemory_inUse() {
   1.184 +    return gHeapInUse;
   1.185 +}
   1.186 +

mercurial