]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/cmemory.c
ICU-57131.0.1.tar.gz
[apple/icu.git] / icuSources / common / cmemory.c
CommitLineData
b75a7d8f
A
1/*
2******************************************************************************
3*
b331163b 4* Copyright (C) 2002-2015, International Business Machines
b75a7d8f
A
5* Corporation and others. All Rights Reserved.
6*
7******************************************************************************
8*
9* File cmemory.c ICU Heap allocation.
10* All ICU heap allocation, both for C and C++ new of ICU
11* class types, comes through these functions.
12*
13* If you have a need to replace ICU allocation, this is the
14* place to do it.
15*
16* Note that uprv_malloc(0) returns a non-NULL pointer, and
17* that a subsequent free of that pointer value is a NOP.
18*
19******************************************************************************
20*/
374ca955 21#include "unicode/uclean.h"
73c04bcf 22#include "cmemory.h"
4388f060 23#include "putilimp.h"
51004dcb 24#include "uassert.h"
73c04bcf 25#include <stdlib.h>
b75a7d8f 26
51004dcb 27/* uprv_malloc(0) returns a pointer to this read-only data. */
b75a7d8f
A
28static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0};
29
374ca955
A
30/* Function Pointers for user-supplied heap functions */
31static const void *pContext;
32static UMemAllocFn *pAlloc;
33static UMemReallocFn *pRealloc;
34static UMemFreeFn *pFree;
35
51004dcb
A
36#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
37#include <stdio.h>
38static int n=0;
39static long b=0;
40#endif
41
42#if U_DEBUG
43
44static char gValidMemorySink = 0;
45
46U_CAPI void uprv_checkValidMemory(const void *p, size_t n) {
47 /*
48 * Access the memory to ensure that it's all valid.
49 * Load and save a computed value to try to ensure that the compiler
50 * does not throw away the whole loop.
51 * A thread analyzer might complain about un-mutexed access to gValidMemorySink
52 * which is true but harmless because no one ever uses the value in gValidMemorySink.
53 */
54 const char *s = (const char *)p;
55 char c = gValidMemorySink;
56 size_t i;
57 U_ASSERT(p != NULL);
58 for(i = 0; i < n; ++i) {
59 c ^= s[i];
60 }
61 gValidMemorySink = c;
62}
63
64#endif /* U_DEBUG */
65
b75a7d8f
A
66U_CAPI void * U_EXPORT2
67uprv_malloc(size_t s) {
51004dcb
A
68#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
69#if 1
70 putchar('>');
71 fflush(stdout);
72#else
73 fprintf(stderr,"MALLOC\t#%d\t%ul bytes\t%ul total\n", ++n,s,(b+=s)); fflush(stderr);
74#endif
75#endif
b75a7d8f 76 if (s > 0) {
374ca955
A
77 if (pAlloc) {
78 return (*pAlloc)(pContext, s);
79 } else {
4388f060 80 return uprv_default_malloc(s);
374ca955 81 }
b75a7d8f
A
82 } else {
83 return (void *)zeroMem;
84 }
85}
86
87U_CAPI void * U_EXPORT2
88uprv_realloc(void * buffer, size_t size) {
51004dcb
A
89#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
90 putchar('~');
91 fflush(stdout);
92#endif
b75a7d8f
A
93 if (buffer == zeroMem) {
94 return uprv_malloc(size);
95 } else if (size == 0) {
374ca955
A
96 if (pFree) {
97 (*pFree)(pContext, buffer);
98 } else {
4388f060 99 uprv_default_free(buffer);
374ca955 100 }
b75a7d8f
A
101 return (void *)zeroMem;
102 } else {
374ca955
A
103 if (pRealloc) {
104 return (*pRealloc)(pContext, buffer, size);
105 } else {
4388f060 106 return uprv_default_realloc(buffer, size);
374ca955 107 }
b75a7d8f
A
108 }
109}
110
111U_CAPI void U_EXPORT2
112uprv_free(void *buffer) {
51004dcb
A
113#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
114 putchar('<');
115 fflush(stdout);
116#endif
b75a7d8f 117 if (buffer != zeroMem) {
374ca955
A
118 if (pFree) {
119 (*pFree)(pContext, buffer);
120 } else {
4388f060 121 uprv_default_free(buffer);
374ca955
A
122 }
123 }
124}
125
4388f060
A
126U_CAPI void * U_EXPORT2
127uprv_calloc(size_t num, size_t size) {
128 void *mem = NULL;
129 size *= num;
130 mem = uprv_malloc(size);
131 if (mem) {
132 uprv_memset(mem, 0, size);
133 }
134 return mem;
135}
136
374ca955
A
137U_CAPI void U_EXPORT2
138u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, UErrorCode *status)
139{
140 if (U_FAILURE(*status)) {
141 return;
142 }
143 if (a==NULL || r==NULL || f==NULL) {
144 *status = U_ILLEGAL_ARGUMENT_ERROR;
145 return;
146 }
374ca955
A
147 pContext = context;
148 pAlloc = a;
149 pRealloc = r;
150 pFree = f;
151}
152
153
154U_CFUNC UBool cmemory_cleanup(void) {
155 pContext = NULL;
156 pAlloc = NULL;
157 pRealloc = NULL;
158 pFree = NULL;
374ca955
A
159 return TRUE;
160}