source: git/omalloc/omAllocSystem.c @ f3b65d

fieker-DuValspielwiese
Last change on this file since f3b65d was 79e9d1, checked in by Hans Schoenemann <hannes@…>, 5 years ago
fix: xalloc for OsX: malloc.h vs. malloc/malloc.h
  • Property mode set to 100644
File size: 10.1 KB
Line 
1/*******************************************************************
2 *  File:    omAllocSystem.c
3 *  Purpose: implementation of main lowl-level alloc functions
4 *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
5 *  Created: 11/99
6 *******************************************************************/
7#ifndef OM_ALLOC_SYSTEM_C
8#define OM_ALLOC_SYSTEM_C
9
10#include <unistd.h>
11#include <limits.h>
12
13
14#include "omConfig.h"
15
16#ifdef HAVE_OMALLOC
17#include "omDefaultConfig.h"
18#include "omMalloc.h"
19#include "omalloc.h"
20/* include after omMalloc.h */
21#include <string.h>
22
23#define OM_MALLOC_FROM_SYSTEM   OM_MALLOC_MALLOC
24#define OM_REALLOC_FROM_SYSTEM  OM_MALLOC_REALLOC
25#define OM_FREE_TO_SYSTEM       OM_MALLOC_FREE
26
27/*******************************************************************
28 *
29 *  AllocLarge/FreeLarge if malloc can not return sizeof(addr)
30 *
31 *******************************************************************/
32/* allocation of large addr */
33#if defined(HAVE_MALLOC_SIZE)
34  #ifdef HAVE_MALLOC_H
35  #include <malloc.h>
36  #elif defined(HAVE_MALLOC_MALLOC_H)
37  #include <malloc/malloc.h>
38  #endif
39  #define _omSizeOfLargeAddr(addr) (malloc_size(addr))
40#elif defined(HAVE_MALLOC_USABLE_SIZE)
41  #include <stdlib.h>
42  #define _omSizeOfLargeAddr(addr) (malloc_usable_size(addr))
43#else
44void* omAllocLarge(size_t size)
45{
46  char* addr;
47  size = OM_ALIGN_SIZE(size);
48  addr = omAllocFromSystem(size + SIZEOF_STRICT_ALIGNMENT);
49  *((size_t*) addr) = size;
50  return (void *)(addr + SIZEOF_STRICT_ALIGNMENT);
51}
52
53void* omReallocLarge(void* old_addr, size_t new_size)
54{
55  char* _old_addr;
56  char* new_addr;
57
58  omAssume(omIsLargeAddr(old_addr));
59
60  new_size = OM_ALIGN_SIZE(new_size);
61  _old_addr = (char *)old_addr - SIZEOF_STRICT_ALIGNMENT;
62  new_addr = omReallocSizeFromSystem(_old_addr,
63                                     *((size_t*) _old_addr) + SIZEOF_STRICT_ALIGNMENT,
64                                     new_size + SIZEOF_STRICT_ALIGNMENT);
65  *((size_t*) new_addr) = new_size;
66  return (void *)(new_addr + SIZEOF_STRICT_ALIGNMENT);
67}
68
69void omFreeLarge(void* addr)
70{
71  char* _addr = (char *)addr - SIZEOF_STRICT_ALIGNMENT;
72  omFreeSizeToSystem(_addr, *((size_t*) _addr) + SIZEOF_STRICT_ALIGNMENT);
73}
74
75#define _omSizeOfLargeAddr(addr)  (*((size_t*) ((char*) addr - SIZEOF_STRICT_ALIGNMENT)))
76#endif /* HAVE_MALLOC_SIZE/HAVE_MALLOC_USABLE_SIZE */
77
78void* omAlloc0Large(size_t size)
79{
80  void* addr = omAllocLarge(size);
81  memset(addr, 0, size);
82  return addr;
83}
84
85void* omRealloc0Large(void* old_addr, size_t new_size)
86{
87  size_t old_size;
88  char* new_addr;
89
90  omAssume(!omIsBinPageAddr(old_addr));
91
92  old_size = omSizeOfLargeAddr(old_addr);
93
94  new_addr = omReallocLarge(old_addr, new_size);
95  new_size = omSizeOfLargeAddr(new_addr);
96  if (new_size > old_size)
97    memset(new_addr + old_size, 0, new_size - old_size);
98  return (void *)new_addr;
99}
100
101size_t omSizeOfLargeAddr(void* addr)
102{
103  return _omSizeOfLargeAddr((char *)addr);
104}
105
106size_t omSizeOfAddr(const void* addr)
107{
108  /*if (addr==NULL) return 0; */
109
110  return (omIsBinPageAddr(addr) ?
111#ifdef OM_HAVE_TRACK
112          (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr((char *)addr) : omSizeOfBinAddr(addr)) :
113#else
114          omSizeOfBinAddr(addr) :
115#endif
116          omSizeOfLargeAddr((char *)addr));
117}
118
119size_t omSizeWOfAddr(void* addr)
120{
121
122  return (omIsBinPageAddr(addr) ?
123#ifdef OM_HAVE_TRACK
124          (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr(addr) >> LOG_SIZEOF_LONG : omSizeWOfBinAddr(addr)) :
125#else
126          omSizeWOfBinAddr(addr) :
127#endif
128          omSizeOfLargeAddr(addr) >> LOG_SIZEOF_LONG);
129}
130
131/*******************************************************************
132 *
133 *  Valloc
134 *
135 *******************************************************************/
136#ifdef OM_HAVE_VALLOC_MMAP
137
138#include "omMmap.c"
139
140#define OM_VALLOC_FROM_SYSTEM   omVallocMmap
141#define OM_VFREE_TO_SYSTEM      omVfreeMmap
142
143#elif defined(OM_HAVE_VALLOC_MALLOC)
144
145#define OM_VALLOC_FROM_SYSTEM OM_MALLOC_VALLOC
146#define OM_VFREE_TO_SYSTEM    OM_MALLOC_VFREE
147
148#else
149
150#define OM_VALLOC_FROM_SYSTEM   omEmulateValloc
151#define OM_VFREE_TO_SYSTEM      omEmulateVfree
152
153#define OM_ALIGN_PAGE(addr) ( ((long)addr + (SIZEOF_SYSTEM_PAGE -1)) & ~(SIZEOF_SYSTEM_PAGE - 1))
154/* now we implement an emulation */
155void* omEmulateValloc(size_t size)
156{
157  void* addr;
158  size_t padding = SIZEOF_VOIDP;
159  size = OM_ALIGN_SIZE(size);
160  while (1)
161  {
162    addr = OM_MALLOC_FROM_SYSTEM(size + padding);
163    if (addr == NULL) return NULL;
164    if ((OM_ALIGN_PAGE(addr) + SIZEOF_VOIDP) - (long) addr <= padding)
165    {
166      void* ret_addr = (void*) OM_ALIGN_PAGE(addr);
167      *((void**) ((void*) ret_addr + size)) = addr;
168      return ret_addr;
169    }
170    else
171    {
172      OM_FREE_TO_SYSTEM(addr);
173      padding = padding << 1;
174    }
175  }
176}
177
178void omEmulateVfree(void* addr, size_t size)
179{
180  size = OM_ALIGN_SIZE(size);
181  OM_FREE_TO_SYSTEM( *((void**) ((void*) addr + size)) );
182}
183#endif /* OM_HAVE_VALLOC_MMAP */
184
185/*******************************************************************
186 *
187 *  System-level Alloc/Free
188 *
189 *******************************************************************/
190void* omAllocFromSystem(size_t size)
191{
192  void* ptr;
193
194  ptr = OM_MALLOC_FROM_SYSTEM(size);
195  if (ptr == NULL)
196  {
197    OM_MEMORY_LOW_HOOK();
198    ptr = OM_MALLOC_FROM_SYSTEM(size);
199    if (ptr == NULL)
200    {
201      OM_OUT_OF_MEMORY_HOOK();
202      exit(1);
203    }
204  }
205#if defined(HAVE_MALLOC_SIZE) || defined(HAVE_MALLOC_USABLE_SIZE)
206  size=_omSizeOfLargeAddr(ptr);
207#else
208  size=omSizeOfAddr(ptr);
209#endif
210#ifndef OM_NDEBUG
211  if (((unsigned long) ptr) + size > om_MaxAddr)
212    om_MaxAddr = ((unsigned long) ptr) + size;
213  if (((unsigned long) ptr) < om_MinAddr)
214    om_MinAddr = ((unsigned long) ptr);
215#endif
216
217  om_Info.CurrentBytesFromMalloc += size;
218  if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc)
219  {
220    om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc;
221#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
222    if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
223      om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
224#endif
225#if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
226    if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size;
227    if (om_Info.MaxBytesFromMalloc
228#ifndef OM_HAVE_VALLOC_MMAP
229        + om_Info.CurrentBytesFromValloc
230#endif
231        > om_Info.MaxBytesSbrk)
232    {
233      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
234    }
235#endif
236  }
237  OM_MALLOC_HOOK(size);
238  return ptr;
239}
240
241void* omReallocFromSystem(void* addr, size_t newsize)
242{
243  return omReallocSizeFromSystem(addr, omSizeOfAddr(addr), newsize);
244}
245
246void* omReallocSizeFromSystem(void* addr, size_t oldsize, size_t newsize)
247{
248  void* res;
249
250  /*oldsize=omSizeOfLargeAddr(addr);*/
251  res = OM_REALLOC_FROM_SYSTEM(addr, newsize);
252  if (res == NULL)
253  {
254    OM_MEMORY_LOW_HOOK();
255    /* Can do a realloc again: manpage reads:
256       "If realloc() fails the original block is left untouched -
257       it is not freed or moved." */
258    res = OM_REALLOC_FROM_SYSTEM(addr, newsize);
259    if (res == NULL)
260    {
261      OM_OUT_OF_MEMORY_HOOK();
262      /* should never get here */
263      omAssume(0);
264      exit(1);
265    }
266  }
267  /*newsize=omSizeOfAddr(res);*/
268
269#ifndef OM_NDEBUG
270  if (((unsigned long) res) + newsize > om_MaxAddr)
271    om_MaxAddr = ((unsigned long) res) + newsize;
272  if (((unsigned long) res) < om_MinAddr)
273    om_MinAddr = ((unsigned long) res);
274#endif
275
276  om_Info.CurrentBytesFromMalloc += (long) newsize - (long) oldsize;
277
278
279  if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc)
280  {
281    om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc;
282#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
283    if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
284      om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
285#endif
286#if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
287    if (om_Info.MaxBytesFromMalloc
288#ifndef OM_HAVE_VALLOC_MMAP
289        + om_Info.CurrentBytesFromValloc
290#endif
291        > om_Info.MaxBytesSbrk)
292    {
293      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
294    }
295#endif
296  }
297
298  OM_REALLOC_HOOK(oldsize, newsize);
299  return res;
300}
301
302void omFreeToSystem(void* addr)
303{
304  omFreeSizeToSystem(addr, omSizeOfAddr(addr));
305}
306
307void omFreeSizeToSystem(void* addr, size_t size)
308{
309  OM_FREE_TO_SYSTEM( addr );
310  om_Info.CurrentBytesFromMalloc -= size;
311  OM_FREE_HOOK(size);
312}
313
314void* _omVallocFromSystem(size_t size, int fail)
315{
316  void* page = OM_VALLOC_FROM_SYSTEM(size);
317  if (page == NULL)
318  {
319    OM_MEMORY_LOW_HOOK();
320    page = OM_VALLOC_FROM_SYSTEM(size);
321    if (page == NULL)
322    {
323      if (fail) return NULL;
324      else
325      {
326        OM_OUT_OF_MEMORY_HOOK();
327        /* should never get here */
328        omAssume(0);
329        exit(1);
330      }
331    }
332  }
333
334#ifndef OM_NDEBUG
335  if (((unsigned long) page) + size > om_MaxAddr)
336    om_MaxAddr = ((unsigned long) page) + size;
337  if (((unsigned long) page) < om_MinAddr)
338    om_MinAddr = ((unsigned long) page);
339#endif
340
341  omAssume(omIsAddrPageAligned(page));
342  om_Info.CurrentBytesFromValloc += size;
343  if (om_Info.CurrentBytesFromValloc > om_Info.MaxBytesFromValloc)
344  {
345    om_Info.MaxBytesFromValloc = om_Info.CurrentBytesFromValloc;
346#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
347    if (om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
348      om_Info.MaxBytesSystem = om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
349#endif
350#if defined(HAVE_SBRK) && !defined(OM_HAVE_VALLOC_MMAP) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
351    if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size;
352    if (om_Info.CurrentBytesFromMalloc + om_Info.CurrentBytesFromValloc > om_Info.MaxBytesSbrk)
353    {
354      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
355      omAssume(om_Info.MaxBytesSbrk >= om_Info.CurrentBytesFromMalloc
356               + om_Info.CurrentBytesFromValloc);
357    }
358#endif
359  }
360  OM_VALLOC_HOOK(size);
361  return page;
362}
363
364void omVfreeToSystem(void* page, size_t size)
365{
366  omAssume(omIsAddrPageAligned(page));
367  OM_VFREE_TO_SYSTEM(page, size);
368  om_Info.CurrentBytesFromValloc  -= size;
369  OM_VFREE_HOOK(size);
370}
371
372#endif /*HAVE_OMALLOC*/
373#endif /* OM_ALLOC_SYSTEM_C */
Note: See TracBrowser for help on using the repository browser.